Skip to content

Commit e8efbac

Browse files
Merge pull request #35 from ukby1234/email-custom-headers
add custom headers support for emails
2 parents 876cd3a + b6cf1fc commit e8efbac

File tree

7 files changed

+144
-5
lines changed

7 files changed

+144
-5
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ All _notable_ changes to this project will be documented in this file.
55
The format is based on _[Keep a Changelog][keepachangelog]_, and this project
66
adheres to _[Semantic Versioning][semver]_.
77

8+
## [1.1.2] (released: 2024-01-26)
9+
### Updated
10+
- add ability for MailgunMessagesApi to support arbitrary email headers through `.headers`.
11+
812
## [1.1.1] (released: 2023-12-12)
913
### Updated
1014
- add ability for primary accounts to make API calls on behalf of their subaccounts, e.g. sending messages, managing mailing lists, etc.
@@ -67,6 +71,7 @@ adheres to _[Semantic Versioning][semver]_.
6771
- Add Import a list of bounces from CSV file API
6872

6973

74+
[1.1.2]: https://github.com/mailgun/mailgun-java/compare/release/1.1.1...release/1.1.2
7075
[1.1.1]: https://github.com/mailgun/mailgun-java/compare/release/1.1.0...release/1.1.1
7176
[1.1.0]: https://github.com/mailgun/mailgun-java/compare/release/1.0.9...release/1.1.0
7277
[1.0.9]: https://github.com/mailgun/mailgun-java/compare/release/1.0.8...release/1.0.9

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ Add the following to your `pom.xml`:
7676
<dependency>
7777
<groupId>com.mailgun</groupId>
7878
<artifactId>mailgun-java</artifactId>
79-
<version>1.1.1</version>
79+
<version>1.1.2</version>
8080
</dependency>
8181
...
8282
</dependencies>
@@ -85,7 +85,7 @@ Add the following to your `pom.xml`:
8585
Gradle Groovy DSL .
8686

8787
```xml
88-
implementation 'com.mailgun:mailgun-java:1.1.1'
88+
implementation 'com.mailgun:mailgun-java:1.1.2'
8989
```
9090

9191

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.mailgun</groupId>
88
<artifactId>mailgun-java</artifactId>
9-
<version>1.1.1</version>
9+
<version>1.1.2</version>
1010
<packaging>jar</packaging>
1111

1212
<name>${project.groupId}:${project.artifactId}</name>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.mailgun.form;
2+
3+
import java.lang.annotation.Documented;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.Target;
6+
7+
import static java.lang.annotation.ElementType.FIELD;
8+
import static java.lang.annotation.RetentionPolicy.RUNTIME;
9+
10+
@Documented
11+
@Target(FIELD)
12+
@Retention(RUNTIME)
13+
public @interface CustomProperties {
14+
15+
/**
16+
* The name of the property.
17+
*/
18+
String prefix ();
19+
20+
}

src/main/java/com/mailgun/form/FormEncoder.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
import feign.form.util.CharsetUtil;
1717
import lombok.val;
1818

19-
import static feign.form.util.PojoUtil.isUserPojo;
20-
import static feign.form.util.PojoUtil.toMap;
19+
import static com.mailgun.form.PojoUtil.isUserPojo;
20+
import static com.mailgun.form.PojoUtil.toMap;
2121
import static java.util.Arrays.asList;
2222

2323
public class FormEncoder implements Encoder {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package com.mailgun.form;
2+
3+
import feign.form.FormProperty;
4+
import lombok.NoArgsConstructor;
5+
import lombok.NonNull;
6+
import lombok.Setter;
7+
import lombok.SneakyThrows;
8+
import lombok.experimental.FieldDefaults;
9+
import lombok.val;
10+
11+
import java.lang.reflect.Field;
12+
import java.lang.reflect.Type;
13+
import java.rmi.UnexpectedException;
14+
import java.security.AccessController;
15+
import java.security.PrivilegedAction;
16+
import java.util.HashMap;
17+
import java.util.Map;
18+
19+
import static java.lang.reflect.Modifier.isFinal;
20+
import static java.lang.reflect.Modifier.isStatic;
21+
import static lombok.AccessLevel.PRIVATE;
22+
23+
/**
24+
*
25+
* @author Artem Labazin
26+
*/
27+
public final class PojoUtil {
28+
29+
public static boolean isUserPojo (@NonNull Object object) {
30+
val type = object.getClass();
31+
val packageName = type.getPackage().getName();
32+
return !packageName.startsWith("java.");
33+
}
34+
35+
public static boolean isUserPojo (@NonNull Type type) {
36+
val typeName = type.toString();
37+
return !typeName.startsWith("class java.");
38+
}
39+
40+
@SneakyThrows
41+
public static Map<String, Object> toMap (@NonNull Object object) {
42+
val result = new HashMap<String, Object>();
43+
val type = object.getClass();
44+
val setAccessibleAction = new PojoUtil.SetAccessibleAction();
45+
for (val field : type.getDeclaredFields()) {
46+
val modifiers = field.getModifiers();
47+
if (isFinal(modifiers) || isStatic(modifiers)) {
48+
continue;
49+
}
50+
setAccessibleAction.setField(field);
51+
AccessController.doPrivileged(setAccessibleAction);
52+
53+
val fieldValue = field.get(object);
54+
if (fieldValue == null) {
55+
continue;
56+
}
57+
if (field.isAnnotationPresent(CustomProperties.class)) {
58+
String prefix = field.getAnnotation(CustomProperties.class).prefix();
59+
Map<String, String> properties = (Map<String, String>) fieldValue;
60+
for (Map.Entry<String, String> entry : properties.entrySet()) {
61+
result.put(prefix + entry.getKey(), entry.getValue());
62+
}
63+
} else {
64+
val propertyKey = field.isAnnotationPresent(FormProperty.class)
65+
? field.getAnnotation(FormProperty.class).value()
66+
: field.getName();
67+
68+
result.put(propertyKey, fieldValue);
69+
}
70+
71+
}
72+
return result;
73+
}
74+
75+
private PojoUtil () throws UnexpectedException {
76+
throw new UnexpectedException("It is not allowed to instantiate this class");
77+
}
78+
79+
@Setter
80+
@NoArgsConstructor
81+
@FieldDefaults(level = PRIVATE)
82+
private static class SetAccessibleAction implements PrivilegedAction<Object> {
83+
84+
Field field;
85+
86+
@Override
87+
public Object run () {
88+
field.setAccessible(true);
89+
return null;
90+
}
91+
}
92+
}

src/main/java/com/mailgun/model/message/Message.java

+22
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.util.Map;
77
import java.util.Set;
88

9+
import com.mailgun.form.CustomProperties;
910
import org.apache.commons.collections4.CollectionUtils;
1011
import org.apache.commons.lang3.StringUtils;
1112

@@ -287,6 +288,14 @@ public class Message {
287288
@FormProperty("t:variables")
288289
String mailgunVariables;
289290

291+
/**
292+
* <p>
293+
* Specify custom email headers
294+
* </p>
295+
*/
296+
@CustomProperties(prefix = "h:")
297+
Map<String, String> headers;
298+
290299
public static MessageBuilder builder() {
291300
return new CustomMessageBuilder();
292301
}
@@ -768,6 +777,19 @@ public MessageBuilder mailgunVariables(String mailgunVariables) {
768777
this.mailgunVariables = mailgunVariables;
769778
return this;
770779
}
780+
781+
/**
782+
* <p>
783+
* Specify custom email headers
784+
* </p>
785+
*
786+
* @param headers custom email headers
787+
* @return Returns a reference to this object so that method calls can be chained together.
788+
*/
789+
public MessageBuilder headers(Map<String, String> headers) {
790+
this.headers = headers;
791+
return this;
792+
}
771793
}
772794

773795
}

0 commit comments

Comments
 (0)