- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-23-2025 08:15 PM - edited 04-23-2025 08:15 PM
Hello,
I want to set up an inbound email action that triggers the creation of an RITM and SCTASK based on an existing catalog item and workflow.
However, the work I've done so far results in the email sender receiving the template body but no content. The RITM generated is not part of an existing workflow and therefore does not update the item field, create a child SCTASK record, or follow any other steps outlined in the workflow.
Thank you in advance for any help you can give, and please ask any clarifying questions.
Here's what I've done so far in the following areas:
1. Email Properties
2. Catalog and Workflow
3. Inbound Emails Actions record
1. Email Properties
Enabled email receiving
2. Catalog Item and Workflow
Created the catalog item, activated it, and updated the user criteria so specific requestors could access it (we'll revisit this later).
I created the workflow and linked it to the catalog item via the Process Engine Tab field.
I tested the workflow by submitting a request, and everything worked as expected:
- REQ created and email sent to requester
- RITM created and email sent to requester
- SCTASK created and email sent to the fulfillment team.
3. Inbound Email Actions Record
I created a new record and did the following:
- Named it
- Set Target table to Requested Item [sc_req_item]
- Set Action type to Record Action
- Set Active to True
- Set Stop Processing to True
Tab 1: When to run--see screenshot
Tab 2: Actions
Note: I'm pasting code for three different scripts I created, all of which result in the same issue/problem.
Actions > Field actions are the same for all three scripts.
Turn on ECMAScript2021 toggled OFF
Code Snippet 1
(function process(email, action, event) {
/* 1 ── Security: allow only Senior Leadership */
var leaderGR = new GlideRecord('sys_user_grmember');
leaderGR.addQuery('group', 'a6b9bc4697569110a4b279200153af04'); // SL group :contentReference[oaicite:2]{index=2}​:contentReference[oaicite:3]{index=3}
leaderGR.addQuery('user.email', email.from).query();
if (!leaderGR.next()) { // sender not in the group
event.state = 'stop_processing';
gs.warn('[CTS-REQ] Sender not authorised: ' + email.from);
return;
}
/* 2 ── Create Request + Requested Item */
var req = new GlideRecord('sc_request');
req.initialize();
req.requested_for = leaderGR.user; // caller = sender
req.short_description = email.subject;
var reqID = req.insert();
var ritm = new GlideRecord('sc_req_item');
ritm.initialize();
ritm.request = reqID;
ritm.cat_item = 'a05b23758741aa10802afe28dabb35d1'; // catalog item :contentReference[oaicite:4]{index=4}​:contentReference[oaicite:5]{index=5}
ritm.short_description = email.subject.replace(/^SEN-REQ:\s*/i,'');
ritm.description = email.body_text;
/* 3 ── Map catalog-item variables */
if (email.body.who_is_this_request_for) // variable sys_name from XML :contentReference[oaicite:6]{index=6}​:contentReference[oaicite:7]{index=7}
ritm.variables.who_is_this_request_for = email.body.who_is_this_request_for;
if (email.body.watchlist)
ritm.variables.watchlist = email.body.watchlist;
/* 4 ── Assignment */
ritm.assignment_group = '5697f51f9322de50eeeeb22efaba108e';
var ritmID = ritm.insert();
/* 5 ── Copy attachments & acknowledge */
email.copyAttachments(ritmID, 'sc_req_item');
var reply = new GlideEmailOutbound();
reply.setTo(email.from);
reply.setSubject('Request logged: ' + ritm.number);
reply.setBody('Thank you—your request (' + ritm.number + ') is in progress.');
reply.setWatermark(ritmID);
reply.send();
})(email, action, event);
Code Snippet 2
(function process(email, action, event) {
/* 1 ── Security: allow only Senior Leadership */
var member = new GlideRecord('sys_user_grmember');
member.addQuery('group', 'a6b9bc4697569110a4b279200153af04'); // SL group
member.addQuery('user.email', email.from).query();
if (!member.next()) {
event.state = 'stop_processing';
gs.warn('[CTS-REQ] Sender not authorised: ' + email.from);
return;
}
/* 2 ── Create the Request */
var req = new GlideRecord('sc_request');
req.initialize();
req.requested_for = member.user; // caller = sender
req.short_description = email.subject;
var reqID = req.insert();
/* 3 ── Create the RITM *as system* so cat_item survives ACLs */
var ritmID;
gs.asUser('system', function () {
var ritm = new GlideRecord('sc_req_item');
ritm.initialize();
ritm.request = reqID;
ritm.cat_item = 'A05B23758741AA10802AFE28DABB35D1'; // CTS SL catalog item
ritm.short_description = email.subject.replace(/^SEN-REQ:\s*/i, '');
ritm.description = email.body_text;
/* 3a ─ Map catalog variables */
if (email.body.who_is_this_request_for)
ritm.variables.who_is_this_request_for = email.body.who_is_this_request_for;
if (email.body.watchlist)
ritm.variables.watchlist = email.body.watchlist;
/* 3b ─ Assignment (skip if workflow handles it) */
ritm.assignment_group = '5697f51f9322de50eeeeb22efaba108e';
ritmID = ritm.insert(); // ← workflow/flow now starts
});
/* 4 ─ Attachments */
if (ritmID)
email.copyAttachments(ritmID, 'sc_req_item');
/* 5 ─ Acknowledge – comment-out if you prefer the standard notification */
var ack = new GlideEmailOutbound();
ack.setTo(email.from);
ack.setSubject('Request logged: ' + new GlideRecord('sc_req_item').get(ritmID).number);
ack.setBody('Thank you—your request has been received and is in progress.');
ack.setWatermark(ritmID);
ack.send();
})(email, action, event);
Code Snippet 3
(function process(email, action, event) {
/* 1 ── Security: allow only Senior Leadership */
var member = new GlideRecord('sys_user_grmember');
member.addQuery('group', 'a6b9bc4697569110a4b279200153af04'); // SL group
member.addQuery('user.email', email.from).query();
if (!member.next()) {
event.state = 'stop_processing';
gs.warn('[CTS-REQ] Sender not authorised: ' + email.from);
return;
}
/* 2 ── Build variable object expected by the catalog item */
var vars = {};
if (email.body.who_is_this_request_for)
vars.who_is_this_request_for = email.body.who_is_this_request_for;
if (email.body.watchlist)
vars.watchlist = email.body.watchlist;
/* 3 ── Place order via Service Catalog API (same as portal) */
var cartJS = new sn_sc.CartJS();
var cartId = cartJS.createCartForUser(member.user); // ownership correct
cartJS.addToCart(cartId, 'A05B23758741AA10802AFE28DABB35D1', 1, vars); // item
var requestSysId = cartJS.placeOrder(cartId); // submits & starts flow
/* 4 ── Copy attachments to the new RITM */
var ritmGR = new GlideRecord('sc_req_item');
ritmGR.addQuery('request', requestSysId);
ritmGR.query();
if (ritmGR.next())
email.copyAttachments(ritmGR.sys_id, 'sc_req_item');
/* 5 ── (Optional) Send custom acknowledgement – portal workflow already sends
“Requested Item Opened” & approval emails, so you can omit this section. */
/*
var ack = new GlideEmailOutbound();
ack.setTo(email.from);
ack.setSubject('Request logged: ' + ritmGR.number);
ack.setBody('Thank you—your request (' + ritmGR.number + ') is in progress.');
ack.setWatermark(ritmGR.sys_id);
ack.send();
*/
})(email, action, event);
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-28-2025 07:36 AM
Hello @Ankur Bawiskar,
Unfortunately, I had no luck using the scripted Inbound Action module/record.
Instead, I used the Inbound Email trigger in Workflow Studio, followed by the Submit Catalog Item Request action. And for anyone experiencing the same issue, for context, I had already created a catalog items and its flow as the first stage of the development process. The "Submit Catalog Item Request " action does what CartJS is supposed to do: submit the catalog item via an automated workflow.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-23-2025 08:26 PM
Hi @Xavier_Wharton ,
you have to use CartJS to trigger the workflow
or you can ui catalog api
cartjs is the better approach
you can refer below posts for similar asks
Please mark my answer as helpful/correct if it resolves your query.
Regards,
Chaitanya
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-23-2025 09:03 PM
you can use either CartJS or Cart class for this
check this link and you can do this with inbound flow as well
Create RITM through inbound action by parsing mail body
you should use Snippet 3
I updated this part, I commented your code and added mine with logic to show how you can add variables, if you want to set variables then set, if not then don't set
(function process(email, action, event) {
/* 1 ── Security: allow only Senior Leadership */
var member = new GlideRecord('sys_user_grmember');
member.addQuery('group', 'a6b9bc4697569110a4b279200153af04'); // SL group
member.addQuery('user.email', email.from).query();
if (!member.next()) {
event.state = 'stop_processing';
gs.warn('[CTS-REQ] Sender not authorised: ' + email.from);
return;
}
/* 2 ── Build variable object expected by the catalog item */
var vars = {};
if (email.body.who_is_this_request_for)
vars.who_is_this_request_for = email.body.who_is_this_request_for;
if (email.body.watchlist)
vars.watchlist = email.body.watchlist;
/* 3 ── Place order via Service Catalog API (same as portal) */
/* var cartJS = new sn_sc.CartJS();
var cartId = cartJS.createCartForUser(member.user); // ownership correct
cartJS.addToCart(cartId, 'A05B23758741AA10802AFE28DABB35D1', 1, vars); // item
var requestSysId = cartJS.placeOrder(cartId); // submits & starts flow
*/
var cart = new sn_sc.CartJS();
var request1 = {
'sysparm_id': 'ec10f4fd47266110b81cd855d36d4308', // sys_id of catalog item
'sysparm_quantity': '1',
'variables': {
'requested_for': producer.requested_for, //'8efae6cbdb038b00d6563cae7c961
'short_description': producer.short_description,
'description': producer.description
}
};
var checkoutInfo = cart.checkoutCart();
var cartDetails = cart.orderNow(request);
var requestDetails = cart.submitOrder(request);
// parse the JSON and get request sysId
var requestSysId = requestDetails.request_id;
/* 4 ── Copy attachments to the new RITM */
var ritmGR = new GlideRecord('sc_req_item');
ritmGR.addQuery('request', requestSysId);
ritmGR.query();
if (ritmGR.next())
email.copyAttachments(ritmGR.sys_id, 'sc_req_item');
/* 5 ── (Optional) Send custom acknowledgement – portal workflow already sends
“Requested Item Opened” & approval emails, so you can omit this section. */
/*
var ack = new GlideEmailOutbound();
ack.setTo(email.from);
ack.setSubject('Request logged: ' + ritmGR.number);
ack.setBody('Thank you—your request (' + ritmGR.number + ') is in progress.');
ack.setWatermark(ritmGR.sys_id);
ack.send();
*/
})(email, action, event);
If my response helped please mark it correct and close the thread so that it benefits future readers.
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-24-2025 03:35 PM - edited 04-24-2025 03:37 PM
Hello @Ankur Bawiskar,
I copied and pasted the code you gave me, retained the same form field values within the "When to run" and "Actions" tabs, and maintained the same target table, active = actual, and stop processing = true. However, I am still not having success with the inbound email action. Do you have any other suggestions?
Here is what I encountered:
1. System-generated email sent back to me using the organization's email template, but with no content except for "Thank you, Fulfillment Team". Please take a look at the screenshot below.
2. Here is a screenshot of the email log, followed by a screenshot of the record that was generated.
3. Code applied to Inbound Email Action record script
(function process(email, action, event) {
/* 1 ── Security: allow only Senior Leadership */
var member = new GlideRecord('sys_user_grmember');
member.addQuery('group', 'a6b9bc4697569110a4b279200153af04'); // SL group
member.addQuery('user.email', email.from).query();
if (!member.next()) {
event.state = 'stop_processing';
gs.warn('[CTS-REQ] Sender not authorised: ' + email.from);
return;
}
/* 2 ── Build variable object expected by the catalog item */
var vars = {};
if (email.body.who_is_this_request_for)
vars.who_is_this_request_for = email.body.who_is_this_request_for;
if (email.body.watchlist)
vars.watchlist = email.body.watchlist;
/* 3 ── Place order via Service Catalog API (same as portal) */
/* var cartJS = new sn_sc.CartJS();
var cartId = cartJS.createCartForUser(member.user); // ownership correct
cartJS.addToCart(cartId, 'A05B23758741AA10802AFE28DABB35D1', 1, vars); // item
var requestSysId = cartJS.placeOrder(cartId); // submits & starts flow
*/
var cart = new sn_sc.CartJS();
var request1 = {
'sysparm_id': 'ec10f4fd47266110b81cd855d36d4308', // sys_id of catalog item
'sysparm_quantity': '1',
'variables': {
'requested_for': producer.requested_for, //'8efae6cbdb038b00d6563cae7c961
'short_description': producer.short_description,
'description': producer.description
}
};
var checkoutInfo = cart.checkoutCart();
var cartDetails = cart.orderNow(request);
var requestDetails = cart.submitOrder(request);
// parse the JSON and get request sysId
var requestSysId = requestDetails.request_id;
/* 4 ── Copy attachments to the new RITM */
var ritmGR = new GlideRecord('sc_req_item');
ritmGR.addQuery('request', requestSysId);
ritmGR.query();
if (ritmGR.next())
email.copyAttachments(ritmGR.sys_id, 'sc_req_item');
/* 5 ── (Optional) Send custom acknowledgement – portal workflow already sends
"Requested Item Opened" & approval emails, so you can omit this section. */
/*
var ack = new GlideEmailOutbound();
ack.setTo(email.from);
ack.setSubject('Request logged: ' + ritmGR.number);
ack.setBody('Thank you—your request (' + ritmGR.number + ') is in progress.');
ack.setWatermark(ritmGR.sys_id);
ack.send();
*/
})(email, action, event);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
04-24-2025 08:00 PM
Glad to know that my script worked to create REQ, RITM.
Ensure your flow is configured to Run as System User if you are using flow
If you are using workflow and it didn't trigger then check this link which talks about triggering the workflow from script
If my response helped please mark it correct and close the thread so that it benefits future readers.
Ankur
✨ Certified Technical Architect || ✨ 9x ServiceNow MVP || ✨ ServiceNow Community Leader