@@ -92,13 +92,45 @@ public class Email {
92
92
* Map of header name and values, such as <code>X-Priority</code> etc.
93
93
*/
94
94
private final Map <String , String > headers ;
95
+
96
+ /**
97
+ * Indicates the new emails should set the <a href="https://tools.ietf.org/html/rfc8098">NPM flag "Disposition-Notification-To"</a>. This flag can
98
+ * be used to request a return receipt from the recipient to signal that the recipient has read the email.
99
+ * <p>
100
+ * This flag may be ignored by SMTP clients (for example gmail ignores it completely, while the Google Apps business suite honors it).
101
+ * <p>
102
+ * If no address is provided, {@link #dispositionNotificationTo} will default to {@link #replyToRecipient} if available or else
103
+ * {@link #fromRecipient}.
104
+ */
105
+ private boolean useDispositionNotificationTo ;
106
+
107
+ /**
108
+ * @see #useDispositionNotificationTo
109
+ */
110
+ private Recipient dispositionNotificationTo ;
111
+
112
+ /**
113
+ * Indicates the new emails should set the <a href="https://en.wikipedia.org/wiki/Return_receipt">RRT flag "Return-Receipt-To"</a>. This flag
114
+ * can be used to request a notification from the SMTP server recipient to signal that the recipient has read the email.
115
+ * <p>
116
+ * This flag is rarely used, but your mail server / client might implement this flag to automatically send back a notification that the email
117
+ * was received on the mail server or opened in the client, depending on the chosen implementation.
118
+ * <p>
119
+ * If no address is provided, {@link #returnReceiptTo} will default to {@link #replyToRecipient} if available or else {@link #fromRecipient}.
120
+ */
121
+ private boolean useReturnReceiptTo ;
122
+
123
+ /**
124
+ * @see #useReturnReceiptTo
125
+ */
126
+ private Recipient returnReceiptTo ;
95
127
96
128
/*
97
129
DKIM properties
98
130
*/
99
131
private boolean applyDKIMSignature = false ;
100
132
private InputStream dkimPrivateKeyInputStream ;
101
- private File dkimPrivateKeyFile ; // supported seperately , so we don't have to do resource management ourselves for the InputStream
133
+ private File dkimPrivateKeyFile ; // supported separately , so we don't have to do resource management ourselves for the InputStream
102
134
private String dkimSigningDomain ;
103
135
private String dkimSelector ;
104
136
@@ -189,16 +221,25 @@ public void signWithDomainKey(@Nonnull final InputStream dkimPrivateKeyInputStre
189
221
public void setId (@ Nullable final String id ) {
190
222
this .id = id ;
191
223
}
192
-
224
+
193
225
/**
194
226
* Sets the sender address.
195
227
*
196
228
* @param name The sender's name.
197
- * @param fromAddress The sender's email address.
229
+ * @param fromAddress The sender's email address, mandatory .
198
230
*/
199
231
public void setFromAddress (@ Nullable final String name , @ Nonnull final String fromAddress ) {
200
232
fromRecipient = new Recipient (name , checkNonEmptyArgument (fromAddress , "fromAddress" ), null );
201
233
}
234
+
235
+ /**
236
+ * Sets the sender address from a preconfigured {@link Recipient} object..
237
+ *
238
+ * @param recipient The Recipient optional name and mandatory address.
239
+ */
240
+ public void setFromAddress (@ Nonnull Recipient recipient ) {
241
+ fromRecipient = new Recipient (recipient .getName (), checkNonEmptyArgument (recipient .getAddress (), "fromAddress" ), null );
242
+ }
202
243
203
244
/**
204
245
* Sets the reply-to address (optional).
@@ -209,14 +250,51 @@ public void setFromAddress(@Nullable final String name, @Nonnull final String fr
209
250
public void setReplyToAddress (@ Nullable final String name , @ Nonnull final String replyToAddress ) {
210
251
replyToRecipient = new Recipient (name , checkNonEmptyArgument (replyToAddress , "replyToAddress" ), null );
211
252
}
253
+
254
+ /**
255
+ * Sets the reply-to address from a preconfigured {@link Recipient} object..
256
+ *
257
+ * @param recipient The Recipient optional name and mandatory address.
258
+ */
259
+ public void setReplyToAddress (@ Nonnull Recipient recipient ) {
260
+ replyToRecipient = new Recipient (recipient .getName (), checkNonEmptyArgument (recipient .getAddress (), "replyToAddress" ), null );
261
+ }
212
262
213
263
/**
214
264
* Bean setter for {@link #subject}.
215
265
*/
216
266
public void setSubject (@ Nonnull final String subject ) {
217
267
this .subject = checkNonEmptyArgument (subject , "subject" );
218
268
}
219
-
269
+
270
+ /**
271
+ * Bean setter for {@link #useDispositionNotificationTo}.
272
+ */
273
+ public void setUseDispositionNotificationTo (boolean useDispositionNotificationTo ) {
274
+ this .useDispositionNotificationTo = useDispositionNotificationTo ;
275
+ }
276
+
277
+ /**
278
+ * Bean setter for {@link #dispositionNotificationTo}.
279
+ */
280
+ public void setDispositionNotificationTo (Recipient dispositionNotificationTo ) {
281
+ this .dispositionNotificationTo = dispositionNotificationTo ;
282
+ }
283
+
284
+ /**
285
+ * Bean setter for {@link #useReturnReceiptTo}.
286
+ */
287
+ public void setUseReturnReceiptTo (boolean useReturnReceiptTo ) {
288
+ this .useReturnReceiptTo = useReturnReceiptTo ;
289
+ }
290
+
291
+ /**
292
+ * Bean setter for {@link #returnReceiptTo}.
293
+ */
294
+ public void setReturnReceiptTo (Recipient returnReceiptTo ) {
295
+ this .returnReceiptTo = returnReceiptTo ;
296
+ }
297
+
220
298
/**
221
299
* Bean setter for {@link #text}.
222
300
*/
@@ -394,7 +472,35 @@ public Recipient getReplyToRecipient() {
394
472
public String getSubject () {
395
473
return subject ;
396
474
}
397
-
475
+
476
+ /**
477
+ * Bean getter for {@link #useDispositionNotificationTo}.
478
+ */
479
+ public boolean isUseDispositionNotificationTo () {
480
+ return useDispositionNotificationTo ;
481
+ }
482
+
483
+ /**
484
+ * Bean getter for {@link #dispositionNotificationTo}.
485
+ */
486
+ public Recipient getDispositionNotificationTo () {
487
+ return dispositionNotificationTo ;
488
+ }
489
+
490
+ /**
491
+ * Bean getter for {@link #useReturnReceiptTo}.
492
+ */
493
+ public boolean isUseReturnReceiptTo () {
494
+ return useReturnReceiptTo ;
495
+ }
496
+
497
+ /**
498
+ * Bean getter for {@link #returnReceiptTo}.
499
+ */
500
+ public Recipient getReturnReceiptTo () {
501
+ return returnReceiptTo ;
502
+ }
503
+
398
504
/**
399
505
* Bean getter for {@link #text}.
400
506
*/
@@ -467,7 +573,7 @@ public boolean equals(final Object o) {
467
573
return (this == o ) || (o != null && getClass () == o .getClass () &&
468
574
EqualsHelper .equalsEmail (this , (Email ) o ));
469
575
}
470
-
576
+
471
577
@ Override
472
578
public String toString () {
473
579
return "Email{" +
@@ -478,9 +584,16 @@ public String toString() {
478
584
",\n \t textHTML='" + textHTML + '\'' +
479
585
",\n \t subject='" + subject + '\'' +
480
586
",\n \t recipients=" + recipients +
587
+ ",\n \t applyDKIMSignature=" + applyDKIMSignature +
588
+ ",\n \t \t dkimSelector=" + dkimSelector +
589
+ ",\n \t \t dkimSigningDomain=" + dkimSigningDomain +
590
+ ",\n \t useDispositionNotificationTo=" + useDispositionNotificationTo +
591
+ ",\n \t \t dispositionNotificationTo=" + dispositionNotificationTo +
592
+ ",\n \t useReturnReceiptTo=" + useReturnReceiptTo +
593
+ ",\n \t \t returnReceiptTo=" + returnReceiptTo +
594
+ ",\n \t headers=" + headers +
481
595
",\n \t embeddedImages=" + embeddedImages +
482
596
",\n \t attachments=" + attachments +
483
- ",\n \t headers=" + headers +
484
597
"\n }" ;
485
598
}
486
599
@@ -503,6 +616,31 @@ public String toString() {
503
616
textHTML = builder .getTextHTML ();
504
617
subject = builder .getSubject ();
505
618
619
+ useDispositionNotificationTo = builder .isUseDispositionNotificationTo ();
620
+ useReturnReceiptTo = builder .isUseReturnReceiptTo ();
621
+ dispositionNotificationTo = builder .getDispositionNotificationTo ();
622
+ returnReceiptTo = builder .getReturnReceiptTo ();
623
+
624
+ if (useDispositionNotificationTo ) {
625
+ if (valueNullOrEmpty (builder .getDispositionNotificationTo ())) {
626
+ if (builder .getReplyToRecipient () != null ) {
627
+ dispositionNotificationTo = builder .getReplyToRecipient ();
628
+ } else {
629
+ dispositionNotificationTo = builder .getFromRecipient ();
630
+ }
631
+ }
632
+ }
633
+
634
+ if (useReturnReceiptTo ) {
635
+ if (valueNullOrEmpty (builder .getDispositionNotificationTo ())) {
636
+ if (builder .getReplyToRecipient () != null ) {
637
+ returnReceiptTo = builder .getReplyToRecipient ();
638
+ } else {
639
+ returnReceiptTo = builder .getFromRecipient ();
640
+ }
641
+ }
642
+ }
643
+
506
644
if (builder .getDkimPrivateKeyFile () != null ) {
507
645
signWithDomainKey (builder .getDkimPrivateKeyFile (), builder .getSigningDomain (), builder .getDkimSelector ());
508
646
} else if (builder .getDkimPrivateKeyInputStream () != null ) {
0 commit comments