I really wouldn't think that would almost ever happen. I really wish you were compatible with @ritchierich's format.
But thanks for adding the feature!
I really wouldn't think that would almost ever happen. I really wish you were compatible with @ritchierich's format.
But thanks for adding the feature!
@kahn-hubitat happy to work with you to make something consistent. I considered including other attributes such as To but decided against it for my initial release. One thought is to require an “object/map” be passed via message string and our code could look for message starting with { and ending with }. For example:
{Subject:Email Subject, To:user@example.com, Message: This is a test}
Then code would parse the string to JSON object and gather the values and substitute from default settings if entered. This wouldn’t require prefixes and keys could be entered in any order but it will require a Message key.
Interesting but no need to change the message as i want to still allow that at the end so that anything in place works without changes.
I was also thinking of leaving what have done
And just adding the subject: header and then it would work with what you have and that would by far be simplest.
I also could easily alleviate the order dependency with what i have by checking at top with a big compound if and wrapping the code in a loop but figured it wasn't necessary as the functionality is already there.
But if you implement something with {header: value, header: value }, Message
I would use your code
The cc case was a slightly more complicated for me as it adds a new header not just swap one.
Also what would happen with multiple subjects or multiple froms as the syntax would allow it.
Ok for.now i will just two ver 4.91 and add the subject: header and then see what shakes out.
Rambling done.
2 sec. change
new version 4.91
@kahn-hubitat I just tested this in my app and it works. Message sent would be:
{Subject:Email Subject , Message:Email body, To:name@example.com}
Only difference is my Gmail notification won't accept a From since that is defaulted by the API.
I tried to convert the string to a JSON object but ran into issues since it would require quotes around the key and value so came up with a different method. Hopefully this works in your app:
if (message.startsWith("{") && message.endsWith("}")) {
message = message.replace("{", "")
message = message.replace("}", "")
def messageSplit = message.split(",")
def messageObject = [:]
for (int i = 0; i < messageSplit.size(); i++) {
def messagePart = messageSplit[i]
def messagePartSplit = messagePart.split(":")
if (messagePartSplit.size() == 2) {
messageObject[messagePartSplit[0]] = messagePartSplit[1].trim()
}
}
toEmail = (messageObject.containsKey("To")) ? messageObject.To : toEmail
subject = (messageObject.containsKey("Subject")) ? messageObject.Subject : subject
message = (messageObject.containsKey("Message")) ? messageObject.Message : message
fromEmail = (messageObject.containsKey("From")) ? messageObject.From : fromEmail
}
That's not gonna work for me as i said it would break all existing stuff to have the closing bracket at the end and the message inside.
Also would break messages with commas in them which is why i.didnt use.split. i could modify it to isolate the begin and end bracket leaving the message after it and then call your code.
crap already had this code in and it breaks the brackets.. not sure what i was trying to do i think pull out the message if passed som xml
if(msgData.substring(0,1) == "{") {
def slurper = new groovy.json.JsonSlurper()
def result = slurper.parseText(msgData)
emlBody = result.Body
emlSubject = (result.Subject != null ? result.Subject : "")
} else {
emlBody = msgData
emlSubject = (Subject != null ? "${Subject}" : "")
}
ya already had this code to parse the subject out of straight xml.. weird. so brackets are not going to work or it will break anyone using this feature.. must have added it for a reason.
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.
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 }
Just tested changing the Subject of an email and it works great! Thanks.
Here is what I did using this in WebCore:
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.
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...
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.
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.
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:
Thank you!
Thank you for the response!