Skip to content

Commit 043e73e

Browse files
committed
Add Stats API
1 parent 1136e25 commit 043e73e

File tree

17 files changed

+569
-3
lines changed

17 files changed

+569
-3
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package io.mailtrap.examples.general;
2+
3+
import io.mailtrap.api.stats.StatsFilter;
4+
import io.mailtrap.config.MailtrapConfig;
5+
import io.mailtrap.factory.MailtrapClientFactory;
6+
7+
public class StatsExample {
8+
9+
private static final String TOKEN = "<YOUR MAILTRAP TOKEN>";
10+
private static final long ACCOUNT_ID = 1L;
11+
12+
// Set these to the desired date range (format: YYYY-MM-DD)
13+
private static final String START_DATE = "<START_DATE>";
14+
private static final String END_DATE = "<END_DATE>";
15+
16+
public static void main(String[] args) {
17+
final var config = new MailtrapConfig.Builder()
18+
.token(TOKEN)
19+
.build();
20+
21+
final var client = MailtrapClientFactory.createMailtrapClient(config);
22+
23+
final var filter = StatsFilter.builder()
24+
.startDate(START_DATE)
25+
.endDate(END_DATE)
26+
.build();
27+
28+
System.out.println("=== Aggregated Stats ===");
29+
System.out.println(client.sendingApi().stats().getStats(ACCOUNT_ID, filter));
30+
31+
System.out.println("\n=== Stats by Domains ===");
32+
System.out.println(client.sendingApi().stats().byDomain(ACCOUNT_ID, filter));
33+
34+
System.out.println("\n=== Stats by Categories ===");
35+
System.out.println(client.sendingApi().stats().byCategory(ACCOUNT_ID, filter));
36+
37+
System.out.println("\n=== Stats by Email Service Providers ===");
38+
System.out.println(client.sendingApi().stats().byEmailServiceProvider(ACCOUNT_ID, filter));
39+
40+
System.out.println("\n=== Stats by Date ===");
41+
System.out.println(client.sendingApi().stats().byDate(ACCOUNT_ID, filter));
42+
}
43+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package io.mailtrap.api.stats;
2+
3+
import io.mailtrap.model.response.stats.SendingStatGroupResponse;
4+
import io.mailtrap.model.response.stats.SendingStatsResponse;
5+
6+
import java.util.List;
7+
8+
/**
9+
* Interface representing the Mailtrap API for interaction with sending statistics
10+
*/
11+
public interface Stats {
12+
13+
/**
14+
* Get aggregated sending stats
15+
*
16+
* @param accountId unique account ID
17+
* @param filter stats filter parameters
18+
* @return aggregated sending statistics
19+
*/
20+
SendingStatsResponse getStats(long accountId, StatsFilter filter);
21+
22+
/**
23+
* Get sending stats grouped by domains
24+
*
25+
* @param accountId unique account ID
26+
* @param filter stats filter parameters
27+
* @return list of sending statistics grouped by domain
28+
*/
29+
List<SendingStatGroupResponse> byDomain(long accountId, StatsFilter filter);
30+
31+
/**
32+
* Get sending stats grouped by categories
33+
*
34+
* @param accountId unique account ID
35+
* @param filter stats filter parameters
36+
* @return list of sending statistics grouped by category
37+
*/
38+
List<SendingStatGroupResponse> byCategory(long accountId, StatsFilter filter);
39+
40+
/**
41+
* Get sending stats grouped by email service providers
42+
*
43+
* @param accountId unique account ID
44+
* @param filter stats filter parameters
45+
* @return list of sending statistics grouped by email service provider
46+
*/
47+
List<SendingStatGroupResponse> byEmailServiceProvider(long accountId, StatsFilter filter);
48+
49+
/**
50+
* Get sending stats grouped by date
51+
*
52+
* @param accountId unique account ID
53+
* @param filter stats filter parameters
54+
* @return list of sending statistics grouped by date
55+
*/
56+
List<SendingStatGroupResponse> byDate(long accountId, StatsFilter filter);
57+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.mailtrap.api.stats;
2+
3+
import io.mailtrap.model.SendingStream;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
6+
import lombok.Data;
7+
import lombok.NoArgsConstructor;
8+
9+
import java.util.List;
10+
11+
@Data
12+
@NoArgsConstructor
13+
@AllArgsConstructor
14+
@Builder
15+
public class StatsFilter {
16+
private String startDate;
17+
private String endDate;
18+
private List<Long> sendingDomainIds;
19+
private List<SendingStream> sendingStreams;
20+
private List<String> categories;
21+
private List<String> emailServiceProviders;
22+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package io.mailtrap.api.stats;
2+
3+
import io.mailtrap.Constants;
4+
import io.mailtrap.api.apiresource.ApiResource;
5+
import io.mailtrap.config.MailtrapConfig;
6+
import io.mailtrap.http.RequestData;
7+
import io.mailtrap.model.response.stats.SendingStatGroupResponse;
8+
import io.mailtrap.model.response.stats.SendingStatsResponse;
9+
10+
import java.util.List;
11+
import java.util.Map;
12+
import java.util.Optional;
13+
14+
import static io.mailtrap.http.RequestData.entry;
15+
16+
public class StatsImpl extends ApiResource implements Stats {
17+
18+
public StatsImpl(final MailtrapConfig config) {
19+
super(config);
20+
this.apiHost = Constants.GENERAL_HOST;
21+
}
22+
23+
@Override
24+
public SendingStatsResponse getStats(final long accountId, final StatsFilter filter) {
25+
return httpClient.get(
26+
buildUrl(accountId, ""),
27+
new RequestData(buildStatsQueryParams(filter)),
28+
SendingStatsResponse.class
29+
);
30+
}
31+
32+
@Override
33+
public List<SendingStatGroupResponse> byDomain(final long accountId, final StatsFilter filter) {
34+
return httpClient.getList(
35+
buildUrl(accountId, "/domains"),
36+
new RequestData(buildStatsQueryParams(filter)),
37+
SendingStatGroupResponse.class
38+
);
39+
}
40+
41+
@Override
42+
public List<SendingStatGroupResponse> byCategory(final long accountId, final StatsFilter filter) {
43+
return httpClient.getList(
44+
buildUrl(accountId, "/categories"),
45+
new RequestData(buildStatsQueryParams(filter)),
46+
SendingStatGroupResponse.class
47+
);
48+
}
49+
50+
@Override
51+
public List<SendingStatGroupResponse> byEmailServiceProvider(final long accountId, final StatsFilter filter) {
52+
return httpClient.getList(
53+
buildUrl(accountId, "/email_service_providers"),
54+
new RequestData(buildStatsQueryParams(filter)),
55+
SendingStatGroupResponse.class
56+
);
57+
}
58+
59+
@Override
60+
public List<SendingStatGroupResponse> byDate(final long accountId, final StatsFilter filter) {
61+
return httpClient.getList(
62+
buildUrl(accountId, "/date"),
63+
new RequestData(buildStatsQueryParams(filter)),
64+
SendingStatGroupResponse.class
65+
);
66+
}
67+
68+
private String buildUrl(final long accountId, final String suffix) {
69+
return String.format(apiHost + "/api/accounts/%d/stats%s", accountId, suffix);
70+
}
71+
72+
private Map<String, ? extends Optional<?>> buildStatsQueryParams(final StatsFilter filter) {
73+
if (filter == null) {
74+
throw new IllegalArgumentException("filter must not be null");
75+
}
76+
if (filter.getStartDate() == null || filter.getStartDate().trim().isEmpty()) {
77+
throw new IllegalArgumentException("startDate must not be null or empty");
78+
}
79+
if (filter.getEndDate() == null || filter.getEndDate().trim().isEmpty()) {
80+
throw new IllegalArgumentException("endDate must not be null or empty");
81+
}
82+
83+
return RequestData.buildQueryParams(
84+
entry("start_date", Optional.ofNullable(filter.getStartDate())),
85+
entry("end_date", Optional.ofNullable(filter.getEndDate())),
86+
entry("sending_domain_ids[]", Optional.ofNullable(filter.getSendingDomainIds())),
87+
entry("sending_streams[]", Optional.ofNullable(filter.getSendingStreams())),
88+
entry("categories[]", Optional.ofNullable(filter.getCategories())),
89+
entry("email_service_providers[]", Optional.ofNullable(filter.getEmailServiceProviders()))
90+
);
91+
}
92+
}

src/main/java/io/mailtrap/client/api/MailtrapEmailSendingApi.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import io.mailtrap.api.sendingdomains.SendingDomains;
44
import io.mailtrap.api.sendingemails.SendingEmails;
5+
import io.mailtrap.api.stats.Stats;
56
import io.mailtrap.api.suppressions.Suppressions;
67
import lombok.Getter;
78
import lombok.RequiredArgsConstructor;
@@ -17,4 +18,5 @@ public class MailtrapEmailSendingApi {
1718
private final SendingEmails emails;
1819
private final SendingDomains domains;
1920
private final Suppressions suppressions;
21+
private final Stats stats;
2022
}

src/main/java/io/mailtrap/factory/MailtrapClientFactory.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import io.mailtrap.api.projects.ProjectsImpl;
2020
import io.mailtrap.api.sendingdomains.SendingDomainsImpl;
2121
import io.mailtrap.api.sendingemails.SendingEmailsImpl;
22+
import io.mailtrap.api.stats.StatsImpl;
2223
import io.mailtrap.api.suppressions.SuppressionsImpl;
2324
import io.mailtrap.api.testingemails.TestingEmailsImpl;
2425
import io.mailtrap.client.MailtrapClient;
@@ -95,8 +96,9 @@ private static MailtrapEmailSendingApi createSendingApi(final MailtrapConfig con
9596
final var emails = new SendingEmailsImpl(config, VALIDATOR);
9697
final var domains = new SendingDomainsImpl(config);
9798
final var suppressions = new SuppressionsImpl(config);
99+
final var stats = new StatsImpl(config);
98100

99-
return new MailtrapEmailSendingApi(emails, domains, suppressions);
101+
return new MailtrapEmailSendingApi(emails, domains, suppressions, stats);
100102
}
101103

102104
private static MailtrapEmailTestingApi createTestingApi(final MailtrapConfig config) {

src/main/java/io/mailtrap/model/response/suppressions/SendingStream.java renamed to src/main/java/io/mailtrap/model/SendingStream.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package io.mailtrap.model.response.suppressions;
1+
package io.mailtrap.model;
22

33
import com.fasterxml.jackson.annotation.JsonCreator;
44
import com.fasterxml.jackson.annotation.JsonValue;
@@ -19,6 +19,11 @@ public String getValue() {
1919
return value;
2020
}
2121

22+
@Override
23+
public String toString() {
24+
return value;
25+
}
26+
2227
@JsonCreator
2328
public static SendingStream fromValue(String value) {
2429
for (SendingStream type : SendingStream.values()) {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package io.mailtrap.model.response.stats;
2+
3+
import com.fasterxml.jackson.annotation.JsonAnySetter;
4+
import lombok.Data;
5+
6+
@Data
7+
public class SendingStatGroupResponse {
8+
9+
private String name;
10+
private Object value;
11+
private SendingStatsResponse stats;
12+
13+
@JsonAnySetter
14+
public void setDynamicField(String key, Object value) {
15+
if (!"stats".equals(key)) {
16+
this.name = key;
17+
this.value = value;
18+
}
19+
}
20+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package io.mailtrap.model.response.stats;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import lombok.Data;
5+
6+
@Data
7+
public class SendingStatsResponse {
8+
9+
@JsonProperty("delivery_count")
10+
private int deliveryCount;
11+
12+
@JsonProperty("delivery_rate")
13+
private double deliveryRate;
14+
15+
@JsonProperty("bounce_count")
16+
private int bounceCount;
17+
18+
@JsonProperty("bounce_rate")
19+
private double bounceRate;
20+
21+
@JsonProperty("open_count")
22+
private int openCount;
23+
24+
@JsonProperty("open_rate")
25+
private double openRate;
26+
27+
@JsonProperty("click_count")
28+
private int clickCount;
29+
30+
@JsonProperty("click_rate")
31+
private double clickRate;
32+
33+
@JsonProperty("spam_count")
34+
private int spamCount;
35+
36+
@JsonProperty("spam_rate")
37+
private double spamRate;
38+
}

src/main/java/io/mailtrap/model/response/suppressions/SuppressionsResponse.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.mailtrap.model.response.suppressions;
22

33
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import io.mailtrap.model.SendingStream;
45
import lombok.Data;
56

67
import java.time.OffsetDateTime;

0 commit comments

Comments
 (0)