request-management
SKILL.md
Request Management for ServiceNow
Request Management handles service requests from catalog items through fulfillment.
Request Hierarchy
Request (sc_request)
├── Request Item (sc_req_item) - RITM
│ ├── Catalog Tasks (sc_task)
│ └── Variables (sc_item_option_mtom)
└── Request Item
└── Catalog Tasks
Key Tables
| Table | Purpose |
|---|---|
sc_request |
Parent request record |
sc_req_item |
Requested items (RITM) |
sc_task |
Fulfillment tasks |
sc_item_option_mtom |
Variable values |
sc_cat_item |
Catalog item definitions |
Request Items (ES5)
Create Request Programmatically
// Create request and RITM (ES5 ONLY!)
function createServiceRequest(catalogItemName, requestedFor, variables) {
// Get catalog item
var catItem = new GlideRecord("sc_cat_item")
if (!catItem.get("name", catalogItemName)) {
gs.error("Catalog item not found: " + catalogItemName)
return null
}
// Create request
var request = new GlideRecord("sc_request")
request.initialize()
request.setValue("requested_for", requestedFor)
request.setValue("opened_by", gs.getUserID())
request.setValue("description", "Request for " + catalogItemName)
var requestSysId = request.insert()
// Create RITM
var ritm = new GlideRecord("sc_req_item")
ritm.initialize()
ritm.setValue("request", requestSysId)
ritm.setValue("cat_item", catItem.getUniqueValue())
ritm.setValue("requested_for", requestedFor)
ritm.setValue("quantity", 1)
var ritmSysId = ritm.insert()
// Set variables
if (variables) {
setRITMVariables(ritmSysId, variables)
}
return {
request: request.getValue("number"),
ritm: ritm.getValue("number"),
request_sys_id: requestSysId,
ritm_sys_id: ritmSysId,
}
}
function setRITMVariables(ritmSysId, variables) {
var ritm = new GlideRecord("sc_req_item")
if (!ritm.get(ritmSysId)) return
for (var varName in variables) {
if (variables.hasOwnProperty(varName)) {
ritm.variables[varName] = variables[varName]
}
}
ritm.update()
}
Query Request Items
// Get user's open requests (ES5 ONLY!)
function getUserRequests(userSysId, includeCompleted) {
var requests = []
var ritm = new GlideRecord("sc_req_item")
ritm.addQuery("requested_for", userSysId)
if (!includeCompleted) {
ritm.addQuery("state", "!=", "3") // Not Closed Complete
ritm.addQuery("state", "!=", "4") // Not Closed Incomplete
}
ritm.orderByDesc("sys_created_on")
ritm.query()
while (ritm.next()) {
requests.push({
sys_id: ritm.getUniqueValue(),
number: ritm.getValue("number"),
short_description: ritm.getValue("short_description"),
cat_item: ritm.cat_item.getDisplayValue(),
state: ritm.state.getDisplayValue(),
stage: ritm.stage.getDisplayValue(),
opened_at: ritm.getValue("sys_created_on"),
due_date: ritm.getValue("due_date"),
})
}
return requests
}
Fulfillment Tasks (ES5)
Create Catalog Tasks
// Create fulfillment tasks for RITM (ES5 ONLY!)
function createFulfillmentTasks(ritmSysId, taskDefinitions) {
var ritm = new GlideRecord("sc_req_item")
if (!ritm.get(ritmSysId)) {
return []
}
var createdTasks = []
for (var i = 0; i < taskDefinitions.length; i++) {
var taskDef = taskDefinitions[i]
var task = new GlideRecord("sc_task")
task.initialize()
task.setValue("request_item", ritmSysId)
task.setValue("request", ritm.getValue("request"))
task.setValue("short_description", taskDef.description)
task.setValue("assignment_group", taskDef.assignmentGroup)
task.setValue("order", (i + 1) * 100)
// Calculate due date if specified
if (taskDef.daysToComplete) {
var dueDate = new GlideDateTime()
dueDate.addDaysLocalTime(taskDef.daysToComplete)
task.setValue("due_date", dueDate)
}
var taskSysId = task.insert()
createdTasks.push({
sys_id: taskSysId,
number: task.getValue("number"),
})
}
return createdTasks
}
// Example usage
var tasks = createFulfillmentTasks(ritmSysId, [
{ description: "Verify request details", assignmentGroup: "Service Desk", daysToComplete: 1 },
{ description: "Provision access", assignmentGroup: "IAM Team", daysToComplete: 2 },
{ description: "Notify user", assignmentGroup: "Service Desk", daysToComplete: 1 },
])
Auto-close RITM on Task Completion
// Business Rule: after, update, sc_task (ES5 ONLY!)
;(function executeRule(current, previous) {
// Check if task was just closed
if (current.state.changesTo("3") || current.state.changesTo("4")) {
checkAndCloseRITM(current.getValue("request_item"))
}
})(current, previous)
function checkAndCloseRITM(ritmSysId) {
// Check if all tasks are complete
var openTasks = new GlideAggregate("sc_task")
openTasks.addQuery("request_item", ritmSysId)
openTasks.addQuery("state", "NOT IN", "3,4,7") // Not closed or cancelled
openTasks.addAggregate("COUNT")
openTasks.query()
if (openTasks.next()) {
var count = parseInt(openTasks.getAggregate("COUNT"), 10)
if (count === 0) {
// All tasks complete, close RITM
var ritm = new GlideRecord("sc_req_item")
if (ritm.get(ritmSysId)) {
ritm.state = 3 // Closed Complete
ritm.update()
}
}
}
}
Variable Management (ES5)
Access RITM Variables
// Get variable values from RITM (ES5 ONLY!)
function getRITMVariables(ritmSysId) {
var variables = {}
var ritm = new GlideRecord("sc_req_item")
if (!ritm.get(ritmSysId)) {
return variables
}
// Get all variable values
var varValue = new GlideRecord("sc_item_option_mtom")
varValue.addQuery("request_item", ritmSysId)
varValue.query()
while (varValue.next()) {
var varName = varValue.sc_item_option.item_option_new.name.toString()
var value = varValue.getValue("sc_item_option")
// Get display value for reference fields
var varDef = varValue.sc_item_option.item_option_new.getRefRecord()
if (varDef.getValue("type") === "8") {
// Reference
var refRecord = new GlideRecord(varDef.getValue("reference"))
if (refRecord.get(value)) {
variables[varName] = {
value: value,
display_value: refRecord.getDisplayValue(),
}
}
} else {
variables[varName] = {
value: value,
display_value: varValue.sc_item_option.getDisplayValue(),
}
}
}
return variables
}
Validate Variables
// Validate RITM variables (ES5 ONLY!)
function validateRITMVariables(ritmSysId) {
var errors = []
var ritm = new GlideRecord("sc_req_item")
if (!ritm.get(ritmSysId)) {
return ["RITM not found"]
}
// Get catalog item variable definitions
var catItem = ritm.cat_item.getRefRecord()
var varDef = new GlideRecord("item_option_new")
varDef.addQuery("cat_item", catItem.getUniqueValue())
varDef.addQuery("mandatory", true)
varDef.query()
while (varDef.next()) {
var varName = varDef.getValue("name")
var varValue = ritm.variables[varName]
if (!varValue || varValue.toString() === "") {
errors.push("Missing required variable: " + varDef.getValue("question_text"))
}
}
return errors
}
Request Approvals (ES5)
Check Approval Status
// Get approval status for request (ES5 ONLY!)
function getRequestApprovalStatus(requestSysId) {
var approvals = []
var approval = new GlideRecord("sysapproval_approver")
approval.addQuery("sysapproval", requestSysId)
approval.query()
while (approval.next()) {
approvals.push({
approver: approval.approver.getDisplayValue(),
state: approval.state.getDisplayValue(),
comments: approval.getValue("comments"),
sys_updated_on: approval.getValue("sys_updated_on"),
})
}
// Determine overall status
var pending = 0
var approved = 0
var rejected = 0
for (var i = 0; i < approvals.length; i++) {
var state = approvals[i].state
if (state === "Requested") pending++
else if (state === "Approved") approved++
else if (state === "Rejected") rejected++
}
return {
approvals: approvals,
summary: {
pending: pending,
approved: approved,
rejected: rejected,
overall: rejected > 0 ? "Rejected" : pending > 0 ? "Pending" : "Approved",
},
}
}
MCP Tool Integration
Available Tools
| Tool | Purpose |
|---|---|
snow_query_table |
Query requests and RITMs |
snow_find_artifact |
Find catalog items |
snow_execute_script_with_output |
Test request scripts |
snow_create_catalog_item |
Create catalog items |
Example Workflow
// 1. Query open requests
await snow_query_table({
table: "sc_req_item",
query: "state!=3^state!=4^requested_for=javascript:gs.getUserID()",
fields: "number,short_description,cat_item,state,stage",
})
// 2. Get request details
await snow_execute_script_with_output({
script: `
var vars = getRITMVariables('ritm_sys_id');
gs.info(JSON.stringify(vars));
`,
})
// 3. Check approvals
await snow_query_table({
table: "sysapproval_approver",
query: "sysapproval=request_sys_id",
fields: "approver,state,comments",
})
Best Practices
- Clear Descriptions - User-friendly short descriptions
- Variable Validation - Validate before processing
- Task Ordering - Logical fulfillment sequence
- SLA Tracking - Set appropriate due dates
- Notifications - Keep requesters informed
- Approval Rules - Configure appropriate approvals
- Auto-closure - Close RITMs when tasks complete
- ES5 Only - No modern JavaScript syntax
Weekly Installs
52
Repository
groeimetai/snow-flowGitHub Stars
53
First Seen
Jan 22, 2026
Security Audits
Installed on
gemini-cli48
codex47
cursor47
opencode47
github-copilot47
claude-code46