snow-flow 1.3.16 → 1.3.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +56 -68
- package/COMMIT_MESSAGE.txt +31 -0
- package/README.md +28 -25
- package/action-v2-implementation.js +338 -0
- package/decode-action-values.js +164 -0
- package/dist/agents/index.js +1 -4
- package/dist/agents/queen-agent.js +3 -1
- package/dist/cli.js +50 -30
- package/dist/mcp/servicenow-deployment-mcp-refactored.js +3 -0
- package/dist/mcp/servicenow-deployment-mcp.js +135 -0
- package/dist/mcp/servicenow-flow-composer-mcp.js +208 -40
- package/dist/mcp/servicenow-platform-development-mcp.js +27 -2
- package/dist/mcp/servicenow-update-set-mcp-refactored.js +4 -0
- package/dist/mcp/servicenow-update-set-mcp.js +4 -0
- package/dist/mcp/servicenow-xml-flow-mcp.js +120 -7
- package/dist/types/index.js +0 -1
- package/dist/utils/improved-flow-xml-generator.js +68 -10
- package/dist/utils/xml-first-flow-generator.js +23 -32
- package/package.json +1 -1
package/CLAUDE.md
CHANGED
|
@@ -38,21 +38,15 @@ const gapAnalysis = await analyzeGaps("your objective", mcpTools, logger, {
|
|
|
38
38
|
console.log('🧠 Queen Agent spawning 6+ parallel agents for 2.8x faster development...');
|
|
39
39
|
|
|
40
40
|
// 5. MANDATORY: Real ServiceNow deployment
|
|
41
|
-
// For flows: Use XML-first approach (
|
|
41
|
+
// For flows: Use XML-first approach with full automation (NEW v1.3.17!)
|
|
42
42
|
if (isFlowDesignerTask) {
|
|
43
|
-
// XML generation
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
//
|
|
47
|
-
const deployment = await snow_deploy({
|
|
48
|
-
type: "xml_update_set",
|
|
49
|
-
xml_file_path: xmlResult.filePath,
|
|
50
|
-
auto_preview: true,
|
|
51
|
-
auto_commit: true
|
|
43
|
+
// ✅ SINGLE COMMAND: XML generation + automatic deployment
|
|
44
|
+
const deployment = await snow_create_flow({
|
|
45
|
+
instruction: "your natural language flow description",
|
|
46
|
+
deploy_immediately: true // 🚀 Fully automated: Generate → Import → Preview → Commit
|
|
52
47
|
});
|
|
53
48
|
|
|
54
|
-
//
|
|
55
|
-
console.log(`Deploy with: snow-flow deploy-xml "${xmlResult.filePath}"`);
|
|
49
|
+
// That's it! Flow is now live in ServiceNow Flow Designer
|
|
56
50
|
} else {
|
|
57
51
|
// For widgets, applications, scripts: Use standard MCP deployment
|
|
58
52
|
const deployment = await snow_deploy({
|
|
@@ -226,52 +220,42 @@ When you run any flow-related swarm command, Snow-flow automatically:
|
|
|
226
220
|
- `sys_hub_action_instance` - All flow activities (approval, notification, etc.)
|
|
227
221
|
- `sys_hub_flow_logic` - Activity connections and flow paths
|
|
228
222
|
|
|
229
|
-
4. **🚀
|
|
223
|
+
4. **🚀 Fully Automated Deployment** (NEW v1.3.17!):
|
|
230
224
|
```bash
|
|
231
|
-
🚀 Auto-Deploy enabled -
|
|
232
|
-
|
|
233
|
-
|
|
225
|
+
🚀 Auto-Deploy enabled - deploying directly to ServiceNow...
|
|
226
|
+
✅ XML imported successfully (sys_id: abc123...)
|
|
227
|
+
✅ Update set loaded: Flow_Import_2025
|
|
228
|
+
🔍 Preview completed with no problems
|
|
229
|
+
✅ Update set committed successfully!
|
|
230
|
+
🎉 Flow is ready in Flow Designer!
|
|
234
231
|
```
|
|
235
232
|
|
|
236
|
-
### 🚀
|
|
233
|
+
### 🚀 Zero-Manual-Steps Deployment
|
|
237
234
|
|
|
238
|
-
|
|
239
|
-
# Deploy any generated XML flow directly to ServiceNow
|
|
240
|
-
snow-flow deploy-xml flow-update-sets/my_flow.xml
|
|
235
|
+
**No commands needed!** Everything happens automatically in one swarm call:
|
|
241
236
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
**
|
|
248
|
-
|
|
249
|
-
2. ✅ **Load**: Loads the update set into local update sets
|
|
250
|
-
3. ✅ **Preview**: Checks for problems and conflicts
|
|
251
|
-
4. ✅ **Commit**: Auto-commits if preview is clean
|
|
252
|
-
5. ✅ **Verify**: Confirms flow is available in Flow Designer
|
|
237
|
+
**What happens automatically:**
|
|
238
|
+
1. ✅ **Generate**: Creates production-ready Update Set XML
|
|
239
|
+
2. ✅ **Import**: Uploads XML to ServiceNow as remote update set
|
|
240
|
+
3. ✅ **Load**: Loads the update set into local update sets
|
|
241
|
+
4. ✅ **Preview**: Checks for problems and conflicts
|
|
242
|
+
5. ✅ **Commit**: Auto-commits if preview is clean
|
|
243
|
+
6. ✅ **Verify**: Confirms flow is available in Flow Designer
|
|
253
244
|
|
|
254
245
|
### 🎯 Complete Flow Development Workflow
|
|
255
246
|
|
|
256
|
-
**End-to-End Flow Creation (Zero Manual Steps):**
|
|
247
|
+
**End-to-End Flow Creation (Truly Zero Manual Steps):**
|
|
257
248
|
|
|
258
249
|
```bash
|
|
259
|
-
#
|
|
250
|
+
# Single command creates AND deploys flow automatically!
|
|
260
251
|
snow-flow swarm "create incident escalation flow with email notifications"
|
|
261
252
|
|
|
262
|
-
# Output:
|
|
253
|
+
# Complete Output:
|
|
263
254
|
# 🔧 Flow Designer Detected - Using XML-First Approach!
|
|
255
|
+
# 📋 Creating production-ready ServiceNow flow XML...
|
|
264
256
|
# ✅ XML Generated Successfully!
|
|
265
257
|
# 📁 File saved to: flow-update-sets/incident_escalation_flow.xml
|
|
266
|
-
# 🚀 Auto-Deploy enabled -
|
|
267
|
-
# 💡 To deploy, use the following command:
|
|
268
|
-
# snow-flow deploy-xml "flow-update-sets/incident_escalation_flow.xml"
|
|
269
|
-
|
|
270
|
-
# 2. Deploy to ServiceNow (one command!)
|
|
271
|
-
snow-flow deploy-xml flow-update-sets/incident_escalation_flow.xml
|
|
272
|
-
|
|
273
|
-
# Output:
|
|
274
|
-
# 📦 Deploying XML Update Set: flow-update-sets/incident_escalation_flow.xml
|
|
258
|
+
# 🚀 Auto-Deploy enabled - deploying directly to ServiceNow...
|
|
275
259
|
# ✅ XML imported successfully (sys_id: abc123...)
|
|
276
260
|
# ✅ Update set loaded: Incident_Escalation_Flow_Import
|
|
277
261
|
# 🔍 Previewing update set...
|
|
@@ -279,37 +263,41 @@ snow-flow deploy-xml flow-update-sets/incident_escalation_flow.xml
|
|
|
279
263
|
# 🚀 Committing update set...
|
|
280
264
|
# ✅ Update Set committed successfully!
|
|
281
265
|
# 📍 Navigate to Flow Designer > Designer to see your flow
|
|
282
|
-
# 🎉
|
|
266
|
+
# 🎉 Flow deployed and ready to use!
|
|
283
267
|
```
|
|
284
268
|
|
|
285
|
-
|
|
269
|
+
**That's it! One command, zero manual steps.** 🚀
|
|
286
270
|
|
|
287
|
-
|
|
271
|
+
### 🔧 Advanced Auto-Deployment Features
|
|
272
|
+
|
|
273
|
+
**Built-in Safety & Intelligence**:
|
|
288
274
|
- **Preview Problems Detection**: Automatically detects and reports conflicts
|
|
289
|
-
- **Safe Auto-Commit**: Only commits if preview is completely clean
|
|
290
|
-
- **Graceful Fallbacks**: Provides manual
|
|
275
|
+
- **Safe Auto-Commit**: Only commits if preview is completely clean
|
|
276
|
+
- **Graceful Fallbacks**: Provides manual instructions if auto-deployment fails
|
|
291
277
|
- **Authentication Validation**: Ensures valid ServiceNow connection before deployment
|
|
278
|
+
- **Error Recovery**: Intelligent retry and fallback strategies
|
|
292
279
|
|
|
293
|
-
**
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
280
|
+
**What Happens Behind the Scenes**:
|
|
281
|
+
```javascript
|
|
282
|
+
// When you run: snow-flow swarm "create approval flow"
|
|
283
|
+
await snow_create_flow({
|
|
284
|
+
instruction: "create approval flow",
|
|
285
|
+
deploy_immediately: true // This triggers all safety checks:
|
|
286
|
+
});
|
|
300
287
|
|
|
301
|
-
|
|
302
|
-
|
|
288
|
+
// 1. ✅ Authentication check
|
|
289
|
+
// 2. ✅ XML generation with validation
|
|
290
|
+
// 3. ✅ Import to ServiceNow as remote update set
|
|
291
|
+
// 4. ✅ Preview for conflicts
|
|
292
|
+
// 5. ✅ Auto-commit only if clean
|
|
293
|
+
// 6. ✅ Error handling with manual fallback instructions
|
|
303
294
|
```
|
|
304
295
|
|
|
305
|
-
**Troubleshooting**:
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
3. Ensure admin permissions in ServiceNow
|
|
311
|
-
4. Review any preview problems reported
|
|
312
|
-
```
|
|
296
|
+
**Troubleshooting (if auto-deployment fails)**:
|
|
297
|
+
- Error messages include specific troubleshooting steps
|
|
298
|
+
- Authentication issues: `snow-flow auth status`
|
|
299
|
+
- Manual fallback: `snow-flow deploy-xml filename.xml`
|
|
300
|
+
- Permission issues: Check admin roles in ServiceNow
|
|
313
301
|
|
|
314
302
|
## 🔒 MANDATORY ServiceNow Development Workflow
|
|
315
303
|
|
|
@@ -711,7 +699,7 @@ snow-flow swarm "create incident dashboard widget"
|
|
|
711
699
|
# Swarm handles all MCP orchestration with multiple agents
|
|
712
700
|
snow-flow swarm "create approval workflow for equipment requests"
|
|
713
701
|
|
|
714
|
-
# What happens: snow_create_flow(
|
|
702
|
+
# What happens: snow_create_flow({ deploy_immediately: true }) → live deployment → flow ready in ServiceNow
|
|
715
703
|
```
|
|
716
704
|
|
|
717
705
|
### 🎯 Smart Discovery Before Creation
|
|
@@ -783,9 +771,9 @@ snow-flow swarm "deploy mobile-responsive widget with accessibility features"
|
|
|
783
771
|
### 🚀 Complete Commands Reference
|
|
784
772
|
|
|
785
773
|
```bash
|
|
786
|
-
# Flow Designer workflows (
|
|
774
|
+
# Flow Designer workflows (fully automated generation + deployment)
|
|
787
775
|
snow-flow swarm "create approval flow for equipment requests"
|
|
788
|
-
|
|
776
|
+
# ✅ Above command automatically deploys! No manual steps needed.
|
|
789
777
|
|
|
790
778
|
# Widget development (standard MCP deployment)
|
|
791
779
|
snow-flow swarm "create incident dashboard widget"
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
chore: bump version to 1.3.17 - fix critical flow generation issue
|
|
2
|
+
|
|
3
|
+
BREAKING FIX: ServiceNow Flow Designer Integration
|
|
4
|
+
|
|
5
|
+
This release fixes the critical "Flow sys_id not found" error that was preventing
|
|
6
|
+
generated flows from being recognized by ServiceNow Flow Designer.
|
|
7
|
+
|
|
8
|
+
Key fixes:
|
|
9
|
+
- Use sys_hub_action_instance_v2 instead of v1
|
|
10
|
+
- Encode action parameters as Base64+gzip arrays (not raw inputs)
|
|
11
|
+
- Add sys_hub_flow_logic_instance_v2 records to connect actions
|
|
12
|
+
- Include ui_id fields for visual designer rendering
|
|
13
|
+
- Use real ServiceNow action type sys_ids
|
|
14
|
+
|
|
15
|
+
Technical changes:
|
|
16
|
+
- Updated ImprovedFlowXMLGenerator with v2 encoding methods
|
|
17
|
+
- Added encodeActionParameters() for proper parameter array structure
|
|
18
|
+
- Implemented generateFlowLogicV2XML() for flow connections
|
|
19
|
+
- Updated action type mappings with real ServiceNow IDs
|
|
20
|
+
|
|
21
|
+
New analysis files:
|
|
22
|
+
- SERVICENOW_ACTION_ANALYSIS.md - Complete technical analysis
|
|
23
|
+
- action-v2-implementation.js - Reference implementation
|
|
24
|
+
- decode-action-values.js - Debugging utility
|
|
25
|
+
|
|
26
|
+
Impact: Flows generated with snow-flow will now properly import and execute
|
|
27
|
+
in ServiceNow Flow Designer without errors.
|
|
28
|
+
|
|
29
|
+
🚀 Generated with Claude Code
|
|
30
|
+
|
|
31
|
+
Co-Authored-By: Claude <noreply@anthropic.com>
|
package/README.md
CHANGED
|
@@ -17,21 +17,22 @@
|
|
|
17
17
|
### 🚀 BREAKTHROUGH: Complete XML Update Set Auto-Import!
|
|
18
18
|
- **✅ ZERO MANUAL STEPS**: One command imports, previews, and commits XML update sets automatically
|
|
19
19
|
- **✅ FLOW DESIGNER INTEGRATION**: Automatic detection of Flow Designer artifacts in swarm commands
|
|
20
|
-
- **✅
|
|
21
|
-
- **✅
|
|
22
|
-
- **✅
|
|
23
|
-
- **✅
|
|
20
|
+
- **✅ FULLY AUTOMATED FLOW DEPLOYMENT**: Complete workflow from natural language to live ServiceNow flow in one command
|
|
21
|
+
- **✅ ZERO MANUAL STEPS**: XML generation, import, preview, and commit all happen automatically
|
|
22
|
+
- **✅ INTELLIGENT SAFETY**: Auto-preview with problem detection, only commits if clean
|
|
23
|
+
- **✅ GRACEFUL FALLBACKS**: Provides manual instructions if auto-deployment fails
|
|
24
24
|
|
|
25
|
-
### 🔄 Flow
|
|
25
|
+
### 🔄 Fully Automated Flow Workflow (NEW v1.3.17!)
|
|
26
26
|
```bash
|
|
27
|
-
#
|
|
27
|
+
# Single command creates AND deploys flow automatically!
|
|
28
28
|
snow-flow swarm "create approval workflow for equipment requests"
|
|
29
29
|
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
|
|
30
|
+
# Complete output shows:
|
|
31
|
+
# 🔧 Flow Designer Detected - Using XML-First Approach!
|
|
32
|
+
# ✅ XML Generated & Auto-Deployed to ServiceNow!
|
|
33
|
+
# 🎉 Flow ready in Flow Designer!
|
|
33
34
|
|
|
34
|
-
# ✅
|
|
35
|
+
# ✅ Zero manual steps: Generate → Import → Preview → Commit (only if clean)
|
|
35
36
|
```
|
|
36
37
|
|
|
37
38
|
### 🚀 Previous Release: v1.1.93 - Revolutionary Parallel Agent Spawning WORKING!
|
|
@@ -114,7 +115,7 @@ snow-flow deploy-xml flow-update-sets/flow_approval_workflow.xml
|
|
|
114
115
|
- **Flow Design**: Creates Flow Designer workflows with intelligent structure
|
|
115
116
|
- **Trigger Configuration**: Sets up optimal triggers (record events, scheduled, manual)
|
|
116
117
|
- **Approval Processes**: Implements complex approval hierarchies with escalation
|
|
117
|
-
- **Integration**: Uses `
|
|
118
|
+
- **Integration**: Uses `snow_xml_flow_from_instruction` with auto-deployment for maximum reliability
|
|
118
119
|
|
|
119
120
|
### 📝 Script Writer Agent
|
|
120
121
|
- **Business Rules**: Creates optimized business logic with performance considerations
|
|
@@ -194,9 +195,9 @@ snow-flow swarm "Create incident management dashboard with real-time charts"
|
|
|
194
195
|
# 🧠 NEW: Advanced example showing Gap Analysis Engine
|
|
195
196
|
snow-flow queen "create ITSM solution with LDAP authentication and custom approval workflows"
|
|
196
197
|
|
|
197
|
-
# 🚀 NEW:
|
|
198
|
+
# 🚀 NEW: Fully automated Flow Designer deployment (v1.3.17!)
|
|
198
199
|
snow-flow swarm "create approval workflow for equipment requests"
|
|
199
|
-
|
|
200
|
+
# ✅ Above command automatically deploys flow to ServiceNow! Zero manual steps.
|
|
200
201
|
```
|
|
201
202
|
|
|
202
203
|
### 🧠 What You'll See with Gap Analysis Engine
|
|
@@ -259,17 +260,20 @@ snow-flow memory stats
|
|
|
259
260
|
snow-flow memory export <file>
|
|
260
261
|
```
|
|
261
262
|
|
|
262
|
-
### 🚀 NEW:
|
|
263
|
+
### 🚀 NEW: Fully Automated Flow Deployment (v1.3.17!)
|
|
263
264
|
```bash
|
|
264
|
-
#
|
|
265
|
-
snow-flow
|
|
265
|
+
# Single command creates AND deploys flows automatically!
|
|
266
|
+
snow-flow swarm "create approval workflow for equipment requests"
|
|
266
267
|
|
|
267
|
-
#
|
|
268
|
-
|
|
269
|
-
|
|
268
|
+
# What happens automatically:
|
|
269
|
+
# 1. ✅ Detects Flow Designer task
|
|
270
|
+
# 2. ✅ Generates production-ready XML
|
|
271
|
+
# 3. ✅ Imports to ServiceNow as remote update set
|
|
272
|
+
# 4. ✅ Previews for conflicts
|
|
273
|
+
# 5. ✅ Auto-commits if clean
|
|
274
|
+
# 6. ✅ Reports deployment status
|
|
270
275
|
|
|
271
|
-
#
|
|
272
|
-
snow-flow deploy-xml flow-update-sets/flow_approval_workflow.xml
|
|
276
|
+
# Manual deployment (fallback only): snow-flow deploy-xml filename.xml
|
|
273
277
|
```
|
|
274
278
|
|
|
275
279
|
### 🚀 Intelligent Features (Enabled by Default)
|
|
@@ -343,11 +347,10 @@ snow-flow swarm "Build approval flow for equipment requests with manager and fin
|
|
|
343
347
|
# 1. Spawn Flow Builder + Security Agent
|
|
344
348
|
# 2. Flow Builder designs multi-step approval process
|
|
345
349
|
# 3. Security Agent validates permissions and compliance
|
|
346
|
-
# 4. Automatic XML generation
|
|
347
|
-
# 5.
|
|
350
|
+
# 4. Automatic XML generation AND deployment to ServiceNow
|
|
351
|
+
# 5. Flow ready in Flow Designer - zero manual steps!
|
|
348
352
|
|
|
349
|
-
# 🚀 NEW:
|
|
350
|
-
snow-flow deploy-xml flow-update-sets/flow_equipment_approval.xml
|
|
353
|
+
# 🚀 NEW: Fully automated - no separate deployment command needed!
|
|
351
354
|
|
|
352
355
|
# ✅ Automatic process:
|
|
353
356
|
# • Import XML to ServiceNow
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ServiceNow Flow Action v2 Implementation
|
|
3
|
+
*
|
|
4
|
+
* This module demonstrates the correct way to encode action values
|
|
5
|
+
* and generate proper flow XML for ServiceNow Flow Designer.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const pako = require('pako');
|
|
9
|
+
const crypto = require('crypto');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Encodes action parameters for sys_hub_action_instance_v2
|
|
13
|
+
*
|
|
14
|
+
* @param {Array} parameters - Array of parameter objects
|
|
15
|
+
* @param {string} parameters[].name - Parameter name
|
|
16
|
+
* @param {string} parameters[].value - Parameter value
|
|
17
|
+
* @param {string} parameters[].valueType - Type: 'static', 'fd_data', 'expression'
|
|
18
|
+
* @returns {string} Base64-encoded gzipped parameter array
|
|
19
|
+
*/
|
|
20
|
+
function encodeActionValue(parameters) {
|
|
21
|
+
// Ensure parameters is an array
|
|
22
|
+
if (!Array.isArray(parameters)) {
|
|
23
|
+
throw new Error('Parameters must be an array');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Normalize parameter structure
|
|
27
|
+
const normalizedParams = parameters.map(param => ({
|
|
28
|
+
name: param.name,
|
|
29
|
+
value: param.value,
|
|
30
|
+
valueType: param.valueType || 'static'
|
|
31
|
+
}));
|
|
32
|
+
|
|
33
|
+
// Convert to JSON string
|
|
34
|
+
const jsonString = JSON.stringify(normalizedParams);
|
|
35
|
+
|
|
36
|
+
// Gzip compress
|
|
37
|
+
const compressed = pako.gzip(jsonString);
|
|
38
|
+
|
|
39
|
+
// Base64 encode
|
|
40
|
+
const base64 = Buffer.from(compressed).toString('base64');
|
|
41
|
+
|
|
42
|
+
return base64;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Decodes action value for debugging/verification
|
|
47
|
+
*
|
|
48
|
+
* @param {string} encodedValue - Base64-encoded gzipped value
|
|
49
|
+
* @returns {Array} Decoded parameter array
|
|
50
|
+
*/
|
|
51
|
+
function decodeActionValue(encodedValue) {
|
|
52
|
+
// Base64 decode
|
|
53
|
+
const compressed = Buffer.from(encodedValue, 'base64');
|
|
54
|
+
|
|
55
|
+
// Gunzip
|
|
56
|
+
const jsonString = pako.ungzip(compressed, { to: 'string' });
|
|
57
|
+
|
|
58
|
+
// Parse JSON
|
|
59
|
+
return JSON.parse(jsonString);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Generates a unique UI ID for flow components
|
|
64
|
+
*
|
|
65
|
+
* @returns {number} Unique UI ID
|
|
66
|
+
*/
|
|
67
|
+
let uiIdCounter = 1;
|
|
68
|
+
function generateUniqueUiId() {
|
|
69
|
+
return uiIdCounter++;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Creates a sys_hub_action_instance_v2 record
|
|
74
|
+
*
|
|
75
|
+
* @param {Object} config - Action configuration
|
|
76
|
+
* @param {string} config.flowSysId - Parent flow sys_id
|
|
77
|
+
* @param {string} config.actionType - Action type ID
|
|
78
|
+
* @param {string} config.actionName - Display name
|
|
79
|
+
* @param {Array} config.parameters - Action parameters
|
|
80
|
+
* @param {number} config.x - X position in designer
|
|
81
|
+
* @param {number} config.y - Y position in designer
|
|
82
|
+
* @returns {Object} Action instance record
|
|
83
|
+
*/
|
|
84
|
+
function createActionInstance(config) {
|
|
85
|
+
const actionSysId = crypto.randomUUID().replace(/-/g, '');
|
|
86
|
+
const uiId = generateUniqueUiId();
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
sys_id: actionSysId,
|
|
90
|
+
table: 'sys_hub_action_instance_v2',
|
|
91
|
+
parent: config.flowSysId,
|
|
92
|
+
ui_id: uiId,
|
|
93
|
+
group_ui_id: uiId,
|
|
94
|
+
type: config.actionType,
|
|
95
|
+
name: config.actionName,
|
|
96
|
+
value: encodeActionValue(config.parameters),
|
|
97
|
+
x: config.x || 100,
|
|
98
|
+
y: config.y || 100,
|
|
99
|
+
active: 'true',
|
|
100
|
+
base_table: 'sys_hub_action_instance_v2'
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Creates a sys_hub_flow_logic_instance_v2 record
|
|
106
|
+
*
|
|
107
|
+
* @param {Object} config - Flow logic configuration
|
|
108
|
+
* @param {string} config.flowSysId - Parent flow sys_id
|
|
109
|
+
* @param {number} config.fromUiId - Source action UI ID
|
|
110
|
+
* @param {number} config.toUiId - Target action UI ID
|
|
111
|
+
* @param {string} config.condition - Optional condition
|
|
112
|
+
* @returns {Object} Flow logic record
|
|
113
|
+
*/
|
|
114
|
+
function createFlowLogic(config) {
|
|
115
|
+
const logicSysId = crypto.randomUUID().replace(/-/g, '');
|
|
116
|
+
const uiId = generateUniqueUiId();
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
sys_id: logicSysId,
|
|
120
|
+
table: 'sys_hub_flow_logic_instance_v2',
|
|
121
|
+
parent: config.flowSysId,
|
|
122
|
+
parent_ui_id: config.fromUiId,
|
|
123
|
+
ui_id: uiId,
|
|
124
|
+
group_ui_id: config.toUiId,
|
|
125
|
+
type: config.toUiId.toString(),
|
|
126
|
+
condition: config.condition || '',
|
|
127
|
+
active: 'true',
|
|
128
|
+
ended: 'false',
|
|
129
|
+
base_table: 'sys_hub_flow_logic_instance_v2'
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Example: Create Record action with proper encoding
|
|
135
|
+
*/
|
|
136
|
+
function exampleCreateRecordAction(flowSysId) {
|
|
137
|
+
return createActionInstance({
|
|
138
|
+
flowSysId: flowSysId,
|
|
139
|
+
actionType: '65', // Create Record action type
|
|
140
|
+
actionName: 'Create Equipment Request',
|
|
141
|
+
x: 200,
|
|
142
|
+
y: 150,
|
|
143
|
+
parameters: [
|
|
144
|
+
{
|
|
145
|
+
name: 'table',
|
|
146
|
+
value: 'sc_request',
|
|
147
|
+
valueType: 'static'
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: 'field_values',
|
|
151
|
+
value: JSON.stringify({
|
|
152
|
+
short_description: '{{fd_data.trigger.current.short_description}}',
|
|
153
|
+
requested_for: '{{fd_data.trigger.current.opened_by}}',
|
|
154
|
+
priority: '3'
|
|
155
|
+
}),
|
|
156
|
+
valueType: 'fd_data'
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Example: Complete flow with trigger, actions, and logic
|
|
164
|
+
*/
|
|
165
|
+
function generateCompleteFlow() {
|
|
166
|
+
const flowSysId = crypto.randomUUID().replace(/-/g, '');
|
|
167
|
+
|
|
168
|
+
// Reset UI ID counter for new flow
|
|
169
|
+
uiIdCounter = 1;
|
|
170
|
+
|
|
171
|
+
// Main flow record
|
|
172
|
+
const flow = {
|
|
173
|
+
sys_id: flowSysId,
|
|
174
|
+
table: 'sys_hub_flow',
|
|
175
|
+
name: 'Equipment Request Approval',
|
|
176
|
+
description: 'Automated approval workflow for equipment requests',
|
|
177
|
+
active: 'true',
|
|
178
|
+
type: 'flow',
|
|
179
|
+
category: 'Request Management'
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
// Trigger (Record Created)
|
|
183
|
+
const triggerUiId = generateUniqueUiId();
|
|
184
|
+
const trigger = {
|
|
185
|
+
sys_id: crypto.randomUUID().replace(/-/g, ''),
|
|
186
|
+
table: 'sys_hub_trigger_instance_v2',
|
|
187
|
+
parent: flowSysId,
|
|
188
|
+
ui_id: triggerUiId,
|
|
189
|
+
type: '14', // Record Created/Updated
|
|
190
|
+
name: 'Equipment Request Created',
|
|
191
|
+
configuration: encodeActionValue([
|
|
192
|
+
{
|
|
193
|
+
name: 'table',
|
|
194
|
+
value: 'sc_req_item',
|
|
195
|
+
valueType: 'static'
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
name: 'condition',
|
|
199
|
+
value: 'category=hardware^active=true',
|
|
200
|
+
valueType: 'static'
|
|
201
|
+
}
|
|
202
|
+
])
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// Action 1: Create Request
|
|
206
|
+
const createAction = createActionInstance({
|
|
207
|
+
flowSysId: flowSysId,
|
|
208
|
+
actionType: '65',
|
|
209
|
+
actionName: 'Create Approval Request',
|
|
210
|
+
x: 300,
|
|
211
|
+
y: 150,
|
|
212
|
+
parameters: [
|
|
213
|
+
{
|
|
214
|
+
name: 'table',
|
|
215
|
+
value: 'sc_request',
|
|
216
|
+
valueType: 'static'
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: 'requested_for',
|
|
220
|
+
value: '{{fd_data.trigger.current.requested_for}}',
|
|
221
|
+
valueType: 'fd_data'
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// Action 2: Send Notification
|
|
227
|
+
const notifyAction = createActionInstance({
|
|
228
|
+
flowSysId: flowSysId,
|
|
229
|
+
actionType: '89', // Send Email
|
|
230
|
+
actionName: 'Notify Approver',
|
|
231
|
+
x: 500,
|
|
232
|
+
y: 150,
|
|
233
|
+
parameters: [
|
|
234
|
+
{
|
|
235
|
+
name: 'to',
|
|
236
|
+
value: '{{fd_data.trigger.current.requested_for.manager}}',
|
|
237
|
+
valueType: 'fd_data'
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
name: 'subject',
|
|
241
|
+
value: 'Equipment Request Approval Needed',
|
|
242
|
+
valueType: 'static'
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
name: 'body',
|
|
246
|
+
value: 'Please review the equipment request from {{fd_data.trigger.current.requested_for.name}}',
|
|
247
|
+
valueType: 'fd_data'
|
|
248
|
+
}
|
|
249
|
+
]
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
// Flow Logic: Trigger → Create Action
|
|
253
|
+
const logic1 = createFlowLogic({
|
|
254
|
+
flowSysId: flowSysId,
|
|
255
|
+
fromUiId: triggerUiId,
|
|
256
|
+
toUiId: createAction.ui_id
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// Flow Logic: Create Action → Notify Action
|
|
260
|
+
const logic2 = createFlowLogic({
|
|
261
|
+
flowSysId: flowSysId,
|
|
262
|
+
fromUiId: createAction.ui_id,
|
|
263
|
+
toUiId: notifyAction.ui_id
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
return {
|
|
267
|
+
flow,
|
|
268
|
+
trigger,
|
|
269
|
+
actions: [createAction, notifyAction],
|
|
270
|
+
logic: [logic1, logic2]
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Generates complete XML for import
|
|
276
|
+
*/
|
|
277
|
+
function generateFlowXML() {
|
|
278
|
+
const flowData = generateCompleteFlow();
|
|
279
|
+
const xml2js = require('xml2js');
|
|
280
|
+
const builder = new xml2js.Builder();
|
|
281
|
+
|
|
282
|
+
const xmlData = {
|
|
283
|
+
unload: {
|
|
284
|
+
$: {
|
|
285
|
+
unload_date: new Date().toISOString()
|
|
286
|
+
},
|
|
287
|
+
sys_hub_flow: flowData.flow,
|
|
288
|
+
sys_hub_trigger_instance_v2: flowData.trigger,
|
|
289
|
+
sys_hub_action_instance_v2: flowData.actions,
|
|
290
|
+
sys_hub_flow_logic_instance_v2: flowData.logic
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
return builder.buildObject(xmlData);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Export functions for use in other modules
|
|
298
|
+
module.exports = {
|
|
299
|
+
encodeActionValue,
|
|
300
|
+
decodeActionValue,
|
|
301
|
+
createActionInstance,
|
|
302
|
+
createFlowLogic,
|
|
303
|
+
generateCompleteFlow,
|
|
304
|
+
generateFlowXML
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
// Example usage
|
|
308
|
+
if (require.main === module) {
|
|
309
|
+
console.log('ServiceNow Flow Action v2 Implementation Example\n');
|
|
310
|
+
|
|
311
|
+
// Example 1: Encode parameters
|
|
312
|
+
const params = [
|
|
313
|
+
{ name: 'table', value: 'incident', valueType: 'static' },
|
|
314
|
+
{ name: 'priority', value: '{{fd_data.trigger.current.urgency}}', valueType: 'fd_data' }
|
|
315
|
+
];
|
|
316
|
+
|
|
317
|
+
const encoded = encodeActionValue(params);
|
|
318
|
+
console.log('Encoded parameters:', encoded);
|
|
319
|
+
|
|
320
|
+
// Example 2: Decode to verify
|
|
321
|
+
const decoded = decodeActionValue(encoded);
|
|
322
|
+
console.log('\nDecoded parameters:', JSON.stringify(decoded, null, 2));
|
|
323
|
+
|
|
324
|
+
// Example 3: Generate complete flow
|
|
325
|
+
const flow = generateCompleteFlow();
|
|
326
|
+
console.log('\nGenerated flow structure:');
|
|
327
|
+
console.log('- Flow:', flow.flow.name);
|
|
328
|
+
console.log('- Trigger:', flow.trigger.name);
|
|
329
|
+
console.log('- Actions:', flow.actions.map(a => a.name).join(', '));
|
|
330
|
+
console.log('- Logic connections:', flow.logic.length);
|
|
331
|
+
|
|
332
|
+
// Example 4: Generate XML
|
|
333
|
+
console.log('\nGenerating XML...');
|
|
334
|
+
const xml = generateFlowXML();
|
|
335
|
+
console.log('XML length:', xml.length, 'characters');
|
|
336
|
+
console.log('\nFirst 500 characters:');
|
|
337
|
+
console.log(xml.substring(0, 500) + '...');
|
|
338
|
+
}
|