Sendmail - Send email and text notifications, (notification device) no local server needed

  • v 4.92
    the original header replacement above still works
  • but added an alternative message based on ritchierich pseudo xml at the start of the message
    ie
    {header: value, header: value}, this is the message
    or
    {header: value, header: value. Message: this is the message}
    both work.
    Legal header values for replacement are: Subject: From: To: CC: Message:
    order is not important.
    example:
    {Subject: new subject, CC:kahn-zzspam@lgk.com, Message:newmessage here,To: kahn-saved@lgk.com, From: kahn@lgk.com}, this is a test
    or
    {Subject: new subject, CC:kahn-zzspam@lgk.com, Message:newmessage here,To: kahn-saved@lgk.com, From: kahn@lgk.com}

caveat: just notice if you use the message: replacement option the message itself cannot have a colon : in it or it will truncate past the colon.

4 Likes

here is the bulk of the code change

// handle bracket case for ehader replacement
if (emlBody.startsWith("{"))
{

               def newFrom = ""
               def newTo = ""
               def newCC = ""
               def newSubject = ""
               def newMessage = ""
               def headers = ""
               def body = ""
               
               if (state.debug) log.debug "found header directive start {."     
               // now find end and separate
               def sMsg = emlBody.split("}")
               emlBody = emlBody.replace("{", "")
               if (state.debug) log.debug "size = ${sMsg.size()}"
               
               if (sMsg.size() == 2)
               {
                   // now strip out comma on message
                   def cMsg = sMsg[1].split(",")
                   headers = sMsg[0]
                   body = cMsg[1]
                   if (state.debug) log.debug "left side (headers) = $headers, right side (msg} = ${cMsg[1]}, body = $body"
               }
               else 
               {
                   // message must be inside
                   headers = sMsg[0]
                   if (state.debug) log.debug "left side (headers) = $headers, right side blank (message must be in options)!"                     
               }                     
                   //emlBody = cMSg[1]
                   headers = headers.replace("}", "")
                   headers = headers.replace("{", "")
                   def headerSplit = headers.split(",")

                   if (state.debug) log.debug "header split = ${headerSplit} size = ${headerSplit.size()}"
                   for (int i = 0; i < headerSplit.size(); i++) 
                   {                          
	                  def headerPart = headerSplit[i]
	                  def headerPartSplit = headerPart.split(":")
                       
                       if (state.debug) log.debug "part = ${headerPart}"
                    
                    if (headerPart.contains("To")) 
                     {
                         def dh = headerPart.split(":")
                         if (dh.size() == 2) newTo = dh[1].trim() 
                     }
                        
                    if (headerPart.contains("Subject")) 
                     {
                         def dh = headerPart.split(":")
                         if (dh.size() == 2) newSubject = dh[1].trim()
                     }
                     
                    if (headerPart.contains("From")) 
                     {
                       def dh = headerPart.split(":")
                       if (dh.size() == 2) newFrom = dh[1].trim()
                     } 
                       
                     if (headerPart.contains("CC")) 
                     {
                       def dh = headerPart.split(":")
                       if (dh.size() == 2) newCC = dh[1].trim()
                     } 
                       
                     if (headerPart.contains("Message")) 
                     {
                       def dh = headerPart.split(":")
                       if (dh.size() == 2) newMessage = dh[1].trim()
                     }     
                   } // loop
                   
                    if (state.debug) log.debug "newFrom = *${newFrom}*, newTo = *${newTo}*, newSubject = *${newSubject}* newCC = *${newCC}* newMessage = *${newMessage}*"
                   // now handle using the new fields if there
                   if (newFrom != "") From = newFrom
                   if (newTo != "") To = newTo
                   if (newSubject != "") emlSubject = newSubject
                   if (newMessage != "") emlBody = newMessage
                     else emlBody = body
                   if (newCC != "") 
                     {
                       cc = newCC
                       ccFound = true
                     }
                     
           } // starts with }
2 Likes

Just tested changing the Subject of an email and it works great! Thanks.

Here is what I did using this in WebCore:

4 Likes

This project is a great idea. Couple of questions...

Is it attachment capable (local files) or is it just text?

Can you use global varialbes on the driver page instead of header directives?

no for attachments .. where would you get the file anyway from the file manager..

too complicated to pull a file in and start uuencoding it anyway.

second, there is no way to know even what global variable you would want to use nor access. so no to that as well.

1 Like

Not really sure I follow your use case but the stock Notifications app supports Global Variables to be included in the message as of v2.3.4 and Rule Machine does as well. So if the notification you are trying to send comes from one of those apps you can include the GV values within the notification as they get sent to the notification devices and from there to whatever device it is set to send it to Email vs Push vs SMS vs etc...

1 Like

Thanks.. I ended up creating a webcore template to take care of associating gv's and applying them to the directives. Now I can just set them and call it from all my other instances.

1 Like

Hi, I am looking to do SMTP notifications to an internal email server. There will be no need for authentication.

This is a very long thread going back several years so I was wondering if someone could point me to the correct spot to just install the latest version of the app and then the process for just sending over to a local email server. Thanks!

Easiest methos is to use Hubitat Package Manager and search for "sendmail" and install it from there. Otherwise list most community solutions the code links are in the very first post.

3 Likes

As noted, install it from Hubitat Package Manager.

The process/setup is documented above - you create a new device on the Device tab in HE, and then complete the setup of the parent,which then creates the child devices.

Example setup:


Once you save preferences on the parent device it will create the necessary number of children matching the "concurrent messages" setting:
2023-02-01 08_42_38-Chrome Main
2023-02-01 08_43_04-Chrome Main

3 Likes

Thank you!

Thank you for the response!

1 Like

NP...now you're prepared to handle the next initial setup question that gets posted here. :wink:

We'll see...

1 Like

I got SendMail installed and got it connected to my email server. I was able to send test messages successfully but I had some questions. I got 6 test messages, I assume this is because there were 5 children and it was testing all of them? I won't get six messages each time, right?

After creating the Sendmail device, it had the parent device and 5 children (I left it at defaults). When i go into, for example, HSM for water alerts, I see "Sendmail Parent". So I would select this as the notification option, correct? What's the purpose of the child nodes?

And I can use this same Parent device for notifications for multiple different apps within Hubitat right? I am asking because I was reading over the forum and thought I saw somewhere that you had to create separate ones different apps but maybe I misread that.

Sendmail should not (and never has for me) duplicate indvidual messages. Not sure what happened. Can you repeat the duplication?

The children are there to ensure that messages queued up don't get lost...

Yes, you should use it anywhere you want to get notifications, in as many apps as you want to. I use it in all apps where I want text notifications.

i assume that is because you did not use the function to send a test message, but the button to test concurrency.. which it did, send all the messages concurrent based on the number of children. to test one you would fill in the text and use the "send message" or "device notification" button.

correct the parent is the only one that should come up in the list of notification devices.. you can use it for any notification but if you want it to goto a different email you either setup another instance or use the header modification function.

the different ones were before header modification was implemented and you would create a separate instance for each unique email you wanted to send notifications to, it had nothing to do with which app was sending the notification.

Not to interrupt or distract from Kato's issue, but I still have one point of confusion I'm hoping someone can assist me in clarifying.
I understand that telnet is used...but for which element? Is telnet the protocol used to connect to the email server itself? Telnet connections will not be accepted by my email server. However, when I attempt to send a test message, it connects to the specified SMTP port. So what, is it shoehorning telnet into the SMTP port? Or is telnet being used somewhere else in the chain, entirely?
I'm getting errors codes from the email server, so something isn't set up correctly.

Thank you!

Thanks to both Kahn and Danabw for the responses. Kahn is correct. I was just using the button to test. I hadn't yet incorporated it into a rule for notification. I think it should work based upon your responses and will test it soon.

1 Like

Telnet is just a communication protocol. You can use it connect to many different things assuming the other end is listening on a specified port. If you specified port 25 when connecting to your email server from your telnet client, it should connect. You would have to do additional commands after that such as specifying the recipient, send address, subject, etc., to actually send a message.

1 Like