integration-hub

IntegrationHub for ServiceNow

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "integration-hub" with this command: npx skills add groeimetai/snow-flow/groeimetai-snow-flow-integration-hub

IntegrationHub for ServiceNow

IntegrationHub provides reusable integration components for Flow Designer and workflows.

IntegrationHub Architecture

Spoke (sn_ih_spoke) ├── Actions (sn_ih_action) │ ├── Inputs │ ├── Steps │ └── Outputs ├── Connection Alias └── Credential Alias

Flow Designer └── Uses Spoke Actions

Key Tables

Table Purpose

sn_ih_spoke

Spoke definitions

sn_ih_action

Spoke actions

sn_ih_step_config

Action step configuration

sys_alias

Connection/credential aliases

Connection & Credential Aliases (ES5)

Create Connection Alias

// Create connection alias (ES5 ONLY!) var alias = new GlideRecord("sys_alias") alias.initialize()

alias.setValue("name", "Jira Connection") alias.setValue("id", "x_myapp_jira_connection") alias.setValue("type", "connection") alias.setValue("connection_type", "http")

// Connection attributes alias.setValue( "attributes", JSON.stringify({ base_url: "https://mycompany.atlassian.net/rest/api/3", timeout: 30000, }), )

alias.insert()

Create Credential Alias

// Create credential alias (ES5 ONLY!) var credAlias = new GlideRecord("sys_alias") credAlias.initialize()

credAlias.setValue("name", "Jira API Token") credAlias.setValue("id", "x_myapp_jira_credential") credAlias.setValue("type", "credential")

credAlias.insert()

// Link to actual credential var credential = new GlideRecord("basic_auth_credentials") credential.initialize() credential.setValue("name", "Jira API Token Credential") credential.setValue("user_name", "api-user@company.com") credential.setValue("password", "") // Set via secure method credential.insert()

// Create alias-credential mapping var mapping = new GlideRecord("sys_alias_credential") mapping.initialize() mapping.setValue("alias", credAlias.getUniqueValue()) mapping.setValue("credential", credential.getUniqueValue()) mapping.insert()

Spoke Development (ES5)

Create Custom Spoke

// Create spoke (ES5 ONLY!) var spoke = new GlideRecord("sn_ih_spoke") spoke.initialize()

spoke.setValue("name", "Custom ITSM Connector") spoke.setValue("label", "Custom ITSM Connector") spoke.setValue("description", "Integration with external ITSM system") spoke.setValue("vendor", "My Company") spoke.setValue("version", "1.0.0")

// Scope spoke.setValue("scope", "x_myapp_itsm")

// Logo spoke.setValue("logo", "attachment_sys_id")

spoke.insert()

Create Spoke Action

// Create action for spoke (ES5 ONLY!) var action = new GlideRecord("sn_ih_action") action.initialize()

action.setValue("name", "Create External Ticket") action.setValue("label", "Create External Ticket") action.setValue("spoke", spokeSysId) action.setValue("description", "Creates a ticket in external ITSM system")

// Category action.setValue("category", "record_operations")

// Accessibility action.setValue("accessible_from", "flow_designer")

action.insert()

// Add inputs addActionInput(action.getUniqueValue(), "summary", "String", true, "Ticket summary") addActionInput(action.getUniqueValue(), "description", "String", false, "Ticket description") addActionInput(action.getUniqueValue(), "priority", "String", false, "Priority level")

// Add outputs addActionOutput(action.getUniqueValue(), "ticket_id", "String", "Created ticket ID") addActionOutput(action.getUniqueValue(), "ticket_url", "String", "URL to ticket")

Action Input/Output Helpers

// Add action input (ES5 ONLY!) function addActionInput(actionSysId, name, type, mandatory, label) { var input = new GlideRecord("sn_ih_input") input.initialize() input.setValue("action", actionSysId) input.setValue("name", name) input.setValue("label", label) input.setValue("type", type) input.setValue("mandatory", mandatory) input.setValue("order", getNextOrder(actionSysId, "input")) return input.insert() }

// Add action output (ES5 ONLY!) function addActionOutput(actionSysId, name, type, label) { var output = new GlideRecord("sn_ih_output") output.initialize() output.setValue("action", actionSysId) output.setValue("name", name) output.setValue("label", label) output.setValue("type", type) output.setValue("order", getNextOrder(actionSysId, "output")) return output.insert() }

Action Steps (ES5)

REST Step Configuration

// Create REST step for action (ES5 ONLY!) var step = new GlideRecord("sn_ih_step_config") step.initialize()

step.setValue("action", actionSysId) step.setValue("name", "Call External API") step.setValue("order", 100) step.setValue("step_type", "rest")

// REST configuration step.setValue( "rest_config", JSON.stringify({ connection_alias: "x_myapp_jira_connection", credential_alias: "x_myapp_jira_credential", http_method: "POST", resource_path: "/issue", request_body: { fields: { project: { key: "${inputs.project_key}" }, summary: "${inputs.summary}", description: "${inputs.description}", issuetype: { name: "Task" }, }, }, headers: { "Content-Type": "application/json", }, }), )

step.insert()

Script Step

// Create script step (ES5 ONLY!) var scriptStep = new GlideRecord("sn_ih_step_config") scriptStep.initialize()

scriptStep.setValue("action", actionSysId) scriptStep.setValue("name", "Process Response") scriptStep.setValue("order", 200) scriptStep.setValue("step_type", "script")

// Script (ES5 ONLY!) scriptStep.setValue( "script", "(function execute(inputs, outputs) {\n" + " // Get REST response from previous step\n" + " var response = inputs.rest_response;\n" + " \n" + " if (response.status_code === 201) {\n" + " var body = JSON.parse(response.body);\n" + " outputs.ticket_id = body.id;\n" + " outputs.ticket_url = body.self;\n" + " outputs.success = true;\n" + " } else {\n" + " outputs.success = false;\n" + ' outputs.error_message = "Failed: " + response.status_code;\n' + " }\n" + "})(inputs, outputs);", )

scriptStep.insert()

Subflows for Reuse (ES5)

Create Integration Subflow

// Subflows encapsulate reusable integration logic // Created via Flow Designer UI, but can be invoked via script

// Invoke subflow from script (ES5 ONLY!) var inputs = { ticket_id: "INC0010001", action: "update", fields: { status: "resolved", resolution: "Fixed", }, }

// Start subflow sn_fd.FlowAPI.startSubflow("x_myapp_update_external_ticket", inputs)

Execute Action from Script

// Execute spoke action from script (ES5 ONLY!) var actionInputs = { summary: "New ticket from ServiceNow", description: "Created via integration", priority: "Medium", }

try { var result = sn_fd.FlowAPI.executeAction("x_myapp_itsm.create_external_ticket", actionInputs)

if (result.outputs.success) { gs.info("Created ticket: " + result.outputs.ticket_id) } else { gs.error("Failed: " + result.outputs.error_message) } } catch (e) { gs.error("Action execution failed: " + e.message) }

Error Handling (ES5)

Action Error Handling

// Error handling in action script (ES5 ONLY!) ;(function execute(inputs, outputs) { try { // Main logic var response = callExternalAPI(inputs)

if (response.status_code >= 400) {
  throw new Error("API error: " + response.status_code + " - " + response.body)
}

outputs.result = JSON.parse(response.body)
outputs.success = true

} catch (e) { outputs.success = false outputs.error_code = "INTEGRATION_ERROR" outputs.error_message = e.message

// Log for debugging
gs.error("IntegrationHub action failed: " + e.message)

// Optionally throw to trigger Flow Designer error handling
// throw e;

} })(inputs, outputs)

Retry Logic

// Retry wrapper for transient failures (ES5 ONLY!) function executeWithRetry(fn, maxRetries, delayMs) { var attempts = 0 var lastError = null

while (attempts < maxRetries) { try { return fn() } catch (e) { lastError = e attempts++

  if (attempts &#x3C; maxRetries) {
    gs.info("Retry " + attempts + " of " + maxRetries + " after error: " + e.message)
    gs.sleep(delayMs * attempts) // Exponential backoff
  }
}

}

throw new Error("Failed after " + maxRetries + " attempts: " + lastError.message) }

MCP Tool Integration

Available Tools

Tool Purpose

snow_query_table

Query spokes and actions

snow_find_artifact

Find integration configs

snow_test_rest_connection

Test connections

snow_execute_script_with_output

Test action scripts

Example Workflow

// 1. Find available spokes await snow_query_table({ table: "sn_ih_spoke", query: "active=true", fields: "name,label,vendor,version", })

// 2. Get spoke actions await snow_query_table({ table: "sn_ih_action", query: "spoke.name=Jira Spoke", fields: "name,label,description,category", })

// 3. Test connection await snow_test_rest_connection({ connection_alias: "x_myapp_jira_connection", credential_alias: "x_myapp_jira_credential", })

Best Practices

  • Connection Aliases - Abstract connection details

  • Credential Security - Never hardcode credentials

  • Error Handling - Graceful failure handling

  • Retry Logic - Handle transient failures

  • Logging - Comprehensive debug logging

  • Testing - Test with mock data first

  • Versioning - Track spoke versions

  • ES5 Only - No modern JavaScript syntax

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

predictive-intelligence

No summary provided by upstream source.

Repository SourceNeeds Review
General

scheduled-jobs

No summary provided by upstream source.

Repository SourceNeeds Review
General

document-management

No summary provided by upstream source.

Repository SourceNeeds Review
General

reporting-dashboards

No summary provided by upstream source.

Repository SourceNeeds Review