Hey guys! Are you looking to get more out of your basic email initiation integration? Are you sending emails into xMatters and wish you could pull out pieces of the body to make them useful? Then you've come to the right place!
My name is Kevin, and I'll walk you through the process of improving a basic email initiation workflow to be at least 10* times more useful.
Triggering events from an email in flow designer is as easy as 1 and 2:
- Email trigger step
- Create event step
Super easy and super simple. But this only maps the subject and body as blobs:
And the resulting email is just a wrapper around what we sent in:
I mean that acorn harvester is big business and if we aren't getting our acorns someone's going to hear about it. So instead of just passing the body in, nuts and all, let's parse out each piece and map them to individual properties in the event.
The first thing we need to do is add a couple properties to the form as place holders and don't forget to add these new properties to your email message template.
Use the handy + icon on the form layout to quickly add new properties.
Then, break open the flow designer canvas again and edit the xMatters Create Event Step. Notice we have the new properties as available inputs! Yay! But where are the pills from our email trigger step? Boo.
Well, this is where the power of the flow designer custom steps come in. We'll create a custom step that parses out each property from the body, which will then be mapped to their corresponding place holders in the event step.
Populate the settings for our custom step:
This will just have one input - the body:
And our 3 outputs - priority, application and time:
Parsing the email will depend on the format of your email. Our farm equipment monitor is pretty standard and just has each field listed with a colon and a space separating the label from the value, and a newline separating each pair. Like so:
Priority: High
Application: Acorn harvester
Time: Tue Sep 24 10:03 AM GMT
Our custom steps use a javascript engine to execute the code, and javascript has plenty of tools for slicing and dicing strings. One option would be to do some String.indexOf and chopping the string based on what is found, but I think regular expressions (RegEx) are best suited for a task like this one.
RegExr is a handy site for building and testing your regular expressions.
After some tinkering and poking and more than a little cursing, this is the scriptlett I came up with:
console.log( `Body: \n|${input["body"]}|` );
var body = input['body'];
var priority = body.match( /.*Priority: (.*)(\r\n)/ );
var application = body.match( /.*Application: (.*)(\r\n)/ );
var time = body.match( /.*Time: (.*)(\r\n)?/ );
output['priority'] = (priority.length ? priority[1] : '' );
output['application'] = (application.length ? application[1] : '' );
output['time'] = (time.length ? time[1] : '' );
Let's break down the match stuff. The RegEx part is .*Priority: (.*)\r\n
.... The .*
part looks at any character 0 or more times, then we look for Priority:<space>. This means we found the part that defines the value for Priority. Then comes a capture group:(.*)
. A capture group "holds" the value therein for later use. In our case, this is the value of the Priority we want to extract. We then look for the end of the line which we consider the termination of the value. So make sure each name/value pair is on a separate line.
We repeat for the application and time value, with the exception that for Time, the last one, we add in an extra ? which indicates the preceding capture group, the \r\n, can be found 0 or 1 times. Meaning it is optional. I found this made for easier testing because sometimes I would have a new line at the end and some times I wouldn't and then I would curse the world.
The match function returns an array if stuff was found, and null if not. So the last couple lines inspect this result of this match and if something is found, then dig it out of the array. The first, 0th, position is the full match, the second position is the first capture group, so we grab that one.
Some notes:
- I find that dumping the body and surrounding it with a start and stop character can help with determining exactly what you are matching against.
- Remember that in plain text emails the new line is a \r\n, which is carriage return and new line. Thanks typewriters!
- The javascript String.prototype.match function takes a regular expression and returns an array. I originally thought we needed the "g" flag for a global search, but as noted in the doc, using this flag means the capturing groups will not be returned. The capturing groups are the stuff in ()s:
.*Priority: (.*)(\r\n)
. - I played with making 1 big match, for Priority, Application and Time all at once in one big regex, but I think breaking it into 3 separate searches makes it safer and more flexible for when your email format changes.
Woo! Success!
All Done! I've attached the full comm plan below so you can inspect if needed.
* Figures based on estimates, not guaranteed, results may vary by species.
Comments
0 commentsPlease sign in to leave a comment.