Skip to content

Commit 8b1d0e4

Browse files
committed
Added Account Webhooks
1 parent cb71222 commit 8b1d0e4

9 files changed

Lines changed: 621 additions & 0 deletions
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
package com.mailgun.api.v1;
2+
3+
import com.mailgun.api.MailgunApi;
4+
import com.mailgun.enums.ApiVersion;
5+
import com.mailgun.model.webhooks.AccountWebhook;
6+
import com.mailgun.model.webhooks.AccountWebhookCreatedResult;
7+
import com.mailgun.model.webhooks.AccountWebhookListResult;
8+
import com.mailgun.model.webhooks.AccountWebhookRequest;
9+
import com.mailgun.model.webhooks.AccountWebhooksDeleteQuery;
10+
import com.mailgun.model.webhooks.AccountWebhooksListQuery;
11+
import feign.Headers;
12+
import feign.Param;
13+
import feign.QueryMap;
14+
import feign.RequestLine;
15+
import feign.Response;
16+
17+
/**
18+
* Account Webhooks API (v1): create, retrieve, update, and delete account-level webhooks.
19+
* Account-level webhooks are configured independently for US and EU regions.
20+
* When triggered, webhook URLs are deduplicated by event type across account and domain levels.
21+
* Note: Webhook changes can take up to 10 minutes to become effective due to caching.
22+
*
23+
* @see <a href="https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-webhooks/get-v1-webhooks.md">List account-level webhooks</a>
24+
* @see <a href="https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-webhooks/post-v1-webhooks.md">Create an account-level webhook</a>
25+
* @see <a href="https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-webhooks/put-v1-webhooks--webhook-id-.md">Update an account-level webhook</a>
26+
* @see <a href="https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-webhooks/delete-v1-webhooks.md">Delete account-level webhooks</a>
27+
* @see <a href="https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-webhooks/get-v1-webhooks--webhook-id-.md">Get account-level webhook by ID</a>
28+
* @see <a href="https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-webhooks/delete-v1-webhooks--webhook-id-.md">Delete account-level webhook by ID</a>
29+
*/
30+
@Headers("Accept: application/json")
31+
public interface MailgunAccountWebhooksApi extends MailgunApi {
32+
33+
static ApiVersion getApiVersion() {
34+
return ApiVersion.V_1;
35+
}
36+
37+
/**
38+
* Retrieve all account-level webhooks.
39+
*
40+
* @return {@link AccountWebhookListResult}
41+
*/
42+
@RequestLine("GET /webhooks")
43+
AccountWebhookListResult getAllWebhooks();
44+
45+
/**
46+
* Retrieve all account-level webhooks (raw response).
47+
*
48+
* @return {@link Response}
49+
*/
50+
@RequestLine("GET /webhooks")
51+
Response getAllWebhooksFeignResponse();
52+
53+
/**
54+
* Retrieve account-level webhooks filtered by specific webhook IDs.
55+
*
56+
* @param query {@link AccountWebhooksListQuery} optional filter by comma-separated webhook IDs
57+
* @return {@link AccountWebhookListResult}
58+
*/
59+
@RequestLine("GET /webhooks")
60+
AccountWebhookListResult getAllWebhooks(@QueryMap AccountWebhooksListQuery query);
61+
62+
/**
63+
* Retrieve account-level webhooks filtered by specific webhook IDs (raw response).
64+
*
65+
* @param query {@link AccountWebhooksListQuery} optional filter by comma-separated webhook IDs
66+
* @return {@link Response}
67+
*/
68+
@RequestLine("GET /webhooks")
69+
Response getAllWebhooksFeignResponse(@QueryMap AccountWebhooksListQuery query);
70+
71+
/**
72+
* Retrieve a specific account-level webhook by its ID.
73+
*
74+
* @param webhookId the webhook ID to retrieve
75+
* @return {@link AccountWebhook}
76+
*/
77+
@RequestLine("GET /webhooks/{webhook_id}")
78+
AccountWebhook getWebhook(@Param("webhook_id") String webhookId);
79+
80+
/**
81+
* Retrieve a specific account-level webhook by its ID (raw response).
82+
*
83+
* @param webhookId the webhook ID to retrieve
84+
* @return {@link Response}
85+
*/
86+
@RequestLine("GET /webhooks/{webhook_id}")
87+
Response getWebhookFeignResponse(@Param("webhook_id") String webhookId);
88+
89+
/**
90+
* Create an account-level webhook.
91+
*
92+
* @param request {@link AccountWebhookRequest} with url, event_types, and optional description
93+
* @return {@link AccountWebhookCreatedResult} containing the new webhook ID
94+
*/
95+
@Headers("Content-Type: multipart/form-data")
96+
@RequestLine("POST /webhooks")
97+
AccountWebhookCreatedResult createWebhook(AccountWebhookRequest request);
98+
99+
/**
100+
* Create an account-level webhook (raw response).
101+
*
102+
* @param request {@link AccountWebhookRequest} with url, event_types, and optional description
103+
* @return {@link Response}
104+
*/
105+
@Headers("Content-Type: multipart/form-data")
106+
@RequestLine("POST /webhooks")
107+
Response createWebhookFeignResponse(AccountWebhookRequest request);
108+
109+
/**
110+
* Update an existing account-level webhook by replacing its URL, description, and event types.
111+
*
112+
* @param webhookId the webhook ID to update
113+
* @param request {@link AccountWebhookRequest} with the replacement configuration
114+
* @return {@link AccountWebhookCreatedResult} containing the webhook ID
115+
*/
116+
@Headers("Content-Type: multipart/form-data")
117+
@RequestLine("PUT /webhooks/{webhook_id}")
118+
AccountWebhookCreatedResult updateWebhook(@Param("webhook_id") String webhookId, AccountWebhookRequest request);
119+
120+
/**
121+
* Update an existing account-level webhook (raw response).
122+
*
123+
* @param webhookId the webhook ID to update
124+
* @param request {@link AccountWebhookRequest} with the replacement configuration
125+
* @return {@link Response}
126+
*/
127+
@Headers("Content-Type: multipart/form-data")
128+
@RequestLine("PUT /webhooks/{webhook_id}")
129+
Response updateWebhookFeignResponse(@Param("webhook_id") String webhookId, AccountWebhookRequest request);
130+
131+
/**
132+
* Delete account-level webhooks. Either set {@code all=true} to remove all webhooks,
133+
* or provide {@code webhook_ids} to delete specific ones.
134+
*
135+
* @param query {@link AccountWebhooksDeleteQuery} specifying which webhooks to delete
136+
*/
137+
@RequestLine("DELETE /webhooks")
138+
void deleteWebhooks(@QueryMap AccountWebhooksDeleteQuery query);
139+
140+
/**
141+
* Delete account-level webhooks (raw response).
142+
*
143+
* @param query {@link AccountWebhooksDeleteQuery} specifying which webhooks to delete
144+
* @return {@link Response}
145+
*/
146+
@RequestLine("DELETE /webhooks")
147+
Response deleteWebhooksFeignResponse(@QueryMap AccountWebhooksDeleteQuery query);
148+
149+
/**
150+
* Delete a specific account-level webhook by its ID.
151+
*
152+
* @param webhookId the webhook ID to delete
153+
*/
154+
@RequestLine("DELETE /webhooks/{webhook_id}")
155+
void deleteWebhook(@Param("webhook_id") String webhookId);
156+
157+
/**
158+
* Delete a specific account-level webhook by its ID (raw response).
159+
*
160+
* @param webhookId the webhook ID to delete
161+
* @return {@link Response}
162+
*/
163+
@RequestLine("DELETE /webhooks/{webhook_id}")
164+
Response deleteWebhookFeignResponse(@Param("webhook_id") String webhookId);
165+
166+
}

src/main/java/com/mailgun/enums/WebhookName.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99
*/
1010
public enum WebhookName implements EnumWithValue {
1111

12+
/**
13+
* <p>
14+
* Tracking Accepted messages.
15+
* </p>
16+
*/
17+
ACCEPTED("accepted"),
18+
1219
/**
1320
* <p>
1421
* Tracking Clicks.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.mailgun.model.webhooks;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import lombok.Builder;
6+
import lombok.Value;
7+
import lombok.extern.jackson.Jacksonized;
8+
9+
import java.util.List;
10+
11+
/**
12+
* Account-level webhook details returned by the Account Webhooks API.
13+
*
14+
* @see <a href="https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-webhooks/get-v1-webhooks--webhook-id-.md">Get account-level webhook by ID</a>
15+
*/
16+
@Value
17+
@Jacksonized
18+
@Builder
19+
@JsonIgnoreProperties(ignoreUnknown = true)
20+
public class AccountWebhook {
21+
22+
/**
23+
* Unique identifier for the webhook.
24+
*/
25+
@JsonProperty("webhook_id")
26+
String webhookId;
27+
28+
/**
29+
* User-provided description of the webhook.
30+
*/
31+
String description;
32+
33+
/**
34+
* The endpoint URL where webhook events are delivered.
35+
*/
36+
String url;
37+
38+
/**
39+
* List of event types that trigger this webhook.
40+
*/
41+
@JsonProperty("event_types")
42+
List<String> eventTypes;
43+
44+
/**
45+
* Timestamp indicating when the webhook was created in RFC3339 format.
46+
*/
47+
@JsonProperty("created_at")
48+
String createdAt;
49+
50+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.mailgun.model.webhooks;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import com.fasterxml.jackson.annotation.JsonProperty;
5+
import lombok.Builder;
6+
import lombok.Value;
7+
import lombok.extern.jackson.Jacksonized;
8+
9+
/**
10+
* Response returned when an account-level webhook is created or updated.
11+
*
12+
* @see <a href="https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-webhooks/post-v1-webhooks.md">Create an account-level webhook</a>
13+
* @see <a href="https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-webhooks/put-v1-webhooks--webhook-id-.md">Update an account-level webhook</a>
14+
*/
15+
@Value
16+
@Jacksonized
17+
@Builder
18+
@JsonIgnoreProperties(ignoreUnknown = true)
19+
public class AccountWebhookCreatedResult {
20+
21+
/**
22+
* Unique identifier for the created or updated webhook.
23+
*/
24+
@JsonProperty("webhook_id")
25+
String webhookId;
26+
27+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.mailgun.model.webhooks;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import lombok.Builder;
5+
import lombok.Value;
6+
import lombok.extern.jackson.Jacksonized;
7+
8+
import java.util.List;
9+
10+
/**
11+
* Response wrapper for the list of account-level webhooks.
12+
*
13+
* @see <a href="https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-webhooks/get-v1-webhooks.md">List account-level webhooks</a>
14+
*/
15+
@Value
16+
@Jacksonized
17+
@Builder
18+
@JsonIgnoreProperties(ignoreUnknown = true)
19+
public class AccountWebhookListResult {
20+
21+
/**
22+
* List of account-level webhooks.
23+
*/
24+
List<AccountWebhook> webhooks;
25+
26+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.mailgun.model.webhooks;
2+
3+
import feign.form.FormProperty;
4+
import lombok.Builder;
5+
import lombok.EqualsAndHashCode;
6+
import lombok.Getter;
7+
import lombok.Singular;
8+
import lombok.ToString;
9+
import org.apache.commons.collections4.CollectionUtils;
10+
import org.apache.commons.lang3.StringUtils;
11+
12+
import java.util.Set;
13+
14+
import static com.mailgun.util.Constants.FIELD_CANNOT_BE_NULL_OR_EMPTY;
15+
16+
/**
17+
* Request for creating or updating an account-level webhook.
18+
* Both create (POST /v1/webhooks) and update (PUT /v1/webhooks/{webhook_id}) share the same fields.
19+
* Use the builder's {@code eventType(String)} method to add individual event types,
20+
* e.g. {@code eventType(WebhookName.CLICKED.getValue())}.
21+
*
22+
* @see <a href="https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-webhooks/post-v1-webhooks.md">Create an account-level webhook</a>
23+
* @see <a href="https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-webhooks/put-v1-webhooks--webhook-id-.md">Update an account-level webhook</a>
24+
*/
25+
@Getter
26+
@ToString
27+
@EqualsAndHashCode
28+
@Builder
29+
public class AccountWebhookRequest {
30+
31+
/**
32+
* Optional description for the webhook.
33+
*/
34+
@FormProperty("description")
35+
String description;
36+
37+
/**
38+
* Event types to subscribe to (e.g. "accepted", "clicked", "delivered").
39+
* Use the builder's singular {@code eventType(String)} to add individual types,
40+
* or pass {@link com.mailgun.enums.WebhookName#getValue()} for type safety.
41+
* Maximum of 3 unique URLs per event type.
42+
*/
43+
@Singular
44+
@FormProperty("event_types")
45+
Set<String> eventTypes;
46+
47+
/**
48+
* URL for the webhook to be sent to.
49+
*/
50+
@FormProperty("url")
51+
String url;
52+
53+
public static AccountWebhookRequestBuilder builder() {
54+
return new CustomAccountWebhookRequestBuilder();
55+
}
56+
57+
private static class CustomAccountWebhookRequestBuilder extends AccountWebhookRequestBuilder {
58+
59+
@Override
60+
public AccountWebhookRequest build() {
61+
if (CollectionUtils.isEmpty(super.eventTypes)) {
62+
throw new IllegalArgumentException(String.format(FIELD_CANNOT_BE_NULL_OR_EMPTY, "event_types"));
63+
}
64+
if (StringUtils.isBlank(super.url)) {
65+
throw new IllegalArgumentException(String.format(FIELD_CANNOT_BE_NULL_OR_EMPTY, "url"));
66+
}
67+
return super.build();
68+
}
69+
}
70+
71+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.mailgun.model.webhooks;
2+
3+
import lombok.Builder;
4+
import lombok.Value;
5+
import lombok.extern.jackson.Jacksonized;
6+
7+
/**
8+
* Query parameters for bulk-deleting account-level webhooks (DELETE /v1/webhooks).
9+
* Either {@code webhook_ids} or {@code all} must be provided. If both are set,
10+
* only the specified {@code webhook_ids} are deleted.
11+
*
12+
* @see <a href="https://documentation.mailgun.com/docs/mailgun/api-reference/send/mailgun/account-webhooks/delete-v1-webhooks.md">Delete account-level webhooks</a>
13+
*/
14+
@Value
15+
@Jacksonized
16+
@Builder
17+
public class AccountWebhooksDeleteQuery {
18+
19+
/**
20+
* Comma-separated list of webhook IDs to delete.
21+
* If provided, only these specific webhooks will be deleted.
22+
*/
23+
// field name matches the query param name as required by FieldQueryMapEncoder
24+
String webhook_ids;
25+
26+
/**
27+
* Set to {@code true} to delete all account-level webhooks.
28+
* Acts as a safety mechanism to prevent accidental deletion.
29+
*/
30+
Boolean all;
31+
32+
}

0 commit comments

Comments
 (0)