diff --git a/build.gradle b/build.gradle index d12e571..b93d4fa 100644 --- a/build.gradle +++ b/build.gradle @@ -119,6 +119,9 @@ dependencies { // Twilio SDK for SMS compile 'com.twilio.sdk:twilio:7.14.5' + // SendGrid SDK to send emails from GCE + compile 'com.sendgrid:sendgrid-java:2.2.2' + testCompile 'junit:junit:4.12' testCompile 'com.github.tomakehurst:wiremock:2.8.0' } diff --git a/src/main/java/io/kamax/mxisd/config/threepid/connector/EmailSendGridConfig.java b/src/main/java/io/kamax/mxisd/config/threepid/connector/EmailSendGridConfig.java new file mode 100644 index 0000000..6c6c0da --- /dev/null +++ b/src/main/java/io/kamax/mxisd/config/threepid/connector/EmailSendGridConfig.java @@ -0,0 +1,202 @@ +/* + * mxisd - Matrix Identity Server Daemon + * Copyright (C) 2017 Maxime Dor + * + * https://max.kamax.io/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package io.kamax.mxisd.config.threepid.connector; + +import io.kamax.mxisd.util.GsonUtil; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import javax.annotation.PostConstruct; + +@Configuration +@ConfigurationProperties("notification.handlers.sendgrid") +public class EmailSendGridConfig { + + public static class EmailTemplate { + + public static class EmailBody { + + private String text; + private String html; + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public String getHtml() { + return html; + } + + public void setHtml(String html) { + this.html = html; + } + + } + + private String subject; + private EmailBody body = new EmailBody(); + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public EmailBody getBody() { + return body; + } + + public void setBody(EmailBody body) { + this.body = body; + } + + } + + public static class Api { + + private String key; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + } + + public static class Identity { + + private String from; + private String name; + + public String getFrom() { + return from; + } + + public void setFrom(String from) { + this.from = from; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + } + + public static class Templates { + + public static class TemplateSession { + + private EmailTemplate local = new EmailTemplate(); + private EmailTemplate remote = new EmailTemplate(); + + public EmailTemplate getLocal() { + return local; + } + + public void setLocal(EmailTemplate local) { + this.local = local; + } + + public EmailTemplate getRemote() { + return remote; + } + + public void setRemote(EmailTemplate remote) { + this.remote = remote; + } + } + + private EmailTemplate invite = new EmailTemplate(); + private TemplateSession session = new TemplateSession(); + + public EmailTemplate getInvite() { + return invite; + } + + public void setInvite(EmailTemplate invite) { + this.invite = invite; + } + + public TemplateSession getSession() { + return session; + } + + public void setSession(TemplateSession session) { + this.session = session; + } + + } + + private Logger log = LoggerFactory.getLogger(EmailSendGridConfig.class); + + private Api api = new Api(); + private Identity identity = new Identity(); + private Templates templates = new Templates(); + + public Api getApi() { + return api; + } + + public void setApi(Api api) { + this.api = api; + } + + public Identity getIdentity() { + return identity; + } + + public void setIdentity(Identity identity) { + this.identity = identity; + } + + public Templates getTemplates() { + return templates; + } + + public void setTemplates(Templates templates) { + this.templates = templates; + } + + @PostConstruct + public void build() { + log.info("--- Email SendGrid connector config ---"); + log.info("API key configured?: {}", StringUtils.isNotBlank(api.getKey())); + log.info("Identity: {}", GsonUtil.build().toJson(identity)); + log.info("Templates: {}", GsonUtil.build().toJson(templates)); + } + +} diff --git a/src/main/java/io/kamax/mxisd/config/threepid/notification/NotificationConfig.java b/src/main/java/io/kamax/mxisd/config/threepid/notification/NotificationConfig.java new file mode 100644 index 0000000..fbba700 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/config/threepid/notification/NotificationConfig.java @@ -0,0 +1,57 @@ +/* + * mxisd - Matrix Identity Server Daemon + * Copyright (C) 2017 Maxime Dor + * + * https://max.kamax.io/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package io.kamax.mxisd.config.threepid.notification; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import javax.annotation.PostConstruct; +import java.util.HashMap; +import java.util.Map; + +@Configuration +@ConfigurationProperties("notification") +public class NotificationConfig { + + private Logger log = LoggerFactory.getLogger(NotificationConfig.class); + + private Map handler = new HashMap<>(); + + public Map getHandler() { + return handler; + } + + public void setHandler(Map handler) { + this.handler = handler; + } + + @PostConstruct + public void build() { + log.info("--- Notification config ---"); + log.info("Handlers:"); + handler.forEach((k, v) -> { + log.info("\t{}: {}", k, v); + }); + } + +} diff --git a/src/main/java/io/kamax/mxisd/notification/INotificationHandler.java b/src/main/java/io/kamax/mxisd/notification/INotificationHandler.java index e42735f..2bfc1e2 100644 --- a/src/main/java/io/kamax/mxisd/notification/INotificationHandler.java +++ b/src/main/java/io/kamax/mxisd/notification/INotificationHandler.java @@ -25,6 +25,8 @@ import io.kamax.mxisd.threepid.session.IThreePidSession; public interface INotificationHandler { + String getId(); + String getMedium(); void sendForInvite(IThreePidInviteReply invite); diff --git a/src/main/java/io/kamax/mxisd/notification/NotificationManager.java b/src/main/java/io/kamax/mxisd/notification/NotificationManager.java index 78a38a2..ef5fbdd 100644 --- a/src/main/java/io/kamax/mxisd/notification/NotificationManager.java +++ b/src/main/java/io/kamax/mxisd/notification/NotificationManager.java @@ -20,9 +20,13 @@ package io.kamax.mxisd.notification; +import io.kamax.mxisd.config.threepid.notification.NotificationConfig; import io.kamax.mxisd.exception.NotImplementedException; import io.kamax.mxisd.invitation.IThreePidInviteReply; import io.kamax.mxisd.threepid.session.IThreePidSession; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -33,12 +37,25 @@ import java.util.Map; @Component public class NotificationManager { + private Logger log = LoggerFactory.getLogger(NotificationManager.class); + private Map handlers; @Autowired - public NotificationManager(List handlers) { + public NotificationManager(NotificationConfig cfg, List handlers) { this.handlers = new HashMap<>(); - handlers.forEach(h -> this.handlers.put(h.getMedium(), h)); + handlers.forEach(h -> { + log.info("Found handler {} for medium {}", h.getId(), h.getMedium()); + String handlerId = cfg.getHandler().get(h.getMedium()); + if (StringUtils.isBlank(handlerId) || StringUtils.equals(handlerId, h.getId())) { + this.handlers.put(h.getMedium(), h); + } + }); + + log.info("--- Notification handler ---"); + this.handlers.forEach((k, v) -> { + log.info("\tHandler for {}: {}", k, v.getId()); + }); } private INotificationHandler ensureMedium(String medium) { @@ -46,7 +63,6 @@ public class NotificationManager { if (handler == null) { throw new NotImplementedException(medium + " is not a supported 3PID medium type"); } - return handler; } diff --git a/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSendGridNotificationHandler.java b/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSendGridNotificationHandler.java new file mode 100644 index 0000000..d7644ee --- /dev/null +++ b/src/main/java/io/kamax/mxisd/threepid/connector/email/EmailSendGridNotificationHandler.java @@ -0,0 +1,136 @@ +/* + * mxisd - Matrix Identity Server Daemon + * Copyright (C) 2017 Maxime Dor + * + * https://max.kamax.io/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package io.kamax.mxisd.threepid.connector.email; + +import com.sendgrid.SendGrid; +import com.sendgrid.SendGridException; +import io.kamax.matrix.ThreePidMedium; +import io.kamax.mxisd.config.MatrixConfig; +import io.kamax.mxisd.config.ServerConfig; +import io.kamax.mxisd.config.threepid.connector.EmailSendGridConfig; +import io.kamax.mxisd.invitation.IThreePidInviteReply; +import io.kamax.mxisd.notification.INotificationHandler; +import io.kamax.mxisd.threepid.notification.PlaceholderNotificationGenerator; +import io.kamax.mxisd.threepid.session.IThreePidSession; +import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import static com.sendgrid.SendGrid.Email; +import static com.sendgrid.SendGrid.Response; +import static io.kamax.mxisd.config.threepid.connector.EmailSendGridConfig.EmailTemplate; + +@Component +public class EmailSendGridNotificationHandler extends PlaceholderNotificationGenerator implements INotificationHandler { + + private Logger log = LoggerFactory.getLogger(EmailSendGridNotificationHandler.class); + + private EmailSendGridConfig cfg; + private SendGrid sendgrid; + + @Autowired + public EmailSendGridNotificationHandler(MatrixConfig mxCfg, ServerConfig srvCfg, EmailSendGridConfig cfg) { + super(mxCfg, srvCfg); + this.cfg = cfg; + this.sendgrid = new SendGrid(cfg.getApi().getKey()); + } + + @Override + public String getId() { + return "sendgrid"; + } + + @Override + public String getMedium() { + return ThreePidMedium.Email.getId(); + } + + protected Email getEmail() { + Email email = new Email(); + email.setFrom(cfg.getIdentity().getFrom()); + email.setFromName(cfg.getIdentity().getName()); + return email; + } + + private String getFromFile(String path) { + try { + return IOUtils.toString(new FileInputStream(path), StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException("Couldn't create notification content using file " + path, e); + } + } + + @Override + public void sendForInvite(IThreePidInviteReply invite) { + EmailTemplate template = cfg.getTemplates().getInvite(); + Email email = getEmail(); + email.setSubject(populateForInvite(invite, template.getSubject())); + email.setText(populateForInvite(invite, getFromFile(template.getBody().getText()))); + email.setHtml(populateForInvite(invite, getFromFile(template.getBody().getHtml()))); + + send(invite.getInvite().getAddress(), email); + } + + @Override + public void sendForValidation(IThreePidSession session) { + EmailTemplate template = cfg.getTemplates().getSession().getLocal(); + Email email = getEmail(); + email.setSubject(populateForValidation(session, template.getSubject())); + email.setText(populateForValidation(session, getFromFile(template.getBody().getText()))); + email.setHtml(populateForValidation(session, getFromFile(template.getBody().getHtml()))); + + send(session.getThreePid().getAddress(), email); + } + + @Override + public void sendForRemoteValidation(IThreePidSession session) { + EmailTemplate template = cfg.getTemplates().getSession().getLocal(); + Email email = getEmail(); + email.setSubject(populateForRemoteValidation(session, template.getSubject())); + email.setText(populateForRemoteValidation(session, getFromFile(template.getBody().getText()))); + email.setHtml(populateForRemoteValidation(session, getFromFile(template.getBody().getHtml()))); + + send(session.getThreePid().getAddress(), email); + } + + private void send(String recipient, Email email) { + try { + email.addTo(recipient); + email.setFrom(cfg.getIdentity().getFrom()); + email.setFromName(cfg.getIdentity().getName()); + Response response = sendgrid.send(email); + if (response.getStatus()) { + log.info("Successfully sent email to {} using SendGrid", recipient); + } else { + throw new RuntimeException("Error sending via SendGrid to " + recipient + ": " + response.getMessage()); + } + } catch (SendGridException e) { + throw new RuntimeException("Unable to send e-mail invite via SendGrid to " + recipient, e); + } + } + +} diff --git a/src/main/java/io/kamax/mxisd/threepid/notification/GenericTemplateNotificationGenerator.java b/src/main/java/io/kamax/mxisd/threepid/notification/GenericTemplateNotificationGenerator.java index bf2ef50..a85cfbc 100644 --- a/src/main/java/io/kamax/mxisd/threepid/notification/GenericTemplateNotificationGenerator.java +++ b/src/main/java/io/kamax/mxisd/threepid/notification/GenericTemplateNotificationGenerator.java @@ -20,17 +20,14 @@ package io.kamax.mxisd.threepid.notification; -import io.kamax.mxisd.ThreePid; import io.kamax.mxisd.config.MatrixConfig; import io.kamax.mxisd.config.ServerConfig; import io.kamax.mxisd.config.threepid.medium.GenericTemplateConfig; -import io.kamax.mxisd.controller.v1.IdentityAPIv1; import io.kamax.mxisd.exception.InternalServerError; import io.kamax.mxisd.invitation.IThreePidInviteReply; import io.kamax.mxisd.threepid.session.IThreePidSession; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.WordUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -43,39 +40,20 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; @Component -public abstract class GenericTemplateNotificationGenerator implements INotificationGenerator { +public abstract class GenericTemplateNotificationGenerator extends PlaceholderNotificationGenerator implements INotificationGenerator { private Logger log = LoggerFactory.getLogger(GenericTemplateNotificationGenerator.class); - private MatrixConfig mxCfg; - private ServerConfig srvCfg; private GenericTemplateConfig cfg; @Autowired private ApplicationContext app; public GenericTemplateNotificationGenerator(MatrixConfig mxCfg, ServerConfig srvCfg, GenericTemplateConfig cfg) { - this.mxCfg = mxCfg; - this.srvCfg = srvCfg; + super(mxCfg, srvCfg); this.cfg = cfg; } - protected String populateForCommon(String body, ThreePid recipient) { - return body; - } - - private String populateCommon(String body, ThreePid recipient) { - body = populateForCommon(body, recipient); - - String domainPretty = WordUtils.capitalizeFully(mxCfg.getDomain()); - body = body.replace("%DOMAIN%", mxCfg.getDomain()); - body = body.replace("%DOMAIN_PRETTY%", domainPretty); - body = body.replace("%RECIPIENT_MEDIUM%", recipient.getMedium()); - body = body.replace("%RECIPIENT_ADDRESS%", recipient.getAddress()); - - return body; - } - private String getTemplateContent(String location) { try { InputStream is = StringUtils.startsWith(location, "classpath:") ? @@ -86,65 +64,22 @@ public abstract class GenericTemplateNotificationGenerator implements INotificat } } - private String getTemplateAndPopulate(String location, ThreePid recipient) { - return populateCommon(getTemplateContent(location), recipient); - } - @Override public String getForInvite(IThreePidInviteReply invite) { - ThreePid tpid = new ThreePid(invite.getInvite().getMedium(), invite.getInvite().getAddress()); - String templateBody = getTemplateAndPopulate(cfg.getInvite(), tpid); - - String senderName = invite.getInvite().getProperties().getOrDefault("sender_display_name", ""); - String senderNameOrId = StringUtils.defaultIfBlank(senderName, invite.getInvite().getSender().getId()); - String roomName = invite.getInvite().getProperties().getOrDefault("room_name", ""); - String roomNameOrId = StringUtils.defaultIfBlank(roomName, invite.getInvite().getRoomId()); - - templateBody = templateBody.replace("%SENDER_ID%", invite.getInvite().getSender().getId()); - templateBody = templateBody.replace("%SENDER_NAME%", senderName); - templateBody = templateBody.replace("%SENDER_NAME_OR_ID%", senderNameOrId); - templateBody = templateBody.replace("%INVITE_MEDIUM%", tpid.getMedium()); - templateBody = templateBody.replace("%INVITE_ADDRESS%", tpid.getAddress()); - templateBody = templateBody.replace("%ROOM_ID%", invite.getInvite().getRoomId()); - templateBody = templateBody.replace("%ROOM_NAME%", roomName); - templateBody = templateBody.replace("%ROOM_NAME_OR_ID%", roomNameOrId); - - return templateBody; + log.info("Generating notification content for 3PID invite"); + return populateForInvite(invite, getTemplateContent(cfg.getInvite())); } @Override public String getForValidation(IThreePidSession session) { log.info("Generating notification content for 3PID Session validation"); - String templateBody = getTemplateAndPopulate(cfg.getSession().getValidation().getLocal(), session.getThreePid()); - - String validationLink = srvCfg.getPublicUrl() + IdentityAPIv1.getValidate( - session.getThreePid().getMedium(), - session.getId(), - session.getSecret(), - session.getToken()); - - templateBody = templateBody.replace("%VALIDATION_LINK%", validationLink); - templateBody = templateBody.replace("%VALIDATION_TOKEN%", session.getToken()); - - return templateBody; + return populateForValidation(session, getTemplateContent(cfg.getSession().getValidation().getLocal())); } @Override public String getForRemoteValidation(IThreePidSession session) { log.info("Generating notification content for remote-only 3PID session"); - String templateBody = getTemplateAndPopulate(cfg.getSession().getValidation().getRemote(), session.getThreePid()); - - String validationLink = srvCfg.getPublicUrl() + IdentityAPIv1.getValidate( - session.getThreePid().getMedium(), - session.getId(), - session.getSecret(), - session.getToken()); - - templateBody = templateBody.replace("%VALIDATION_LINK%", validationLink); - templateBody = templateBody.replace("%VALIDATION_TOKEN%", session.getToken()); - templateBody = templateBody.replace("%NEXT_URL%", validationLink); - - return templateBody; + return populateForRemoteValidation(session, getTemplateContent(cfg.getSession().getValidation().getRemote())); } } diff --git a/src/main/java/io/kamax/mxisd/threepid/notification/PlaceholderNotificationGenerator.java b/src/main/java/io/kamax/mxisd/threepid/notification/PlaceholderNotificationGenerator.java new file mode 100644 index 0000000..7a185b6 --- /dev/null +++ b/src/main/java/io/kamax/mxisd/threepid/notification/PlaceholderNotificationGenerator.java @@ -0,0 +1,89 @@ +/* + * mxisd - Matrix Identity Server Daemon + * Copyright (C) 2017 Maxime Dor + * + * https://max.kamax.io/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package io.kamax.mxisd.threepid.notification; + +import io.kamax.mxisd.ThreePid; +import io.kamax.mxisd.config.MatrixConfig; +import io.kamax.mxisd.config.ServerConfig; +import io.kamax.mxisd.controller.v1.IdentityAPIv1; +import io.kamax.mxisd.invitation.IThreePidInviteReply; +import io.kamax.mxisd.threepid.session.IThreePidSession; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.WordUtils; + +public abstract class PlaceholderNotificationGenerator { + + private MatrixConfig mxCfg; + private ServerConfig srvCfg; + + public PlaceholderNotificationGenerator(MatrixConfig mxCfg, ServerConfig srvCfg) { + this.mxCfg = mxCfg; + this.srvCfg = srvCfg; + } + + protected String populateForCommon(String input, ThreePid recipient) { + String domainPretty = WordUtils.capitalizeFully(mxCfg.getDomain()); + + return input + .replace("%DOMAIN%", mxCfg.getDomain()) + .replace("%DOMAIN_PRETTY%", domainPretty) + .replace("%RECIPIENT_MEDIUM%", recipient.getMedium()) + .replace("%RECIPIENT_ADDRESS%", recipient.getAddress()); + } + + protected String populateForInvite(IThreePidInviteReply invite, String input) { + ThreePid tpid = new ThreePid(invite.getInvite().getMedium(), invite.getInvite().getAddress()); + + String senderName = invite.getInvite().getProperties().getOrDefault("sender_display_name", ""); + String senderNameOrId = StringUtils.defaultIfBlank(senderName, invite.getInvite().getSender().getId()); + String roomName = invite.getInvite().getProperties().getOrDefault("room_name", ""); + String roomNameOrId = StringUtils.defaultIfBlank(roomName, invite.getInvite().getRoomId()); + + return populateForCommon(input, tpid) + .replace("%SENDER_ID%", invite.getInvite().getSender().getId()) + .replace("%SENDER_NAME%", senderName) + .replace("%SENDER_NAME_OR_ID%", senderNameOrId) + .replace("%INVITE_MEDIUM%", tpid.getMedium()) + .replace("%INVITE_ADDRESS%", tpid.getAddress()) + .replace("%ROOM_ID%", invite.getInvite().getRoomId()) + .replace("%ROOM_NAME%", roomName) + .replace("%ROOM_NAME_OR_ID%", roomNameOrId); + } + + protected String populateForValidation(IThreePidSession session, String input) { + String validationLink = srvCfg.getPublicUrl() + IdentityAPIv1.getValidate( + session.getThreePid().getMedium(), + session.getId(), + session.getSecret(), + session.getToken() + ); + + return populateForCommon(input, session.getThreePid()) + .replace("%VALIDATION_LINK%", validationLink) + .replace("%VALIDATION_TOKEN%", session.getToken()) + .replace("%NEXT_URL%", validationLink); + } + + protected String populateForRemoteValidation(IThreePidSession session, String input) { + return populateForValidation(session, input); + } + +} diff --git a/src/main/java/io/kamax/mxisd/threepid/notification/email/EmailNotificationHandler.java b/src/main/java/io/kamax/mxisd/threepid/notification/email/EmailRawNotificationHandler.java similarity index 85% rename from src/main/java/io/kamax/mxisd/threepid/notification/email/EmailNotificationHandler.java rename to src/main/java/io/kamax/mxisd/threepid/notification/email/EmailRawNotificationHandler.java index 8991610..a46f009 100644 --- a/src/main/java/io/kamax/mxisd/threepid/notification/email/EmailNotificationHandler.java +++ b/src/main/java/io/kamax/mxisd/threepid/notification/email/EmailRawNotificationHandler.java @@ -30,16 +30,21 @@ import org.springframework.stereotype.Component; import java.util.List; @Component -public class EmailNotificationHandler extends GenericNotificationHandler { +public class EmailRawNotificationHandler extends GenericNotificationHandler { private EmailConfig cfg; @Autowired - public EmailNotificationHandler(EmailConfig cfg, List generators, List connectors) { + public EmailRawNotificationHandler(EmailConfig cfg, List generators, List connectors) { this.cfg = cfg; process(connectors, generators); } + @Override + public String getId() { + return "raw"; + } + @Override public String getMedium() { return ThreePidMedium.Email.getId(); diff --git a/src/main/java/io/kamax/mxisd/threepid/notification/phone/PhoneNotificationHandler.java b/src/main/java/io/kamax/mxisd/threepid/notification/phone/PhoneNotificationHandler.java index ff651b6..9ba5109 100644 --- a/src/main/java/io/kamax/mxisd/threepid/notification/phone/PhoneNotificationHandler.java +++ b/src/main/java/io/kamax/mxisd/threepid/notification/phone/PhoneNotificationHandler.java @@ -40,6 +40,11 @@ public class PhoneNotificationHandler extends GenericNotificationHandler