From 585811ab88d22b01be15086139bf9d57546b87c8 Mon Sep 17 00:00:00 2001 From: Michael Zhou Date: Sat, 9 Jan 2021 23:20:12 -0800 Subject: [PATCH 1/3] Add content export API --- .../controller/ExportContentController.java | 30 ++ .../controller/models/ContentExport.java | 45 +++ .../messaging/MessagingService.java | 258 +++++++++--------- 3 files changed, 209 insertions(+), 124 deletions(-) create mode 100644 backend/src/main/java/com/bulletjournal/controller/ExportContentController.java create mode 100644 backend/src/main/java/com/bulletjournal/controller/models/ContentExport.java diff --git a/backend/src/main/java/com/bulletjournal/controller/ExportContentController.java b/backend/src/main/java/com/bulletjournal/controller/ExportContentController.java new file mode 100644 index 000000000..1d50b150b --- /dev/null +++ b/backend/src/main/java/com/bulletjournal/controller/ExportContentController.java @@ -0,0 +1,30 @@ +package com.bulletjournal.controller; + +import com.bulletjournal.clients.UserClient; +import com.bulletjournal.controller.models.ContentExport; +import com.bulletjournal.messaging.MessagingService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +@RestController +public class ExportContentController { + + private static final String EXPORT_PUBLIC_CONTENT_ROUTE = "/api/content/export"; + private static final Logger LOGGER = LoggerFactory.getLogger(ExportContentController.class); + + @Autowired + private MessagingService messagingService; + + @PostMapping(EXPORT_PUBLIC_CONTENT_ROUTE) + public void exportContent(@Valid @RequestBody ContentExport contentExport) { + String username = MDC.get(UserClient.USER_NAME_KEY); + this.messagingService.sendExportContentToUsers(username, contentExport); + } +} diff --git a/backend/src/main/java/com/bulletjournal/controller/models/ContentExport.java b/backend/src/main/java/com/bulletjournal/controller/models/ContentExport.java new file mode 100644 index 000000000..a8b5a19c1 --- /dev/null +++ b/backend/src/main/java/com/bulletjournal/controller/models/ContentExport.java @@ -0,0 +1,45 @@ +package com.bulletjournal.controller.models; + +import java.util.List; + +public class ContentExport { + + private String htmlContent; + + private String title; + + private List receivers; + + public ContentExport() { + } + + public ContentExport(String htmlContent, String title, List receivers) { + this.htmlContent = htmlContent; + this.title = title; + this.receivers = receivers; + } + + public String getHtmlContent() { + return htmlContent; + } + + public void setHtmlContent(String htmlContent) { + this.htmlContent = htmlContent; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public List getReceivers() { + return receivers; + } + + public void setReceivers(List receivers) { + this.receivers = receivers; + } +} diff --git a/backend/src/main/java/com/bulletjournal/messaging/MessagingService.java b/backend/src/main/java/com/bulletjournal/messaging/MessagingService.java index 4b0c85224..51e9d3781 100644 --- a/backend/src/main/java/com/bulletjournal/messaging/MessagingService.java +++ b/backend/src/main/java/com/bulletjournal/messaging/MessagingService.java @@ -1,6 +1,7 @@ package com.bulletjournal.messaging; import com.bulletjournal.clients.UserClient; +import com.bulletjournal.controller.models.ContentExport; import com.bulletjournal.messaging.firebase.FcmClient; import com.bulletjournal.messaging.firebase.FcmMessageParams; import com.bulletjournal.messaging.mailjet.MailjetEmailClient; @@ -13,18 +14,6 @@ import com.bulletjournal.repository.models.Notification; import com.bulletjournal.repository.models.Task; import com.bulletjournal.repository.models.User; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; @@ -35,93 +24,67 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + /** * Handle mobile device notification and email service */ @Service public class MessagingService { - private static final Logger LOGGER = LoggerFactory.getLogger(MessagingService.class); - public static final String NONE_STRING = "None"; - public static final String ALIAS_PROPERTY = "alias"; - public static final String AVATAR_PROPERTY = "avatar"; - public static final String ASSIGNEES_PROPERTY = "assignees"; - public static final String TASK_NAME_PROPERTY = "taskName"; - public static final String TIMESTAMP_PROPERTY = "timestamp"; - public static final String TASK_URL_PROPERTY = "taskUrl"; - public static final String BASE_TASK_URL = "https://bulletjournal.us/#/task/"; - public static final String TASK_OWNER_PROPERTY = "owner_name"; - public static final String TASK_OWNER_AVATAR_PROPERTY = "owner_avatar"; - public static final String CLICK_ACTION_KEY = "click_action"; - + private static final Logger LOGGER = LoggerFactory.getLogger(MessagingService.class); private static final String CLICK_ACTION_VALUE = "FLUTTER_NOTIFICATION_CLICK"; - - private FcmClient fcmClient; - - private MailjetEmailClient mailjetClient; - - private DeviceTokenDaoJpa deviceTokenDaoJpa; - - private UserDaoJpa userDaoJpa; - - private UserAliasDaoJpa userAliasDaoJpa; - - private UserClient userClient; - // JOIN GROUP PROPERTIES private static final String GROUP_INVITATION_BASE_URL = - "http://bulletjournal.us/public/notifications/"; - + "http://bulletjournal.us/public/notifications/"; private static final String GROUP_INVITATION_ACCEPT_SUFFIX = "?action=accept"; - private static final String GROUP_INVITATION_DECLINE_SUFFIX = "?action=decline"; - private static final String GROUP_INVITATION_ACCEPT_URL_PROPERTY = "groupInvitationAcceptURL"; - private static final String GROUP_INVITATION_DECLINE_URL_PROPERTY = "groupInvitationDeclineURL"; - private static final String GROUP_INVITER_PROPERTY = "groupInviter"; - private static final String GROUP_INVITER_AVATAR_PROPERTY = "groupInviterAvatar"; - private static final String GROUP_NAME_PROPERTY = "groupName"; - // APP INVITATION PROPERTIES private static final String APP_BASIC_URL = "https://bulletjournal.us/home/index.html"; - private static final String APP_URL_PROPERTY = "appUrl"; - private static final String APP_INVITER_PROPERTY = "appInviter"; - private static final String APP_INVITER_AVATAR_PROPERTY = "appInviterAvatar"; - // Regex Pattern private static final Pattern EMAIL_PATTERN = Pattern - .compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$", Pattern.CASE_INSENSITIVE); - - private static final Pattern GROUP_INVITATION_TITLE_PATTERN = Pattern - .compile("(?s)(?<=##).*?(?=##)"); + .compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$", Pattern.CASE_INSENSITIVE); + private static final Pattern GROUP_INVITATION_TITLE_PATTERN = Pattern + .compile("(?s)(?<=##).*?(?=##)"); + private final FcmClient fcmClient; + private final MailjetEmailClient mailjetClient; + private final DeviceTokenDaoJpa deviceTokenDaoJpa; + private final UserDaoJpa userDaoJpa; + private final UserAliasDaoJpa userAliasDaoJpa; + private final UserClient userClient; @Autowired public MessagingService( - FcmClient fcmClient, - MailjetEmailClient mailjetClient, - DeviceTokenDaoJpa deviceTokenDaoJpa, - UserDaoJpa userDaoJpa, - UserAliasDaoJpa userAliasDaoJpa, - UserClient userClient + FcmClient fcmClient, + MailjetEmailClient mailjetClient, + DeviceTokenDaoJpa deviceTokenDaoJpa, + UserDaoJpa userDaoJpa, + UserAliasDaoJpa userAliasDaoJpa, + UserClient userClient ) { this.fcmClient = fcmClient; this.mailjetClient = mailjetClient; @@ -135,36 +98,51 @@ public void sendEtagUpdateNotificationToUsers(Collection usernames) { LOGGER.info("Sending notification to users: {}", usernames); List deviceTokens = deviceTokenDaoJpa.getTokensByUsers(usernames); List params = deviceTokens.stream() - .map(token -> new FcmMessageParams(token.getToken(), "type", "Notification", CLICK_ACTION_KEY, CLICK_ACTION_VALUE)) - .collect(Collectors.toList()); + .map(token -> new FcmMessageParams(token.getToken(), "type", "Notification", CLICK_ACTION_KEY, CLICK_ACTION_VALUE)) + .collect(Collectors.toList()); fcmClient.sendAllMessagesAsync(params); } + public void sendExportContentToUsers(String sender, ContentExport contentExport) { + List recipients = contentExport.getReceivers(); + + LOGGER.info("Sending exported content to users: {}", recipients); + try { + List emailParamsList = new ArrayList<>(); + Map targetUserEmailMap = getTargetUserEmailMap(new HashSet<>(recipients)); + String senderAvatar = getAvatar(sender); + contentExport.getReceivers().forEach(receiver -> emailParamsList + .add(createEmailParamsForContentExport(sender, + receiver, + targetUserEmailMap, + contentExport.getTitle(), + contentExport.getHtmlContent(), + senderAvatar))); + mailjetClient.sendAllEmailAsync(emailParamsList); + } catch (Exception e) { + LOGGER.error("sendExportContentToUsers failed", e); + } + } + public void sendJoinGroupNotificationEmailsToUser( - List> notificationWithUIDs) { + List> notificationWithUIDs) { LOGGER.info("Sending join group notifications ..."); try { Set distinctTargetUsers = notificationWithUIDs.stream().flatMap(item -> - Stream.of(item.getValue().getTargetUser())) - .collect(Collectors.toSet()); - List targetUsers = userDaoJpa.getUsersByNames(distinctTargetUsers); - Map targetUserEmailMap = new HashMap<>(); - for (User user : targetUsers) { - if (user.getEmail() != null && !user.getEmail().endsWith("@anon.1o24bbs.com")) { - targetUserEmailMap.put(user.getName(), user.getEmail()); - } - } + Stream.of(item.getValue().getTargetUser())) + .collect(Collectors.toSet()); + Map targetUserEmailMap = getTargetUserEmailMap(distinctTargetUsers); Set distinctInviters = notificationWithUIDs.stream().flatMap(item -> - Stream.of(item.getValue().getOriginator())) - .collect(Collectors.toSet()); + Stream.of(item.getValue().getOriginator())) + .collect(Collectors.toSet()); Map inviterAvatarMap = getAvatarMap(new ArrayList<>(distinctInviters)); List emailParamsList = new ArrayList<>(); for (Pair notificationWithUID : notificationWithUIDs) { MailjetEmailParams mailjetEmailParams = - createEmailParamsForGroupInvitation(notificationWithUID, - targetUserEmailMap, inviterAvatarMap); + createEmailParamsForGroupInvitation(notificationWithUID, + targetUserEmailMap, inviterAvatarMap); if (mailjetEmailParams != null) { emailParamsList.add(mailjetEmailParams); } @@ -175,6 +153,17 @@ public void sendJoinGroupNotificationEmailsToUser( } } + private Map getTargetUserEmailMap(Set distinctTargetUsers) { + Map targetUserEmailMap = new HashMap<>(); + List targetUsers = userDaoJpa.getUsersByNames(distinctTargetUsers); + for (User user : targetUsers) { + if (user.getEmail() != null && !user.getEmail().endsWith("@anon.1o24bbs.com")) { + targetUserEmailMap.put(user.getName(), user.getEmail()); + } + } + return targetUserEmailMap; + } + public void sendTaskDueNotificationAndEmailToUsers(List taskList) { LOGGER.info("Sending task due notification for tasks: {}", taskList); try { @@ -189,8 +178,8 @@ public void sendTaskDueNotificationAndEmailToUsers(List taskList) { return; } Set distinctUsers = taskList.stream() - .flatMap(task -> task.getAssignees().stream()) - .collect(Collectors.toSet()); + .flatMap(task -> task.getAssignees().stream()) + .collect(Collectors.toSet()); List tokens = deviceTokenDaoJpa.getTokensByUsers(distinctUsers); List users = userDaoJpa.getUsersByNames(distinctUsers); Map> nameTokensMap = new HashMap<>(); @@ -223,7 +212,7 @@ public void sendTaskDueNotificationAndEmailToUsers(List taskList) { } private List createFcmMessageParamsListFromDueTask( - Task task, Map> nameTokenMap + Task task, Map> nameTokenMap ) { List paramsList = new ArrayList<>(); List targetTokens = new ArrayList<>(); @@ -237,17 +226,17 @@ private List createFcmMessageParamsListFromDueTask( } Pair notificationTitleBody - = new ImmutablePair<>(getTitle(task), ""); + = new ImmutablePair<>(getTitle(task), ""); for (String token : targetTokens) { paramsList.add(new FcmMessageParams( - token, - notificationTitleBody, - "type", - "taskDueNotification", - "taskId", - String.valueOf(task.getId()), - CLICK_ACTION_KEY, - CLICK_ACTION_VALUE + token, + notificationTitleBody, + "type", + "taskDueNotification", + "taskId", + String.valueOf(task.getId()), + CLICK_ACTION_KEY, + CLICK_ACTION_VALUE )); } return paramsList; @@ -259,7 +248,7 @@ public void sendAppInvitationEmailsToUser(String inviter, List emails) { List emailParamsList = new ArrayList<>(); for (String email : new HashSet<>(emails)) { MailjetEmailParams mailjetEmailParams = - createEmailPramsForAppInvitation(inviter, this.getAvatar(inviter), email); + createEmailPramsForAppInvitation(inviter, this.getAvatar(inviter), email); if (mailjetEmailParams != null) { emailParamsList.add(mailjetEmailParams); } @@ -274,28 +263,28 @@ public MailjetEmailParams createEmailPramsForAppInvitation(String inviter, String inviterAvatar, String email) { if (!this.isValidEmailAddr(email)) { - LOGGER.error("Invalid app invitation email address: {}", email); - return null; + LOGGER.error("Invalid app invitation email address: {}", email); + return null; } if (inviter == null || inviterAvatar == null) { - LOGGER.error("APP Invitation: Invalid inviter infor"); - return null; + LOGGER.error("APP Invitation: Invalid inviter infor"); + return null; } String title = inviter + " invited your to join BulletJournal"; return new MailjetEmailParams( - Arrays.asList(new ImmutablePair(null, email)), - title, - null, - Template.APP_INVITATION, - APP_URL_PROPERTY, - APP_BASIC_URL, - APP_INVITER_PROPERTY, - inviter, - APP_INVITER_AVATAR_PROPERTY, - inviterAvatar + Arrays.asList(new ImmutablePair(null, email)), + title, + null, + Template.APP_INVITATION, + APP_URL_PROPERTY, + APP_BASIC_URL, + APP_INVITER_PROPERTY, + inviter, + APP_INVITER_AVATAR_PROPERTY, + inviterAvatar ); } @@ -318,9 +307,30 @@ private String getDueTime(Task task) { return ret.toString(); } + private MailjetEmailParams createEmailParamsForExportContent(String content, Map targetUserEmailMap, + String inviterAvatar) { + + return null; + } + + private MailjetEmailParams createEmailParamsForContentExport(String sender, + String receiver, + Map targetUserEmailMap, + String title, + String htmlContent, + String senderAvatar) { + // TODO: Add Template for Content Export + return new MailjetEmailParams( + Collections.singletonList(new ImmutablePair<>(receiver, targetUserEmailMap.get(receiver))), + title, + htmlContent, + null); + } + + private MailjetEmailParams createEmailParamsForGroupInvitation( - Pair notificationWithUID, Map targetUserEmailMap, - Map inviterAvatarMap + Pair notificationWithUID, Map targetUserEmailMap, + Map inviterAvatarMap ) { Notification notification = notificationWithUID.getValue(); String receiver = notification.getTargetUser(); @@ -355,12 +365,12 @@ private MailjetEmailParams createEmailParamsForGroupInvitation( matchResults.get(2), GROUP_INVITER_AVATAR_PROPERTY, groupInviterAvatar - ); + ); } private List createEmailParamsForDueTask( - Task task, Map nameEmailMap + Task task, Map nameEmailMap ) { List ret = new ArrayList<>(); List assignees = task.getAssignees(); @@ -374,22 +384,22 @@ private List createEmailParamsForDueTask( continue; } MailjetEmailParams params = - new MailjetEmailParams( - Arrays.asList(new ImmutablePair<>(receiver, nameEmailMap.get(receiver))), - getTitle(task), - null, - MailjetEmailClient.Template.TASK_DUE_NOTIFICATION, - TASK_NAME_PROPERTY, - task.getName(), - TIMESTAMP_PROPERTY, - getDueTime(task), - TASK_URL_PROPERTY, - taskUrl, - TASK_OWNER_PROPERTY, - ownerName, - TASK_OWNER_AVATAR_PROPERTY, - ownerAvatar - ); + new MailjetEmailParams( + Arrays.asList(new ImmutablePair<>(receiver, nameEmailMap.get(receiver))), + getTitle(task), + null, + MailjetEmailClient.Template.TASK_DUE_NOTIFICATION, + TASK_NAME_PROPERTY, + task.getName(), + TIMESTAMP_PROPERTY, + getDueTime(task), + TASK_URL_PROPERTY, + taskUrl, + TASK_OWNER_PROPERTY, + ownerName, + TASK_OWNER_AVATAR_PROPERTY, + ownerAvatar + ); JSONArray assigneeInfoList = new JSONArray(); JSONObject selfInfo = new JSONObject(); selfInfo.put(ALIAS_PROPERTY, receiver); From f1b85390bc8d0230c1d3c0aba0e128b4d295853b Mon Sep 17 00:00:00 2001 From: singerdmx Date: Sat, 9 Jan 2021 23:59:32 -0800 Subject: [PATCH 2/3] Revert "Add content export API" This reverts commit 585811ab88d22b01be15086139bf9d57546b87c8. --- .../controller/ExportContentController.java | 30 -- .../controller/models/ContentExport.java | 45 --- .../messaging/MessagingService.java | 258 +++++++++--------- 3 files changed, 124 insertions(+), 209 deletions(-) delete mode 100644 backend/src/main/java/com/bulletjournal/controller/ExportContentController.java delete mode 100644 backend/src/main/java/com/bulletjournal/controller/models/ContentExport.java diff --git a/backend/src/main/java/com/bulletjournal/controller/ExportContentController.java b/backend/src/main/java/com/bulletjournal/controller/ExportContentController.java deleted file mode 100644 index 1d50b150b..000000000 --- a/backend/src/main/java/com/bulletjournal/controller/ExportContentController.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.bulletjournal.controller; - -import com.bulletjournal.clients.UserClient; -import com.bulletjournal.controller.models.ContentExport; -import com.bulletjournal.messaging.MessagingService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.slf4j.MDC; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -import javax.validation.Valid; - -@RestController -public class ExportContentController { - - private static final String EXPORT_PUBLIC_CONTENT_ROUTE = "/api/content/export"; - private static final Logger LOGGER = LoggerFactory.getLogger(ExportContentController.class); - - @Autowired - private MessagingService messagingService; - - @PostMapping(EXPORT_PUBLIC_CONTENT_ROUTE) - public void exportContent(@Valid @RequestBody ContentExport contentExport) { - String username = MDC.get(UserClient.USER_NAME_KEY); - this.messagingService.sendExportContentToUsers(username, contentExport); - } -} diff --git a/backend/src/main/java/com/bulletjournal/controller/models/ContentExport.java b/backend/src/main/java/com/bulletjournal/controller/models/ContentExport.java deleted file mode 100644 index a8b5a19c1..000000000 --- a/backend/src/main/java/com/bulletjournal/controller/models/ContentExport.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.bulletjournal.controller.models; - -import java.util.List; - -public class ContentExport { - - private String htmlContent; - - private String title; - - private List receivers; - - public ContentExport() { - } - - public ContentExport(String htmlContent, String title, List receivers) { - this.htmlContent = htmlContent; - this.title = title; - this.receivers = receivers; - } - - public String getHtmlContent() { - return htmlContent; - } - - public void setHtmlContent(String htmlContent) { - this.htmlContent = htmlContent; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public List getReceivers() { - return receivers; - } - - public void setReceivers(List receivers) { - this.receivers = receivers; - } -} diff --git a/backend/src/main/java/com/bulletjournal/messaging/MessagingService.java b/backend/src/main/java/com/bulletjournal/messaging/MessagingService.java index 51e9d3781..4b0c85224 100644 --- a/backend/src/main/java/com/bulletjournal/messaging/MessagingService.java +++ b/backend/src/main/java/com/bulletjournal/messaging/MessagingService.java @@ -1,7 +1,6 @@ package com.bulletjournal.messaging; import com.bulletjournal.clients.UserClient; -import com.bulletjournal.controller.models.ContentExport; import com.bulletjournal.messaging.firebase.FcmClient; import com.bulletjournal.messaging.firebase.FcmMessageParams; import com.bulletjournal.messaging.mailjet.MailjetEmailClient; @@ -14,6 +13,18 @@ import com.bulletjournal.repository.models.Notification; import com.bulletjournal.repository.models.Task; import com.bulletjournal.repository.models.User; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; @@ -24,67 +35,93 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; - /** * Handle mobile device notification and email service */ @Service public class MessagingService { + private static final Logger LOGGER = LoggerFactory.getLogger(MessagingService.class); + public static final String NONE_STRING = "None"; + public static final String ALIAS_PROPERTY = "alias"; + public static final String AVATAR_PROPERTY = "avatar"; + public static final String ASSIGNEES_PROPERTY = "assignees"; + public static final String TASK_NAME_PROPERTY = "taskName"; + public static final String TIMESTAMP_PROPERTY = "timestamp"; + public static final String TASK_URL_PROPERTY = "taskUrl"; + public static final String BASE_TASK_URL = "https://bulletjournal.us/#/task/"; + public static final String TASK_OWNER_PROPERTY = "owner_name"; + public static final String TASK_OWNER_AVATAR_PROPERTY = "owner_avatar"; + public static final String CLICK_ACTION_KEY = "click_action"; - private static final Logger LOGGER = LoggerFactory.getLogger(MessagingService.class); + private static final String CLICK_ACTION_VALUE = "FLUTTER_NOTIFICATION_CLICK"; + + private FcmClient fcmClient; + + private MailjetEmailClient mailjetClient; + + private DeviceTokenDaoJpa deviceTokenDaoJpa; + + private UserDaoJpa userDaoJpa; + + private UserAliasDaoJpa userAliasDaoJpa; + + private UserClient userClient; + // JOIN GROUP PROPERTIES private static final String GROUP_INVITATION_BASE_URL = - "http://bulletjournal.us/public/notifications/"; + "http://bulletjournal.us/public/notifications/"; + private static final String GROUP_INVITATION_ACCEPT_SUFFIX = "?action=accept"; + private static final String GROUP_INVITATION_DECLINE_SUFFIX = "?action=decline"; + private static final String GROUP_INVITATION_ACCEPT_URL_PROPERTY = "groupInvitationAcceptURL"; + private static final String GROUP_INVITATION_DECLINE_URL_PROPERTY = "groupInvitationDeclineURL"; + private static final String GROUP_INVITER_PROPERTY = "groupInviter"; + private static final String GROUP_INVITER_AVATAR_PROPERTY = "groupInviterAvatar"; + private static final String GROUP_NAME_PROPERTY = "groupName"; + // APP INVITATION PROPERTIES private static final String APP_BASIC_URL = "https://bulletjournal.us/home/index.html"; + private static final String APP_URL_PROPERTY = "appUrl"; + private static final String APP_INVITER_PROPERTY = "appInviter"; + private static final String APP_INVITER_AVATAR_PROPERTY = "appInviterAvatar"; + // Regex Pattern private static final Pattern EMAIL_PATTERN = Pattern - .compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$", Pattern.CASE_INSENSITIVE); - private static final Pattern GROUP_INVITATION_TITLE_PATTERN = Pattern - .compile("(?s)(?<=##).*?(?=##)"); - private final FcmClient fcmClient; - private final MailjetEmailClient mailjetClient; - private final DeviceTokenDaoJpa deviceTokenDaoJpa; - private final UserDaoJpa userDaoJpa; - private final UserAliasDaoJpa userAliasDaoJpa; - private final UserClient userClient; + .compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$", Pattern.CASE_INSENSITIVE); + + private static final Pattern GROUP_INVITATION_TITLE_PATTERN = Pattern + .compile("(?s)(?<=##).*?(?=##)"); @Autowired public MessagingService( - FcmClient fcmClient, - MailjetEmailClient mailjetClient, - DeviceTokenDaoJpa deviceTokenDaoJpa, - UserDaoJpa userDaoJpa, - UserAliasDaoJpa userAliasDaoJpa, - UserClient userClient + FcmClient fcmClient, + MailjetEmailClient mailjetClient, + DeviceTokenDaoJpa deviceTokenDaoJpa, + UserDaoJpa userDaoJpa, + UserAliasDaoJpa userAliasDaoJpa, + UserClient userClient ) { this.fcmClient = fcmClient; this.mailjetClient = mailjetClient; @@ -98,51 +135,36 @@ public void sendEtagUpdateNotificationToUsers(Collection usernames) { LOGGER.info("Sending notification to users: {}", usernames); List deviceTokens = deviceTokenDaoJpa.getTokensByUsers(usernames); List params = deviceTokens.stream() - .map(token -> new FcmMessageParams(token.getToken(), "type", "Notification", CLICK_ACTION_KEY, CLICK_ACTION_VALUE)) - .collect(Collectors.toList()); + .map(token -> new FcmMessageParams(token.getToken(), "type", "Notification", CLICK_ACTION_KEY, CLICK_ACTION_VALUE)) + .collect(Collectors.toList()); fcmClient.sendAllMessagesAsync(params); } - public void sendExportContentToUsers(String sender, ContentExport contentExport) { - List recipients = contentExport.getReceivers(); - - LOGGER.info("Sending exported content to users: {}", recipients); - try { - List emailParamsList = new ArrayList<>(); - Map targetUserEmailMap = getTargetUserEmailMap(new HashSet<>(recipients)); - String senderAvatar = getAvatar(sender); - contentExport.getReceivers().forEach(receiver -> emailParamsList - .add(createEmailParamsForContentExport(sender, - receiver, - targetUserEmailMap, - contentExport.getTitle(), - contentExport.getHtmlContent(), - senderAvatar))); - mailjetClient.sendAllEmailAsync(emailParamsList); - } catch (Exception e) { - LOGGER.error("sendExportContentToUsers failed", e); - } - } - public void sendJoinGroupNotificationEmailsToUser( - List> notificationWithUIDs) { + List> notificationWithUIDs) { LOGGER.info("Sending join group notifications ..."); try { Set distinctTargetUsers = notificationWithUIDs.stream().flatMap(item -> - Stream.of(item.getValue().getTargetUser())) - .collect(Collectors.toSet()); + Stream.of(item.getValue().getTargetUser())) + .collect(Collectors.toSet()); + List targetUsers = userDaoJpa.getUsersByNames(distinctTargetUsers); + Map targetUserEmailMap = new HashMap<>(); + for (User user : targetUsers) { + if (user.getEmail() != null && !user.getEmail().endsWith("@anon.1o24bbs.com")) { + targetUserEmailMap.put(user.getName(), user.getEmail()); + } + } - Map targetUserEmailMap = getTargetUserEmailMap(distinctTargetUsers); Set distinctInviters = notificationWithUIDs.stream().flatMap(item -> - Stream.of(item.getValue().getOriginator())) - .collect(Collectors.toSet()); + Stream.of(item.getValue().getOriginator())) + .collect(Collectors.toSet()); Map inviterAvatarMap = getAvatarMap(new ArrayList<>(distinctInviters)); List emailParamsList = new ArrayList<>(); for (Pair notificationWithUID : notificationWithUIDs) { MailjetEmailParams mailjetEmailParams = - createEmailParamsForGroupInvitation(notificationWithUID, - targetUserEmailMap, inviterAvatarMap); + createEmailParamsForGroupInvitation(notificationWithUID, + targetUserEmailMap, inviterAvatarMap); if (mailjetEmailParams != null) { emailParamsList.add(mailjetEmailParams); } @@ -153,17 +175,6 @@ public void sendJoinGroupNotificationEmailsToUser( } } - private Map getTargetUserEmailMap(Set distinctTargetUsers) { - Map targetUserEmailMap = new HashMap<>(); - List targetUsers = userDaoJpa.getUsersByNames(distinctTargetUsers); - for (User user : targetUsers) { - if (user.getEmail() != null && !user.getEmail().endsWith("@anon.1o24bbs.com")) { - targetUserEmailMap.put(user.getName(), user.getEmail()); - } - } - return targetUserEmailMap; - } - public void sendTaskDueNotificationAndEmailToUsers(List taskList) { LOGGER.info("Sending task due notification for tasks: {}", taskList); try { @@ -178,8 +189,8 @@ public void sendTaskDueNotificationAndEmailToUsers(List taskList) { return; } Set distinctUsers = taskList.stream() - .flatMap(task -> task.getAssignees().stream()) - .collect(Collectors.toSet()); + .flatMap(task -> task.getAssignees().stream()) + .collect(Collectors.toSet()); List tokens = deviceTokenDaoJpa.getTokensByUsers(distinctUsers); List users = userDaoJpa.getUsersByNames(distinctUsers); Map> nameTokensMap = new HashMap<>(); @@ -212,7 +223,7 @@ public void sendTaskDueNotificationAndEmailToUsers(List taskList) { } private List createFcmMessageParamsListFromDueTask( - Task task, Map> nameTokenMap + Task task, Map> nameTokenMap ) { List paramsList = new ArrayList<>(); List targetTokens = new ArrayList<>(); @@ -226,17 +237,17 @@ private List createFcmMessageParamsListFromDueTask( } Pair notificationTitleBody - = new ImmutablePair<>(getTitle(task), ""); + = new ImmutablePair<>(getTitle(task), ""); for (String token : targetTokens) { paramsList.add(new FcmMessageParams( - token, - notificationTitleBody, - "type", - "taskDueNotification", - "taskId", - String.valueOf(task.getId()), - CLICK_ACTION_KEY, - CLICK_ACTION_VALUE + token, + notificationTitleBody, + "type", + "taskDueNotification", + "taskId", + String.valueOf(task.getId()), + CLICK_ACTION_KEY, + CLICK_ACTION_VALUE )); } return paramsList; @@ -248,7 +259,7 @@ public void sendAppInvitationEmailsToUser(String inviter, List emails) { List emailParamsList = new ArrayList<>(); for (String email : new HashSet<>(emails)) { MailjetEmailParams mailjetEmailParams = - createEmailPramsForAppInvitation(inviter, this.getAvatar(inviter), email); + createEmailPramsForAppInvitation(inviter, this.getAvatar(inviter), email); if (mailjetEmailParams != null) { emailParamsList.add(mailjetEmailParams); } @@ -263,28 +274,28 @@ public MailjetEmailParams createEmailPramsForAppInvitation(String inviter, String inviterAvatar, String email) { if (!this.isValidEmailAddr(email)) { - LOGGER.error("Invalid app invitation email address: {}", email); - return null; + LOGGER.error("Invalid app invitation email address: {}", email); + return null; } if (inviter == null || inviterAvatar == null) { - LOGGER.error("APP Invitation: Invalid inviter infor"); - return null; + LOGGER.error("APP Invitation: Invalid inviter infor"); + return null; } String title = inviter + " invited your to join BulletJournal"; return new MailjetEmailParams( - Arrays.asList(new ImmutablePair(null, email)), - title, - null, - Template.APP_INVITATION, - APP_URL_PROPERTY, - APP_BASIC_URL, - APP_INVITER_PROPERTY, - inviter, - APP_INVITER_AVATAR_PROPERTY, - inviterAvatar + Arrays.asList(new ImmutablePair(null, email)), + title, + null, + Template.APP_INVITATION, + APP_URL_PROPERTY, + APP_BASIC_URL, + APP_INVITER_PROPERTY, + inviter, + APP_INVITER_AVATAR_PROPERTY, + inviterAvatar ); } @@ -307,30 +318,9 @@ private String getDueTime(Task task) { return ret.toString(); } - private MailjetEmailParams createEmailParamsForExportContent(String content, Map targetUserEmailMap, - String inviterAvatar) { - - return null; - } - - private MailjetEmailParams createEmailParamsForContentExport(String sender, - String receiver, - Map targetUserEmailMap, - String title, - String htmlContent, - String senderAvatar) { - // TODO: Add Template for Content Export - return new MailjetEmailParams( - Collections.singletonList(new ImmutablePair<>(receiver, targetUserEmailMap.get(receiver))), - title, - htmlContent, - null); - } - - private MailjetEmailParams createEmailParamsForGroupInvitation( - Pair notificationWithUID, Map targetUserEmailMap, - Map inviterAvatarMap + Pair notificationWithUID, Map targetUserEmailMap, + Map inviterAvatarMap ) { Notification notification = notificationWithUID.getValue(); String receiver = notification.getTargetUser(); @@ -365,12 +355,12 @@ private MailjetEmailParams createEmailParamsForGroupInvitation( matchResults.get(2), GROUP_INVITER_AVATAR_PROPERTY, groupInviterAvatar - ); + ); } private List createEmailParamsForDueTask( - Task task, Map nameEmailMap + Task task, Map nameEmailMap ) { List ret = new ArrayList<>(); List assignees = task.getAssignees(); @@ -384,22 +374,22 @@ private List createEmailParamsForDueTask( continue; } MailjetEmailParams params = - new MailjetEmailParams( - Arrays.asList(new ImmutablePair<>(receiver, nameEmailMap.get(receiver))), - getTitle(task), - null, - MailjetEmailClient.Template.TASK_DUE_NOTIFICATION, - TASK_NAME_PROPERTY, - task.getName(), - TIMESTAMP_PROPERTY, - getDueTime(task), - TASK_URL_PROPERTY, - taskUrl, - TASK_OWNER_PROPERTY, - ownerName, - TASK_OWNER_AVATAR_PROPERTY, - ownerAvatar - ); + new MailjetEmailParams( + Arrays.asList(new ImmutablePair<>(receiver, nameEmailMap.get(receiver))), + getTitle(task), + null, + MailjetEmailClient.Template.TASK_DUE_NOTIFICATION, + TASK_NAME_PROPERTY, + task.getName(), + TIMESTAMP_PROPERTY, + getDueTime(task), + TASK_URL_PROPERTY, + taskUrl, + TASK_OWNER_PROPERTY, + ownerName, + TASK_OWNER_AVATAR_PROPERTY, + ownerAvatar + ); JSONArray assigneeInfoList = new JSONArray(); JSONObject selfInfo = new JSONObject(); selfInfo.put(ALIAS_PROPERTY, receiver); From cf41aa80fb877ba63f83b6dcbdada2a7aa4cc886 Mon Sep 17 00:00:00 2001 From: singerdmx Date: Sun, 10 Jan 2021 00:01:45 -0800 Subject: [PATCH 3/3] Add redux logging --- frontend/src/store/index.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/src/store/index.ts b/frontend/src/store/index.ts index 59823fa1b..203342e48 100644 --- a/frontend/src/store/index.ts +++ b/frontend/src/store/index.ts @@ -4,16 +4,19 @@ import createSagaMiddleware from 'redux-saga'; import {combineReducers} from 'redux-starter-kit'; import sagas from './sagas'; import reducers from './reducers'; +import { createLogger } from 'redux-logger'; const reducer = combineReducers(reducers); export type IState = ReturnType; export default () => { const composeEnhancers = composeWithDevTools({}); + const loggerMiddleware = createLogger({ collapsed: true, duration: true }); const sagaMiddleware = createSagaMiddleware(); - const middleware = [sagaMiddleware]; + const middleware = [loggerMiddleware, sagaMiddleware] const middlewares = applyMiddleware(...middleware); const store = createStore(reducer, composeEnhancers(middlewares)); + (window as any).store = store; sagaMiddleware.run(sagas); return store;