package org.activityinfo.server.mail; import com.google.common.base.Charsets; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import freemarker.template.Configuration; import org.activityinfo.service.DeploymentConfiguration; import org.apache.commons.codec.binary.Base64; import javax.inject.Inject; import javax.mail.MessagingException; import javax.mail.internet.InternetAddress; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.URL; import java.net.URLConnection; import java.util.Arrays; import java.util.logging.Logger; /** * Sends emails through the Postmark API using the HTTP API. * <p/> * <p/> * PostMark is a service for transactional email that help ensure a high * delivery rate. * <p/> * <p/> * The API key can be set in the configuration file with the property * {@code postmark.key } * <p/> * <p/> * The docs are available from * http://developer.postmarkapp.com/developer-build.html */ public class PostmarkMailSender extends MailSender { public static final String POSTMARK_API_KEY = "postmark.key"; private final String apiKey; private static final Logger LOGGER = Logger.getLogger(PostmarkMailSender.class.getName()); @Inject public PostmarkMailSender(DeploymentConfiguration deploymentConfig, Configuration templateCfg) { super(templateCfg); this.apiKey = deploymentConfig.getProperty(POSTMARK_API_KEY); } @Override public void send(Message message) throws MessagingException { try { JsonObject json = toJson(message); postMessage(json); } catch (IOException e) { e.printStackTrace(); } } private void postMessage(JsonObject node) throws IOException { URL url = new URL("http://api.postmarkapp.com/email"); URLConnection conn = url.openConnection(); conn.setDoOutput(true); conn.setRequestProperty("X-Postmark-Server-Token", apiKey); conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); conn.setRequestProperty("Accept", "application/json"); conn.setConnectTimeout(5 * 60 * 1000); conn.setReadTimeout(5 * 60 * 1000); OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), Charsets.UTF_8); writer.write(node.toString()); writer.flush(); String line; BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); while ((line = reader.readLine()) != null) { System.out.println(line); } writer.close(); reader.close(); } private JsonObject toJson(Message message) throws MessagingException, IOException { JsonObject json = new JsonObject(); json.addProperty("From", "notifications@activityinfo.org"); json.addProperty("To", toString(message.getTo())); json.addProperty("Subject", message.getSubject()); if (message.hasTextBody()) { json.addProperty("TextBody", message.getTextBody()); } if (message.hasHtmlBody()) { json.addProperty("HtmlBody", message.getSafeHtmlBody()); } JsonArray attachments = new JsonArray(); for (MessageAttachment part : message.getAttachments()) { JsonObject attachment = new JsonObject(); attachment.addProperty("Name", part.getFilename()); attachment.addProperty("Content", toBase64(part)); attachment.addProperty("ContentType", stripContentType(part.getContentType())); attachments.add(attachment); } if (attachments.size() > 0) { json.add("Attachments", attachments); } if (message.getReplyTo() != null) { json.addProperty("ReplyTo", toString(Arrays.asList(message.getReplyTo()))); } return json; } private String stripContentType(String contentType) { int semicolon = contentType.indexOf(';'); if (semicolon == -1) { return contentType.trim(); } return contentType.substring(0, semicolon).trim(); } private String toBase64(MessageAttachment part) throws IOException { return new String(Base64.encodeBase64(part.getContent())); } private String toString(Iterable<InternetAddress> addresses) { StringBuilder sb = new StringBuilder(); if (addresses != null) { for (InternetAddress address : addresses) { if (sb.length() > 0) { sb.append(", "); } sb.append(address.getAddress()); } } return sb.toString(); } }