Local Email driver using Telnet

Trying to use the telnet capability to attach to a local smtp server. While not the most secure thing the idea is to be able to bypass an external RESTful server like my other driver in order to send email messages.

The issue is I can connect to the server but cannot send any messages. Tried playing around with various parameters (terminate chars CR,LF,CR\LF, terminal type) as well as embedding "\n" & "\r\n"'s in the message strings but no go. I CAN connect, authorize (plain) and send an email via the command line telnet utility in Linux so thought I should be able to do it in HE.

Here are the related code snippets.. this is the connection (which works) - I left the commented out attempts in just to show some of my testing:

    	logDebug("Connecting to ${EmailServer}:${EmailPort}")
	    telnetClose()
	    //telnetConnect([terminalType: 'VT100',termChars:[13,10]],EmailServer, 
EmailPort.toInteger(), null, null)
	    //telnetConnect([termChars:[10]],EmailServer, EmailPort.toInteger(), null, null)
	    //telnetConnect([termChars:[13]],EmailServer, EmailPort.toInteger(), null, null)
	    telnetConnect(EmailServer, EmailPort.toInteger(), null, null)

And here is the parse function.. I am embedding some sendMsgs which may or may not be a good idea but I need to sequence things as the messages appear...

    def parse(String msg) {
       logDebug("parse ${msg}")
	   if (msg.startsWith("220")) {
		   logDebug("Connected!")
		   sendMsg("ehlo ${EmailDomain}")
	   }

	   if (msg.startsWith("250")) {
		   logDebug("Domain Configured!")
	   }

	   if ( msg != state.lastMsg){
		   logDebug("setting state.lastMsg to ${msg}")
		   state.lastMsg = "${msg}"
	   }
	   sendEvent([name: "telnet", value: "${msg}"])
    }

Here is the sendMsg function..

def sendMsg(String msg) {
	logDebug("Sending ${msg}")
	return new hubitat.device.HubAction("${msg}", hubitat.device.Protocol.TELNET)
}

It may not help, but I use the Protocol.TELNET stuff in one of my line-oriented Drivers.

To setup the connection, I use:

telnetConnect([termChars:[13]], ip, (int)port, null, null)

To send something on the connection, I use:

sendHubCommand(new hubitat.device.HubAction(message,
                                            hubitat.device.Protocol.TELNET))

Note: My device only needs the CR char at the end of lines, if you need both then put both in the list (eg. [10,13]). The framework will strip/buffer these out before calling your parse() code, and it'll add them to everything sent via sendHubCommand(), so you can skip that part.

Apart from that, I also have the telnetStatus(String status) method from the "Telnet" capability. It'll get called when there are connectivity-oriented errors.

1 Like

Thanks for the response!

I didn't post my sendMsg function which does the "return sendHubCommand..." thing.. I did try and include different variations of termChars but nothing is working. I figure I am missing something.

For email I think I don't want a persistent connection to the server rather when a notification comes in establish a connection, assemble and send the email and then close the connection.

mmmm.. correction YOU have a "sendHubCommand" but I do not so maybe that's where I missed!

yeah, I was looking at the prior sendMsg() you had posted which was using sendEvent. Looks like you've edited the post to correct that.

Looking at the RFC 5321 - Simple Mail Transfer Protocol, you'll want CR-LF (termChars: [13, 10]) , kinda like your first bit of commented code (minus the terminalType: ... part.

1 Like

Thanks again, just added it and yep that's what I was missing... wooooo!!!!

1 Like

Cool! Glad you got it working. You'll definitely want to telnetClose() after sending an email. No point keeping the connection around.

Yes I agree - don't need that hanging around.

Also planning on upgrading my other HE Driver that uses Node to handle mail relay. The nice thing about that one is I can probably use different security methods to connect and send unlike this one... but we make do with what we have I guess.