Email notification?

So I want to use my own email server, and I want to use SSL/TLS. I'm not very concerned about my password being visible on my local machines, but it would be nice to not have it visible. Anyway, I managed to hack some things together and write my first ever Groovy driver, and it is working for me! My SMTP server supports SSL on port 465 with PLAIN authentication.

This is really not any kind of release. It doesn't check email address formats or server formats, and it uses nasty hacks to send a curl command over telnet to my NAS, and then disconnect when the command completes. I'd love to be able to use curl on the Hubitat, but can't figure out if that's possible. (Are there any ways to perform local shell commands from a driver?)

So anyway, here is the code. I don't have it on GitHub or anything. It's too fragile, and won't work generally, but maybe someone here could look at it and fix my silliness. I'm sure I don't understand the code flow correctly for this.

/**
*   
*   File: telnet-curl-email.groovy
*   Platform: Hubitat
*   Modification History:
*       Date    Time		Who		What
*       v0.0.1  2020-04-02      21:21   @BrianP Initial test
*       v0.0.2  2020-04-03      16:21   @BrianP Trying to disconnect when done
*       v0.0.3  2020-04-03      16:30   @BrianP Fixed missing smtps://
*       v0.1.0  2020-04-03      17:05   @BrianP Things seem to be working
*       v0.1.1  2020-04-03      17:25   @BrianP Trying to get parse/disconnect working better
*       v0.2.0  2020-04-03      18:30   @BrianP This is a real hack but it works for my setup
*       v0.2.1  2020-04-03      20:15   @BrianP Alllow multiple comma-separated recipients
*
*  Copyright 2020 @BrianP
*
*  This software 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 3 of the License, or
*  (at your option) any later version.
*
*  This software 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 this program.  If not, see <https://www.gnu.org/licenses/>.
*
*
*/
def version() {"v0.2.1"}

preferences 
{
	section("Device Settings:") 
	{
		input("telnetServer", "text", title: "Telnet server", description: "Enter address of Telnet server", required: true, displayDuringSetup: true)
		input("telnetPort", "integer", title: "Telnet port", description: "Enter port number, default 23", required: false, defaultvalue: 23, displayDuringSetup: true)
		input("telnetUsername", "text", title: "Telnet username", description: "User ID", required: false, displayDuringSetup: true)
		input("telnetPassword", "text", title: "Telnet password", description: "Password", required: false, displayDuringSetup: true)
	}
	section("SMTP Server Settings:")
	{
		input("emlServer", "text", title: "Email server", description: "Enter SMTP server address", required: true, displayDuringSetup: true)
		input("emlPort", "text", title: "Email port", description: "Enter SMTP server port (SSL required)", required: true, defaultvalue: 465, displayDuringSetup: true)
		input("emlUsername", "text", title: "Email username", description: "Enter SMTP server username", required: true, displayDuringSetup: true)
		input("emlPassword", "text", title: "Email password", description: "Enter SMTP server password", required: true, displayDuringSetup: true)
	}
	section("Email Settings:")
	{
		input("emlTo", "text", title:"To", description: "Enter email address(es) (comma-separated) to which notifications should be sent", required: true, displayDuringSetup: true)
		input("emlFrom", "text", title:"From", description: "Enter email address from which notifications should be sent", required: true, displayDuringSetup: true)
		input("emlSubject", "text", title:"Subject", description: "Enter email subject line", required: true, displayDuringSetup: true)
	}
	input("debugMode", "bool", title: "Enable logging", required: true, defaultValue: true, displayDuringSetup: true)
}

metadata 
{
	definition (name: "Telnet-curl-email", namespace: "BrianP", author: "BrianP")
	{
        capability "Notification"
        capability "Actuator"
	capability "Telnet"        
	}
}

def installed() 
{
	log.info('Telnet-curl-email: installed()')
	initialize()
}

def updated() 
{
	log.info('Telnet-curl-email: updated()')
	initialize()
}

def initialize() 
{
    state.version = version()
	state.lastMsg = ""
	state.LastCode = 0
	state.EmailBody = ""
}

def deviceNotification(message) {

	state.EmailBody = "${message}"
	state.LastCode = 0
	logDebug("Connecting to ${telnetServer}:${telnetPort}")
	
	telnetClose()
	telnetConnect(telnetServer, telnetPort.toInteger(), telnetUsername, telnetPassword)

}

def parse(String msg) 
{
	logDebug("Parse: " + msg)

	if (msg.startsWith('sh: pts')){ // this is a hack that works on my systems
		def emlRcpts = emlTo.split(', *') //support multiple comma-delimited recipients
		String mailRcpts = ''
		emlRcpts.each {
			mailRcpts = mailRcpts + "--mail-rcpt '${it}' "
		}
		def sndCommand = "echo 'To: ${emlTo}\nSubject: ${emlSubject}\nFrom: ${emlFrom}\nContent-Type: text/plain;\n${state.EmailBody}' | curl --url 'smtps://${emlServer}:${emlPort}' --ssl-reqd --mail-from '${emlFrom}' ${mailRcpts}--upload-file '-' --user '${emlUsername}:${emlPassword}'"//WARNING: username and password on command line! >:(

		logDebug("Sending email command")
		hubCmd = sendHubCommand(new hubitat.device.HubAction(sndCommand, hubitat.device.Protocol.TELNET))
	}

	if (msg.startsWith('[~] #')){ // this is a hack that works on my systems
		try {
			telnetClose()
			logDebug("Telnet connection to ${telnetServer} closed.")
		} catch(e) {
			logDebug("Connection already closed, No need to close connection again.")
		}
	}

}

def logDebug(txt) {
    try {
    	if (debugMode) { log.debug("${txt}") }
    } catch(ex) {
    	log.error("logDebug unable to output requested data!")
    }
}

Any comments/help on this?

I'm happy that I have everything under my control, up to the secure transmission to my mail service. I'd really love for the command send and telnet close to not be such nasty hacks, but that's what I managed given my total lack of experience.

I wanted to mention that this logs in to my NAS with a root-privileged account (which explains '[~]Β #' being the prompt that returns when curl is complete). Unfortunately, I haven't figured out a way to enable a non-privileged account to login to my NAS over telnet yet. The built-in telnet daemon is set up to only allow the root user to login. :man_shrugging: This would be so easy to do with a RPi or something, but I don't have one and wanted to get it to work with my existing equipment.

From what I can tell, mailgun no longer has a free tier... at least not after three months of "trial" usage.

What would be really great is if there was a complete e-mail driver that supported TLS... most of us have an ISP-provided SMTP server that can be used as the outgoing server for the volumes that we're talking about.

This has been brought up. I think it’s on a future enhancement list. It seems like it would be somewhat tribal to build this into the platform compared to writing it in groovy.

Here is hoping it makes it higher on the priority list

Perhaps there's a way to switch from Mailgun to Pepipost. They offer an email api and their "Free Trial" terms are "Send Up to 30,000 Emails Free For First 30 Days Then 100/day Free, Forever", no Credit Card required.

2 Likes

This would be a great compliment to HSM imo - I would like to send Home/Away and Arriving and leaving email events to my o365 account for Security audit reasons.

We had a home break-in once and due to the lack of forced entry evidence, it took months of wrangling and pain to get the insurance company to pay up. being able to show an audit trail of our comings and goings would be very helpful if this ever happened again.

1 Like

I applied for Cobra and was denied...Will try MailGun. But it would be great just to be able to put in your outlook.com username and password. I have 3 apps that already do that.

1 Like

FWIW: I found a solution using my Synology NAS + HEmail:

2 Likes