Skip to content

Commit 49b769c

Browse files
authored
Merge pull request #396 from zhx828/auto-reply-email
Automatically send clarification for non-institution email with academic account & send intake form to all commercial account
2 parents ceaf31a + 2d35c9c commit 49b769c

15 files changed

+150
-131
lines changed

src/main/java/org/mskcc/cbio/oncokb/config/application/ApplicationProperties.java

+14-5
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ public class ApplicationProperties {
1717
private Boolean sitemapEnabled;
1818
private RedisProperties redis;
1919
private String accountApprovalWhitelist;
20+
private String academicEmailClarifyDomain;
2021
private String googleWebmasterVerification;
21-
private String mailFrom;
22+
private EmailAddresses emailAddresses;
2223
private String tokenUsageCheck;
2324
private String tokenUsageCheckWhitelist;
2425

@@ -46,6 +47,14 @@ public void setAccountApprovalWhitelist(String accountApprovalWhitelist) {
4647
this.accountApprovalWhitelist = accountApprovalWhitelist;
4748
}
4849

50+
public String getAcademicEmailClarifyDomain() {
51+
return academicEmailClarifyDomain;
52+
}
53+
54+
public void setAcademicEmailClarifyDomain(String academicEmailClarifyDomain) {
55+
this.academicEmailClarifyDomain = academicEmailClarifyDomain;
56+
}
57+
4958
public ProjectProfile getProfile() {
5059
return profile;
5160
}
@@ -78,12 +87,12 @@ public void setGoogleWebmasterVerification(String googleWebmasterVerification) {
7887
this.googleWebmasterVerification = googleWebmasterVerification;
7988
}
8089

81-
public String getMailFrom() {
82-
return mailFrom;
90+
public EmailAddresses getEmailAddresses() {
91+
return emailAddresses;
8392
}
8493

85-
public void setMailFrom(String mailFrom) {
86-
this.mailFrom = mailFrom;
94+
public void setEmailAddresses(EmailAddresses emailAddresses) {
95+
this.emailAddresses = emailAddresses;
8796
}
8897

8998
public String getTokenUsageCheck() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.mskcc.cbio.oncokb.config.application;
2+
3+
/**
4+
* Created by Hongxin Zhang on 3/27/20.
5+
*/
6+
public class EmailAddresses {
7+
private String licenseAddress;
8+
private String registrationAddress;
9+
10+
public String getLicenseAddress() {
11+
return licenseAddress;
12+
}
13+
14+
public void setLicenseAddress(String licenseAddress) {
15+
this.licenseAddress = licenseAddress;
16+
}
17+
18+
public String getRegistrationAddress() {
19+
return registrationAddress;
20+
}
21+
22+
public void setRegistrationAddress(String registrationAddress) {
23+
this.registrationAddress = registrationAddress;
24+
}
25+
}

src/main/java/org/mskcc/cbio/oncokb/service/MailService.java

+18-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import javax.mail.MessagingException;
99

10+
import org.mskcc.cbio.oncokb.domain.enumeration.LicenseType;
1011
import org.mskcc.cbio.oncokb.domain.enumeration.MailType;
1112
import org.mskcc.cbio.oncokb.service.dto.UserDTO;
1213
import org.mskcc.cbio.oncokb.service.dto.UserMailsDTO;
@@ -26,10 +27,7 @@
2627
import java.io.File;
2728
import java.nio.charset.StandardCharsets;
2829
import java.time.Instant;
29-
import java.util.Arrays;
30-
import java.util.List;
31-
import java.util.Locale;
32-
import java.util.Optional;
30+
import java.util.*;
3331
import java.util.stream.Collectors;
3432

3533
/**
@@ -182,8 +180,23 @@ public void sendCommercialLicenseReview(UserDTO user) {
182180
sendEmailFromTemplate(user, MailType.LICENSE_REVIEW_COMMERCIAL);
183181
}
184182

183+
public MailType getIntakeFormMailType(LicenseType licenseType) {
184+
switch (licenseType) {
185+
case COMMERCIAL:
186+
return MailType.SEND_INTAKE_FORM_COMMERCIAL;
187+
case HOSPITAL:
188+
return MailType.SEND_INTAKE_FORM_HOSPITAL;
189+
case RESEARCH_IN_COMMERCIAL:
190+
return MailType.SEND_INTAKE_FORM_RESEARCH_COMMERCIAL;
191+
default:
192+
return null;
193+
}
194+
}
185195
public List<String> getMailFrom() {
186-
return Arrays.stream(applicationProperties.getMailFrom().split(",")).map(from -> from.trim()).collect(Collectors.toList());
196+
List<String> mailFrom = new ArrayList<>();
197+
mailFrom.add(applicationProperties.getEmailAddresses().getRegistrationAddress());
198+
mailFrom.add(applicationProperties.getEmailAddresses().getLicenseAddress());
199+
return mailFrom;
187200
}
188201

189202
private Optional<String> getTitleKeyByMailType(MailType mailType) {

src/main/java/org/mskcc/cbio/oncokb/service/SlackService.java

+79-15
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.mskcc.cbio.oncokb.service;
22

3+
import ch.qos.logback.core.Layout;
34
import com.github.seratch.jslack.Slack;
45
import com.github.seratch.jslack.api.model.block.ActionsBlock;
56
import com.github.seratch.jslack.api.model.block.LayoutBlock;
@@ -15,6 +16,7 @@
1516
import org.apache.commons.lang3.StringUtils;
1617
import org.mskcc.cbio.oncokb.config.application.ApplicationProperties;
1718
import org.mskcc.cbio.oncokb.domain.enumeration.LicenseType;
19+
import org.mskcc.cbio.oncokb.domain.enumeration.MailType;
1820
import org.mskcc.cbio.oncokb.service.dto.UserDTO;
1921
import org.slf4j.Logger;
2022
import org.slf4j.LoggerFactory;
@@ -23,6 +25,7 @@
2325

2426
import java.io.IOException;
2527
import java.util.*;
28+
import java.util.stream.Collectors;
2629

2730

2831
/**
@@ -37,10 +40,15 @@ public class SlackService {
3740

3841
private static final String APPROVE_USER = "approve-user";
3942

43+
private static final String ACADEMIC_CLARIFICATION_NOTE = "We have sent the clarification email to the user asking why they could not use an institution email to register.";
44+
private static final String COMMERCIAL_APPROVE_NOTE = "We have sent the intake form automatically.";
45+
4046
private final ApplicationProperties applicationProperties;
47+
private final MailService mailService;
4148

42-
public SlackService(ApplicationProperties applicationProperties) {
49+
public SlackService(ApplicationProperties applicationProperties, MailService mailService) {
4350
this.applicationProperties = applicationProperties;
51+
this.mailService = mailService;
4452
}
4553

4654
@Async
@@ -49,8 +57,22 @@ public void sendUserRegistrationToChannel(UserDTO user) {
4957
if (StringUtils.isEmpty(this.applicationProperties.getUserRegistrationWebhook())) {
5058
log.debug("\tSkipped, the webhook is not configured");
5159
} else {
60+
List<LayoutBlock> layoutBlocks = new ArrayList<>();
61+
if (getAcademicEmailClarifyDomains().size() > 0 &&
62+
getAcademicEmailClarifyDomains().stream().filter(domain -> user.getEmail().endsWith(domain)).collect(Collectors.toList()).size() > 0 &&
63+
user.getLicenseType().equals(LicenseType.ACADEMIC)) {
64+
mailService.sendEmailFromTemplate(user, MailType.CLARIFY_ACADEMIC_NON_INSTITUTE_EMAIL, applicationProperties.getEmailAddresses().getLicenseAddress(), null, null);
65+
layoutBlocks = buildAcademicClarifyBlocks(user);
66+
} else {
67+
layoutBlocks = buildCommercialApprovalBlocks(user);
68+
// Send intake form email
69+
MailType intakeEmailMailType = mailService.getIntakeFormMailType(user.getLicenseType());
70+
if (intakeEmailMailType != null) {
71+
mailService.sendEmailFromTemplate(user, intakeEmailMailType, applicationProperties.getEmailAddresses().getLicenseAddress(), null, null);
72+
}
73+
}
5274
Payload payload = Payload.builder()
53-
.blocks(buildUserApprovalBlocks(user))
75+
.blocks(layoutBlocks)
5476
.build();
5577

5678
Slack slack = Slack.getInstance();
@@ -95,25 +117,67 @@ public Optional<BlockActionPayload.Action> getApproveUserAction(BlockActionPaylo
95117
return blockActionPayload.getActions().stream().filter(action -> action.getActionId().equalsIgnoreCase(APPROVE_USER)).findFirst();
96118
}
97119

120+
private List<String> getAcademicEmailClarifyDomains() {
121+
return Arrays.stream(applicationProperties.getAcademicEmailClarifyDomain().split(",")).map(domain -> domain.trim()).collect(Collectors.toList());
122+
}
123+
98124
private TextObject getTextObject(String title, String content) {
99125
StringBuilder sb = new StringBuilder();
100126
sb.append("*" + title + ":*\n");
101127
sb.append(content);
102128
return MarkdownTextObject.builder().text(sb.toString()).build();
103129
}
104130

105-
private List<LayoutBlock> buildUserApprovalBlocks(UserDTO user) {
131+
private List<LayoutBlock> buildCommercialApprovalBlocks(UserDTO user) {
132+
List<LayoutBlock> blocks = new ArrayList<>();
133+
134+
// Add mention
135+
blocks.add(buildHereMentionBlock());
136+
137+
// Add Title
138+
blocks.add(buildTitleBlock(user));
139+
140+
// Add user info section
141+
blocks.add(buildUserInfoBlock(user));
106142

143+
// Add Approve button
144+
blocks.add(buildApproveButton(user));
145+
146+
// Add Approve button
147+
blocks.add(buildPlainTextBlock(COMMERCIAL_APPROVE_NOTE));
148+
149+
return blocks;
150+
}
151+
152+
private List<LayoutBlock> buildAcademicClarifyBlocks(UserDTO user) {
107153
List<LayoutBlock> blocks = new ArrayList<>();
108-
blocks.add(SectionBlock.builder().text(MarkdownTextObject.builder().text("<!here>").build()).build());
109154

110-
// Title
155+
// Add mention
156+
blocks.add(buildHereMentionBlock());
157+
158+
// Add Title
159+
blocks.add(buildTitleBlock(user));
160+
161+
// Add user info section
162+
blocks.add(buildUserInfoBlock(user));
163+
164+
// Add Approve button
165+
blocks.add(buildPlainTextBlock(ACADEMIC_CLARIFICATION_NOTE));
166+
167+
return blocks;
168+
}
169+
170+
private LayoutBlock buildHereMentionBlock() {
171+
return SectionBlock.builder().text(MarkdownTextObject.builder().text("<!here>").build()).build();
172+
}
173+
174+
private LayoutBlock buildTitleBlock(UserDTO user) {
111175
List<TextObject> title = new ArrayList<>();
112176
title.add(getTextObject("The following user registered an " + user.getLicenseType() + " account", ""));
113-
blocks.add(SectionBlock.builder().fields(title).build());
114-
177+
return SectionBlock.builder().fields(title).build();
178+
}
115179

116-
// User info section
180+
private LayoutBlock buildUserInfoBlock(UserDTO user) {
117181
List<TextObject> userInfo = new ArrayList<>();
118182
userInfo.add(getTextObject("Email", user.getEmail()));
119183
userInfo.add(getTextObject("Name", user.getFirstName() + " " + user.getLastName()));
@@ -122,16 +186,16 @@ private List<LayoutBlock> buildUserApprovalBlocks(UserDTO user) {
122186
userInfo.add(getTextObject("City", user.getCity()));
123187
userInfo.add(getTextObject("Country", user.getCountry()));
124188

125-
blocks.add(SectionBlock.builder().fields(userInfo).build());
189+
return SectionBlock.builder().fields(userInfo).build();
190+
}
126191

127-
// Approve button
192+
private LayoutBlock buildApproveButton(UserDTO user) {
128193
ButtonElement button = ButtonElement.builder()
129194
.text(PlainTextObject.builder().emoji(true).text("Approve").build())
130195
.style("primary")
131196
.actionId(APPROVE_USER)
132197
.value(user.getLogin())
133198
.build();
134-
135199
if (user.getLicenseType() != LicenseType.ACADEMIC) {
136200
ConfirmationDialogObject confirmationDialogObject = ConfirmationDialogObject.builder()
137201
.title(PlainTextObject.builder().text("Are you sure?").build())
@@ -141,10 +205,10 @@ private List<LayoutBlock> buildUserApprovalBlocks(UserDTO user) {
141205
.build();
142206
button.setConfirm(confirmationDialogObject);
143207
}
144-
145-
blocks.add(ActionsBlock.builder().elements(Arrays.asList(button)).build());
146-
147-
return blocks;
208+
return ActionsBlock.builder().elements(Arrays.asList(button)).build();
148209
}
149210

211+
private LayoutBlock buildPlainTextBlock(String text) {
212+
return SectionBlock.builder().text(PlainTextObject.builder().text(text).build()).build();
213+
}
150214
}

src/main/java/org/mskcc/cbio/oncokb/web/rest/AccountResource.java

-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package org.mskcc.cbio.oncokb.web.rest;
22

33

4-
import com.github.seratch.jslack.Slack;
5-
import org.mskcc.cbio.oncokb.config.application.ApplicationProperties;
64
import org.mskcc.cbio.oncokb.domain.Token;
75
import org.mskcc.cbio.oncokb.domain.User;
86
import org.mskcc.cbio.oncokb.domain.enumeration.LicenseType;

src/main/resources/config/application-dev.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,14 @@ application:
140140
user-registration-webhook:
141141
google-webmaster-verification:
142142
account-approval-whitelist:
143-
mail-from:
144143
token-usage-check:
145144
token-usage-check-whitelist:
146145
redis:
147146
type: 'single'
148147
password: 'oncokb-public-redis-password'
149148
single-cache:
150149
address: 'redis://localhost:6379'
150+
email-addresses:
151+
license-address:
152+
registration-address:
153+
academic-email-clarify-domain:

src/main/resources/config/application-prod.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ application:
149149
user-registration-webhook:
150150
google-webmaster-verification:
151151
account-approval-whitelist:
152-
mail-from:
153152
token-usage-check:
154153
token-usage-check-whitelist:
155154
redis:
@@ -158,3 +157,6 @@ application:
158157
master-slave-cache:
159158
master-address: 'redis://oncokb-public-redis-master:6379'
160159
slave-address: 'redis://oncokb-public-redis-slave:6379'
160+
email-addresses:
161+
license-address:
162+
registration-address:

src/main/resources/config/liquibase/changelog/20190823204705_added_entity_Token.xml

-22
Original file line numberDiff line numberDiff line change
@@ -45,27 +45,5 @@
4545
</changeSet>
4646
<!-- jhipster-needle-liquibase-add-changeset - JHipster will add changesets here, do not remove-->
4747

48-
<!--
49-
Load sample data generated with Faker.js
50-
- This data can be easily edited using a CSV editor (or even MS Excel) and
51-
is located in the 'src/main/resources/config/liquibase/fake-data' directory
52-
- By default this data is applied when running with the JHipster 'dev' profile.
53-
This can be customized by adding or removing 'faker' in the 'spring.liquibase.contexts'
54-
Spring Boot configuration key.
55-
-->
56-
<changeSet id="20190823204705-1-data" author="jhipster" context="faker">
57-
<loadData
58-
file="config/liquibase/fake-data/token.csv"
59-
separator=";"
60-
tableName="token">
61-
<column name="id" type="numeric"/>
62-
<column name="token" type="string"/>
63-
<column name="creation" type="datetime"/>
64-
<column name="expiration" type="datetime"/>
65-
<column name="usage_limit" type="numeric"/>
66-
<column name="current_usage" type="numeric"/>
67-
<!-- jhipster-needle-liquibase-add-loadcolumn - JHipster (and/or extensions) can add load columns here, do not remove-->
68-
</loadData>
69-
</changeSet>
7048

7149
</databaseChangeLog>

src/main/resources/config/liquibase/changelog/20190826144658_added_entity_TokenStats.xml

-20
Original file line numberDiff line numberDiff line change
@@ -38,25 +38,5 @@
3838
</changeSet>
3939
<!-- jhipster-needle-liquibase-add-changeset - JHipster will add changesets here, do not remove-->
4040

41-
<!--
42-
Load sample data generated with Faker.js
43-
- This data can be easily edited using a CSV editor (or even MS Excel) and
44-
is located in the 'src/main/resources/config/liquibase/fake-data' directory
45-
- By default this data is applied when running with the JHipster 'dev' profile.
46-
This can be customized by adding or removing 'faker' in the 'spring.liquibase.contexts'
47-
Spring Boot configuration key.
48-
-->
49-
<changeSet id="20190826144658-1-data" author="jhipster" context="faker">
50-
<loadData
51-
file="config/liquibase/fake-data/token_stats.csv"
52-
separator=";"
53-
tableName="token_stats">
54-
<column name="id" type="numeric"/>
55-
<column name="access_ip" type="string"/>
56-
<column name="resource" type="string"/>
57-
<column name="access_time" type="datetime"/>
58-
<!-- jhipster-needle-liquibase-add-loadcolumn - JHipster (and/or extensions) can add load columns here, do not remove-->
59-
</loadData>
60-
</changeSet>
6141

6242
</databaseChangeLog>

src/main/resources/config/liquibase/changelog/20190826161330_added_entity_UserDetails.xml

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
<column name="city" type="string"/>
6767
<column name="country" type="string"/>
6868
<column name="address" type="string"/>
69+
<column name="user_id" type="numeric"/>
6970
<!-- jhipster-needle-liquibase-add-loadcolumn - JHipster (and/or extensions) can add load columns here, do not remove-->
7071
</loadData>
7172
</changeSet>

0 commit comments

Comments
 (0)