
Mailbox: Ignore duplicated email
If there is two emails with same id in mailbox, Yobi handles the first one only. It occurs quite frequently because mail servers send an email twice if the email has two addresses differ from each other: e.g. yobi+my/proj@mail.com and yobi+your/proj@mail.com. Warn if the older email was handled one hour or more ago. Because it is quite long time so that possibly the ignored email is actually new one which should be handled. This feature is not necessary for some IMAP servers, like Gmail, which drop duplicated emails.
@c96352a45975929b5199d02d141a244134d521fb
--- app/mailbox/EmailHandler.java
+++ app/mailbox/EmailHandler.java
... | ... | @@ -23,7 +23,9 @@ |
23 | 23 |
import com.sun.mail.imap.IMAPFolder; |
24 | 24 |
import com.sun.mail.imap.IMAPMessage; |
25 | 25 |
import info.schleichardt.play2.mailplugin.Mailer; |
26 |
-import mailbox.exceptions.*; |
|
26 |
+import mailbox.exceptions.IllegalDetailException; |
|
27 |
+import mailbox.exceptions.MailHandlerException; |
|
28 |
+import models.OriginalEmail; |
|
27 | 29 |
import models.Project; |
28 | 30 |
import models.Property; |
29 | 31 |
import models.User; |
... | ... | @@ -33,6 +35,7 @@ |
33 | 35 |
import org.apache.commons.lang3.StringUtils; |
34 | 36 |
import org.apache.commons.lang3.exception.ExceptionUtils; |
35 | 37 |
import org.apache.commons.mail.HtmlEmail; |
38 |
+import org.joda.time.DateTime; |
|
36 | 39 |
import play.Logger; |
37 | 40 |
import play.api.i18n.Lang; |
38 | 41 |
import play.i18n.Messages; |
... | ... | @@ -166,7 +169,32 @@ |
166 | 169 |
return; |
167 | 170 |
} |
168 | 171 |
} catch (MessagingException e) { |
169 |
- play.Logger.warn("Failed to determine whether the email is auto-replied or not", e); |
|
172 |
+ play.Logger.warn( |
|
173 |
+ "Failed to determine whether the email is auto-replied or not: " + msg, e); |
|
174 |
+ } |
|
175 |
+ |
|
176 |
+ try { |
|
177 |
+ // Ignore the email if there is an email with the same id. It occurs |
|
178 |
+ // quite frequently because mail servers send an email twice if the |
|
179 |
+ // email has two addresses differ from each other: e.g. |
|
180 |
+ // yobi+my/proj@mail.com and yobi+your/proj@mail.com. |
|
181 |
+ OriginalEmail sameMessage = |
|
182 |
+ OriginalEmail.finder.where().eq("messageId", msg.getMessageID()).findUnique(); |
|
183 |
+ if (sameMessage != null) { |
|
184 |
+ // Warn if the older email was handled one hour or more ago. Because it is |
|
185 |
+ // quite long time so that possibly the ignored email is actually |
|
186 |
+ // new one which should be handled. |
|
187 |
+ if (sameMessage.getHandledDate().before(new DateTime().minusHours(1).toDate())) { |
|
188 |
+ String warn = String.format("This email '%s' is ignored because an email with" + |
|
189 |
+ " the same id '%s' was already handled at '%s'", |
|
190 |
+ msg, sameMessage.messageId, sameMessage.getHandledDate()); |
|
191 |
+ play.Logger.warn(warn); |
|
192 |
+ } |
|
193 |
+ return; |
|
194 |
+ } |
|
195 |
+ } catch (MessagingException e) { |
|
196 |
+ play.Logger.warn( |
|
197 |
+ "Failed to determine whether the email is duplicated or not: " + msg, e); |
|
170 | 198 |
} |
171 | 199 |
|
172 | 200 |
InternetAddress[] senderAddresses; |
--- app/models/OriginalEmail.java
+++ app/models/OriginalEmail.java
... | ... | @@ -26,6 +26,7 @@ |
26 | 26 |
import play.db.ebean.Model; |
27 | 27 |
|
28 | 28 |
import javax.persistence.*; |
29 |
+import java.util.Date; |
|
29 | 30 |
|
30 | 31 |
@Entity |
31 | 32 |
@Table(uniqueConstraints = @UniqueConstraint(columnNames = {"resource_type", "resource_id"})) |
... | ... | @@ -49,6 +50,9 @@ |
49 | 50 |
@Constraints.Required |
50 | 51 |
public String resourceId; |
51 | 52 |
|
53 |
+ @Constraints.Required |
|
54 |
+ private Date handledDate; |
|
55 |
+ |
|
52 | 56 |
public static OriginalEmail findBy(Resource resource) { |
53 | 57 |
return finder.where() |
54 | 58 |
.eq("resourceType", resource.getType()) |
... | ... | @@ -65,4 +69,14 @@ |
65 | 69 |
this.resourceType = resource.getType(); |
66 | 70 |
this.resourceId = resource.getId(); |
67 | 71 |
} |
72 |
+ |
|
73 |
+ @Override |
|
74 |
+ public void save() { |
|
75 |
+ handledDate = new Date(); |
|
76 |
+ super.save(); |
|
77 |
+ } |
|
78 |
+ |
|
79 |
+ public Date getHandledDate() { |
|
80 |
+ return handledDate; |
|
81 |
+ } |
|
68 | 82 |
} |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?