logo

NJP

Inbound Actions Tips

Import · Sep 26, 2017 · article

For anyone who has created a new Inbound Action you may have found that there are some "gotchas" that can be encountered along the way.

I thought I'd share some of the points I've found useful on my own Inbound Action journey, and I'd like to encourage people to share their own thoughts in the comments section too

Some good starting points

Firstly there are some really good reference pages for Inbound Actions that are important to keep in mind when you are designing/creating Inbound Actions. Planning with these in mind can save a LOT of testing/debugging time later on:

- The flowchart here is invaluable regarding how emails are classified as "New", "Reply", or "Forward"

https://docs.servicenow.com/bundle/istanbul-servicenow-platform/page/administer/notification/concept/inbound-action-types.html

- Another flowchart that outlines how and when Inbound Actions are processed

https://docs.servicenow.com/bundle/jakarta-servicenow-platform/page/administer/notification/concept/inbound-action-processing.html

Now for the tips:

1. Target table

This can cause some confusion since it doesn't always restrict the Inbound Action as you may anticipate. If your inbound email is matched to an existing record, for example by a watermark or record number, then only Inbound Actions associated with that records table will be executed. However if your Inbound Action is for "New" emails, then this field will be used to set the record of the "current" variable that can be used in your script.

Also worth noting here is that if you have an email matched to a record, then the Inbound Actions for that records table, and NOT any parent tables that it extends, will be run.

2. Conditions

There are some built in conditions based on some of the other fields you can set, e.g. Type (None/New/Reply/Forward), but the Conditions field itself is important to use to match the desired Inbound Action to the email being received. Including meaningful conditions here will have multiple benefits, including making debugging/troubleshooting easier, reduce the load on the instance (this gets more important the more Inbound Actions you define), can make log entries more meaningful.

Sometimes you may have more complex conditions that you may need to include in the Script section (discussed in point 7), but as a general rule, if you CAN include the conditions here then it's beneficial.

3. Order

Setting the order appropriately for an Inbound Action often requires you to think of the big picture of how a received email should be processed. I would recommend that you put the most important or specific Inbound Actions with a lower Order, and if you have a "catch-all" Inbound Action it should have a higher number to catch the emails that are not picked up by other Inbound Actions. This field works well in conjunction with the next point on "Stop Processing".

4. Stop processing

This is an option that should be checked if you would like to stop the search for other Inbound Actions if an email matches the defined Conditions on this Inbound Action. If you are also using conditions within your script however, you might like to leave this option unchecked and instead set it within the script at the appropriate point(s). See point 7 for more details.

5. Type

This is used to match the Inbound Action to the appropriate type of received email. As mentioned earlier (link to flowchart at the top of this post) a received email will be classified by the system as either "New", "Reply", or "Forward". You might like to set an Inbound Action to only operate on a specific type, and this can be beneficial for the same reasons as mentioned in point 2.

6. Setting the Target record on the received email

This can be done by the Inbound Action in a number of ways, e.g.

- matching the email to a record based on a watermark in the email

- matching the email to a record based on a record number

- matching the email to a record in the script by using the "current" variable (discussed further in point 7)

- setting the target explicitly in the script, although this is not recommended and should only be used as a last resort, more for reference/reporting purposes (discussed further in point 7)

7. Script (the fun bit!!)

This part of the Inbound Action config is where you will most likely spend quite a bit of time, and there are a number of points I think it's important to mention here.

Encapsulate code

Within your Inbound Action it is good practice to encapsulate your code within a function, and there is one provided conveniently for this purpose

(function runAction(/*GlideRecord*/ current, /*GlideRecord*/ event, /*EmailWrapper*/ email, /*ScopedEmailLogger*/ logger, /*EmailClassifier*/ classifier) {

// Implement email action here

})(current, event, email, logger, classifier);

If you don't encapsulate your code, your Inbound Action may work perfectly fine 99.999% of the time, but it runs the risk of impacting other code in a way you may not anticipate

Current

There is a variable within an Inbound Action called "current", and it is used to reference the record the Inbound Action is acting on. It is also linked to the Target record of the email, so setting the current variable correct will ensure that your Target record and also logging will appear correctly, since if the Target record is not set, then the Inbound Action will report as skipped in the logs.

Performing an update/insert with the variable current is the recommended way to set the Target record for the email, but there might be times when you don't want the Inbound Action to update/create a record, but still want the Target to be set. This can be done in the script with these lines of code, and you may even use a variable other than current here:

sys_email.instance = current.sys_id;

sys_email.target_table = current.getTableName();

Logging

This one is especially important during your initial testing and if you need to perform some troubleshooting later on. When you view a received email in your instance, you will see at the bottom of the page the log entries for the processing of that email. These log entries will report if an Inbound Action was "Processed" or "Skipped", and if skipped, will normally give a reason as to why. However, if your Inbound Action has not successfully set the Target record for the email being processed, then the log entry will report as skipped, even if it WAS processed, and it will include the text "did not create or update".

I like to use logging statements in my code while testing or troubleshooting to confirm what the code is doing, and if it's doing what I HOPED it would do. normally I would use a statement like gs.log("...") for this, but for Inbound Actions I found it more convenient to use logger.logInfo("...") since this was then included in the log entries at the bottom of the page on the email record. This meant that if I was modifying code and reprocessing an email I could see the output easily instead of also having to search in the system log. It is also useful to use logger.logInfo() if for some reason your Inbound Action does not set the Target record of the email, instead you can include an addition log line here stating that the Inbound Action HAS in fact been processed, and not skipped e.g.

logger.logInfo("Processing 'Update Incident from new email'");

Meaningful comments

One of the golden rules, but in the case of Inbound Actions I like to try and include some text in the log statement that identifies which Inbound Action has created it. e.g.

logger.logInfo("'Update Incident from new email' - searching for an existing record");

this then makes it easier to troubleshoot when there are possibly multiple Inbound Actions being triggered.

Conditions

If you would like to perform more complex condition checks, then they can also be included within your script in the form of conditional statements, e.g. IF statements. It's important to keep in mind in this case what you would like to happen if the conditions FAIL. Do you want no further action to be taken for the received email, or would you like the Inbound Action processing to continue to another Inbound Action? If you would like the processing to continue, then you should avoid enabling the Stop processing checkbox in the Inbound Action config, but this same functionality can be set in the code, which brings us to the next tip....

Stop processing

You might also like to consider implementing a "stop processing" when an Inbound Action is successfully processed. This is commonly used if you have included some conditional statements in your script and would only like to stop the processing if the conditions have been met and the appropriate action already taken (see example below)

Here is a quick example Inbound Action I have created as an example of some of these points. The Inbound Action is designed to update the specified Incident when the received email is of type "New":

(function runAction(/*GlideRecord*/ current, /*GlideRecord*/ event, /*EmailWrapper*/ email, /*ScopedEmailLogger*/ logger, /*EmailClassifier*/ classifier) {

//search for the Incident number in the subject

var intpos = email.subject.indexOf("INC");

var length = 10; //length of INC number

var intnumber = email.subject.substr(intpos, length);

//search for the record referenced by the incident number

// in this IF condition, we are also setting current to the target record mentioned in the subject

if (current.get('number', intnumber)){

current.comments = "reply from: " + email.origemail + "\n\n" + email.body_text;

if (gs.hasRole("itil")) {

if (email.body.assign != undefined)

current.assigned_to = email.body.assign;

if (email.body.priority != undefined && isNumeric(email.body.priority))

current.priority = email.body.priority;

}

// this line updates the INC record with the changes, and also sets the Target on the received email

// and sets the log line to "Processed" instead of "Skipped"

current.update();

// if you do not (or cannot) use current, you can set the target manually using these lines

//sys_email.instance = current.sys_id;

//sys_email.target_table = current.getTableName();

// similarly you can add a line to the log which will appear as well as the "Skipping" line, but makes it a little more meaningful

//logger.logInfo("Processing 'Update Incident from new email'");

// this line will stop the system from processing further Inbound Actions, and is useful to put next to "current.update"

event.state="stop_processing";

}

})(current, event, email, logger, classifier);

I think the above tips make it easier for me to create Inbound Actions that work in harmony together, and help to make troubleshooting easier, I hope they might help you too

Have you found your own tips when working with Inbound Actions? I'd love to hear about them in the comments below!

Thanks for reading!

Sam

View original source

https://www.servicenow.com/community/developer-articles/inbound-actions-tips/ta-p/2322860