The TaskOperations class provides convenience operations for common task-related actions in ServiceNow, such as adding comments, assigning tasks, resolving/closing incidents, and approving change requests.
The TaskOperations class enables you to:
- Add comments or work notes to any task-based record
- Assign tasks to users and assignment groups
- Resolve incidents with resolution notes and close codes
- Close incidents with close notes
- Approve change requests
- Look up task records by their number field
constructor(instance: ServiceNowInstance)import { ServiceNowInstance, TaskOperations } from '@sonisoft/now-sdk-ext-core';
const taskOps = new TaskOperations(instance);Add a comment or work note to a task record.
async addComment(options: AddCommentOptions): Promise<TaskRecord>| Parameter | Type | Description |
|---|---|---|
options |
AddCommentOptions |
The comment options |
| Property | Type | Required | Description |
|---|---|---|---|
table |
string |
Yes | The table name (e.g., "incident", "change_request") |
recordSysId |
string |
Yes | The sys_id of the record to add the comment to |
comment |
string |
Yes | The comment text |
isWorkNote |
boolean |
No | When true, adds a work note instead of a customer-visible comment. Defaults to false. |
Promise<TaskRecord> - The updated task record.
// Add a customer-visible comment
const record = await taskOps.addComment({
table: 'incident',
recordSysId: 'abc123',
comment: 'We are investigating your issue and will update you shortly.'
});
// Add a work note (internal only)
await taskOps.addComment({
table: 'incident',
recordSysId: 'abc123',
comment: 'Escalating to network team for further analysis.',
isWorkNote: true
});Assign a task record to a user and optionally to an assignment group.
async assignTask(options: AssignTaskOptions): Promise<TaskRecord>| Parameter | Type | Description |
|---|---|---|
options |
AssignTaskOptions |
The assignment options |
| Property | Type | Required | Description |
|---|---|---|---|
table |
string |
Yes | The table name (e.g., "incident", "sc_task") |
recordSysId |
string |
Yes | The sys_id of the record to assign |
assignedTo |
string |
Yes | The sys_id or user_name of the user to assign to |
assignmentGroup |
string |
No | Optional sys_id of the assignment group |
Promise<TaskRecord> - The updated task record.
const record = await taskOps.assignTask({
table: 'incident',
recordSysId: 'abc123',
assignedTo: 'admin',
assignmentGroup: 'group-sys-id'
});
console.log(`Assigned to: ${record.sys_id}`);Resolve an incident by setting its state to 6 (Resolved).
async resolveIncident(options: ResolveIncidentOptions): Promise<TaskRecord>| Parameter | Type | Description |
|---|---|---|
options |
ResolveIncidentOptions |
The resolve options |
| Property | Type | Required | Description |
|---|---|---|---|
sysId |
string |
Yes | The sys_id of the incident to resolve |
resolutionNotes |
string |
Yes | Resolution notes describing how the incident was resolved |
closeCode |
string |
No | The close code (e.g., "Solved (Work Around)", "Solved (Permanently)") |
Promise<TaskRecord> - The updated incident record.
const resolved = await taskOps.resolveIncident({
sysId: 'incident-sys-id',
resolutionNotes: 'Restarted the application server, service restored.',
closeCode: 'Solved (Permanently)'
});
console.log(`Incident state: ${resolved.state}`);Close an incident by setting its state to 7 (Closed).
async closeIncident(options: CloseIncidentOptions): Promise<TaskRecord>| Parameter | Type | Description |
|---|---|---|
options |
CloseIncidentOptions |
The close options |
| Property | Type | Required | Description |
|---|---|---|---|
sysId |
string |
Yes | The sys_id of the incident to close |
closeNotes |
string |
Yes | Close notes describing why the incident is being closed |
closeCode |
string |
No | The close code (e.g., "Solved (Work Around)", "Solved (Permanently)") |
Promise<TaskRecord> - The updated incident record.
const closed = await taskOps.closeIncident({
sysId: 'incident-sys-id',
closeNotes: 'Confirmed resolution with the end user. Closing.',
closeCode: 'Solved (Permanently)'
});
console.log(`Incident state: ${closed.state}`);Approve a change request by setting its approval field to 'approved'.
async approveChange(options: ApproveChangeOptions): Promise<TaskRecord>| Parameter | Type | Description |
|---|---|---|
options |
ApproveChangeOptions |
The approval options |
| Property | Type | Required | Description |
|---|---|---|---|
sysId |
string |
Yes | The sys_id of the change request to approve |
comments |
string |
No | Optional comments to include with the approval |
Promise<TaskRecord> - The updated change request record.
const approved = await taskOps.approveChange({
sysId: 'change-sys-id',
comments: 'Reviewed and approved. Deployment window looks good.'
});
console.log(`Change approved: ${approved.sys_id}`);Find a task record by its number field (e.g., "INC0010001").
async findByNumber(table: string, number: string): Promise<TaskRecord | null>| Parameter | Type | Description |
|---|---|---|
table |
string |
The table to search in |
number |
string |
The task number to find |
Promise<TaskRecord | null> - The matching task record, or null if not found.
const incident = await taskOps.findByNumber('incident', 'INC0010001');
if (incident) {
console.log(`Found: ${incident.sys_id}`);
} else {
console.log('Incident not found');
}interface AddCommentOptions {
table: string;
recordSysId: string;
comment: string;
isWorkNote?: boolean;
}interface AssignTaskOptions {
table: string;
recordSysId: string;
assignedTo: string;
assignmentGroup?: string;
}interface ResolveIncidentOptions {
sysId: string;
resolutionNotes: string;
closeCode?: string;
}interface CloseIncidentOptions {
sysId: string;
closeNotes: string;
closeCode?: string;
}interface ApproveChangeOptions {
sysId: string;
comments?: string;
}interface TaskRecord {
sys_id: string;
number?: string;
state?: string;
[key: string]: unknown;
}interface TaskRecordResponse {
result: TaskRecord;
}interface TaskRecordListResponse {
result: TaskRecord[];
}async function manageIncidentLifecycle() {
const taskOps = new TaskOperations(instance);
// Find the incident by number
const incident = await taskOps.findByNumber('incident', 'INC0010042');
if (!incident) {
console.error('Incident not found');
return;
}
// Assign to a technician
await taskOps.assignTask({
table: 'incident',
recordSysId: incident.sys_id,
assignedTo: 'john.smith',
assignmentGroup: 'network-team-sys-id'
});
// Add a work note
await taskOps.addComment({
table: 'incident',
recordSysId: incident.sys_id,
comment: 'Assigned to network team for investigation.',
isWorkNote: true
});
// Resolve the incident
await taskOps.resolveIncident({
sysId: incident.sys_id,
resolutionNotes: 'Network switch rebooted. Connectivity restored.',
closeCode: 'Solved (Permanently)'
});
// Close the incident after confirmation
await taskOps.closeIncident({
sysId: incident.sys_id,
closeNotes: 'User confirmed resolution. Closing ticket.',
closeCode: 'Solved (Permanently)'
});
console.log('Incident lifecycle complete');
}async function bulkApproveChanges(changeNumbers: string[]) {
const taskOps = new TaskOperations(instance);
const results: { number: string; approved: boolean }[] = [];
for (const num of changeNumbers) {
const change = await taskOps.findByNumber('change_request', num);
if (!change) {
console.log(`Change ${num} not found, skipping`);
results.push({ number: num, approved: false });
continue;
}
try {
await taskOps.approveChange({
sysId: change.sys_id,
comments: 'Batch approved via automation'
});
results.push({ number: num, approved: true });
} catch (err) {
console.error(`Failed to approve ${num}: ${(err as Error).message}`);
results.push({ number: num, approved: false });
}
}
console.log('\n=== Approval Summary ===');
results.forEach(r => {
const status = r.approved ? 'Approved' : 'Failed';
console.log(`${r.number}: ${status}`);
});
}async function handleWebhookEvent(event: { incidentNumber: string; message: string; assignTo: string }) {
const taskOps = new TaskOperations(instance);
const incident = await taskOps.findByNumber('incident', event.incidentNumber);
if (!incident) {
throw new Error(`Incident ${event.incidentNumber} not found`);
}
// Add the external message as a comment
await taskOps.addComment({
table: 'incident',
recordSysId: incident.sys_id,
comment: `[External Webhook] ${event.message}`
});
// Reassign if requested
if (event.assignTo) {
await taskOps.assignTask({
table: 'incident',
recordSysId: incident.sys_id,
assignedTo: event.assignTo
});
}
console.log(`Processed webhook for ${event.incidentNumber}`);
}- Use
findByNumberBefore Operations: Look up records by their human-readable number instead of hardcoding sys_ids - Provide Close Codes: Always include a
closeCodewhen resolving or closing incidents for accurate reporting - Distinguish Comments from Work Notes: Use
isWorkNote: truefor internal notes that should not be visible to end users - Handle Null Returns:
findByNumberreturnsnullwhen no record matches; always check before proceeding - Catch Errors on Bulk Operations: When processing multiple records, wrap each call in try/catch to avoid one failure stopping the batch
- Specify Assignment Groups: When assigning tasks, include the
assignmentGroupto ensure proper queue routing