flow-designer

安装量: 54
排名: #13697

安装

npx skills add https://github.com/groeimetai/snow-flow --skill flow-designer

Flow Designer is the modern automation engine in ServiceNow, replacing legacy Workflows for new development.

Flow Designer Components

| Flow | Main automation process | No

| Subflow | Reusable flow logic | Yes

| Action | Single operation (Script, REST, etc.) | Yes

| Spoke | Collection of related actions | Yes

Flow Triggers

Record-Based Triggers

Trigger: Created
Table: incident
Condition: Priority = 1

Trigger: Updated
Table: incident
Condition: State changes to Resolved

Trigger: Created or Updated
Table: change_request
Condition: Risk = High

Schedule Triggers

Trigger: Daily
Time: 02:00 AM
Timezone: America/New_York

Trigger: Weekly
Day: Monday
Time: 08:00 AM

Service Catalog Triggers

Trigger: Service Catalog
Catalog Item: Request New Laptop

Flow Best Practices

1. Use Subflows for Reusability

Main Flow: Incident P1 Handler
├── Trigger: Incident Created (Priority = 1)
├── Action: Log Event
├── Subflow: Notify On-Call Team     ← Reusable!
├── Subflow: Create Major Incident   ← Reusable!
└── Action: Update Incident

2. Error Handling

Flow: Process Integration
├── Try
│   ├── Action: Call REST API
│   ├── Action: Parse Response
│   └── Action: Update Record
├── Catch (all errors)
│   ├── Action: Log Error Details
│   ├── Action: Create Error Task
│   └── Action: Send Alert
└── Always
    └── Action: Cleanup Temp Data

3. Flow Variables

// Input Variables (from trigger)
var incidentSysId = fd_data.trigger.current.sys_id;
var priority = fd_data.trigger.current.priority;

// Scratch Variables (within flow)
fd_data.scratch.approval_required = priority == '1';
fd_data.scratch.notification_sent = false;

// Output Variables (to calling flow/subflow)
fd_data.output.success = true;
fd_data.output.message = 'Processed successfully';

4. Conditions and Branches

If: Priority = Critical
  Then:
    - Notify VP
    - Create Major Incident
    - Page On-Call
  Else If: Priority = High
    - Notify Manager
    - Escalate in 4 hours
  Else:
    - Standard Processing

Custom Actions (Scripts)

Basic Script Action

(function execute(inputs, outputs) {
  // Inputs defined in Action Designer
  var incidentId = inputs.incident_sys_id;
  var newState = inputs.target_state;

  // Process
  var gr = new GlideRecord('incident');
  if (gr.get(incidentId)) {
    gr.setValue('state', newState);
    gr.update();

    // Set outputs
    outputs.success = true;
    outputs.incident_number = gr.getValue('number');
  } else {
    outputs.success = false;
    outputs.error_message = 'Incident not found';
  }
})(inputs, outputs);

Script Action with Error Handling

(function execute(inputs, outputs) {
  try {
    var gr = new GlideRecord(inputs.table_name);
    gr.addEncodedQuery(inputs.query);
    gr.query();

    var records = [];
    while (gr.next()) {
      records.push({
        sys_id: gr.getUniqueValue(),
        display_value: gr.getDisplayValue()
      });
    }

    outputs.records = JSON.stringify(records);
    outputs.count = records.length;
    outputs.success = true;

  } catch (e) {
    outputs.success = false;
    outputs.error_message = e.message;
    // Flow Designer will catch this and route to error handler
    throw new Error('Query failed: ' + e.message);
  }
})(inputs, outputs);

REST Action Example

Configuration

Action: Call External API
Connection: My REST Connection Alias
HTTP Method: POST
Endpoint: /api/v1/tickets

Headers:
  Content-Type: application/json
  Authorization: Bearer ${connection.credential.token}

Request Body:
{
  "title": "${inputs.short_description}",
  "priority": "${inputs.priority}",
  "reporter": "${inputs.caller_email}"
}

Parse Response: JSON

Response Handling

// In a Script step after REST call
var response = fd_data.action_outputs.rest_response;

if (response.status_code == 201) {
  outputs.external_id = response.body.id;
  outputs.success = true;
} else {
  outputs.success = false;
  outputs.error = response.body.error || 'Unknown error';
}

Subflow Patterns

Notification Subflow

Subflow: Send Notification
Inputs:
  - recipient_email (String)
  - subject (String)
  - body (String)
  - priority (String, default: "normal")

Actions:
  1. Look Up: User by email
  2. If: User found
     - Send Email notification
     - Output: success = true
  3. Else:
     - Log Warning
     - Output: success = false

Approval Subflow

Subflow: Request Approval
Inputs:
  - record_sys_id (Reference)
  - approver (Reference: sys_user)
  - approval_message (String)

Actions:
  1. Create: Approval record
  2. Wait: For approval state change
  3. If: Approved
     - Output: approved = true
  4. Else:
     - Output: approved = false
     - Output: rejection_reason = comments

Flow Designer vs Workflow

| Interface | Modern, visual | Legacy

| Reusability | Subflows, Actions | Limited

| Testing | Built-in testing | Manual

| Version Control | Yes | Limited

| Integration Hub | Yes | No

| Performance | Better | Slower

| Recommendation | Use for new development | Maintain existing only

Debugging Flows

Flow Context Logs

// In Script Action
fd_log.info('Processing incident: ' + inputs.incident_number);
fd_log.debug('Input data: ' + JSON.stringify(inputs));
fd_log.warn('Retry attempt: ' + inputs.retry_count);
fd_log.error('Failed to process: ' + error.message);

Flow Execution History

Navigate: Flow Designer > Executions
Filter by: Flow name, Status, Date range
View: Step-by-step execution details

Common Patterns

Pattern 1: SLA Escalation Flow

Trigger: SLA breached (Task SLA)
Actions:
  1. Get: Task details
  2. Get: Assignment group manager
  3. Send: Escalation email
  4. Update: Task priority
  5. Create: Escalation task

Pattern 2: Approval Routing

Trigger: Request Item created
Actions:
  1. If: Amount < $1000
     - Auto-approve
  2. Else If: Amount < $10000
     - Request: Manager approval
  3. Else:
     - Request: VP approval
     - Wait: 3 business days
     - If timeout: Escalate to CFO

Pattern 3: Integration Sync

Trigger: Scheduled (every 15 minutes)
Actions:
  1. Call: External API (get changes)
  2. For Each: Changed record
     a. Look Up: Matching local record
     b. If exists: Update
     c. Else: Create
  3. Log: Sync summary

Performance Tips

  • Use conditions early - Filter before expensive operations

  • Limit loops - Set max iterations on For Each

  • Async where possible - Don't block on slow operations

  • Cache lookups - Store repeated queries in scratch variables

  • Batch operations - Group similar updates together

返回排行榜