ServiceNow Work Order Integration

1. Introduction

This guide outlines the process for integrating ServiceNow, an external work order management system, with the AirHub® Portal. The goal is to establish a seamless two-way flow of work order data: creating work orders in the Portal from ServiceNow and reflecting Portal status updates back into ServiceNow.

2. Overview of the Integration Flow

The integration involves a two-way communication setup:

  • Inbound Flow (ServiceNow to AirHub® Portal - Work Order Creation):

    1. A record is created or updated in ServiceNow.

    2. This triggers a ServiceNow Business Rule to send an HTTP request containing work order data.

    3. A Power Automate Flow (Inbound) receives this request, transforms the ServiceNow data format into Airspace Link's standard work order schema.

    4. The Power Automate flow calls the Airspace Link API to create or update the work order in the AirHub® Portal.

    5. The work order appears in the AirHub® Portal, mapped to the correct organization.

  • Outbound Flow (AirHub® Portal to ServiceNow - Status Updates):

    1. An update is made to a work order within the AirHub® Portal (e.g., status, notes, deliverable URL).

    2. This triggers an internal AirHub® Portal process that calls a Power Automate Flow (Outbound).

    3. This Power Automate Flow transforms Airspace Link's update schema into ServiceNow's expected format.

    4. The Power Automate flow publishes the update to a designated ServiceNow Scripted REST API endpoint.

    5. The original work order record in ServiceNow is updated.

3. Pre-Integration Steps & Information Gathering (From Customer)

Before configuring the integration, essential information and access are required from the customer:

3.1. Understand the Customer's ServiceNow Configuration

  • Familiarize yourself with their specific ServiceNow instance and how they use it for work orders.

  • Understand their existing intake forms and the fields they use.

3.2. Gather Key Information & Access from the Customer

  • ServiceNow Instance URL: The base URL of their ServiceNow instance.

  • User Credentials: A dedicated user account within their ServiceNow instance for integration purposes.

    • Required Permissions: This user needs permissions to:

      • Create Business Rules.

      • Create Scripted REST APIs.

      • Update tables

  • Field Mapping Details: For ALL fields in their intake form that need to be integrated with AirHub® Portal:

    • Exact field names (as they appear in ServiceNow).

    • All possible values for each field, including their underlying numeric or exact database values (not just the displayed text labels).

      • Example: "Pending" might have an underlying value of "-5". These often require direct API calls or specialized ServiceNow views to determine.

      • Note: This often requires experimentation (sending API requests and observing transformations) or direct access to their database schema views within ServiceNow.

  • Custom Field Behavior: Identify any custom fields that behave unusually (e.g., work_notes field requires specific update methods via PATCH rather than direct assignment).

  • Location Data: Understand how they currently define operation locations (e.g., text addresses, no geometry).

  • Draft Inbound Power Automate Flow: Create a Power Automate flow designed to receive HTTP requests from the customer's ServiceNow Business Rule. This flow will generate a unique URL.

  • Draft Outbound Power Automate Flow: Create a Power Automate flow designed to receive updates from the Airspace Link Portal and publish them back to ServiceNow.

  • Obtain Outbound URL: For the outbound flow (Airspace Link to ServiceNow), note the unique HTTP request URL generated by Power Automate. This will be used in Airspace Link's org.json configuration.

  • Navigate to the org.json configuration file in the Airspace Link GitHub repository (specific location to be provided by engineering).

  • For each environment (e.g., Development, Staging, Production), add a new entry for the customer's organization.

  • Required Data for Each Organization Entry:

    • uniqueId: A unique, randomly generated ID (can be generated by Airspace Link).

    • org_name: The exact organization name as defined in Auth0.

    • org_id: The unique organization identifier from Auth0.

    • outbound_url: The HTTP request URL generated from the outbound Power Automate flow (see Section 4.1).

5. ServiceNow System-Specific Configuration

5.1. Business Rule (Inbound Trigger - ServiceNow to AirHub® Portal)

  • Objective: To trigger a send of ServiceNow work order data to Airspace Link's inbound Power Automate flow.

  • Action: Configure a new Business Rule within ServiceNow.

    • Table: Tie this rule to the specific ServiceNow table where work orders are managed.

      • Ensure the Active and Advanced fields are both checked

    • Conditions: Set conditions for when the rule fires (e.g., on insert, update, or delete of a record).

    • Script: In the Advanced tab, implement a custom script within the Business Rule to:

      • Extract relevant fields from the ServiceNow record.

      • Construct an HTTP POST request.

      • Send this request to the unique URL of the inbound Power Automate flow.

      // Example script
      
      (function executeRule(current, previous /*null when async*/) {
          var restMessage = new sn_ws.RESTMessageV2(); 
          restMessage.setEndpoint('https://prod-72.westus.logic.azure.com:443/workflows/uniquePowerAutomateUrlAbc123'); 
          restMessage.setHttpMethod('POST'); 
          
          // Send the current work order as JSON 
          var requestBody = { 
              taskNumber: current.number.toString(),
              priority: current.priority.toString(),
              state: current.state.toString(),
              shortDescription: current.short_description.toString(),
              description: current.description.toString(),
              sys_id: current.sys_id.toString(), 
      		dueDate: current.due_date.toString(),
              link: current.getLink(),
      		location: current.location.toString(),
      		locationDescription: current.u_location_description.toString()
          }; 
          
          restMessage.setRequestBody(JSON.stringify(requestBody)); 
      	restMessage.setRequestHeader('Content-Type', 'application/json');
          var response = restMessage.execute();
      })(current, previous);

5.2. Power Automate Flow (Inbound - Field Transformation)

  • Objective: To receive ServiceNow data, transform it, and send it to the Airspace Link API.

  • Action: Configure the Power Automate flow:

    • Trigger: Set to "When an HTTP request is received".

    • Field Definition: Define the expected fields from the ServiceNow request.

    • Data Mapping: Implement logic to transform ServiceNow's field names and values into Airspace Link's standardized work order schema (e.g., mapping state from "-5" to "Pending").

    • API Call: Add an action to make an HTTP POST or PUT request to the Airspace Link API to create or update the work order.

      • ASL API URL: https://airhub-api-dev.airspacelink.com/v1/workorder/webhook/{uuid} where uuid is the unique organization id contained in the org.json configuration file

5.3. Scripted REST API (Outbound Reception - AirHub® Portal to ServiceNow)

  • Objective: To receive work order updates from AirHub® Portal and apply them to ServiceNow records.

  • Action: Create a Scripted REST API in ServiceNow.

    • Endpoint: Define a unique, external endpoint that can accept calls from outside ServiceNow.

    • Method: Configure the method (e.g., PATCH for updates).

    • Resource path: Note the resource path generated. This will be used by the outbound Power Automate flow to publish updates to ServiceNow.

    • Script: Implement a script within this API to:

      • Receive the update request from the outbound Power Automate flow.

      • Identify the specific ServiceNow record to update (e.g., using a unique ID passed in the request).

      • Update the relevant fields (e.g., status, notes, deliverable URL) in that record.

      • Handle any custom field behaviors as identified in Section 3.2.

      (function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
          // Extract the data from the request body
          var requestBody = request.body.data;
      
          // Extract the unique identifier of the record to update from the request body
          var idNumber = requestBody.id;
      
          // Create a new GlideRecord object for the 'sc_task' table
          var gr = new GlideRecord('sc_task'); 
      
          // Attempt to retrieve the record with the specified 'number' (idNumber)
          if (gr.get('number', idNumber)) { 
              // Iterate over each field in the request body
              for (var field in requestBody) {
                  // Check if the field is a direct property of requestBody
                  if (requestBody.hasOwnProperty(field)) {
                      // Set the value of the field in the GlideRecord object
                      gr.setValue(field, requestBody[field]);
      
                      // Handle special/unique fields separately
                      if (field == 'work_notes') {
                          // Set the 'work_notes' field specifically
                          gr['work_notes'] = requestBody[field];
                      }
                  }
              }
      
              // Disable workflow processing for this update to prevent it from firing other triggers
              gr.setWorkflow(false); 
      
              // Update the record in the database
              gr.update();
      
              // Set the response status to 200 (OK) and return a success message
              response.setStatus(200);
              response.setBody({ message: 'Record updated successfully' });
          } else {
              // If the record is not found, set the response status to 404 (Not Found)
              response.setStatus(404);
              response.setBody({ error: 'Record not found' });
          }
      
      })(request, response);

6. Testing & Validation

Thorough testing is crucial to ensure the two-way integration works as expected.

  • Test Inbound Flow: Create/update a work order in ServiceNow and verify it appears correctly in the AirHub® Portal with all mapped fields.

  • Test Outbound Flow: Update a work order's status, notes, or deliverable URL in the AirHub® Portal and verify these changes are reflected accurately in the original ServiceNow record.

7. Important Considerations & Best Practices

  • Field Mapping Complexity: Be prepared for detailed conversations with customers about their field definitions and values, especially for custom fields that may require specific handling.

  • Power Automate Flow Ownership: A clear decision is needed on whether the customer or Airspace Link will own and manage these Power Automate flows. This impacts necessary access and instruction levels.

  • Documentation: Capture detailed documentation as you go for each integration, particularly for unique customer configurations, to build repeatable processes.

Last updated