Skip to content
This repository has been archived by the owner on Sep 12, 2018. It is now read-only.

Commit

Permalink
adds a feature about recipients limitation per a email when sending n…
Browse files Browse the repository at this point in the history
…otification emails.

* Issue
    - Altough some smtp server has recipients limitation per a email, Yobi sends notification emails regardless of it.

* Solution
    - `application.notification.bymail.recipientLimit` is added to `application.conf.default`. If it is set, notification emails are split along the value.
    - Codes which split the notification emails are added.

Private-issue: 2055
  • Loading branch information
ChangsungKim committed Feb 13, 2015
1 parent f798de7 commit cbcda46
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 45 deletions.
111 changes: 66 additions & 45 deletions app/models/NotificationMail.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@
@Entity
public class NotificationMail extends Model {
private static final long serialVersionUID = 1L;
private static final int RECIPIENT_NO_LIMIT = 0;
static boolean hideAddress = true;
private static int recipientLimit = RECIPIENT_NO_LIMIT;

@Id
public Long id;
Expand All @@ -74,6 +76,9 @@ public static void onStart() {
hideAddress = play.Configuration.root().getBoolean(
"application.notification.bymail.hideAddress", true);

recipientLimit = play.Configuration.root().getInt(
"application.notification.bymail.recipientLimit", RECIPIENT_NO_LIMIT);

if (notificationEnabled()) {
NotificationMail.startSchedule();
}
Expand Down Expand Up @@ -241,61 +246,77 @@ private static void sendNotification(NotificationEvent event) {
}

for (String langCode : usersByLang.keySet()) {
final EventEmail email = new EventEmail(event);

try {
email.setFrom(Config.getEmailFromSmtp(), event.getSender().name);
email.addTo(Config.getEmailFromSmtp(), utils.Config.getSiteName());
List<User> users = usersByLang.get(langCode);

String replyTo = getReplyTo(event.getResource());
boolean acceptsReply = false;
if (replyTo != null) {
email.addReplyTo(replyTo);
acceptsReply = true;
if (recipientLimit == RECIPIENT_NO_LIMIT) {
sendMail(event, users, langCode);
} else {
int usersSize = users.size();
int fromIndex, toIndex = 0;
while (toIndex < usersSize) {
fromIndex = toIndex;
toIndex = Math.min(toIndex + recipientLimit, usersSize);
sendMail(event, users.subList(fromIndex, toIndex), langCode);
}
}
}
}

for (User receiver : usersByLang.get(langCode)) {
if (hideAddress) {
email.addBcc(receiver.email, receiver.name);
} else {
email.addTo(receiver.email, receiver.name);
}
}
private static void sendMail(NotificationEvent event, List<User> receivers, String langCode) {
final EventEmail email = new EventEmail(event);

if (email.getToAddresses().isEmpty()) {
continue;
try {
email.setFrom(Config.getEmailFromSmtp(), event.getSender().name);
email.addTo(Config.getEmailFromSmtp(), utils.Config.getSiteName());

String replyTo = getReplyTo(event.getResource());
boolean acceptsReply = false;
if (replyTo != null) {
email.addReplyTo(replyTo);
acceptsReply = true;
}

for (User receiver : receivers) {
if (hideAddress) {
email.addBcc(receiver.email, receiver.name);
} else {
email.addTo(receiver.email, receiver.name);
}
}

// FIXME: gmail은 From과 To에 같은 주소가 있으면 reply-to를 무시한다.
if (email.getToAddresses().isEmpty()) {
return;
}

Lang lang = Lang.apply(langCode);
// FIXME: gmail은 From과 To에 같은 주소가 있으면 reply-to를 무시한다.

String message = event.getMessage(lang);
String urlToView = event.getUrlToView();
Lang lang = Lang.apply(langCode);

email.setSubject(event.title);
Resource resource = event.getResource();
if (resource.getType() == ResourceType.ISSUE_COMMENT) {
IssueComment issueComment = IssueComment.find.byId(Long.valueOf(resource.getId()));
resource = issueComment.issue.asResource();
}
email.setHtmlMsg(getHtmlMessage(lang, message, urlToView, resource, acceptsReply));
email.setTextMsg(getPlainMessage(lang, message, Url.create(urlToView), acceptsReply));
email.setCharset("utf-8");
email.addReferences();
email.setSentDate(event.created);
Mailer.send(email);
String escapedTitle = email.getSubject().replace("\"", "\\\"");
Set<InternetAddress> recipients = new HashSet<>();
recipients.addAll(email.getToAddresses());
recipients.addAll(email.getCcAddresses());
recipients.addAll(email.getBccAddresses());
String logEntry = String.format("\"%s\" %s", escapedTitle, recipients);
play.Logger.of("mail.out").info(logEntry);
} catch (Exception e) {
Logger.warn("Failed to send a notification: "
+ email + "\n" + ExceptionUtils.getStackTrace(e));
String message = event.getMessage(lang);
String urlToView = event.getUrlToView();

email.setSubject(event.title);
Resource resource = event.getResource();
if (resource.getType() == ResourceType.ISSUE_COMMENT) {
IssueComment issueComment = IssueComment.find.byId(Long.valueOf(resource.getId()));
resource = issueComment.issue.asResource();
}
email.setHtmlMsg(getHtmlMessage(lang, message, urlToView, resource, acceptsReply));
email.setTextMsg(getPlainMessage(lang, message, Url.create(urlToView), acceptsReply));
email.setCharset("utf-8");
email.addReferences();
email.setSentDate(event.created);
Mailer.send(email);
String escapedTitle = email.getSubject().replace("\"", "\\\"");
Set<InternetAddress> recipients = new HashSet<>();
recipients.addAll(email.getToAddresses());
recipients.addAll(email.getCcAddresses());
recipients.addAll(email.getBccAddresses());
String logEntry = String.format("\"%s\" %s", escapedTitle, recipients);
play.Logger.of("mail.out").info(logEntry);
} catch (Exception e) {
Logger.warn("Failed to send a notification: "
+ email + "\n" + ExceptionUtils.getStackTrace(e));
}
}

Expand Down
4 changes: 4 additions & 0 deletions conf/application.conf.default
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ imap.folder = inbox
application.notification.bymail.interval = 60s
# Sending a notification mail delays this seconds.
application.notification.bymail.delay = 180s
# Split notification emails by the recipient limit.
# The value is number of maximum recipients per an email and inclusive.
# (default: 0, This means there is no limitation.)
application.notification.bymail.recipientLimit = 100
# Hide recipients of notification email by using bcc. (default: true)
application.notification.bymail.hideAddress = true
# A new event notification can be merged if possible with previous one which is
Expand Down

0 comments on commit cbcda46

Please sign in to comment.