I have a cron job which automatically processes bounces from transactional emails such as order confirmations. My script finds the original recipient address via one of these headers:
X-Failed-Recipients
Final-Recipient
Recently I’ve found that some bounces have Final-Recipient
not in the headers, but in a section of the email which is neither in the message body nor in attachments.
The mime type is:
message/delivery-status
The query returned by cfpop/cfimap does not include a deliverystatus
column because the Java source for those tags does not check for the message/delivery-status
mime type.
I know Adobe doesn’t parse it either but it would be awesome for Lucee devs to have yet another advantage, made possible by Lucee being open source!
And it’s a super easy feature to add, with changes in only one file:
/core/src/main/java/lucee/runtime/net/mail/MailClient.java
In fact, I’ve already done the coding!
I haven’t submitted a pull request because I don’t know what the workflow is for that, but here are the changes required:
Branch: 6.1
--- a/core/src/main/java/lucee/runtime/net/mail/MailClient.java
+++ b/core/src/main/java/lucee/runtime/net/mail/MailClient.java
@@ -121,18 +121,19 @@ public abstract class MailClient implements PoolItem {
private static final Collection.Key FLAGGED = KeyConstants._flagged;
private static final Collection.Key RECENT = KeyConstants._recent;
private static final Collection.Key SEEN = KeyConstants._seen;
+ private static final Collection.Key DELIVERY_STATUS = KeyConstants._deliverystatus;
public static final int TYPE_POP3 = 0;
public static final int TYPE_IMAP = 1;
private String _popHeaders[] = { "date", "from", "messagenumber", "messageid", "replyto", "subject", "cc", "to", "size", "header", "uid" };
private String _popAll[] = { "date", "from", "messagenumber", "messageid", "replyto", "subject", "cc", "to", "size", "header", "uid", "answered", "deleted", "draft", "flagged",
- "recent", "seen", "body", "textBody", "HTMLBody", "attachments", "attachmentfiles", "cids" };
+ "recent", "seen", "body", "textBody", "HTMLBody", "attachments", "attachmentfiles", "cids", "deliverystatus" };
private String _imapHeaders[] = { "date", "from", "messagenumber", "messageid", "replyto", "subject", "cc", "to", "size", "header", "uid", "answered", "deleted", "draft",
"flagged", "recent", "seen" };
private String _imapAll[] = { "date", "from", "messagenumber", "messageid", "replyto", "subject", "cc", "to", "size", "header", "uid", "answered", "deleted", "draft",
- "flagged", "recent", "seen", "body", "textBody", "HTMLBody", "attachments", "attachmentfiles", "cids" };
+ "flagged", "recent", "seen", "body", "textBody", "HTMLBody", "attachments", "attachmentfiles", "cids", "deliverystatus" };
private String server = null;
private String username = null;
@@ -541,6 +542,11 @@ public abstract class MailClient implements PoolItem {
query.setAtEL(HTML_BODY, row, content);
body.append(content);
}
+ else if (message.isMimeType("message/delivery-status")) {
+ String content = getConent(message);
+ query.setAtEL(DELIVERY_STATUS, row, content);
+ body.append(content);
+ }
else {
Object content = message.getContent();
if (content instanceof MimeMultipart) {
@@ -618,6 +624,11 @@ public abstract class MailClient implements PoolItem {
query.setAtEL(HTML_BODY, row, content);
if (body.length() == 0) body.append(content);
}
+ else if (bodypart.isMimeType("message/delivery-status")) {
+ content = getConent(bodypart);
+ query.setAtEL(DELIVERY_STATUS, row, content);
+ if (body.length() == 0) body.append(content);
+ }
else if ((content = bodypart.getContent()) instanceof Multipart) {
getMultiPart(query, row, attachments, attachmentFiles, cids, (Multipart) content, body);
}
Branch: 5.4
--- a/core/src/main/java/lucee/runtime/net/mail/MailClient.java
+++ b/core/src/main/java/lucee/runtime/net/mail/MailClient.java
@@ -112,13 +112,14 @@ public abstract class MailClient implements PoolItem {
private static final Collection.Key HTML_BODY = KeyImpl.getInstance("HTMLBody");
private static final Collection.Key ATTACHMENTS = KeyImpl.getInstance("attachments");
private static final Collection.Key ATTACHMENT_FILES = KeyImpl.getInstance("attachmentfiles");
+ private static final Collection.Key DELIVERY_STATUS = KeyImpl.getInstance("deliverystatus");
public static final int TYPE_POP3 = 0;
public static final int TYPE_IMAP = 1;
private String _flddo[] = { "date", "from", "messagenumber", "messageid", "replyto", "subject", "cc", "to", "size", "header", "uid" };
private String _fldnew[] = { "date", "from", "messagenumber", "messageid", "replyto", "subject", "cc", "to", "size", "header", "uid", "body", "textBody", "HTMLBody",
- "attachments", "attachmentfiles", "cids" };
+ "attachments", "attachmentfiles", "cids", "deliverystatus" };
private String server = null;
private String username = null;
private String password = null;
@@ -449,6 +450,11 @@ public abstract class MailClient implements PoolItem {
query.setAtEL(HTML_BODY, row, content);
body.append(content);
}
+ else if (message.isMimeType("message/delivery-status")) {
+ String content = getConent(message);
+ query.setAtEL(DELIVERY_STATUS, row, content);
+ body.append(content);
+ }
else {
Object content = message.getContent();
if (content instanceof MimeMultipart) {
@@ -526,6 +532,11 @@ public abstract class MailClient implements PoolItem {
query.setAtEL(HTML_BODY, row, content);
if (body.length() == 0) body.append(content);
}
+ else if (bodypart.isMimeType("message/delivery-status")) {
+ content = getConent(bodypart);
+ query.setAtEL(DELIVERY_STATUS, row, content);
+ if (body.length() == 0) body.append(content);
+ }
else if ((content = bodypart.getContent()) instanceof Multipart) {
getMultiPart(query, row, attachments, attachmentFiles, cids, (Multipart) content, body);
}