/** * * Copyright (c) 2009-2016 Freedomotic team http://freedomotic.com * * This file is part of Freedomotic * * This Program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2, 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 General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * Freedomotic; see the file COPYING. If not, see * <http://www.gnu.org/licenses/>. */ package com.freedomotic.plugins.devices.mailer; import java.io.File; import java.io.IOException; import java.util.Date; import java.util.Properties; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.freedomotic.api.EventTemplate; import com.freedomotic.api.Protocol; import com.freedomotic.app.Freedomotic; import com.freedomotic.events.MessageEvent; import com.freedomotic.exceptions.UnableToExecuteException; import com.freedomotic.reactions.Command; /** * * @author http://www.javapractices.com/topic/TopicAction.do?Id=144 */ public final class Mailer extends Protocol { /** * */ public static final Logger LOG = LoggerFactory.getLogger(Mailer.class.getName()); private final String USERNAME = configuration.getProperty("username"); private final String PASSWORD = configuration.getProperty("password"); private StringBuilder noAttachmentFound = new StringBuilder(); private int sentMails = 0; /** * */ public Mailer() { super("Mailer", "/mailer/mailer-manifest.xml"); addEventListener("app.event.sensor.messages.mail"); } @Override protected void onRun() { // throw new UnsupportedOperationException("Not supported yet."); } @Override protected void onCommand(Command c) throws IOException, UnableToExecuteException { String from = c.getProperty("from"); if (from == null) { from = "your.home@freedomotic.com"; } String to = c.getProperty("to"); if (to == null || to.isEmpty()) { to = USERNAME; } String subject = c.getProperty("subject"); if (subject == null || subject.isEmpty()) { subject = "A notification from Freedomotic"; } final String text = c.getProperty("message"); try { send(from, to, subject, text, this.buildAttachmentFromAbsolutePath(c.getProperty("attachment"))); } catch (MessagingException ex) { this.notifyCriticalError("Error while sending email '" + subject + "' to '" + to + "' for " + Freedomotic.getStackTraceInfo(ex)); } } /** * Returns the attachment file. * * @param path of the attachment file * @return the file or null if it doesn't exist */ private File buildAttachmentFromAbsolutePath(String path) { if (path == null || path.isEmpty()) { return null; } File attachment = new File(path); if (attachment.exists()) { return attachment; } else { LOG.warn("Error while retrieving mail attachment, no existing file at path '{}'", path); noAttachmentFound.append(path); noAttachmentFound.append("\n"); return null; } } /** * Sends the mail with an attachment, if any. * * @param from mail sender * @param to mail receiver * @param subject mail subject * @param text mail body * @param attached file mail attachment, if any * * @throws AddressException * @throws MessagingException * @throws IOException */ private void send(String from, String to, String subject, String text, File attachment) throws AddressException, MessagingException, IOException { Properties props = new Properties(); props.put("mail.smtp.auth", configuration.getProperty("mail.smtp.auth")); if (configuration.getProperty("mail.smtp.connection").equalsIgnoreCase("TLS")) { props.put("mail.smtp.starttls.enable", "true"); } else { props.put("mail.smtp.socketFactory.port", configuration.getProperty("mail.smtp.port")); props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); } props.put("mail.smtp.host", configuration.getProperty("mail.smtp.host")); props.put("mail.smtp.port", configuration.getProperty("mail.smtp.port")); Session session = Session.getInstance(props, new javax.mail.Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(USERNAME, PASSWORD); } }); Message message = new MimeMessage(session); message.setFrom(new InternetAddress(from)); message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to)); message.setSubject(subject); if (attachment != null) { MimeBodyPart textMsg = new MimeBodyPart(); textMsg.setText(text); MimeBodyPart attachedFile = new MimeBodyPart(); attachedFile.attachFile(attachment); Multipart mp = new MimeMultipart(); mp.addBodyPart(textMsg); mp.addBodyPart(attachedFile); message.setContent(mp); } else { if (noAttachmentFound.length() > 0) { text += "\nAttachment(s) not found: " + noAttachmentFound; message.setText(text); } } message.setSentDate(new Date()); Transport.send(message); sentMails++; setDescription(sentMails + " email(s) sent"); } /** * Sends an email with attachment. * * @param from source address * @param to destination address * @param subject mail subject * @param text mail text * @param attachmentPath path of the attachment file * @throws AddressException * @throws MessagingException * @throws IOException */ private void sendWithAttachment(String from, String to, String subject, String text, String attachmentPath) throws AddressException, MessagingException, IOException { File attachment = this.buildAttachmentFromAbsolutePath(attachmentPath); this.send(from, to, subject, text, attachment); } @Override protected boolean canExecute(Command c) { throw new UnsupportedOperationException("Not supported yet."); } @Override protected void onEvent(EventTemplate event) { // filter only mail related events if (event instanceof MessageEvent && event.getProperty("message.type").equalsIgnoreCase("mail")) { MessageEvent mail = (MessageEvent) event; String from = null; String to = null; // set correctly sender and destination address // if not present consider the deafault if (mail.getFrom() == null || mail.getFrom().isEmpty()) { from = "yourhome@freedomotic.com"; } else { from = mail.getFrom(); } if (mail.getTo() == null || mail.getTo().isEmpty()) { to = USERNAME; } else { to = mail.getTo(); } try { this.sendWithAttachment(from, to, null, mail.getText(), mail.getAttachmentPath()); } catch (Exception ex) { this.notifyCriticalError("Error while sending email to '" + mail.getTo() + "' for " + ex.getMessage()); } } } }