Only this pageAll pages
Powered by GitBook
Couldn't generate the PDF for 221 pages, generation stopped at 100.
Extend with 50 more pages.
1 of 100

3.1

Loading...

Release

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Overview

Loading...

Loading...

Loading...

Loading...

Integration Guides

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Unifi User Documentation

What is Unifi?

Unifi is an integration platform built specifically to support complex ticket exchange integrations to and from your ServiceNow instance. From no-code to pro-code, Unifi gives you the flexibility, insight, and control to create exceptional integration experiences for you, your partners and your customers.

How do I get Unifi?

Unifi is a ServiceNow application that is delivered and managed through the . You can find out more information and request a demo through our .

Installation

Follow these steps to install Unifi and get your system up and running quickly.

  1. Install Unifi

  2. Install Global Utility

  3. Install Hotfix

1. Install Unifi

Unifi is exclusively available through the with a limited trial or paid subscription.

To install Unifi on your instance, you will need to ensure it has been given entitlement to the application. You must do this through the ServiceNow Store.

Once you have setup entitlement, you can use the Application Manager in your ServiceNow instance to install Unifi. You can find more information on how to in the ServiceNow Product Documentation.

2. Install Global Utility

Unifi has some powerful features that will only work with access to the global scope. Access is granted through the Unifi Global Utility.

Full details can be found on the page.

3. Install Hotfix

Unifi has the ability to be patched between releases by using a special Script Include called hotfix.

Full details can be found on the page.

4. Go!

You're good to go! Get cracking and start configuring your integrations.

If you’re new to Unifi then you might like to follow one of our integration guides. You can access the Integration Guides from the menu.

Release Notes

Global Utility

Unifi has some functionality that requires access to methods not available to scoped applications. We grant Unifi access to those methods through a single global utility Script Include which you can install via Update Set.

It is strongly advised that you install this utility to get the most out of Unifi.

  1. Download Unifi Global Utility 3.1

  2. Import the file as an update set, then preview and commit it. You can find more information on how to in the ServiceNow Product Documentation.

ServiceNow Store
website
Go!
ServiceNow Store
Install a ServiceNow Store Application
Global Utility
Hotfixes
Unifi 3.1 Release Notes
Unifi 3.0 Release Notes
Unifi 2.2 Release Notes
Unifi 2.1 Release Notes
Unifi 2.0 Release Notes
Dependent Features

Moving Attachments

Method: snd_eb_util.moveAttachments

The ServiceNow scoped attachment API does not support moving attachments from one record to another. This is necessary for inbound attachments which initially reside on the HTTP Request and are then moved to the Target record.

Jelly Processing

Method: snd_eb_util.runJelly

Jelly processing is not supported in the ServiceNow scoped API’s, however it is very useful for XML processing. Use of the Global Utility drastically improves XML payload capabilities if you are working with XML payloads.

SOAP Response Element

Method: snd_eb_util.getSoapResponseElement

When working with Scripted SOAP Services, it’s important to be able to set the soapResponseElement directly in order to preserve the exact payload to be sent back to the calling system. This can only be done with the Global Utility.

Binary Attachment Handling

Method: snd_eb_util.writeAttachment

The Scoped Attachment API does not support writing binary attachments which can cause problems when receiving things like Word documents or PDF’s. This method allows Unifi to use the global attachment API to write those files to the database meaning they will work properly.

Update Set Packaging

Method: snd_eb_util.packager.*

The packager methods included in the global utility allow Unifi to automatically export all the components of an integration in one easy step. The packager methods will allow Unifi to create an update set for the integration, add all the configuration records to that update set, and export it as a file download from the Integration page on the Unifi Integration Designer portal.

Web Service Creation

Method: snd_eb_util.web_service

The web service methods included in the global utility allow Unifi to automatically create and update REST Methods.

Trigger (Business Rule) Creation

Method: snd_eb_util.trigger_rule

The trigger methods included in the global utility allow Unifi to automatically create a Trigger Business Rule on a table if one doesn't already exist.

Load customizations from a single XML file
18KB
Unifi Global Utility 3.1.xml
Open

Unifi 2.2 Release Notes

Here you will find details of what's changed in this release, including new features & improvements, deprecated features and general fixes.

Introduction

Welcome to the release notes for Unifi - Version 2.2. Please have a read through to see new features and fixes that have been added.

Upgrade Notice

Please note that, as with every release, there may be some changes that are not entirely compatible with your existing integrations. While we do everything we can to make sure you won’t have to fix your integrations when upgrading, we strongly encourage all our customers to perform full end-to-end tests of their integrations before upgrading Unifi in Production.

We also highly recommend aligning your Unifi upgrade with your ServiceNow upgrade. This means you only need to test your integrations one time rather than once for the ServiceNow upgrade and once for the Unifi upgrade.

Feedback and Reviews

We really appreciate feedback on what we’re doing - whether it’s right or wrong! We take feedback very seriously, so if you feel you’d give us anything less than a 5 star rating, we’d love to hear from you so we can find out what we need to do to improve!

If you would rate us 5 stars, and haven’t left a review on the ServiceNow Store yet, we’d be grateful if you would head over there to leave us your feedback. It only takes a few minutes and really does help us a lot. Go on, you know you want to ​

Highlights

Paris Support

We’ve tested and verified that Unifi continues to work as expected on the latest Paris release of ServiceNow.

Packager

We’ve introduced a brand new feature that makes exporting and migrating integrations seriously easy, 1-click easy in fact. You can now click the “Package” button on an integration in the Portal and the system will gather all the related files that make that integration work and put them in a brand new update set and download it to your desktop. This feature does require the latest version of the Unifi Global Utility.

Details

New Features & Improvements

  • An API name is automatically generated when creating a new Process. [UN-192]

  • Integration Diagnostic now checks for global utility installation and version. [UN-369]

  • Millisecond time fields have been added to transactional records. [UN-541]

  • Integration Diagnostic now checks for hotfix version. [UN-682]

Changes

  • The display value for Connections now includes the Integration. [UN-347]

  • Bond reference method is no longer available for Response and Receipt type Messages. [UN-603]

  • Integration no longer controls number of attachments per message as this is done by the message itself. [UN-651]

General Fixes

  • Added the connection variable page to Portal. [UN-656]

  • Copying a Connection Variable now works. [UN-657]

  • Fixed icon alignment on Messages list in UID. [UN-755]

  • Fixed typo with Event Action. [UN-659]

Quick Tour

A high-level overview of the Unifi application.

Navigation Overview

The navigation menu items are grouped logically according to several different areas:

  • Bonding records hold all the data that links your instance to external systems.

  • Transport records give full visibility into what messages were sent and received.

  • Configuration is where you create and manage all your integrations.

  • Polling allows for pollers to be setup to automatically pull data from systems that cannot push.

  • Testing records hold the data necessary to perform end-to-end automated integration testing of the Unifi process and capture the results.

  • Administration contains global settings and other items useful for working with the app.

  • Support links to the Unifi Support page. Here you can find contact details and a link to our documentation.

Setup

Navigate to Administration > Properties and ensure the Integrations Enabled property is checked.

Configuration

The configuration can be carried out simply & intuitively using the Unifi Integration Designer portal interface.

Integrations are grouped by Process and each contains the configuration necessary to connect to one external system.

To add a new Integration you must have already configured a Process record (with associated web services) if you want to receive inbound Messages

Integrations must have an active Connection for them to work. The active Connection tells outbound Messages where to go and specifies the user that is allowed to send data inbound (you must create unique users for each vendor).

Add Messages to control when and what data is sent and received and how it is processed.

Operations

Use the Unifi Operations Portal for a real-time view of Transactions coming & going and a live view of the Bonds, showing their state & grouped by integration.

Use the Dashboard to monitor your integrations and see how external systems are performing.

Testing

‌

Use the Unifi Test Assistant portal interface to run and view the results of end-to-end automated Integration Tests (testing the Unifi process).

Supported Features

Details of the API models & integration features Unifi supports.

API Models

Unifi supports push-push and push-pull request models*.

Model
Delivery Response
Sync Process Response
Async Process Response
Poller

Update Scenario

For each of our Scenarios we will need to configure the relevant Messages & Fields. This scenario will need to be tested before moving on to the next.

The Messages we shall be configuring for our Update Scenario are:

  1. Receipt

  2. UpdateIncident

We will define which Field records require configuring for each of those Messages at the appropriate time.

The scenario will need to be successfully tested before we can say it is complete.

Data Model

An overview of the table structure used by Unifi

The Unifi Data Model provides an overview of which tables are included with Unifi and how they relate at a basic level.

Configuration tables are extended from the ServiceNow Metadata [sys_metadata] table and can be packaged as part of your own scoped applications. While the option is available, the means it is not necessary.

Data tables are standalone and are used to store and manage the runtime data needed for your integrations to function.

Resolve Scenario

For each of our Scenarios we will need to configure the relevant Messages & Fields. This scenario will need to be tested before moving on to the next.

The Message we shall be configuring for our Resolve Scenario is:

  1. ResolveIncident

We will define which Field records require configuring for that Message at the appropriate time.

The scenario will need to be successfully tested before we can say it is complete.

We shall look in detail at each of the Messages and their respective Fields in turn over the next few pages, before moving on to Test.

Activity Log will show “No logs.” if no logs are generated. [UN-768]

  • Errors are no longer duplicated in Activity Log to make it easier to debug. [UN-769]

  • Improved documentation interface in UID. [UN-772]

  • Message Scripts now only throw their own errors (e.g. with Fields). [UN-749]

  • Improved spacing with UID Dashboard grid items. [UN-770]

  • leave a 5-star review on the Store!
    ResolveIncident Message
    ResolveIncident Fields
    Test ResolveIncident

    Resolve Scenario

    For each of our Scenarios we will need to configure the relevant Messages & Fields. This scenario will need to be tested before moving on to the next.

    The Message we shall be configuring for the Resolve Scenario is:

    1. ResolveIncident

    We will define which Field records require configuring for that Message at the appropriate time.

    The scenario will need to be successfully tested before we can say it is complete.

    We shall look in detail at the Message and its respective Fields in turn over the next few pages, before moving on to Test.

    ResolveIncident MessageResolveIncident FieldsTest ResolveIncident

    Build the Other Half

    Building the other half of our integration is much easier than you think.

    If you're asking yourself, 'Do we have to do all that again?' the short answer is no, we don't. When using Unifi both ends, building the other half of the integration is a simple two-stage process.

    • First we Move the Integration, exporting it from one instance and importing it to the other (creating a mirror image in the other instance).

    • Second we Reconfigure the Connections so that each is pointed at the other.

    We will look at both in more detail over the next couple of pages.

    Move the IntegrationReconfigure the Connections

    Bond Identification

    In order for both systems to identify & understand which records are bonded and to facilitate only returning data from bonded records, we need to make a few configuration changes.

    Our previously configured Outbound Incident Integration was very simple example and we weren't concerned with identifying which system made the updates. Neither were we concerned with telling the remote system which record they were bonded with.

    Now that we're polling our PDI for data as well as sending data, we need to be aware of both the above concerns.

    The first concern (identifying which system made the updates) has been taken care of in the Poll Processor Setup script (only returning data not updated by the Basic Authentication User). However, it doesn't make sense to try and return that data from all the records in the remote system. We should only be concerned with those records we're bonded with. To facilitate this we need to make a few configuration changes. We need to make a change in the remote system (our PDI) and some changes to our existing outbound CreateIncident Message.

    First, we will need to Edit the Incident Form in our PDI.

    Edit Incident FormEdit CreateIncident Message

    Inbound Message

    We will need to configure an inbound message to process the data returned from the poll.

    In order to process the data that is returned from the remote system, we will need to create the appropriate messages in Unifi. To satisfy the requirements of this Guide, we will only need to configure the one message:

    • UpdateIncidentInbound

    We shall look in detail at how to configure that message and the appropriate message scripts over the next couple of pages.

    Let's begin by configuring the UpdateIncidentInbound Message.

    UpdateIncidentInbound MessageUpdateIncidentInbound Fields

    We shall look in detail at each of the Messages and their respective Fields in turn over the next few pages, before moving on to Test.

    Receipt Message
    UpdateIncident Message
    UpdateIncident Fields
    Test UpdateIncident

    Outbound push

    Async only

    Yes

    Yes

    -

    Inbound push

    Async only

    Yes

    Yes

    -

    Outbound pull

    -

    -

    -

    Yes

    * Use Direct Web Services or custom Scripted Web Services

    Integrations

    Feature
    Supported

    Unique configuration per Integration

    Yes

    Environment management

    Yes

    Vendor specific

    Yes

    Unifi Packager

    Getting Started

    This Guide utilises the Unifi Integration Designer portal interface which allows you to configure and manage integrations much more intuitively and with greater efficiency.

    Unifi Integration Designer

    From within native ServiceNow, open the Unifi Integration Designer portal by navigating to Unifi > Unifi Integration Designer.

    Dashboard

    You will be greeted with the following Dashboard (which opens in a new window):

    Any existing Processes will be listed as tiles, showing the number of Active Integrations for each. The total number of Active Integrations is also shown on the Dashboard.

    Hovering over the tile of an existing Process will display 'Show integrations'. Clicking it will take you to the Integrations page (for that Process).

    If appropriate, you can either edit the Settings of, or add a New Integration to an existing Process by clicking the ellipsis (at the bottom right of the tile).

    In the next section, we shall look at configuring the Process.

    Update Scenario

    For each of our Scenarios we will need to configure the relevant Messages & Fields. This scenario will need to be tested before moving on to the next.

    The Messages we shall be configuring for the Update Scenario are:

    1. Response

    2. UpdateIncident

    We will define which Field records require configuring for each of those Messages at the appropriate time.

    The scenario will need to be successfully tested before we can say it is complete.

    We shall look in detail at each of the Messages and their respective Fields in turn over the next few pages, before moving on to Test.

    Create Scenario

    For each of our Scenarios we will need to configure the relevant Messages & Fields. This scenario will need to be tested before moving on to the next.

    The Messages we shall be configuring for the Create Scenario are:

    1. CreateIncidentResponse

    2. CreateIncident

    We will define which Field records require configuring for each of those Messages at the appropriate time.

    The scenario will need to be successfully tested before we can say it is complete.

    We shall look in detail at each of the Messages and their respective Fields in turn over the next few pages, before moving on to Test.

    Polling

    We will configure a scheduled poll to query the remote system at regular intervals and pull back data that has changed which it will pass to Unifi to process.

    To set up a scheduled poll that will query the remote system at regular intervals, check whether any data has changed and then pass that data to Unifi, we will need to configure the following records:

    • Poll Processor

    • Poller

    Once those records are configured, we will need to configure an inbound message to process the returned data. We will also need to make some changes to our outbound messages before we can test our update scenario (in order to prove the poll is returning the expected data and the target record is updated accordingly). We will look at the polling records in turn over the next couple of pages.

    We're now ready to configure the Poll Processor.

    Edit Incident Form

    The first configuration change we need to make to facilitate Bond identification is to add the Correlation ID field to the Incident form in our PDI.

    Correlation ID

    In order for the remote system to store data about which record they're bonded with and to enable us to identify and only return data from those bonded records, we need to send and store a unique identifier. We will make use of the available correlation_id field on the Incident record. First we will add the field to the Incident form in our PDI.

    Incident Form

    From any Incident record in your PDI, right-click & navigate to Configure > Form Layout.

    Select the Correlation Id field from the 'Available' slushbucket and move it to the 'Selected' slushbucket.

    Save to add the field to your form.

    Next, we will need to Edit the CreateIncident Message.

    Process

    The first element to configure is the Process, which is the top level configuration element where all Integrations are contained.

    The first thing to do when creating a new integration is to assign it to its Process. For instance, a new Incident integration would be created within an Incident Process. If you do not yet have a Process defined, then you will need to create a new Process

    From the Unifi Integration Designer Dashboard, click on New Process.

    On the 'New Process' modal, the fields to be configured are as follows:

    Field
    Description
    Value

    Response Message

    The Response Message is the immediate synchronous response that is sent to acknowledge the successful transport of another Message.

    In Unifi Integration Designer, click on the 'Messages' icon & then New to begin configuring the Response Message.

    The fields to be configured for the New Message modal are as follows:

    Field
    Description
    Value

    Outbound Incident Guide

    Follow this guide to configure a simple outbound integration to the table API of your Personal Developer Instance. It is given as an aid for those new to Unifi, or to play as part of a trial.

    Welcome

    Congratulations on your decision to use Unifi, the only integration platform you need for ServiceNow. We are sure you will be more than satisfied with this extremely powerful, versatile and technically capable solution.

    Create Scenario

    For each of our Scenarios we will need to configure the relevant Messages & Fields. This scenario will need to be tested before moving on to the next.

    The Messages we shall be configuring for our Create Scenario are:

    1. Response

    2. CreateIncidentReceipt

    3. CreateIncident

    Trigger

    The Trigger is a Business Rule which stipulates the conditions under which Messages will be sent for the process concerned.

    Business Rule

    There is no need for you to manually create a Trigger (Business Rule). If you have more than one, you will make duplicate updates.

    Getting Started

    This Guide utilises the Unifi Integration Designer portal interface which allows you to configure and manage integrations much more intuitively and with greater efficiency.

    Unifi Integration Designer

    From within native ServiceNow, open the Unifi Integration Designer portal by navigating to Unifi > Unifi Integration Designer.

    Message Identification

    Unifi needs to identify the name of the inbound message in order to know how to process the inbound data.

    When we configured our Outbound Incident Integration we weren't concerned with identifying inbound messages, because there weren't any (we were only sending outbound).

    Now that we're polling our PDI for data as well as sending data, we need to be aware of the above concern.

    To facilitate this we need to make a change to our Integration.

    Message Identification

    Conclusion

    Congratulations on using this Multiple Message Poller Guide to successfully poll your PDI for updates - deciding between multiple messages in Unifi to process the returned data.

    This Guide has shown us how we might configure a poller integration - polling data from the table API of a Personal Developer Instance (PDI) and then configure multiple inbound messages to process that data (deciding which Message to use in the process). As such, we created the following records:

    • Poll Processor

    • Poller

    Conclusion

    Congratulations on completing this Outbound Incident Integration Guide.

    This Guide has shown us how to configure a basic Incident integration, sending outbound messages via the REST service. The elements we configured were:

    • Process

    • Integration

    • Connection

    Web Service

    The entry point for a Process - there should be one endpoint per Process. Once connected, messages are guided to the Integration based on the unique combination of authentication user & endpoint.

    Scripted REST API

    In native ServiceNow, navigate to System Web Services > Scripted Web Services > Scripted REST APIs. Click Unifi.

    Response Message

    The Response Message is the immediate synchronous response that is sent to acknowledge the successful transport of another Message.

    As previous, after clicking the 'Messages' icon, you will see the following screen (note: both the previously configured messages are now visible in the list):

    Click New.

    New Message Modal

    The fields to be configured for the Response New Message modal are as follows:

    Polling

    We will configure a scheduled poll to query the remote system at regular intervals and pull back data from the relevant, newly created, unbonded records which it will pass to Unifi to process.

    To set up a scheduled poll that will query the remote system at regular intervals, check whether any new records have been created and then pass that data to Unifi, we will need to configure the following records:

    • Poll Processor

    • Poller

    Once those records are configured, we will need to configure the relevant inbound and outbound messages to process and respond to the returned data. We will also need to make some further changes before we can test our create scenario (in order to identify which records to poll for). We will look at the polling records in turn over the next couple of pages.

    Inbound Messages

    We will need to configure inbound Messages to process the data returned from the poll.

    In order to process the data that is returned from the remote system, we will need to create the appropriate Messages in Unifi. The following Messages will be required:

    • UpdateIncidentInbound

    • ResolveIncidentInbound

    To satisfy the requirements of this Guide (and because we have already configured one of those Messages in the previous Incident Update Poller Guide, we will only need to configure the one message i.e. ResolveIncidentInbound.

    We shall look in detail at how to configure that Message and the appropriate Message Scripts over the next couple of pages.

    Messages

    We will need to configure messages to process and respond to the data returned from the poll.

    In order to process and respond to the data that is returned from the remote system, we will need to create the appropriate Messages in Unifi. To satisfy the requirements of this Guide, we will need to configure the following Messages:

    • CreateIncidentInboundReceipt

    • CreateIncidentInbound

    We shall look in detail at how to configure each of those Messages and the appropriate Fields to configure the Message Scripts over the next few pages.

    Let's begin by configuring the CreateIncidentInboundReceipt

    Inbound Message
  • Fields

  • In testing our integration, we created some incidents in the remote instance which were bonded. We then updated the bonded records from both instances (polling for updates each time). We successfully proved that we were only querying bonded records, pulling back updates made in the remote instance since the last update time, only retrieving a select number of fields and that the returned requests were looped through, generating transactions for each updated ticket.

    We also proved that we were able to store previously returned records in order to facilitate comparison & to enable the decision as to which Message to use to process the data - successfully telling Unifi which Message to use.

    By Using the Unifi integration platform, we have discovered that building and testing our integration is simpler and more efficient, saving both time and money. Our hope is that this Guide has been a valuable aid to you in that process.

    For further information please see our technical documentation.

    If you have any feedback or questions, please contact us via our website contact form.

    Messages

  • Fields

  • The items automatically created by Unifi were:

    • Web Service (not used in this Guide)

    • Trigger

    In testing our integration, we created, updated and resolved an Incident - following the data as it flowed from our ServiceNow Incident record, through the Unifi transaction message bus, to the external system's Incident record.

    By Using the Unifi integration platform, we have discovered that building and testing our integration is simpler and more efficient, saving both time and money. Our hope is that this Guide has been a valuable aid to you in that process.

    For further information please see our technical documentation.

    If you have any feedback or questions, please contact us via our website contact form.

    Inbound pull*

    -

    -

    -

    No

    Response Message
    UpdateIncident Message
    UpdateIncident Fields
    Test UpdateIncident
    CreateIncidentResponse Message
    CreateIncidentResponse Fields
    CreateIncident Message
    CreateIncident Fields
    Test CreateIncident
    Poll Processor
    Scope

    We have created this Outbound Incident Guide as an aid to customers who are beginning their journey in deploying the Unifi integration platform. We would not want you to be overwhelmed by exploring all that Unifi has to offer here, so we have deliberately limited the scope of this document. It will guide you through an example of how to configure a basic Incident integration, sending outbound messages via the REST API to the table API of another ServiceNow instance (i.e. your Personal Developer Instance, ‘PDI’).

    We do not recommend synchronous integrations for enterprise ticket exchange. This Guide is purely here for you to have a play as part of a trial. It is designed to connect to a PDI without Unifi being installed on the other side.

    For more technical information on how to use Unifi, please see our technical documentation.

    Warning

    Do not build integrations directly within the Unifi application scope. This can create issues with upgrades and application management.

    Installation

    The prerequisite to configuring Unifi is to have it installed on your instance. As with any other ServiceNow scoped application, Unifi must be purchased via the ServiceNow Store before installation.

    We recommend you follow the Setup instructions prior to configuring your Integration.

    Installation
    We will define which Field records require configuring for each of those Messages at the appropriate time.

    The scenario will need to be successfully tested before we can say it is complete.

    We shall look in detail at each of the Messages and their respective Fields in turn over the next few pages, before moving on to Test.

    Response Message
    CreateIncidentReceipt Message
    CreateIncidentReceipt Fields
    CreateIncident Message
    CreateIncident Fields
    Test CreateIncident
    Before configuring those polling records, let's first look at Connection Variables.

    Connection Variables
    Poll Processor
    Poller

    Let's begin by configuring the ResolveIncidentInbound Message.

    ResolveIncidentInbound Message
    ResolveIncidentInbound Fields
    Message.

    CreateIncidentInboundReceipt Message
    CreateIncidentInboundReceipt Fields
    CreateIncidentInbound Message
    CreateIncidentInbound Fields

    Hotfix

    Unifi can be patched between releases by using a special Script Include called hotfix. If you find a bug in Unifi we may issue a hotfix so you can get the features you need without having to upgrade.

    Hotfix Installation

    Unifi has a Script Include called hotfix. Simply replace the script in the hotfix Script Include with the one shown below and you will instantly have access to the fixes.

    These hotfixes will be shipped as real fixes with the next version of Unifi, so make sure you have the correct hotfix for your version.

    /**
     * Executes a child function corresponding to the object's type property.
     * The object is passed to the child function so methods and properties can be overridden.
     *
     * @param  {Object} obj The full class object to be patched.
     */
    function hotfix(obj) {
      var type = typeof obj === 'function' ? obj.prototype.type : obj.type;
      if (type && typeof hotfix[type] === 'function') {
        hotfix[type](obj);
      }
    }
    
    hotfix.version = '3.1.1.3';
    
    hotfix.WsupInclForm = function (WsupInclForm) {
      WsupInclForm.prototype.getRecordElements = function getRecordElements(gr) {
        var fields = portal_utils.getRecordElements(gr, portal_utils.getFieldNames(gr, true));
        for (var name in fields) {
          fields[name].displayValue = fields[name].display_value;
          delete fields[name].display_value;
        }
        return fields;
      };
    };
    
    hotfix.portal_utils = function (portal_utils) {
      portal_utils.getRecordElements = function getRecordElements(table, sys_id, field_names) {
        var tmp = {}, gr;
    
        if (table.toString().indexOf('GlideRecord') >= 0) {
          gr = table;
          field_names = sys_id;
        } else {
          gr = new GlideRecordSecure(table);
          if (!gr.isValid()) {
            gs.addErrorMessage('Invalid table: ' + table);
            return;
          }
          if (sys_id == '-1') {
            gr.initialize();
          } else if (!gr.get(sys_id)) {
            gs.addErrorMessage('Invalid sys_id for table ' + table + ':' + sys_id);
            return;
          }
        }
    
        $sp.getRecordElements(tmp, gr, field_names || portal_utils.getFieldNames(gr));
    
        for (var name in tmp) {
          tmp[name].readonly = gr.isValidField(name) ? !gr.getElement(name).canWrite() : false;
          tmp[name].sys_readonly = tmp[name].readonly;
        }
    
        return tmp;
      };      
    };
    
    hotfix.Message = function (Message) {
      Message.prototype.evaluateScript = function evaluateScript(record, element, vars) {
        var source = vars.source;
        var result;
        vars.message = this.getRecord();
        vars.variables = this.getIntegration().getActiveConnection().getVariables();
        if (vars.stage) {
          vars.$stage = vars.stage.$stage;
        }
        result = utils.evaluateScript(record, element, vars);
    
        // UN-1003: reset source - GlideScopedEvaluator changes the GlideRecord object
        // to ScopedGlideRecord which breaks object equality.
        if (source && source.$model) {
            source.$model.setRecord(source);
        }
    
        return result;
      };
    };
    
    hotfix.Model = function (Model) {
      // UN-1144 prevent duplicate bonds on integrations using extended tables.
      Model.prototype.getTableName = function getTableName() {
        if (this._record && this._record.isValidField('sys_class_name')) {
          return '' + this._record.sys_class_name;
        }
        return this._table;
      };
    };
    
    hotfix.Integration = function (Integration) {
      // UN-1298 Error messages defined on the Integration are not retrieved properly
      Integration.prototype.getSyncErrorMessage = function getSyncErrorMessage() {
        return Message.getMessageById(this.getConfig(), this.getValue('sync_error_message'));
      };
      Integration.prototype.getAsyncErrorMessage = function getAsyncErrorMessage() {
        return Message.getMessageById(this.getConfig(), this.getValue('async_error_message'));
      };
    };
    
    hotfix.DataSetProcessor = function (DataSetProcessor) {
      // UN-1299 prevent DataSetProcessor events from being queued when there is no additional data to process
      DataSetProcessor.prototype._executeQueue = function _executeQueue(callback) {
        var rows = this._execute(callback);
        if (this.event) {
          if (rows == this.limit && this.gr && this.gr.hasNext()) {
            ws_console.info('Event ' + this.event.name + ' processed the maximum ' + this.limit + ' records. Auto queueing next event.');
            this.queueNext(this.event, this.current);
          } else {
            ws_console.info('Event ' + this.event.name + ' processed less than the maximum ' + this.limit + ' records. Processing complete.');
          }
        } else {
          ws_console.warn('Cannot auto queue additional processing; event not found.');
        }
        return rows;
      };
    };

    Name

    The name of the ServiceNow process being integrated.

    <SN Process Name> (e.g. Incident)

    API Name*

    The unique name of this process for use with the API.

    <your_unique_api>

    Target table

    The primary target or process table that this integration uses.

    'Incident' [incident]

    Reference field

    The field on the target table that is used as the reference for the external system.

    'Number'

    Description

    Describe what this Process is for.

    *API Name

    The API Name is how we identify which Process we are integrating with. The Scripted SOAP/REST Service will reference the API Name (which is why it is important for this to be a unique reference).

    Your 'New Process' modal should look like this:

    Click Create.

    You will be redirected to your Process Dashboard:

    Click either the '+' tile or 'New Integration' in preparation to configure the Integration.

    When you create a Process, Unifi will automatically create the corresponding Web Service (REST methods).

    This is given for your information only as we are only concerned in this Guide with sending outbound messages to the table API of another ServiceNow instance (i.e. your Personal Developer Instance, ‘PDI’). However, It will be of value should you go on to configure polling integrations following our Poller Guides (which will utilize this same Process).

    The primary purpose of the message.

    'Response'

    Direction

    The direction(s) this message is configured to support. (Choices: Inbound, Outbound, Bidirectional)

    'Bidirectional

    Your Response New Message modal should look like this:

    Click Submit.

    You will be redirected to the Messages page. We need not configure our Response Message any further.

    Next, we shall move on and configure the CreateIncidentReceipt Message.

    Message name

    The message name that is unique for this integration.

    'Response'

    Type

    Unifi will automatically create a Trigger (Business Rule) for the Process being integrated (if one doesn't already exist) when you run 'Build' either on the Integration or Message once your Create Message is configured.

    In native ServiceNow, navigate to System Definition > Busines Rules. Find and navigate to the automatically generated Business Rule.

    The format of the name will be '[S] Unifi ' + <Table Name> + ' trigger rule'.

    The top section of your Business Rule record should look like this:

    When to run Fields

    Your 'When to run' tab should look like this:

    Advanced Fields

    The code in the script field should look like this:

    Your 'Advanced' tab should look like this:

    We have confirmed the main elements are in place for our Integration to work. We are now ready to Test our CreateIncident Message.

    Dashboard

    You will be greeted with the following Dashboard (which opens in a new window):

    Any existing Processes will be listed as tiles, showing the number of Active Integrations for each. The total number of Active Integrations is also shown on the Dashboard.

    Hovering over the tile of an existing Process will display 'Show integrations'. Clicking it will take you to the Integrations page (for that Process).

    If appropriate, you can either edit the Settings of, or add a New Integration to an existing Process by clicking the ellipsis (at the bottom right of the tile).

    In the next section, we shall look at configuring a new Process.

    This script is necessary because we have chosen to include the Message name in the structure of the payload object (see Response Script on the 'Poll Processor' page). If we had chosen instead to set it in the options object, it would have been processed and passed to Unifi for automatic Message identification - without the need to configure this script.

    To enable the Integration to identify which messages to use to process inbound requests:

    Navigate to the 'Integration' icon to open < Your Integration >, then navigate to Integration > Message Identification.

    Update the code in the 'Identify message script' field so that it looks like this:

    The Message Identification form should look like this:

    Save the record.

    In order for both systems to identify and understand which records are bonded, we need to make a few more changes which we shall group together under the heading of Bond Identification.

    function identify(payload) {
    
      return (payload.message.name || '') + '';
    
    }
    Scripted REST Resources

    Navigate to the Resources Related List.

    The Unifi Scripted REST API ships with Message template and Attachment template Resources. Unifi uses these templates and substitutes values from the newly created Process to automatically create the equivalent Scripted REST Resources.

    Note: The Default ACLs role [x_snd_eb_integration] will need to be given to your Integration User to access the automatically created REST Resources.

    Updated Process

    Note: The Process record has been updated with the names of the REST Service, Message method and Attachment method. This will enable the Packager to pick it up so that it will be included in the packaged update set. For more information see the Packager Feature Guide.

    We will now continue to configure the Integration.

    Field
    Description
    Value

    Message name

    The message name that is unique for this integration.

    'Response'

    Type

    The primary purpose of the message.

    'Response'

    Direction

    The direction(s) this message is configured to support. (Choices: Inbound, Outbound, Bidirectional)

    'Inbound'

    Your Response New Message modal should look like this:

    Click Submit.

    You will be redirected to the Messages page. You need not configure the Response Message any further.

    Now it's time to move on and configure the UpdateIncident Message.

    Process

    The first element to configure is the Process, which is the top level configuration element where all Integrations are contained.

    The first thing to do when creating a new integration is to assign it to its Process. For instance, a new Incident integration would be created within an Incident Process. If you do not yet have a Process defined, then you will need to create a new Process

    From the Unifi Integration Designer Dashboard, click on New Process.

    On the 'New Process' modal, the fields to be configured are as follows:

    Field
    Description
    Value

    *API Name

    The API Name is how we identify which Process we are integrating with. The Scripted SOAP/REST Service will reference the API Name (which is why it is important for this to be a unique reference).

    Your 'New Process' modal should look like this:

    Click Create.

    You will be redirected to your Process Dashboard:

    Click either the '+' tile or 'New Integration' in preparation to configure the Integration.

    When you create a Process, Unifi will automatically create the corresponding Web Service (REST methods) - so there is no need to manually create them.

    Before we configure the Integration, let's view the Web Service which Unifi has automatically created.

    Trigger

    The Trigger is a Business Rule which stipulates the conditions under which Messages will be sent for the Process concerned.

    Business Rule

    There is no need for you to manually create a Trigger (Business Rule). If you have more than one, you will make duplicate updates.

    Unifi will automatically create a Trigger (Business Rule) for the Process being integrated (if one doesn't already exist) when you run 'Build' either on the Integration or Message once your Create Message is configured.

    In native ServiceNow, navigate to System Definition > Busines Rules. Find and navigate to the automatically generated Business Rule.

    The format of the name will be '[S] Unifi ' + <Table Name> + ' trigger rule'.

    The top section of your Business Rule record should look like this:

    When to run Fields

    Your 'When to run' tab should look like this:

    Advanced Fields

    The code in the script field should look like this:

    Your 'Advanced' tab should look like this:

    We have confirmed the main elements are in place for our Integration to work. We are now ready to Test our CreateIncident Message.

    Incident Update Poller Guide

    Follow this guide to configure a poller integration - polling the table API of your Personal Developer Instance (PDI) for updates only. This is the first of five Poller Guides. See 'Scope' for more.

    Welcome

    We will be configuring a Poller and Poll Processor in order to pull Incident data which has been updated from an external instance and pass it to Unifi. We will then configure the relevant inbound Message in order to process that data.

    If you have been following along with the Outbound Incident Guide you will know that it is given as an example of how you might configure such an integration. It is not meant to be prescriptive. The same applies here.

    Having said that, this Guide has been written to follow on from that previous one and has been structured accordingly.

    Scope

    This document will guide you through an example of how you might configure a poller integration - polling the table API of your Personal Developer Instance (PDI).

    This Guide is complementary to the Outbound Incident Guide. It assumes that both the Integration and the Connection are still in place and will be using those same elements as configured in that Guide. It also assumes that you know how to use the REST API of your PDI to query for information and read ticket data.

    If you haven’t completed the Outbound Incident Guide, please review & complete the following sections of that document, as they must be in place before continuing with this Guide:

    The Outbound Incident Guide demonstrates how to configure outbound messages to the table API of your PDI. This Guide will demonstrate how you might poll data from the table API of your PDI and then configure inbound messages to process that data.

    Definitions

    It is not always possible for a remote system to send us the data. In such cases, we can make a scheduled request for it using Pollers. We can setup, execute and process those Requests using Poll Processors.

    Poller

    A poller defines the frequency of polling and which logic to use. It is effectively a scheduled job which ties together an Integration and Poll Processor. Although a Poller belongs to only one Integration, an Integration can have multiple Pollers.

    Poll Processor

    A Poll Processor contains the logic that will be applied when polling a remote system for data. It contains three main scripts:

    Setup Script

    The Setup Script is used to build the environment for the poll and define what it will do (for example, create/setup the URL that will be called).

    Request Script

    The Request Script is used to reach into the remote system and execute the request. This is usually done by making a REST call to the URL defined in the Setup Script.

    Response Script

    The Response Script is used to process the information returned from the remote system.

    Warning

    Do not build integrations directly within the Unifi application scope. This can create issues with upgrades and application management.

    Approach

    We will need to store and check some returned data in order to evaluate when the data was changed and which system has made the updates to the data (we don’t want to pull back data we have changed).

    We will begin by polling for updates only and processing those requests using an update message in Unifi.

    We will also need to make some additional changes to the previously configured integration in order to allow for message identification and the ability to identify which records are bonded.

    Poller

    A Poller is a configuration record which defines the frequency of polling and which logic to use.

    A Poller is a configuration record which defines the frequency of polling and which logic to use (the logic itself is defined in the Poll Processor). Each time it is run, it creates a corresponding Poll Request record.

    Edit Update Poller

    Rather than create a new poller, you can edit the previously configured 'Update Poller', changing the Name, Description & Poll Processor.

    (You could choose to copy the previous Poller instead. However, there is no need to have two pollers polling for updates every 5 minutes, so if copying the previous poller, remember to deactivate it.)

    Click to open the previously configured Incident Update Poller.

    The fields to be edited for our Poller record are as follows:

    Field
    Description
    Value

    *These fields are mandatory, or automatically defaulted to true.

    Your Multiple Message Poller should look like this:

    Save the Poller.

    In order to process the inbound Requests, we need to configure the Inbound Messages.

    Conclusion

    Congratulations on completing this bidirectional asynchronous Incident integration Guide.

    This Guide has shown us how to configure an asynchronous Incident integration, sending bidirectional messages via the REST service. The elements we configured were:

    • Process

    • Integration

    • Connections

    • Messages

    • Fields

    The items automatically created by Unifi were:

    • Web Service

    • Trigger

    In testing our integration, we created, updated and resolved an Incident - following the data as it flowed from our ServiceNow Incident record, through the Unifi transaction message bus, to the external system's Incident record.

    By Using the Unifi integration platform, we have discovered that building and testing our integration is simpler and more efficient, saving both time and money. Our hope is that this Guide has been a valuable aid to you in that process.

    For further information please see our .

    If you have any feedback or questions, please contact us via our website .

    Conclusion

    Congratulations on successfully polling your PDI for updates using this Update Poller Guide.

    This Guide has shown us how we might configure a poller integration - polling data from the table API of a Personal Developer Instance (PDI) and then configure an inbound message to process that data. As such, we created the following records:

    • Poll Processor

    • Poller

    • Inbound Message

    • Fields

    We also made further configuration changes to both the remote instance (PDI) and internal instance, in order to facilitate the following:

    • Message Identification

    • Bond Identification

    In testing our integration, we created some incidents in the remote instance which were bonded. We then updated the bonded records from both instances (polling for updates each time). We successfully proved that we were only querying bonded records, pulling back updates made in the remote instance since the last update time, only retrieving a select number of fields and that the returned requests were looped through, generating transactions for each updated ticket.

    By Using the Unifi integration platform, we have discovered that building and testing our integration is simpler and more efficient, saving both time and money. Our hope is that this Guide has been a valuable aid to you in that process.

    For further information please see our .

    If you have any feedback or questions, please contact us via our website .

    Build - Integration Level

    It is possible to run the Build process from the Integration. This will cause the process to cycle through each of the Messages on the Integration in turn.

    We have been running the Build process at the Message level in order to see the changes in our Message Scripts as we go. This may be considered good practice (particularly when first starting out) as any discrepancies can be discovered & rectified as you go (in potentially fewer, smaller batches). Once you are more practiced and confident in the accuracy of your configurations, you can run the Build process at the Integration level. This means that the process will cycle through all the Field records on each of the Messages on the Integration in turn & auto-generate all the relevant Message Script code.

    As mentioned in the 'CreateIncidentReceipt Fields' page, we saw that a 'Build Integration' button had appeared in the banner at the top of the page. This was because, whenever a change is made to a Field record that is associated to a Message (whether that is being created, updated, or deleted) the button will be available and act as a visual reminder that changes have been made and Message Script(s) need to be built.

    To run the Build Process at the Integration level we have two choices. We can either either run it from the Integration record, or we can use the 'Build Integration' button which appears in the banner at the top of the page.

    To run it from the Integration record. In Unifi Integration Designer, navigate to: 'Integration' icon.

    Click Build.

    To run it from the 'Build Integration' button which appears in the banner at the top of the page.

    Click Build Integration.

    On the Build Integration modal, click Build.

    When complete, you will see the following Integration Build Worker modal:

    Click Done.

    Navigate to: 'Messages' icon.

    Feature Alert: The widget at the bottom of the page also shows when 'Build' was last run.

    Click through each Message in turn, navigating to Advanced > Script Editor to view the auto-generated code in the Message Scripts.

    We have now built and tested the integration in one instance. We are now ready to move on and Build the other half.

    Testing

    You should have successfully configured a Poll Processor and Poller. You should also have configured the ResolveIncidentInbound message. The next thing to do is to test.

    It may help to esure the Poller we created is turned off (Active set to 'false') whilst conducting these tests and to manually execute it as required (this can still be done even if the Poller is inactive). This is so that we don't have to wait for the Poller to run, but rather manually activate it when needed by clicking 'Execute Now'.

    To turn off the Poller, in the Unifi Integration Designer window, navigate to the 'Pollers' icon & set Active to false. (If you've created this Multiple Message Poller by editing the previously configured Update Poller, it may already be inactive.)

    Our Poll Processor has been configured to poll for updates from our PDI and make a decision, telling Unifi which Message to use to process that data. We will therefore test our poller by means of testing both of the inbound Messages on our Integration:

    • UpdateIncidentInbound

    • ResolveIncidentInbound

    We will look in more detail at the steps for each over the next couple of pages.

    First, we shall test the UpdateIncidentInbound Message.

    Polling

    We will configure a scheduled poll to query the remote system at regular intervals and pull back data that has changed which it will pass to Unifi to process.

    To set up a scheduled poll that will query the remote system at regular intervals, check whether any data has changed and then pass that data to Unifi, we will need to configure the following records:

    • Poll Processor

    • Poller

    Once those records are configured, we will need to configure inbound Messages to process the returned data. We will look at the polling records in turn over the next couple of pages.

    We're now ready to configure the Poll Processor.

    Integration

    This is what defines the connection between a Process and the single system it's connecting with. It is also where most of the configuration and settings are stored.

    New Integration

    In the Unifi Integration Designer window, after clicking either on the '+' tile or 'New Integration', you are given a 'New Integration' modal to complete.

    The fields to be configured for the New Integration modal are as follows:

    Field

    ResolveIncidentInbound Message

    We will configure another inbound update type message to process the data returned from the poll and update our target record.

    Rather than create the ResolveIncidentInbound Message from scratch, it will be quicker to copy the UpdateIncidentInbound Message and make some minor changes.

    Click on the 'Messages' icon to open the Messages page.

    Click the ellipsis to the right of the UpdateIncidentInbound Message & then click Copy.

    Build - Integration Level

    It is possible to run the Build process from the Integration. This will cause the process to cycle through each of the Messages on the Integration in turn.

    We have been running the Build process at the Message level so as to see the changes in our Message Scripts as we go. This may be considered good practice (particularly when first starting out) as any discrepancies can be discovered & rectified as you go (in potentially fewer, smaller batches). Once you are more practiced and confident in the accuracy of your configurations, you can run the Build process at the Integration level. This means that the process will cycle through all the Field records on each of the Messages on the Integration in turn & auto-generate all the relevant Message Script code.

    As mentioned in '', we saw that a 'Build Integration' button had appeared in the banner at the top of the page. This was because, whenever a change is made to a Field record that is associated to a Message (whether that is being created, updated, or deleted) the button will be available and act as a visual reminder that changes have been made and Message Script(s) need to be built.

    To run the Build Process at the Integration level we have two choices. We can either either run it from the Integration record, or we can use the 'Build Integration' button which appears in the banner at the top of the page.

    To run it from the Integration record. In Unifi Integration Designer

    Bidirectional Asynchronous Incident Guide

    Follow this guide to configure a bidirectional asynchronous integration to the Incident table. This push-push integration will use Unifi both ends.

    Welcome

    Congratulations on your decision to use Unifi, the only integration platform you need for ServiceNow. We are sure you will be more than satisfied with this extremely powerful, versatile and technically capable solution.

    Receipt Message

    The Receipt Message is the asynchronous receipt that is sent after processing update type messages.

    Again, after clicking the 'Messages' icon, you are directed to the following screen (note: the three previously configured messages are now visible in the list):

    Click on the ellipsis to the right of the CreateIncidentReceipt Message & click Copy.

    Rather than create the Receipt Message from scratch, it will be quicker to copy the CreateIncidentReceipt Message and make one minor change.

    CreateIncidentResponse Message

    The CreateIncidentResponse Message is the immediate, synchronous response that is sent after processing the Createincident Message.

    New Message Modal

    In Unifi Integration Designer, navigate to the 'Messages' icon. Click New.

    The fields to be configured for the CreateIncidentResponse New Message modal are as follows:

    Field
    Description
    (function executeRule(current, previous /*null when async*/) {
      x_snd_eb.ws_console.logExecute('Business rule: [S] Unifi ' + current.getTableName() + ' trigger rule', function () {
        x_snd_eb.ActivityLog.setDocument(current, 'sys_script');
        x_snd_eb.Message.processOutbound(current);
      });
    })(current, previous);
  • Connection

  • Process
    Integration
    technical documentation
    contact form
    technical documentation
    contact form
    Poll Processor
    Poller
    Scope

    We have created this Guide as an aid to customers who are beginning their journey in deploying the Unifi integration platform. This document will guide you through an example of how to configure a bidirectional asynchronous Incident integration, sending and receiving messages via the Scripted REST Service.

    This guide is here to help you get up and running as quickly as possible, enabling you to realise the enormous benefits to be gained when using Unifi to configure your integration.

    For more technical information on how to use Unifi, please see our technical documentation.

    Warning

    Do not build integrations directly within the Unifi application scope. This can create issues with upgrades and application management.

    Guide Structure and Testing Approach

    All of the configuration is carried out in Unifi Integration Designer (our portal interface) - Processes, Integrations, Connections, Messages, Fields & Field Maps are configured manually. The remaining configuration elements (Web Service & Trigger) - which were previously configured in native ServiceNow - are automatically created by Unifi.

    Automatic creation of the Trigger (Busines Rule) and Web Service (REST Method) make configuring Integrations even easier and more efficient than ever before.

    The Trigger (Business Rule) is automatically created (if one doesn't already exist) when you run 'Build' either on the Integration or Message once your Create Message is configured.

    The Web Service (REST Method) is automatically created when the Process is configured.

    We have structured this Guide to align with the testing approach. Firstly, we shall configure the main elements which have to be in place for the Integration to work, then we shall move on to build & test each of the scenarios individually. For example, build the CreateIncident Message (along with CreateIncidentReceipt & Response), configure the relevant Fields for those Messages and then test the CreateIncident Message. Then do the same for the UpdateIncident Message (& Receipt) and so on.

    Some Dos & Don’ts

    We want to include some advice on things to be aware of - either to ensure you do them, or avoid doing them - when building & testing Unifi integrations; in particular and especially if many people are building in one instance at the same time (whether that be a training instance or sub-production instance).

    • Make sure your Process API name is unique, otherwise use an existing Process.

    • Make sure your SOAP and/or REST endpoints are also unique.

    • When setting up a Connection:

      • Never use your own User as the Inbound User as it will prevent the integration from working.

      • Always ensure that your Inbound User is NOT used by anyone else for the same Process i.e. if you’re creating a Connection for an Integration on the Incident Process, your Inbound User has to be the only User used by an Integration within that Process.

    • There is no need for you to manually create a Trigger (Business Rule) on a table to be integrated if one doesn’t exist already. Unifi will automatically create one. If you have more than one, you will make duplicate updates.

    • There is no need for you to manually create a Web Service. Unifi will automatically create one when the Process is configured.

    Installation

    The prerequisite to configuring Unifi is to have it installed on your instance. As with any other ServiceNow scoped application, Unifi must be purchased via the ServiceNow Store before installation.

    We recommend you follow the Setup instructions prior to configuring your Integration.

    Installation
    Description
    Value

    Name

    The name of the integration.

    <Your Name>

    Service type*

    The type of web service this integration is using (Choices: SOAP/REST).

    'REST'

    Message format*

    Automatically pre-process incoming messages for simpler message scripting. (Choices: XML, JSON, Advanced)

    'JSON'

    *Service type/Message format: these values are defaulted.

    Your 'New Integration' modal should look like this:

    We have chosen to name this integration 'Push-Pull Incident' as it will also later form the basis for the Poller Guides (where we pull data from your Personal Developer Instance, ‘PDI’).

    Click Create.

    You will be redirected to the Details page of the newly created Integration.

    Icons

    Before continuing we would like to draw your attention to some of the relevant icons that are now visible down the left hand navigation strip.

    The icons are:

    a) 'Integration' icon: Opens the current integration's Details page.

    b) 'Messages' icon: Opens the current integration's Messages page.

    c) 'Fields' icon: Opens the current integration's Fields page.

    d) 'Field Maps' icon: Opens the current integration's Field Maps page.

    e) 'Documentation' icon: Opens the automatically generated documentation for the current integration. (Another awesome feature in Unifi.)

    f) 'Connections' icon: Opens the current integration's Connections page.

    Details

    The Details page of your Integration form should look like this:

    Navigate to Settings > Feedback.

    Feedback Settings Fields

    The Feedback fields to be configured for the Integration record are as follows:

    Field
    Description
    Value

    Enable UI messages

    Allow information and error messages to be shown to the user as UI Notifications. Only applies to certain notifications.

    <true>

    Note bond history

    Use the 'Note bond history' to process bond history updates. (Set to true for the history to be promoted to the work notes fields of the record we're integrating - for the analyst to view)

    <true>

    The Feedback Settings fields should look like this:

    The remaining 'Integration' values are to be left as-is:

    • Message Identification

    All of the remaining 'Settings' values are to be left as-is:

    • Attachments Settings

    • Bond Settings

    All of the 'Error handling' values are to be left as-is:

    • General

    • Timeouts

    • Retry

    Click Save.

    Click the 'Connections' icon to move on and configure the Connection.

    Copy Message Modal

    The fields to edit for the Copy Message modal are as follows:

    Field
    Description
    Value

    Message name

    The message name that is unique for this integration.

    'ResolveIncidentInbound'

    Your Copy Message modal should look like this:

    Click Copy.

    You will be redirected to the Details page of the newly created ResolveIncidentInbound Message.

    Details Fields

    The Details fields to be edited are as follows:

    Field
    Description
    Value

    Description

    The description for this message and the requirement it is meeting.

    <Your description>

    Your Details form should look like this:

    Navigate to Message > Bond.

    Bond Fields

    The Bond fields to be edited are as follows:

    Field
    Description
    Value

    Bond pending

    Process this message when the bond state is Pending.

    <true>

    Bond suspended

    Process this message when the bond state is Suspended.

    <true>

    Bond vendor suspended

    Process this message when the bond state is Vendor suspended.

    <true>

    Your Bond form should look like this:

    Click Save.

    We are now ready to configure the Fields for the ResolveIncidentInbound Message.

    , navigate to:
    'Integration' icon
    .

    Click Build.

    To run it from the 'Build Integration' button which appears in the banner at the top of the page.

    Click Build Integration.

    On the Build Integration modal, click Build.

    When complete, you will see the following Integration Build Worker modal:

    Click Done.

    Navigate to: 'Messages' icon.

    Feature Alert: At the bottom right of the window you will see a widget that displays whether the Integration is Active and when 'Build' was last run.

    Click through each Message in turn, navigating to Advanced > Script Editor to view the auto-generated code in the Message Scripts.

    We have now built and tested the Outbound Incident Integration.

    CreateIncidentResponse Fields
    Copy Message Modal

    The fields to edit for the Copy Message modal are as follows:

    Field
    Description
    Value

    Message name

    The message name that is unique for this integration.

    'Receipt'

    Your Copy Message modal should look like this:

    Click Copy.

    You will be redirected to the Details page of the newly created Receipt Message.

    Bond Fields

    Navigate to Message > Bond.

    The Bond fields to be edited are as follows:

    Field
    Description
    Value

    Set bond state inbound*

    Set the Bond State when receiving this message. Use 'None' to leave the Bond State alone or to modify it via a Message/Field Stage to Target script.

    'None'

    *Set bond state choices: None, Pending, Open, Suspended, Vendor suspended, Closed

    Your Bond form should look like this:

    Click Save.

    Click Build Message.

    You will see the 'Message build successful' Info Message.

    Click the 'Messages' icon to move on & configure the UpdateIncident Message.

    There is no further configuration required for the Receipt Message.

    Value

    Message name

    The message name that is unique for this integration.

    'CreateIncidentResponse'

    Type

    The primary purpose of the message.

    'Response'

    Direction

    The direction(s) this message is configured to support. (Choices: Inbound, Outbound, Bidirectional)

    'Inbound'

    Your CreateIncidentResponse New Message modal should look like this:

    Click Submit and view to further configure the Message.

    Bond Fields

    Navigate to Message > Bond.

    The Bond fields to be configured are as follows:

    Field
    Description
    Value

    Set bond state inbound*

    Set the Bond State when receiving this message. Use 'None' to leave the Bond State alone or to modify it via a Message/Field Stage to Target script.

    'Open'

    *Set bond state choices: None, Pending, Open, Suspended, Vendor suspended, Closed

    Your Bond form should look like this:

    Setting the Bond state to Open allows messages to be sent/received. See the 'Bonds' page for details.

    Click Save.

    We are now ready to configure the Fields for our CreateIncidentResponse Message.

    <Your description>

    Name

    The name of the ServiceNow process being integrated.

    <SN Process Name> (e.g. Incident)

    API Name*

    The unique name of this process for use with the API.

    <your_unique_api>

    Target table

    The primary target or process table that this integration uses.

    'Incident' [incident]

    Reference field

    The field on the target table that is used as the reference for the external system.

    'Number'

    Description

    Describe what this Process is for.

    <Your description>

    Name*

    The name of your Poller.

    <Your Name>

    Description

    A description of what this Poller is for and/or how it works.

    <Your Description>

    Poll processor*

    The Poll Processor to use when running this Poller.

    <Your Poll Processor> (the one just created)

    Test UpdateIncidentInbound
    Test ResolveIncidentInbound

    Unifi 3.0 Release Notes

    Here you will find details of what's changed in this release, including new features & improvements, deprecated features and general fixes.

    Introduction

    The ShareLogic Unifi 3.0 release includes a range of new features, improvements and fixes. Read on to find out about exciting new capabilities that will further enhance your experience.

    Upgrade Notice

    Please note that, as with every release, there may be some changes that are not entirely compatible with your existing integrations. While we do everything we can to make sure you won’t have to fix your integrations when upgrading, we strongly encourage all our customers to perform full end-to-end tests of their integrations before upgrading Unifi in Production.

    We also highly recommend aligning your Unifi upgrade with your ServiceNow upgrade. This means you only need to test your integrations one time rather than once for the ServiceNow upgrade and once for the Unifi upgrade.

    Feedback and Reviews

    We really appreciate feedback on what we’re doing - whether it’s right or wrong! We take feedback very seriously, so if you feel you’d give us anything less than a 5 star rating, we’d love to hear from you so we can find out what we need to do to improve!

    Unifi 3.0 Highlights

    Test Assistant

    Unifi 3.0 introduces the Unifi Test Assistant as a way to view, run and analyse automated tests in your instance. Test Assistant helps to remedy the issues of regression testing large numbers of integrations when you come to upgrade your ServiceNow instance or Unifi itself. Tests are created with one click from existing bonds, and can be tested at any time. Exporting tests to your other instances is a breeze as the tests are packaged with your integrations.

    Dynamic Documentation Update

    The integration documentation automatically generated for every integration has had a major overhaul with a new layout, better navigation, and major performance improvements.

    New Features & Improvements

    • UN-114 Added a Connection Test button to perform a simple high-level test of the connection to the specified endpoint.

    • UN-187 Automate creation of the Business Rule on any table that has a Unifi message assigned to it.

    • UN-783 The table field is now cleared when copying Receipt or Response messages.

    • UN-794 Added Run Conditions Section to Event Actions in Unifi Designer.

    Changes

    • UN-830 Bond history has been removed from the Bond form for performance.

    • UN-882 Updated the top navigation menu links in portals.

    • UN-889 Updated the 'Get help' portal page to show new branding and information.

    • UN-978 Field inheritance is now active by default and the form is locked down if inherit box is checked.

    Fixes

    • UN-771 Fixed auto-documentation printing layout.

    • UN-795 Fixed an issue where sending an attachment on new would incorrectly commit a new empty bond when the attachment failed to send.

    • UN-798 Fixed the Event Actions table field so it shows Unifi tables.

    • UN-799 Fixed an issue with the Event Action advanced condition also running the standard condition.

    Poller

    A Poller is a configuration record which defines the frequency of polling and which logic to use.

    A Poller is a configuration record which defines the frequency of polling and which logic to use (the logic itself is defined in the Poll Processor). Each time it is run, it creates a corresponding Poll Request record.

    New Poller

    Click the 'Pollers' icon & then New.

    The fields to be configured for the New Poller modal are as follows:

    Field
    Description
    Value

    *These fields are mandatory, or automatically defaulted to true.

    Your New Poller modal should look like this:

    Submit and view to further configure the Poller.

    Details

    The fields to be configured for the Details form are as follows:

    Field
    Description
    Value

    Your Details form should look like this:

    Navigate to Scheduling.

    Scheduling

    The fields to be configured for the Scheduling form are as follows:

    Field
    Description
    Value

    *This field is mandatory.

    Your Scheduling form should look like this:

    Save the Poller.

    In order to process the inbound Requests, we next need to configure our Inbound Message.

    ResolveIncident Message

    The ResolveIncident Message is an update type message that we will configure to deal specifically with our resolve scenario (resolve the bonded records).

    Again, after clicking the 'Messages' icon, you are directed to the following screen (note: the four previously configured messages are now visible in the list):

    Click the ellipsis to the right of the UpdateIncident Message & then click Copy.

    It is now easier than ever to create the ResolveIncident Message. Rather than create it from scratch, it will be quicker to copy the UpdateIncident Message and make some minor changes.

    Copy Message Modal

    The fields to edit for the Copy Message modal are as follows:

    Field
    Description
    Value

    Your Copy Message modal should look like this:

    Click Copy.

    You will be redirected to the Details page of the newly created ResolveIncident Message.

    Bond Fields

    Navigate to Message > Bond.

    The Bond fields to be edited are as follows:

    Field
    Description
    Value

    Your Bond form should look like this:

    Navigate to Outbound > Trigger.

    Outbound Trigger Fields

    The Outbound Trigger (as required)* fields to be edited are as follows:

    Field
    Description
    Value

    *Outbound condition (as required):

    It is not necessary for you to enter a condition. The value given is an example. You may create any condition (or not) to align with your business process requirements. In this case, it makes sense to send the ResolveIncident Message when the state changes to Resolved.

    Your Outbound Trigger form should look like this:

    Click Save.

    We are now ready to configure the Fields for the ResolveIncident Message.

    Unifi 3.1 Release Notes

    Unifi 3.1.2

    Release date: 17 November, 2021

    CreateIncidentReceipt Message

    The CreateIncidentReceipt Message is the asynchronous receipt that is sent after processing the Createincident Message.

    You will have been redirected to the Messages page after submitting the Response Message. If navigating from elsewhere, click the 'Messages' icon and you will see the following screen (note: the previously configured message is visible in the list):

    Click New.

    New Message Modal

    The fields to be configured for the CreateIncidentReceipt New Message modal are as follows:

    Test ResolveIncidentInbound

    Follow these steps to test the ResolveIncidentInbound Message.

    Resolve Test Incident

    In the remote instance (your PDI), navigate to < Your Incident > created in the earlier test.

    Update the Incident record as follows:

    Field
    Description

    Move the Integration

    The first step to building the other half of the Integration is to export it from one instance and import it to the other.

    Export the Integration

    NOTE: The ServiceNow System Administrator (admin) role is required to see the automatic download and view updates in the Update Set (and to select Application Scope - if required).

    Incident Multiple Message Poller Guide

    Follow this second of five Poller Guides to configure an integration - polling the table API of your Personal Developer Instance (PDI) for updates & deciding between multiple messages to process.

    Welcome

    We will be configuring another Poller and Poll Processor in order to pull data which has been updated from an external instance and then pass it to Unifi. We will then configure the relevant inbound Messages in order to process that data.

    If you have been following along with the Outbound Incident Guide and the previous Poller Guide you will know that they are given as examples of how you might configure such integrations. They are not meant to be prescriptive. The same applies here.

    Having said that, this Guide has been written to follow on from those previous ones and has been structured accordingly.

    ResolveIncident Message

    The ResolveIncident Message is an update type message that we will configure to deal specifically with our resolve scenario (resolve the bonded records).

    Again, after clicking the 'Messages' icon, you are directed to the following screen (note: the five previously configured messages are now visible in the list):

    Click the ellipsis to the right of the UpdateIncident Message & then click Copy.

    Rather than create the ResolveIncident Message from scratch, it will be quicker to copy the UpdateIncident Message and make some minor changes.

    Incident Create Poller Guide

    Follow this guide to configure a poller integration - polling the table API of your Personal Developer Instance (PDI) for creates only. This is the third of five Poller Guides. See 'Scope' for more.

    Welcome

    We will be configuring a Poller and Poll Processor in order to pull Incident records which have been created in an external instance and pass the data to Unifi. We will then configure the relevant Messages in order to process and respond to that data.

    If you have been following along with the Outbound Incident Guide and each of the previous Poller Guides you will know that they are given as examples of how you might configure such integrations. They are not meant to be prescriptive. The same applies here.

    Having said that, this Guide has been written to follow on from those previous ones and has been structured accordingly.

    CreateIncidentInboundReceipt Message

    We will configure an outbound receipt message to respond to the data returned from the poll and update the originating record in the remote instance with the correlation id.

    New Message Modal

    Click the 'Messages' icon, then New.

    The fields to be configured for the CreateIncidentInboundReceipt New Message modal are as follows:

    Field
    Description
    (function executeRule(current, previous /*null when async*/) {
      x_snd_eb.ws_console.logExecute('Business rule: [S] Unifi ' + current.getTableName() + ' trigger rule', function () {
        x_snd_eb.ActivityLog.setDocument(current, 'sys_script');
        x_snd_eb.Message.processOutbound(current);
      });
    })(current, previous);
    If you would rate us 5 stars, and haven’t left a review on the ServiceNow Store yet, we’d be grateful if you would head over there to leave us your feedback. It only takes a few minutes and really does help us a lot. Go on, you know you want to
  • UN-796 Added checks for Unifi properties in Diagnostic.

  • UN-797 Attachment trigger Business Rule is now wrapped by console so it generates Activity Logs.

  • UN-807 Improve ActivityLog performance within loops.

  • UN-809 Added system property to control of the maximum age of Activity Logs.

  • UN-810 Modified attachment processing so that it will only be processed when the related record is already bonded.

  • UN-811 Improvements to Activity Log performance.

  • UN-812 Inbound REST methods are automatically created when Processes are defined/updated.

  • UN-813 Warning during outbound message processing (e.g. "Ignoring messages for integration ...") have been changed to debugs.

  • UN-818 Editing a field map now causes the Integration Build button to be shown.

  • UN-828 Transaction Replay from list view now informs the user if replays have been unsuccessful.

  • UN-890 Connections can be assigned an instance to prevent production integrations running in sub-production instances when cloned.

  • UN-908 Add fields and field maps to documentation.

  • UN-912 Added links to various configuration records in platform so they can be easily opened in Unifi Designer.

  • UN-915 Show number of active integrations to make it easy for people to know how many licences they have used.

  • UN-916 Add Response Actions to Unifi documentation generator.

  • UN-917 Add Poll Processors to Unifi documentation generator.

  • UN-918 Add Scheduled Jobs to Unifi documentation generator.

  • UN-924 Update to Transaction and HTTP Request numbers to show decimal suffix on first attempt.

  • UN-930 Allow message scripts to be toggled on dynamic documentation.

  • UN-952 Bond ownership can now be controlled from Message fields.

  • UN-953 Bond state can now be controlled from Message fields.

  • UN-967 Added information box to Connections page in Unifi Designer to show the inbound endpoints of the integration.

  • UN-968 Process page now shows all fields in Unifi Designer.

  • UN-969 Attempt number is now shown on inbound HTTP requests.

  • UN-972 Related Event Actions are now shown on Messages.

  • UN-973 Messages are no longer prefixed with 'Copy of' if copying to another Integration.

  • UN-976 Messages are now ordered by name in Unifi Designer.

  • UN-977 Inbound transactions now set the source connection on the bond.

  • UN-978 Field inheritance is now active by default.

  • UN-988 Authorization header is masked in the headers on HTTP Request.

  • UN-992 Add support for headers and request in Payload to Stage message scripts.

  • UN-1000 Enhance Activity Log with success messages.

  • Other minor portal improvements.

  • UN-800 Fixed an issue where no table being set on an Event Action would cause it to break.

  • UN-803 Fixed an issue where inactive Event Actions were being processed.

  • UN-808 Fixed domain value during HTTP Request retry.

  • UN-816 The Response Action field is now cleared when replaying a Transaction.

  • UN-820 Modified the attachment business rule condition to prevent an error when 'previous' object does not exist.

  • UN-822 Fixed the Diagnostic and Self-Test roles so they accessible by the Unifi admin role.

  • UN-829 Fixed an issue preventing a Unifi admin user from replaying Transactions.

  • UN-831 Fixed the inbound processing so that the transaction and bond domain are set correctly from the domain on the request.

  • UN-833 Added measures to prevent the increased async rule performance from causing blank tickets.

  • UN-865 Fixed an issue with the domain not being set when replaying a transaction or request.

  • UN-867 Fixed an issue with a successful Transaction not changing the Integration Status from "Awaiting" to "Up".

  • UN-868 Prevented a situation where an outbound sync response that updated the process record could cause an update loop.

  • UN-870 Fixed JellyRunnerLite from leaking a global 'result' object.

  • UN-880 Fixed an issue where copying an integration and clearing the target scope would result in the new integration being in the Unifi scope.

  • UN-909 Fixed an issue where the HTTP Request retry count failed when it gets to number 10.

  • UN-910 Fixed an issue where the HTTP Request attempt number was not updated when Replay is used.

  • UN-914 Introduced auto-refresh to the Operations portal to prevent the connection from being dropped.

  • UN-946 Fixed an issue with the Resume integration worker popup showing the wrong number of transactions

  • UN-962 Field bug where copying a Message between Integrations showed 'Build Integration' in the originating Integration, and not the target integration.

  • UN-971 Fixed an issue where copying a Message to another integration resulted in fields in a different integration.

  • UN-987 Fixed issue with form choice fields becoming unresponsive in portal forms.

  • UN-993 Fixed Resume and Repair worker counters being wrong when processing more than 100 records.

  • leave a 5-star review on the Store!
    Upgrade Notice

    Please note that, as with every release, there may be some changes that are not entirely compatible with your existing integrations. While we do everything we can to make sure you won’t have to fix your integrations when upgrading, we strongly encourage all our customers to perform full end-to-end tests of their integrations before upgrading Unifi in Production.

    We also highly recommend aligning your Unifi upgrade with your ServiceNow upgrade. This means you only need to test your integrations one time rather than once for the ServiceNow upgrade and once for the Unifi upgrade.

    Feedback and Reviews

    We really appreciate feedback on what we’re doing - whether it’s right or wrong! We take feedback very seriously, so if you feel you’d give us anything less than a 5 star rating, we’d love to hear from you so we can find out what we need to do to improve!

    If you would rate us 5 stars, and haven’t left a review on the ServiceNow Store yet, we’d be grateful if you would head over there to leave us your feedback. It only takes a few minutes and really does help us a lot. Go on, you know you want to

    Improvements

    UN-1077 Change "Created ms" and "Updated ms" to be date-time on transactional records

    These fields were previously showing millisecond values. They now show system date-times which will make them easier to read and sort.

    Fixes

    UN-1003 Target caching fails when processing multiple messages in the same thread

    Fixed an issue where multiple bonds could be created. When running multiple updates in the same thread, e.g. a GlideRecord loop, it was possible for the the target record to be changed which could result in new bonds being created unnecessarily. This was due to a new feature of GlideScopedEvaluator which replaces the object in memory thus breaking internal Unifi script references.

    UN-1041 Field default scripts appear to be editable when they are locked

    Due to native Service Portal modifications, script fields in Designer would no longer appear locked even though they were read-only. This fix addresses the styling.

    UN-1055 Designer form loading does not update system fields

    The latest performance improvements to Unifi Designer introduced a caching bug for system fields which is now fixed.

    UN-1072 Execute Now on pollers runs the poller as the current user, not the user specified on the poller

    The Execute Now button on Pollers has been fixed so that Pollers are executed as the specified user and not the user who is logged in.

    UN-1098 Multiple bonded attachments from one attachment

    We've seen some issues caused by attachment records being updated multiple times in rapid succession (thousandths of a second) by the system user which occasionally will result in multiple Bonded Attachment records being created for the same attachment. We suspect that this is due to ServiceNow Antivirus scanning and updating the attachment record. To account for this, we’ve created two business rules to fire attachments, one for inserts and one for updates.

    UN-1106 Global utils version is not correct in the licence report

    Fixed an issue with the licence report not identifying if the Unifi global utility was installed.

    Unifi 3.1

    Release date: 20 September, 2021

    Automatic Heartbeat

    Heartbeat messages can be setup to automatically monitor and manage the integration. When a heartbeat message fails, the integration status will be marked as "Down" and all outbound messages will be queued. As soon as another heartbeat is successful, the integration status is marked as "Up" and the integration is automatically resumed.

    Portal Performance

    Unifi Integration Designer benefits from a significant performance upgrade with lists and forms loading up to 10x faster than previous versions.

    New Features & Improvements

    UN-239 Add connection test/heartbeat

    Users can now create Messages with type heartbeat which will be automatically sent periodically to the target endpoint and help to prevent failed outbound transactions.

    UN-262 Add scripted condition to Response Actions

    Response Actions now benefit from a scripted condition field so complex logic can be used to determine whether or not a Response Action should be used during outbound response processing.

    UN-424 Default Response Action for heartbeat message

    A new Unifi Response Action has been added to support the logic for heartbeat messages pausing and resuming the integration.

    UN-435 Automatically create and maintain heartbeat message scheduled jobs

    A scheduled job is automatically created and managed based on the presence and state of a heartbeat message within an integration and the integration itself.

    UN-623 Add OAuth Get Token button to Connection

    Connection records now benefit from an UI Action/button that can be used to generate OAuth tokens. The button only appears when the connection authentication is set to be OAuth 2.0.

    UN-650 Allow Response Actions to cater for group codes

    Response Actions are now able to handle group codes rather than just one code per action. For example, setting 5xx will match all 500 based response codes.

    UN-1012 Add version and integrations to about modal

    We've made it easier to find what version of Unifi you are using and included the number of active integrations in the About modal, available from the support menu.

    UN-1016 Message Fields list should filter on Message table

    Fields available to add to a Message are now filtered by the Message table in Designer, meaning you won't see fields that aren't relevant anymore.

    UN-1017 Allow Async heartbeat messages

    We've added support for heartbeat messages to be run both synchronously and asynchronously, meaning they work the same way as any other message in Unifi.

    UN-1020 Add cleanup for old heartbeat transactions

    Heartbeat transactions are automatically cleaned up every hour by the "[Unifi] Cleanup old heartbeat transactions" Scheduled Script. Two properties have been added to control the retention for complete vs failed heartbeat transactions.

    UN-1027 Heartbeat messages should automatically send identifying request headers

    Two identifying headers are automatically added to every heartbeat message that is sent: the identifying message header X-SND-EB-Message-Name and the heartbeat indicator X-SND-EB-Heartbeat.

    UN-1029 Heartbeat messages should only send when the integration is active

    As above. Heartbeat messages are sent only when the integration is active - this includes sending when the integration is paused.

    UN-1030 Heartbeat messages should not be queued

    Heartbeat transactions are not queued in the same way other transactions are queued in Unifi.

    UN-1031 Prevent creation of integrations in the Unifi scope

    We've added some measures to help prevent integrations and other content from being created in the Unifi scope. This is disabled by by default in 3.1.2.

    UN-1036 Add headers variable to response action

    Response Actions can now make use of the headers which were provided with the response to an outbound request.

    UN-1037 Transaction Repair should not process heartbeat messages

    Failed heartbeat messages are ignored when repairing an integration.

    UN-1038 Message sending should be queued when the integration is down, not just paused

    To support heartbeat functionality, we allow transactions to be created and queued for sending when the integration is flagged as down, not just when it is manually paused by an administrator.

    UN-1043 Hide portal announcements for Unifi portals

    Customer global portal announcements will no longer be shown in the Unifi portal.

    UN-1046 Reduce number of calls to clear scope messages

    This is a performance improvement to the portal to prevent "scope changed" UI messages from being shown in the native platform view.

    UN-1047 Performance improvements

    Numerous performance improvements made to the portal, including optimising widget dependencies, preventing global UI scripts from loading with every widget request, and reducing the use of $sp.getForm().

    UN-1051 Make all UI Scripts of type "Desktop" to prevent global loading with every widget request

    Addresses a bug with ServiceNow that allows all UI Scripts that are not "Desktop" to be downloaded with every widget request.

    Fixes

    UN-929 Field.active button flickers off before settling on

    Fixed a bug with the portal when activating fields on a message which would have the button enabled then rapidly disabled and enabled again.

    UN-974 Copying Field Records (between Integrations) retains reference to original Field Map

    Updated the copy logic to remove field map references from fields that are copied between integrations. The user needs to specify which field map to use from the target integration.

    UN-1006 Connection Test Response Body Result Overrunning Connection Test Modal

    Updated the Connection Test interface so that large response bodies are contained properly.

    UN-1007 Full page script fields aren't editable - Unifi Integration Designer

    Fixed a bug with script fields not being editable in Designer when they were be the only thing on the page (.e.g. Message XML Template)

    UN-1008 Integration Test Scenario not replacing Connection or Endpoint URL

    Fixed a bug with test assistant not properly updating the URL when porting tests between instances.

    UN-1009 TypeError on Process Portal Page for Unifi Admin role

    Fixed a JavaScript TypeError that only showed for Unifi Admins on the Process page in Designer.

    UN-1010 About Modal Logo Colour Wrong

    Fixed an issue with the about modal logo colour in Designer.

    UN-1011 TypeError for Unifi Admin on Test Assistant Dashboard (Firefox & Edge)

    Fixed a JavaScript TypeError that only showed for Unifi Admins on the Test Assistant Dashboard.

    UN-1018 Event action count is incorrect on Message

    Fixed the record counter for Event Actions related list on Message in Designer.

    UN-1019 When creating a new Message in Designer, async is true by default

    Fixed an issue where creating a new Message from the list view in Designer would always result in a Message that was set to async=true instead of it being controlled by the type of Message being created, e.g. response messages should not be async.

    UN-1022 Inbound endpoints filter on Connection is not specific enough

    Improved the logic for displaying inbound endpoints on the Connections list in Designer so that similarly named API's are no longer shown (i.e. an API of incident would also show inbound endpoints for an API of unifi_incident.

    UN-1026 Number generation does not work correctly when instance is preventing numbering gaps

    When the property glide.itil.assign.number.on.insert is set to true, numbers are not generated for Transaction and HTTP Request records on insert, but because we are adding ".01" to the end, the value was being populated as "null.01" and the number was never generated. We now account for this during record initialisation so numbers are generated correctly.

    UN-1028 Errors in Reference lookup scripts are ignored

    Fixed an issue where errors would be hidden if the payload was null or there was an error in the Reference lookup script on a Message. Errors are now shown correctly in Activity Logs.

    UN-1032 Embedded Field list on Message is not showing non-table fields

    When viewing a list of fields in the embedded list on a message in Designer, the Fields counter would show a different number of records than the number of fields actually shown. This was because of a query to show only table-related Fields. Now, all fields related to the table or no table at all are shown.

    UN-1035 Server scripts with "use strict" cause errors

    Removed "use strict" from two portal widgets because of incompatibilities with the Rhino engine and false errors being thrown from prototype based objects.

    Field
    Description
    Value

    Message name

    The message name that is unique for this integration.

    'CreateIncidentReceipt'

    Type

    The primary purpose of the message.

    'Receipt'

    Direction

    The direction(s) this message is configured to support. (Choices: Inbound, Outbound, Bidirectional)

    'Bidirectional'

    Your CreateIncidentReceipt New Message modal should look like this:

    Submit and view to further configure the Message.

    Response Fields

    Navigate to Message > Response.

    The Response fields to be configured are as follows:

    Field
    Description
    Value

    Response

    The immediate synchronous response to this message.

    lookup: 'Response'

    Your Response form should look like this:

    Navigate to Message > Bond.

    Bond Fields

    The Bond fields to be configured are as follows:

    Field
    Description
    Value

    Set bond state inbound*

    Set the Bond State when receiving this message. Use 'None' to leave the Bond State alone or to modify it via a Message/Field Stage to Target script.

    'Open'

    *Set bond state choices: None, Pending, Open, Suspended, Vendor suspended, Closed

    Your Bond form should look like this:

    Navigate to Inbound > Settings.

    Inbound Settings Fields

    The Inbound Settings fields to be configured are as follows:

    Field
    Description
    Value

    Reference lookup script

    The script containing functions for extracting internal and external references from the request payload.

    Update the code in the Reference lookup script field so that it looks like the code below

    The code in the 'Reference lookup script' field should look like this:

    Reference lookup script: In an asynchronous integration it's important to identify which message an asynchronous receipt is replying to. This script extracts the transaction's unique identifier.

    In the case of an inbound create/update it would return their external message id (source id) to identify which transaction our asynchronous receipt belongs to. In the case of an inbound asynchronous receipt it would return our internal message id (target id) to identify which transaction their asynchronous receipt belongs to.

    Your Inbound Settings form should look like this:

    Click 'Save'.

    We are now ready to configure the Fields for our CreateIncidentReceipt Message.

    Value

    State

    The Incident lifecycle state.

    ‘Resolved’

    Resolution code

    The Incident resolution code.

    <Your Resolution code>

    Resolution notes

    The Incident resolution notes.

    <Your Resolution notes>

    Your Incident record should look like this:

    Right-click & Save.

    Poll for Updates

    Back in the originating instance, navigate to & open < Your Poller >. Click Execute Now.

    Open the corresponding Poll Request & confirm that the Incident was found (and the Message name was ResolveIncidentInbound):

    View the Transactions that have been sent. This can be done either in Native ServiceNow, or in Unifi Operations Manager.

    Navigate to Unifi > Transport > Transactions.

    Navigate to Unifi > Unifi Operations Manager.

    We can see that the ResolveIncidentInbound message has been received, is Complete & Accepted and displays the relevant Incident & Bond numbers.

    Confirm the Transaction has updated the bonded ticket in the originating instance:

    We can see that the State, Resolution code & Resolution notes have been updated on the bonded ticket.

    Navigate to the Notes tab to view the Activities stream:

    We can see that the update has also been logged in the Activities stream.

    Using the Packager feature makes moving integrations between instances simpler and more efficient than ever.

    In Unifi Integration Designer, navigate to and open < Your Integration >.

    Click the 'Integration' icon to open the Details page.

    Click Package.

    The Package Integration modal is displayed.

    Confirm by clicking Package.

    Unifi packages the Integration into an Update Set which is automatically downloaded.

    The Integration Package Worker modal is displayed.

    The modal tells us how many records were processed and the name of the Update Set that was created (the integration name prepended with the date/time).

    Copy the name of the Update Set.

    Click Done to close the modal.

    Navigate to the downloaded Update Set and Show in folder*.

    *Example shown in Chrome. Other browsers may vary.

    Then rename the file (using your Update Set name in order to easily identify it when uploading to the other instance).

    Import the Integration (external instance)

    In the Application Navigator of the external instance, navigate to System Update Sets > Retrieved Update Sets.

    At the bottom of the Retrieved Update Sets list, click the Import Update Set from XML related link.

    If you have the UI16 Developer Patch installed (download from Share by clicking here), you can navigate directly to the Import XML page from the context menu of the Update Set Picker by clicking Import from XML.

    The Import XML screen is displayed:

    Click Choose file to upload the previously downloaded file.

    Upload.

    You are redirected back to the Retrieved Update Sets list view:

    Open the Update Set

    Your Retrieved Update Set form is displayed:

    Click Preview Update Set.

    Close the Update Set Preview modal.

    Click Commit Update Set.

    Close the Update Set Commit progress modal.

    We have successfully installed the application containing our Integration on the external instance. The vast majority of the configuration is already in place. All that remains is to make a few configuration changes and Reconfigure the Connections to enable each instance to connect with the other.

    Scope

    This document will guide you through an example of how you might configure a poller integration - polling the table API of your Personal Developer Instance (PDI).

    This Guide is complementary to the Outbound Incident Guide. It assumes that both the Integration and the Connection are still in place and will be using those same elements as configured there. It also assumes that you know how to use the REST API of your PDI to query for information and read ticket data.

    If you haven’t completed the Outbound Incident Guide, please review & complete the following sections of that document, as they must be in place before continuing with this Guide:

    • Process

    • Integration

    This document also builds on the Incident Update Poller Guide. As such, it assumes that the changes made in that Guide are still in place and will make use of some of those same elements.

    If you haven’t completed the Incident Update Poller Guide, please review & complete the following sections of that document at least, as they must be in place before continuing with this Guide:

    • UpdateIncidentInbound Message

    • UpdateIncidentInbound Fields

    The Incident Update Poller Guide demonstrated how you might poll for updates from the table API of your PDI and then configure an inbound Message to process that data. This Guide will also demonstrate how you might poll for updates from the table API of your PDI, but will also require that we store local data in order to decide which Message to use and then configure multiple inbound Messages to process that data

    Definitions

    It is not always possible for a remote system to send us the data. In such cases, we can make a scheduled request for it using Pollers. We can setup, execute and process those Requests using Poll Processors.

    Poller

    A poller defines the frequency of polling and which logic to use. It is effectively a scheduled job which ties together an Integration and Poll Processor. Although a Poller belongs to only one Integration, an Integration can have multiple Pollers.

    Poll Processor

    A Poll Processor contains the logic that will be applied when polling a remote system for data. It contains three main scripts:

    Setup Script

    The Setup Script is used to build the environment for the poll and define what it will do (for example, create/setup the URL that will be called).

    Request Script

    The Request Script is used to reach into the remote system and execute the request. This is usually done by making a REST call to the URL defined in the Setup Script.

    Response Script

    The Response Script is used to process the information returned from the remote system.

    Warning

    Do not build integrations directly within the Unifi application scope. This can create issues with upgrades and application management.

    Approach

    As well as storing and checking some returned data in order to evaluate when the data was changed and which system has made the updates (we don’t want to pull back data we have changed), we will also need to store and check other data in order to decide which Message to use to process that data.

    We will begin by polling for updates and then process those requests using multiple Messages in Unifi.

    Copy Message Modal

    The fields to edit for the Copy Message modal are as follows:

    Field
    Description
    Value

    Message name

    The message name that is unique for this integration.

    'ResolveIncident'

    Your Copy Message modal should look like this:

    Click Copy.

    You will be redirected to the Details page of the newly created ResolveIncident Message.

    Bond Fields

    Navigate to Message > Bond.

    The Bond fields to be edited are as follows:

    Field
    Description
    Value

    Bond suspended

    Process this message when the bond state is Suspended (internal suspend).

    <true>

    Bond vendor suspended

    Process this message when the bond state is Vendor suspended (external suspend).

    <true>

    Your Bond form should look like this:

    Navigate to Outbound > Trigger.

    Outbound Trigger Fields

    The Outbound Trigger (as required)* fields to be edited are as follows:

    Field
    Description
    Value

    Outbound condition*

    The condition that the ServiceNow record must meet to trigger this message being processed.

    'State > changes to > Resolved'

    Outbound condition*

    The script that must be met for the message to be processed. Use current to get access to the triggering record.

    [Blank]

    *Outbound condition (as required):

    It is not necessary for you to enter a condition. The value given is an example. You may create any condition (or not) to align with your business process requirements. in this case it makes sense to send the Resolve message when the Incident is Resolved.

    Your Outbound Trigger form should look like this:

    Click Save.

    We are now ready to configure the Fields for our ResolveIncident Message.

    Scope

    This document will guide you through an example of how you might configure a poller integration - polling the table API of your Personal Developer Instance (PDI).

    This Guide is complementary to the Outbound Incident Guide. It assumes that both the Integration and the Connection are still in place and will be using those same elements as configured there. It also assumes that you know how to use the REST API of your PDI to query for information and read ticket data.

    If you haven’t completed the Outbound Incident Guide, please review & complete the following sections of that document, as they must be in place before continuing with this Guide:

    • Process

    • Integration

    This document is complementary to and builds on the Incident Update Poller Guide. As such, it assumes that the changes made in that Guide are still in place and will make use of some of those same elements.

    If you haven’t completed the Incident Update Poller Guide, please review & complete the following sections of that document at least, as they must be in place before continuing with this Guide:

    • Message Identification

    • Edit Incident Form

    Both the Incident Update Poller Guide and the Incident Multiple Message Poller Guide demonstrated how you might poll for updates from the table API of your PDI and then configure inbound Messages to process that data. This Guide will demonstrate how you might poll for newly created, unbonded records from the table API of your PDI and then configure an inbound Create Message (along with its outbound Receipt) to process and respond to that data.

    Definitions

    It is not always possible for a remote system to send us the data. In such cases, we can make a scheduled request for it using Pollers. We can setup, execute and process those Requests using Poll Processors.

    Poller

    A poller defines the frequency of polling and which logic to use. It is effectively a scheduled job which ties together an Integration and Poll Processor. Although a Poller belongs to only one Integration, an Integration can have multiple Pollers.

    Poll Processor

    A Poll Processor contains the logic that will be applied when polling a remote system for data. It contains three main scripts:

    Setup Script

    The Setup Script is used to build the environment for the poll and define what it will do (for example, create/setup the URL that will be called).

    Request Script

    The Request Script is used to reach into the remote system and execute the request. This is usually done by making a REST call to the URL defined in the Setup Script.

    Response Script

    The Response Script is used to process the information returned from the remote system.

    Warning

    Do not build integrations directly within the Unifi application scope. This can create issues with upgrades and application management.

    Approach

    We will need to store and check some returned data in order to evaluate when the data was changed and which system has made the updates to the data (we don’t want to pull back data we have changed).

    We will begin by polling for newly created, unbonded records only and processing those requests using a create message in Unifi.

    We will also need to make some additional changes in order to identify which unbonded records to poll.

    Value

    Message name

    The message name that is unique for this integration.

    'CreateIncidentInboundReceipt'

    Type

    The primary purpose of the message.

    'Receipt'

    Direction

    The directions(s) this message is configured to support.

    'Outbound'

    Description

    The description for this message and the requirement is is meeting.

    <Your description>

    Your CreateIncidentInboundReceipt New Message modal should look like this:

    Click Submit and view to further configure the Message.

    Response Fields

    Navigate to Message > Response.

    The Response fields to be configured are as follows:

    Field
    Description
    Value

    Response

    The immediate synchronous response to this message.

    lookup: 'Response'

    Your Response form should look like this:

    Navigate to Outbound > Settings.

    Outbound Settings Fields

    The Outbound Settings fields to be configured are as follows:

    Field
    Description
    Value

    Path*

    A path to append to the URL defined in the connection. Specify a full URL to override the connection. Define inline scripts to reference Stage to Request script variables by wrapping code in braces {}, e.g. /{transaction.message_id}.

    '/table/incident/{bond.getValue("external_reference")}'

    Action method

    The SOAP Action or the REST Method to use for this message. If this field is empty the SOAP Action will default to the message name and the REST Method will default to POST.

    'PUT'

    *Path

    Only add the /table/incident element of this value if you have used the truncated Endpoint URL in the Connection. If you have used the full Endpoint URL, this element can be excluded here.

    Your Outbound Settings form should look like this:

    Click Save.

    We are now ready to configure the Fields for our CreateIncidentInboundReceipt Message.

    Name*

    The name of your Poller.

    <Your Name>

    Poll processor*

    The Poll Processor to use when running this Poller.

    <Your Poll Processor>

    Run

    The frequency at which the Poller should run.

    'Periodically'

    Run as

    Poller will run with credentials of specified user.

    <Your Inbound user> (from Connetion)

    Active*

    Set to true to use this Poller record for processing.

    Description

    A description of what this Poller is for and/or how it works.

    <Your description>

    Repeat interval*

    The interval at which the Poller should repeat.

    '05' (Minutes)

    Starting

    The date/time the Poller should start.

    <Your Start date/time>

    <true>

    Message name

    The message name that is unique for this integration.

    'ResolveIncident'

    Bond suspended

    Process this message when the bond state is Suspended (internal suspend).

    <true>

    Bond vendor suspended

    Process this message when the bond state is Vendor suspended (external suspend).

    <true>

    Outbound condition*

    The condition that the ServiceNow record must meet to trigger this message being processed.

    'State > changes to > Resolved'

    UpdateIncident Message

    The UpdateIncident Message is an update type message that sends updates to the bonded record.

    After submitting the 'Response' Message, you were redirected to the Messages page (note: the three previously configured messages are now visible in the list):

    Click New.

    New Message Modal

    The fields to be configured for the UpdateIncident New Message modal are as follows:

    Field
    Description
    Value

    Your UpdateIncident New Message modal should look like this:

    Submit and view to further configure the Message.

    Response Fields

    Navigate to Message > Response.

    The Response fields to be configured are as follows:

    Field
    Description
    Value

    *This field is automatically defaulted to true.

    Your Response form should look like this:

    Navigate to Message > Bond.

    Bond Fields

    The Bond fields to be configured are as follows:

    Field
    Description
    Value

    *These fields are automatically populated.

    Your Bond form should look like this:

    Navigate to Outbound > Trigger.

    Outbound Trigger Fields

    The Outbound Trigger fields to be configured (as required)* are as follows:

    Field
    Description
    Value

    *Outbound condition (as required):

    It is not necessary for you to enter a condition. The value given is an example. You may create any condition (or not) to align with your business process requirements.

    Your Outbound Trigger form should look like this:

    Navigate to Outbound > Settings.

    Outbound Settings Fields

    The Outbound Settings fields to be configured are as follows:

    Field
    Description
    Value

    *Path

    Only include the /table/incident element of this value if you have used the truncated Endpoint URL in the Connection. If you have used the full Endpoint URL, do not include that element of it here.

    Your Outbound Settings form should look like this:

    Click Save.

    We are now ready to configure the Fields for our UpdateIncident Message.

    Poller

    A Poller is a configuration record which defines the frequency of polling and which logic to use.

    A Poller is a configuration record which defines the frequency of polling and which logic to use (the logic itself is defined in the Poll Processor). Each time it is run, it creates a corresponding Poll Request record.

    New Poller

    Click the 'Pollers' icon & then New.

    The fields to be configured for the New Poller modal are as follows:

    Field
    Description
    Value

    *These fields are mandatory, or automatically defaulted to true.

    Your New Poller modal should look like this:

    Submit and view to further configure the Poller.

    Details

    The fields to be configured for the Details form are as follows:

    Field
    Description
    Value

    Your Details form should look like this:

    Navigate to Scheduling.

    Scheduling

    The fields to be configured for the Scheduling form are as follows:

    Field
    Description
    Value

    *This field is mandatory.

    Your Scheduling form should look like this:

    Save the Poller.

    In order to process and respond to the inbound Requests, we next need to configure our Messages.

    Test ResolveIncident

    We will test our ResolveIncident Message.

    Resolve The Incident

    Navigate to < Your Incident > created in the earlier test.

    Update the Incident record as follows:

    Field
    Description
    Value

    Test UpdateIncident

    We will test our UpdateIncident Message.

    Update The Incident

    Navigate to < Your Incident > created in the previous test.

    Your Incident record should look like this:

    Enter < Your Work notes > in the 'Work notes' field.

    Test Update Poll

    You should have successfully configured a Poll Processor, Poller and an inbound update message. You should also have made further changes to allow for message & bond identification. Now to test.

    It may help to turn off the Poller we created (set Active to 'false') whilst conducting these tests and to manually execute it as required (this can still be done even if the Poller is inactive). This is so that we don't have to wait for the Poller to run, but rather manually activate it when needed by clicking 'Execute Now'.

    To turn off the Poller, in the Unifi Integration Designer window, navigate to the 'Pollers' icon & set Active to false.

    In order to test our integration we will need some bonded tickets in the remote instance. If there aren't any already in place, then they'll need to be created.

    UpdateIncidentInbound Message

    We will configure an inbound update message to process the data returned from the poll and update our target record.

    New Message Modal

    Click the 'Messages' icon, then New.

    The fields to be configured for the UpdateIncidentInbound New Message modal are as follows:

    Field
    Description

    Test UpdateIncident

    Follow these steps to test the UpdateIncident Message.

    Update the Incident

    Navigate to < Your Incident > created in the previous test.

    Your Incident record should look like this:

    Enter < Your Work notes > in the 'Work notes' field.

    Test UpdateIncidentInbound

    Follow these steps to test the UpdateIncidentInbound Message.

    To test our integration we will need some bonded tickets in the remote instance. If there aren't any already in place, then they'll need to be created.

    Create Test Incidents

    In native ServiceNow, navigate to Incident > Create New.

    The Incident fields to configure are as follows:

    Field

    CreateIncidentInboundReceipt Fields

    We will utilise the Field & Field Map records to configure the Message Scripts for the CreateIncidentInboundReceipt Message.

    Field: incident.number

    The ‘incident.number’ (Integration level) Field record should already be in place (i.e. with Active set to false). This was automatically created by Unifi when we first created the Message level record when completing the Incident Update Poller Guide. We will now create its Message level counterpart.

    Integration

    This is what defines the connection between a Process and the single system it's connecting with. It is also where most of the configuration and settings are stored.

    New Integration

    Back in the Unifi Integration Designer window, after clicking either on the '+' tile or 'New Integration', you are given a 'New Integration' modal to complete.

    The fields to be configured for the New Integration modal are as follows:

    Field
    var answer = {};
    
    answer.getExternalMessageID = function (payload, request) {
      return '' + (payload.message.source_id || '');
    };
    
    answer.getInternalMessageID = function (payload, request) {
      return '' + (payload.message.target_id || '');
    };
    leave a 5-star review on the Store!
    Connection
    Message Identification
    Edit Incident Form
    Edit CreateIncident Message
    Connection
    Edit CreateIncident Message

    Application Modules

    A quick overview of the Unifi Application and its modules.

    Unifi Integration Designer

    This is a quick link which will open the Unifi Integration Designer page in a new browser window. From here, much of the configuration of your integrations can be carried out in a more intuitive and efficient manner.

    Unifi Operations Manager

    This is a quick link which will open the Unifi Operations Portal page in a new browser window. It provides a live, real-time view of the last 20 Transactions processed & the Bonds that have been worked on today - showing their state & grouped by Integration. From here, you can jump straight into the relevant records (e.g. Transaction, HTTP Request, Bond, bonded record).

    Unifi Test Assistant

    This is a quick link which will open the Unifi Test Assistant page in a new browser window. From here, you can view, run and analyse the automated tests in your instance.

    Dashboard

    This is a quick link to the legacy Unifi Dashboard which displays reports providing operational insights into the data being exchanged.

    Bonding

    The bonding tables are used to manage the state of the connection between the two records in each system.

    Bonds

    Table: x_snd_eb_bond

    A bond is a record that joins an integration to an internal process record (i.e. a ticket) by storing the internal and external system references together, along with the integration and other bond specific data. It also stores a commentary of the full history of the integration actions, making it very easy to see what has happened across the lifetime of the bond.

    Bonded Attachments

    Table: x_snd_eb_attachment

    Bonded Attachment records track the synchronisation status of attachments on the record that has been bonded.

    Transport

    The communication tables facilitate the transportation, extraction, transformation and loading of data communications. They are used to simplify development and debugging, aid in operations management, and provide full insight into the details of every data exchange.

    Snapshots

    Table: x_snd_eb_snapshot

    A Snapshot is a representation of the bonded record and data from the relevant message that created/updated it. Whenever there is an update to a bonded record, Unifi will take a snapshot of it and capture it in a Snapshot record. The Snapshot is the key to facilitating automated Integration testing.

    Transactions

    Table: x_snd_eb_transaction

    A Transaction is essentially a container used to group together the stages and requests created for single message exchange. Every inbound or outbound message belongs to a Transaction and this includes response and receipt messages.

    Stages

    Table: x_snd_eb_stage

    The Stage table allows data to be extracted and stored before it is processed. Although a requirement for asynchronous messaging, this separation makes it very easy to develop and maintain the integrations that the application supports.

    • Stage is configured so it can be extended for each process.

    • The introduction of Dynamic Stage now means there is no need to manually create the staging table.

    HTTP Requests

    Table: x_snd_eb_http_request

    HTTP Requests are the lowest level of communication, containing the raw data that is exchanged between systems.

    Configuration

    Processes

    Table: x_snd_eb_process

    The Process record allows integrations to be aligned to particular process. Many processes can be made available for integrations, and many integrations can belong to each process.

    Process records define the top level configuration that all integrations using this process will follow. A typical process to be made available for integration would be Incident.

    Integrations

    Table: x_snd_eb_integration

    An Integration acts as the top level container for configuring a process to be used by a single external or internal supplier. All the options specific to the integration are set on this record.

    • An integration is only active when a connection is active.

    Connections

    Table: x_snd_eb_connection

    Connection records allow many endpoint access configurations to be set up for a single integration. This makes managing access for different instances very easy, such as development, test and production.

    Only one Connection can be made active at any time. Making one Connection active will automatically enable the Integration and disable all the other Connections. Disabling a connection will disable the Integration.

    Messages

    Table: x_snd_eb_message

    The Unifi application uses a message centric architecture, meaning that every outbound/inbound request is configured as a single Message. A Message might be a create or update request, a receipt or a response. All Messages will send/receive a response Message and asynchronous Messages can also be configured to send/receive a receipt.

    Fields

    Table: x_snd_eb_field

    Fields simplify and bring additional functionality to the configuring of Messages & Message Scripts. They allow Message Scripts to be broken down into smaller, reusable components.

    A Field record defines the processing of a discrete component of a Message and often represents the handling of an individual field on the source/target record (e.g. Short description). They are also used to define the objects that will carry other Transaction specific data (e.g. Name, Time stamp, Source reference, Target reference).

    Field Maps

    Table: x_snd_eb_field_map

    The Field Map defines the behaviour, or ‘type’ of a Field. It defines template code into which details from Field records are substituted. It has a template script field for each of the Message Script types (Source to Stage, Stage to Request, Payload to Stage, Stage to Target).

    Message Scripts

    Table: x_snd_eb_message_script

    Data extraction, transformation and loading is handled by the Message Scripts. Each message can have custom scripts added that facilitate one of the following scenarios:

    • Payload to Stage (Inbound)

    • Stage to Target (Inbound)

    • Source to Stage (Outbound)

    • Stage to Request (Outbound)

    Response Actions

    Table: x_snd_eb_response_action

    Response Actions are interceptors that allow you to customise the way responses are handled.

    Event Actions

    Table: x_snd_eb_event_action

    Event Actions are a means of triggering an action from an event. In Unifi, we throw events for Transaction State changes. Like standard ServiceNow Script Actions, Event Actions respond to those events.

    Diagnostic

    The Diagnostic module is a link to a diagnostic test that can be run to check the configuration of your integration.

    Polling

    In cases where it is not possible for a remote system to send us the data, we can make a scheduled request for it using Pollers.

    Pollers

    Table: x_snd_eb_poller

    A Poller makes a scheduled request to a remote system. It is a configuration record which defines the frequency of polling and which logic to use.

    Poll Processors

    Table: x_snd_eb_poll_processor

    The Poll Processor is a configuration record which contains the logic that will be applied when polling a remote system for data.

    Poll Requests

    Table: x_snd_eb_poll_request

    The Poll Request is an operational record which stores the details and outcomes of a scheduled poll.

    Testing

    Integration Tests

    Table: x_snd_eb_integration_test

    An Integration Test is the overarching automated test record which correlates to the Bond. The test comprises each of the Integration Test Scenarios (which correlate to the Transactions on that Bond).

    Test Scenarios

    Table: x_snd_eb_integration_test_scenario

    An Integration Test Scenario represents a Transaction on a Bond. Each contains the relevant Test Scenario Data objects for the particular Scenario.

    Test Scenario Data

    Table: x_snd_eb_integration_test_scenario_data

    Test Scenario Data is a snapshot of all the relevant records created during the processing of a Transaction and is used to both generate the test and ascertain the results of each test run.

    Test Results

    Table: x_snd_eb_integration_test_result

    When you run an Integration Test, Unifi creates an Integration Test Result record to capture the results of the test run. Each Integration Test Result record will correlate to the Integration Test that was run.

    Test Scenario Results

    Table: x_snd_eb_integration_test_scenario_result

    Here you will find the results of the individual Integration Test Scenario. Whenever you run an Integration Test, for each Integration Test Scenario, Unifi creates an Integration Test Scenario Result record to capture the results of the test run.

    Administration

    Activity Logs

    Table: x_snd_eb_activity_log

    The Activity Logs module displays all the entries to the Unifi Activity Log table from the current day.

    Data Stores

    Table: x_snd_eb_data_store

    A Data Store is simply a key-value pair stored in the database that is available to all records in the system. They are used primarily in Message Scripts and Poll Requests when you want to get and set functional data that is relevant to the integration but does not belong on the target record.

    Properties

    The Properties module is where you will find the global system settings for the Unifi application.

    Scheduled Scripts

    Table: x_snd_eb_scheduled_script

    The Scheduled Scripts module displays the scripts which are automatically created by the system in order to perform tasks.

    System Logs

    The System Logs module is a quick link to the ServiceNow system logs and shows errors and warnings from the current day.

    Self-test

    The Self-test module is a link to a suite of internal tests that can be run at any time.

    Support

    Get Help

    The Get Help module is a quick link to the Unifi Portal welcome page where you will find links to our Documentation site along with ways to connect with us for application support.

    State

    The Incident lifecycle state.

    'Resolved'

    Resolution code

    The Incident resolution code.

    <Your Resolution code>

    Resolution notes

    The Incident resolution notes.

    <Your Resolution notes>

    Your Incident record should look like this:

    Right-click & Save.

    You should see an Info Message, confirming the ResolveIncident Message is being sent to your Integration:

    The Activities stream is updated with the details:

    View the Bond

    Click through to the Bond record from the related list on the Incident.

    Your Bond record should have been updated as follows:

    Transaction:

    • Message: 'Resolveincident'

    • Direction: 'Outbound'

    • Transaction state: 'Complete' (The data has been successfully transported)

    • Process state: 'Accepted' (The transaction was accepted as within the scope of the business logic that's in place)

    View the Transaction

    Click through to the Transaction record from the related list on the Bond.

    Your Transaction record should look like this:

    Transaction details:

    • Table: 'Incident [incident]'

    • Document: < Your Incident >

    • Integration: < Your Integration >

    • Connection: < Your Connection >

    • Bond: < Your Bond >

    • Message: 'ResolveIncident'

    • Direction: 'Outbound'

    • Transaction state: 'Complete' (The data has been successfully transported)

    • Process state: 'Accepted' (The transaction was accepted as within the scope of the business logic that's in place)

    Errors:

    • Error: (If there was a transactional error the Transaction state would show as 'Error' and the details would be captured here).

    • Process error: (If there was a process error the Process state would show as 'Rejected' and the details would be captured here)

    Stage:

    • Direction: 'Outbound'

    • Message: 'ResolveIncident'

    • Internal reference: < ServiceNow ticket reference > (Same as 'Document')

    • External reference: < External system's ticket reference >

    View the Stage

    Click through to the Stage record from the related list on the Transaction.

    Check the values in the fields match what you expect.

    Your Stage record should look like this:

    Stage details:

    • Direction: 'Outbound'

    • External reference: < External system's ticket reference >

    • Internal reference: < ServiceNow ticket reference >

    • Snapshot: < Snapshot record reference >

    • Message: 'ResolveIncident'

    • Transaction: < Your Transaction >

    • Integration: < Your Integration >

    Mapped Staged Data fields:

    • close_code: < Your Resolution code >

    • close_notes: < Your Resolution notes >

    • state: '6'

    View the HTTP Request

    Click through to the HTTP Request record from the related list on the Transaction.

    Your HTTP Request record should look like this:

    HTTP Request details:

    • Integration: < Your Integration >

    • Connection: < Your Connection >

    • Transaction: < Your Transaction >

    • Message: 'ResolveIncident'

    • Direction: 'Outbound'

    • Request state: 'OK' (There are no errors with the HTTP Request.)

    • Attempt number: < Number of HTTP Request attempts > (Failed requests are retried up to the maximum attempts number as configured on the Integration.)

    • Endpoint URL: < The external system’s access URL >

    • Action Method: 'PUT'

    • Request headers: < The header of the request being sent >

    • Request payload: < The payload of the request being sent >

    Response details:

    • Status code: '200'

    • Response headers: < The header of the response being received >

    • Response payload: < The payload of the response being received >

    Compare with the External System's Incident

    Navigate to the corresponding Incident in the external system.

    Check the values in the fields match those you noted when you saved the Incident in the internal system.

    Your external system's Incident record should look like this (depending on the system you're integrating with, your record may look different; the important matter is that the values match):

    State: 'Resolved'

    Activities: < Your Resolution code/notes & State > (added by < your.external.system.user >)

    Navigate to the Resolution Information tab.

    Your Resolution Information tab should look like this:

    Resolution code: < Your Resolution code >

    Resolution notes: < Your Resolution notes >

    So far, when configuring our scenarios we have built the Message Scripts for each Message individually. Let's now see how we can run the Build process at the Integration level.

    Click
    Post
    .

    The following activities are added to the 'Notes' tab (confirming sending the UpdateIncident Message to your integration):

    View the Bond

    Click through to the Bond record from the related list on the Incident.

    Your Bond record should have been updated as follows:

    Transaction:

    • Message: 'Updateincident'

    • Direction: 'Outbound'

    • Transaction state: 'Complete' (The data has been successfully transported)

    • Process state: 'Accepted' (The transaction was accepted as within the scope of the business logic that's in place)

    View the Transaction

    Click through to the Transaction record from the related list on the Bond.

    Your Transaction record should look like this:

    Transaction details:

    • Table: 'Incident [incident]'

    • Document: < Your Incident >

    • Integration: < Your Integration >

    • Connection: < Your Connection >

    • Bond: < Your Bond >

    • Message: 'UpdateIncident'

    • Direction: 'Outbound'

    • Transaction state: 'Complete' (The data has been successfully transported)

    • Process state: 'Accepted' (The transaction was accepted as within the scope of the business logic that's in place)

    Errors:

    • Error: (If there was a transactional error the Transaction state would show as 'Error' and the details would be captured here).

    • Process error: (If there was a process error the Process state would show as 'Rejected' and the details would be captured here)

    Stage:

    • Direction: 'Outbound'

    • Message: 'UpdateIncident'

    • Internal reference: < ServiceNow ticket reference > (Same as 'Document')

    • External reference: < External system's ticket reference >

    View the Stage

    Click through to the Stage record from the related list on the Transaction.

    Check the values in the fields match what you expect.

    Your Stage record should look like this:

    Stage details:

    • Direction: 'Outbound'

    • External reference: < External system's ticket reference >

    • Internal reference: < ServiceNow ticket reference >

    • Snapshot: < Snapshot record reference >

    • Message: 'UpdateIncident'

    • Transaction: < Your Transaction >

    • Integration: < Your Integration >

    Mapped Staged Data fields:

    • Work notes: < Your Work note >

    View the HTTP Request

    Click through to the HTTP Request record from the related list on the Transaction.

    Your HTTP Request record should look like this:

    HTTP Request details:

    • Integration: < Your Integration >

    • Connection: < Your Connection >

    • Transaction: < Your Transaction >

    • Message: 'UpdateIncident'

    • Direction: 'Outbound'

    • Request state: 'OK' (There are no errors with the HTTP Request.)

    • Attempt number: < Number of HTTP Request attempts > (Failed requests are retried up to the maximum attempts number as configured on the Integration.)

    • Endpoint URL: < The external system’s access URL >

    • Action Method: 'PUT'

    • Request headers: < The header of the request being sent >

    • Request payload: < The payload of the request being sent >

    Response details:

    • Status code: '200'

    • Response headers: < The header of the response being received >

    • Response payload: < The payload of the response being received >

    Compare with the External System's Incident

    Navigate to the corresponding Incident in the external system.

    Check the values in the fields match those you noted when you saved the Incident in the internal system.

    Your external system's Incident record should look like this (depending on the system you're integrating with, your record may look different; the important matter is that the values match):

    Activities: < Your Work note > (added by < your.external.system.user >)

    Challenge

    • Repeat the steps above - this time placing a check in the 'Additional comments (Customer visible)' checkbox.

    • What do you expect to happen?

    Create Test Incidents

    In the native ServiceNow window, navigate to Incident > Create New.

    The Incident fields to configure are as follows:

    Field
    Description
    Value

    Caller

    Person who reported or is affected by this incident.

    <Your Caller>

    Short description

    A brief description of the incident.

    <Your Short description>

    Description

    Detailed explanation on the incident.

    <Your Description>

    Though our CreateIncident Message has been configured to map more than just the Short Description & Description fields, we have only filled these fields because that is all we have included in the payload of our Poller.

    Your Incident form should look like this:

    Note the Info Message confirming the CreateIncident Message is being sent to your Integration.

    Note the Bond is 'Open' and both the Internal & External reference are in place.

    Repeat as necessary so that there are two or three bonded tickets in the remote instance:

    Update from Originating Instance

    Update one of the bonded tickets in the originating instance to cause the UpdateIncident Message to fire:

    View the Transactions that have been sent. This can be done either in Native ServiceNow, or in Unifi Operations Manager.

    Navigate to Unifi > Transport > Transactions.

    Navigate to Unifi > Unifi Operations Manager.

    We can see that the three CreateIncident messages & one UpdateIncident message have been sent. All are Complete & Accepted & display the relevant Incident & Bond numbers.

    Confirm the Transaction has updated the bonded ticket in the remote instance:

    We can see that the update has reached the bonded ticket (& that the correlation id matches the outbound Incident number)

    Poll for Updates

    In Unifi Integration Designer, click on the 'Pollers' icon. Navigate to & open < Your Poller > (created earlier). & click Execute Now:

    In native ServiceNow, navigate to Unifi > Polling > Poll Requests. Click to Open & view the generated Poll Request. Confirm that no Incident was found (this is exactly as we expect because we are only polling for updates made by the remote instance):

    Update from Remote Instance

    In the remote instance, update two of the bonded tickets in turn.

    Updates are made to the Description field only. Correlation ID is highlighted for us to identify the correct bonded ticket.

    Poll for Updates

    Back in the originating instance, navigate to & open < Your Poller >. Click Execute Now.

    Open the corresponding Poll Request & confirm that both Incidents were found (and only those):

    View the Transactions that have been sent. This can be done either in Native ServiceNow, or in Unifi Operations Manager.

    Navigate to Unifi > Transport > Transactions.

    Navigate to Unifi > Unifi Operations Manager.

    We can see that two UpdateIncidentInbound messages have been received. Both are Complete & Accepted & display the relevant Incident & Bond numbers.

    Confirm the Transactions have updated the bonded tickets in the originating instance.

    Challenge

    For completeness, to prove we are only querying and pulling back data from bonded records, update an incident in the remote system which isn't bonded (Correlation ID is empty) & run the Poller again.

    What do you expect to happen?

    Value

    Message name

    The message name that is unique for this integration.

    'UpdateIncidentInbound'

    Type

    The primary purpose of the message.

    'Update'

    Direction

    The direction(s) this message is configured to support.

    'Inbound'

    Description

    The description for this message and the requirement it is meeting.

    <Your description>

    Your UpdateIncidentInbound New Message modal should look like this:

    Click Submit and view to further configure the Message.

    Response Fields

    Navigate to Message > Response.

    The Response fields to be configured are as follows:

    Field
    Description
    Value

    Response

    The immediate synchronous response to this message.

    lookup: 'Response'

    Async*

    Turn this option on if you want inbound processing to occur asynchronously or this message is the first of an asynchronous message pair.

    <false>

    *This field is automatically defaulted to true.

    The 'Response' Message was previously configured (in the Outbound Incident Guide) to apply in an 'Inbound' direction. Change it to 'Bidirectional'.

    Your Response form should look like this:

    Navigate to Message > Bond.

    Bond Fields

    The Bond fields to be configured are as follows:

    Field
    Description
    Value

    Bond ownership*

    Determine if the sender should own the bond or not in order for this message to be processed? Use 'Ignore' to process regardless of the owner flag. (Choices: Ignore, Must own, Must not own.)

    'Ignore'

    Bond condition type*

    The type of conditional check made on the bond. (None: no checks are made. State: checks against the state are made using the conditional checkboxes. Scripted: the 'Bond condition' script is used.)

    'State'

    Bond open

    Process this message when the bond state is Open.

    <true>

    *These fields are automatically populated.

    Your Bond form should look like this:

    Navigate to Inbound > Settings.

    Inbound Settings Fields

    The Inbound Settings fields to be configured are as follows:

    Field
    Description
    Value

    Bond reference method*

    Method of searching for and validating an existing bond for incoming messages.

    'External'

    *Bond reference method:

    Internal - lookup using the internal reference only.

    External - lookup using the external reference only.

    Both - lookup using both the internal and external references.

    We have chosen the 'External' method because, in the payload we built, we only supplied the source_reference. If we had also supplied the correlation_id as the target_reference, then we would have chosen 'Both' (which would have offered an extra level of validation to the checking).

    Your Inbound Settings form should look like this:

    Click Save.

    We are now ready to configure the Fields for our UpdateIncidentInbound Message.

    Click
    Post
    .

    You should see an Info Message, confirming the UpdateIncident Message is being sent to your Integration:

    The Work note is added to the Activities stream on the 'Notes' tab:

    View the Bond

    Click through to the Bond record from the related list on the Incident.

    Your Bond record should have been updated as follows:

    Transaction:

    • Message: 'Updateincident'

    • Direction: 'Outbound'

    • Transaction state: 'Complete' (The data has been successfully transported)

    • Process state: 'Accepted' (The transaction was accepted as within the scope of the business logic that's in place)

    View the Transaction

    Click through to the Transaction record from the related list on the Bond.

    Your Transaction record should look like this:

    Transaction details:

    • Table: 'Incident [incident]'

    • Document: < Your Incident >

    • Integration: < Your Integration >

    • Connection: < Your Connection >

    • Bond: < Your Bond >

    • Message: 'UpdateIncident'

    • Direction: 'Outbound'

    • Transaction state: 'Complete' (The data has been successfully transported)

    • Process state: 'Accepted' (The transaction was accepted as within the scope of the business logic that's in place)

    Errors:

    • Error: (If there was a transactional error the Transaction state would show as 'Error' and the details would be captured here).

    • Process error: (If there was a process error the Process state would show as 'Rejected' and the details would be captured here)

    Stages:

    • Direction: 'Outbound' & 'Inbound'

    • Message: 'UpdateIncident' & 'Receipt'

    • Internal reference: < ServiceNow ticket reference > (Same as 'Document')

    • External reference: < External system's ticket reference >

    View the Stage

    Click through to the Outbound Stage record from the related list on the Transaction. (If you wish, you could also do the same for the Inbound Stage record.)

    Check the values in the fields match what you expect.

    Your Stage record should look like this:

    Stage details:

    • Direction: 'Outbound'

    • External reference: < External system's ticket reference >

    • Internal reference: < ServiceNow ticket reference >

    • Snapshot: < Snapshot record reference >

    • Message: 'UpdateIncident'

    • Transaction: < Your Transaction >

    • Integration: < Your Integration >

    Mapped Staged Data fields:

    • work_notes: < Your Work note >

    View the HTTP Request

    Click through to the Outbound HTTP Request record from the related list on the Transaction. (If you wish, you could also do the same for the Inbound HTTP Request record.)

    Your HTTP Request record should look like this:

    HTTP Request details:

    • Integration: < Your Integration >

    • Connection: < Your Connection >

    • Transaction: < Your Transaction >

    • Message: 'UpdateIncident'

    • Direction: 'Outbound'

    • Request state: 'OK' (There are no errors with the HTTP Request.)

    • Attempt number: < Number of HTTP Request attempts > (Failed requests are retried up to the maximum attempts number as configured on the Integration.)

    • Endpoint URL: < The external system’s access URL >

    • Action Method: 'POST'

    • Request headers: < The header of the request being sent >

    • Request payload: < The payload of the request being sent >

    Response details:

    • Status code: '200'

    • Response headers: < The header of the response being received >

    • Response payload: < The payload of the response being received >

    Compare with the External System's Incident

    Navigate to the corresponding Incident in the external system.

    Check the values in the fields match those you noted when you saved the Incident in the internal system.

    Your external system's Incident record should look like this (depending on the system you're integrating with, your record may look different; the important matter is that the values match):

    Activities: < Your Work note > (added by < your.external.system.user >)

    Challenge

    • Repeat the steps above - this time placing a check in the 'Additional comments (Customer visible)' checkbox.

    • What do you expect to happen?

    As when testing our CreateIncident Message, if completing this test after having integrated with the external system (as opposed to connecting to your own instance), it would be good to test the UpdateIncident Message in both directions.

    We are now ready to move to the Resolve Scenario.

    Description
    Value

    Caller

    Person who reported or is affected by this incident.

    <Your Caller>

    Short description

    A brief description of the incident.

    <Your Short description>

    Description

    Detailed explanation on the incident.

    <Your Description>

    Though the CreateIncident Message has been configured to map more than just the Short Description & Description fields, we have only filled these fields because that is all whe have included in the payload of our Poller.

    Your Incident form should look like this:

    Note the Info Message confirming the CreateIncident Message is being sent to your Integration.

    Note the Bond is 'Open' and both the Internal & External reference are in place.

    Repeat as necessary so that there are two or three bonded tickets in the remote instance:

    Update from Originating Instance

    Update one of the bonded tickets in the originating instance to cause the UpdateIncident Message to fire:

    View the Transactions that have been sent. This can be done either in Native ServiceNow, or in Unifi Operations Manager.

    Navigate to Unifi > Transport > Transactions.

    Navigate to Unifi > Unifi Operations Manager.

    We can see that the three CreateIncident messages & one UpdateIncident message have been sent. All are Complete & Accepted & display the relevant Incident & Bond numbers.

    Confirm the Transaction has updated the bonded ticket in the remote instance:

    We can see that the update has reached the bonded ticket (& that the correlation id matches the outbound Incident number)

    Poll for Updates

    In Unifi Integration Designer, click on the 'Pollers' icon. Navigate to & open < Your Poller > (created earlier). Click Execute Now:

    In native ServiceNow, navigate to Unifi > Polling > Poll Requests. Click to Open & view the generated Poll Request. Confirm that no Incident was found (this is exactly as we expect because we are only polling for updates made by the remote instance):

    Update from Remote Instance

    in the remote instance, update two of the bonded tickets in turn.

    Updates have been made to the Description field only. Correlation ID is highlighted for us to identify the correct bonded ticket.

    Poll for Updates

    Back in the originating instance, navigate to & open < Your Poller >. Click Execute Now.

    Open the corresponding Poll Request & confirm that both Incidents were found (and only those) and that the Message name was UpdateIncidentInbound:

    View the Transactions that have been sent. This can be done either in Native ServiceNow, or in Unifi Operations Manager.

    Navigate to Unifi > Transport > Transactions.

    Navigate to Unifi > Unifi Operations Manager.

    We can see that two UpdateIncidentInbound messages have been received. Both are Complete & Accepted & display the relevant Incident & Bond numbers.

    Confirm the Transactions have updated the bonded tickets in the originating instance.

    Challenge

    For completeness, to prove we are only querying and pulling back data from bonded records, update an incident in the remote system which isn't bonded (Correlation ID is empty) & run the Poller again.

    What do you expect to happen?

    Next, we shall test the ResolveIncidentInbound Message.

    From the CreateIncidentInboundReceipt Message, navigate to Message > Fields.

    Your CreateIncidentInboundReceipt Fields page should look like this:

    Find the incident.number (Integration level) Field & set Active to true.

    The ‘Build Integration’ button becomes visible in the banner and the empty circle icon next to the Field name turns green & contains a green ‘check’ (to indicate that Message level configuration exists for this Field) when we set Active to true. (Note: the empty 'circle icon' indicates that the Integration level Field is available to add to the Message.).

    By setting the Active flag to true on the Integration level Field record listed on the Message, Unifi has automatically created the Message level counterpart.

    Build

    We don't need to configure any more the Field records for the CreateIncidentInboundReceipt Message, so we are ready to build our message scripts.

    Click on Build Message.

    You will see the 'Message build successful' Info Message.

    Navigate to Advanced > Script Editor > View > Outbound to view the auto-generated code.

    Your Script Editor fields should look like this:

    Message Scripts

    We will look at the Message Scripts in turn.

    Source to Stage:

    Your Source to Stage Message Script should look like this:

    Stage to Request:

    Your Stage to Request Message Script should look like this:

    Next, we'll configure the CreateIncidentInbound Message.

    Description
    Value

    Name

    The name of the integration.

    <Your Name>

    Service type*

    The type of web service this integration is using (Choices: SOAP/REST).

    'REST'

    Message format*

    Automatically pre-process incoming messages for simpler message scripting. (Choices: XML, JSON, Advanced)

    'JSON'

    *Service type/Message format: these values are defaulted.

    Your 'New Integration' modal should look like this:

    Click Create.

    You will be redirected to the Details page of the newly created Integration.

    Icons

    Before continuing we would like to draw your attention to some of the relevant icons that are now visible down the left hand navigation strip.

    The icons are:

    a) 'Integration' icon: Opens the current integration's Details page.

    b) 'Messages' icon: Opens the current integration's Messages page.

    c) 'Fields' icon: Opens the current integration's Fields page.

    d) 'Field Maps' icon: Opens the current integration's Field Maps page.

    e) 'Documentation' icon: Opens the automatically generated documentation for the current integration. (Another awesome feature in Unifi.)

    f) 'Connections' icon: Opens the current integration's Connections page.

    Details

    The Details page of your Integration should look like this:

    Navigate to Integration > Message Identification.

    Message Identification Fields

    Unifi needs to identify the name of the inbound message in order to know how to process the inbound data.

    Update the code in the 'Identify message script' field so that it looks like this:

    The Message Identification form should look like this:

    Navigate to Settings > Feedback.

    Feedback Settings Fields

    The Feedback fields to be configured for the Integration record are as follows:

    Field
    Description
    Value

    Enable UI messages

    Allow information and error messages to be shown to the user as UI Notifications. Only applies to certain notifications.

    <true>

    The Feedback Settings form should look like this:

    All of the remaining 'Settings' values are to be left as-is:

    • Attachments Settings

    • Bond Settings

    All of the 'Error handling' values are to be left as-is:

    • General

    • Timeouts

    • Retry

    Click Save.

    Click the 'Connections' icon to move on and configure the Connection.

    Message name

    The message name that is unique for this integration.

    'UpdateIncident'

    Type

    The primary purpose of the message.

    'Update'

    Direction

    The direction(s) this message is configured to support.

    'Outbound'

    Response

    The immediate synchronous response to this message.

    lookup: 'Response'

    Async*

    Turn this option on if you want inbound processing to occur asynchronously or this message is the first of an asynchronous message pair.

    <false>

    Bond ownership*

    Determine if the sender should own the bond or not in order for this message to be processed? Use 'Ignore' to process regardless of the owner flag. (Choices: Ignore, Must own, Must not own.)

    'Ignore'

    Bond condition type*

    The type of conditional check made on the bond. (None: no checks are made. State: checks against the state are made using the conditional checkboxes. Scripted: the 'Bond condition' script is used.)

    'State'

    Bond open

    Process this message when the bond state is Open.

    <true>

    Outbound condition*

    The condition that the ServiceNow record must meet to trigger this message being processed.

    <Your condition> e.g. 'Work notes changes' OR 'Additional comments changes'

    Path*

    A path to append to the URL defined in the connection. Specify a full URL to override the connection. Define inline scripts to reference Stage to Request script variables by wrapping code in braces {}, e.g. /{transaction.message_id}.

    '/table/incident/{bond.getValue("external_reference")}'

    Action method

    The SOAP Action or the REST Method to use for this message. If this field is empty the SOAP Action will default to the message name and the REST Method will default to POST.

    'PUT'

    Name*

    The name of your Poller.

    <Your Name>

    Poll processor*

    The Poll Processor to use when running this Poller.

    <Your Poll Processor>

    Run

    The frequency at which the Poller should run.

    'Periodically'

    Run as

    Poller will run with credentials of specified user.

    <Your Inbound user> (from Connection)

    Active*

    Set to true to use this Poller record for processing.

    Description

    A description of what this Poller is for and/or how it works.

    <Your description>

    Repeat interval*

    The interval at which the Poller should repeat.

    '15' (Minutes)

    Starting

    The date/time the Poller should start.

    <Your Start date/time>

    <true>

    Connection

    The Connection allows messages to be sent and received and stores all the authentication details of the Integration specific to a single environment.

    Inbound User

    Before configuring the Connection, you need to ensure you have a user in the instance to use as the Inbound user for the Integration. To configure your Inbound user:

    In the native ServiceNow window, navigate to User Administration > Users. Click New.

    The fields to be configured for the User record are as follows:

    Field
    Description
    Value

    Roles

    itil: This role is given to access the table of the bonded record.

    x_snd_eb_integration: This role is given to access the automatically created Web Service. Note: this role is not required for this integration as we are only sending outbound messages. However, it will be used when following the Poller Guides, receiving messages to the automatically created inbound endpoints.

    Your User record should look like this:

    Connection

    Although you can set up many connections to enable switching between environments (one connection per environment), it is worth noting that only one connection can be active for an Integration at a time.

    We will, however, set up only one connection in the 'Development' environment.

    Back in the Unifi Integration Designer window, after clicking the 'Connections' icon, the first thing you will notice is a widget at the top of the page which clearly displays the inbound endpoints (REST Resources) which were automatically created when the Process was configured.

    This is given for your information only as we are only concerned in this Guide with sending outbound messages to the table API of another ServiceNow instance (i.e. your Personal Developer Instance, ‘PDI’). However, It will be of value should you go on to configure polling integrations following our Poller Guides (which will utilize this same Connection).

    Click New.

    The fields to be configured for the New Connection modal are as follows:

    Field
    Description
    Value

    Outbound Connectivity

    The format of the Endpoint URL for the ServiceNow Table API is as follows:

    https://<your_developer_instance>.service-now.com/api/now/table/<table_name>

    If you are going to configure this Outbound Integration only, then use the full URL e.g. https://<your_developer_instance>.service-now.com/api/now/table/incident

    If you are going to configure the Pollers also, then truncate the URL as follows https://<your_developer_instance>.service-now.com/api/now

    In which case, the /table/incident part of the URL will need to be added to the 'Path' of the outbound messages (and the Endpoint URLs of the relevant Pollers).

    Your New Connection modal should look like this:

    Click 'Submit and view'.

    Clicking 'Submit' will redirect you to the list view of the record you're creating. Clicking 'Submit and view' will redirect you to the newly created record.

    Connection Details

    The fields to be configured for the Details form are as follows:

    Field
    Description
    Value

    *(External) User/Password: As created/set in your PDI.

    **Inbound user: As created above.

    Your Details form should look like this:

    Save the Connection.

    Connection Test

    At this stage you can carry our a basic connection test which verifies whether the user is authorized (i.e. whether you've configured the user/password/roles correctly). To do this, click Connection Test.

    Then, on the Connection Test modal, click Test.

    The results (Pass/Fail) will be displayed.

    If you attempt the test against the truncated URL you will receive this error.

    Click Done.

    The main, manually configured elements are now in place for our Integration to work. We are now ready to configure and test each of our Scenarios in turn.

    There is no need to manually configure a Trigger (Business Rule) on the Process table being integrated as Unifi will automatically create one for us (if one doesn't already exist).

    Connection

    The Connection allows messages to be sent and received and stores all the authentication details of the Integration specific to a single environment.

    Integration User

    Before we configure our Connection, we need to ensure we have a user in the instance to use as the Inbound user for our Integration. To configure our Integration user:

    In the native ServiceNow window, navigate to User Administration > Users. Click New.

    The fields to be configured for the User record are as follows:

    Field
    Description
    Value

    Roles

    itil: This role is given to access the table of the bonded record.

    x_snd_eb_integration: This role is given to access the automatically created Web Service.

    Your User record should look like this:

    Connection

    You can set up many connections to enable switching between environments (one connection per environment). However, only one connection can be active for an Integration at a time.

    Remember: When setting up a Connection:

    • Make sure your SOAP and/or REST endpoints are unique.

    • Never use your own User as the Inbound User as it will prevent the integration from working.

    We are going to configure a Connection for the Development environment.

    Back in the Unifi Integration Designer window, after clicking the 'Connections' icon, the first thing you will notice is a widget at the top of the page which clearly displays the inbound endpoints (REST Resources) which were automatically created when the Process was configured.

    Clicking the link to the right of the Endpoint URL will open the Scripted REST Resource (in native ServiceNow) in a new window.

    Click New.

    The fields to be configured for the New Connection modal are as follows:

    Field
    Description
    Value

    Outbound Connectivity

    The format of the Endpoint URL is as follows:

    https://<your_instance>.service-now.com/<your_resource_path>

    The entire Endpoint URL can be easily obtained from the automatically created Message Resource on the Unifi Scripted REST API (displayed in the widget at the top of the Connections page).

    For this Development environment Connection, we will set the Endpoint URL to point to our own instance and use the same Integration User for both Inbound and Outbound (as created above). Being able to connect to our own instance makes it simple and efficient to test our integration (seeing Transactions going out and coming in) before we connect to the external system.

    Your New Connection modal should look like this:

    Click Submit and view.

    Clicking 'Submit' will redirect you to the list view of the record you're creating. Clicking 'Submit and view' will redirect you to the newly created record.

    Connection Details

    The fields to be configured for the Details form are as follows:

    Field
    Description
    Value

    Your Details form should look like this:

    Feature Alert: The widget at the bottom of the page now shows the Integration as Active.

    Save the Connection.

    Connection Test

    At this stage you can carry our a basic connection test which verifies whether the user is authorized (i.e. whether you've configured the user/password/roles correctly). To do this, click Connection Test.

    Then, on the Connection Test modal, click Test.

    The results (Pass/Fail) will be displayed.

    Click Done.

    The main, manually configured elements are now in place for our Integration to work. We are now ready to configure and test each of our Scenarios in turn.

    Remember: There is no need to manually configure a Trigger (Business Rule) on the Process table being integrated as Unifi will automatically create one for us (if one doesn't already exist).

    UpdateIncident Message

    The UpdateIncident Message is an update type message that sends updates to the bonded record.

    Again, after clicking the 'Messages' icon, you are directed to the following screen (note: the four previously configured messages are now visible in the list):

    Click New.

    New Message Modal

    The fields to be configured for the UpdateIncident New Message modal are as follows:

    Field
    Description
    Value

    Your UpdateIncident New Message modal should look like this:

    Submit and view to further configure the Message.

    Response Fields

    Navigate to Message > Response.

    The Response fields to be configured are as follows:

    Field
    Description
    Value

    *This field is automatically defaulted to true.

    Your Response form should look like this:

    Navigate to Message > Bond.

    Bond Fields

    The Bond fields to be configured are as follows:

    Field
    Description
    Value

    *These fields are automatically populated.

    Your Bond form should look like this:

    Navigate to Outbound > Trigger.

    Outbound Trigger Fields

    The Outbound Trigger fields to be configured (as required)* are as follows:

    Field
    Description
    Value

    *Outbound condition (as required):

    It is not necessary for you to enter a condition. The value given is an example. You may create any condition (or not) to align with your business process requirements. In this case it makes sense to use this message to send an update where the state doesn't change. Typically, we would configure different messages to align with state changes (e.g. Close, Resolve).

    The code in the 'Outbound condition' script field should look like this:

    Your Outbound Trigger form should look like this:

    Navigate to Inbound > Settings.

    Inbound Settings Fields

    The Inbound Settings fields to be configured are as follows:

    Field
    Description
    Value

    *Bond reference method:

    Internal - lookup using the internal reference only.

    External - lookup using the external reference only.

    Both - lookup using both the internal and external references.

    As mentioned earlier, because this is an update type message, we use 'Both' as it's a more accurate method of validating updates are being sent to/received from the correct bonded records.

    The code in the 'Reference lookup script' field should look like this:

    Your Inbound Settings form should look like this:

    Click Save.

    We are now ready to configure the Fields for our UpdateIncident Message.

    Test ResolveIncident

    Follow these steps to test the ResolveIncident Message.

    Resolve the Incident

    Navigate to < Your Incident > created in the earlier test.

    Update the Incident record as follows:

    Field
    Description
    Value

    Your Incident record should look like this:

    Right-click & Save.

    You should see an Info Message, confirming the ResolveIncident Message is being sent to your Integration:

    The Activities stream is updated with the details:

    View the Bond

    Click through to the Bond record from the related list on the Incident.

    Your Bond record should have been updated as follows:

    Transaction:

    • Message: 'Resolveincident'

    • Direction: 'Outbound'

    • Transaction state: 'Complete' (The data has been successfully transported)

    • Process state: 'Accepted' (The transaction was accepted as within the scope of the business logic that's in place)

    View the Transaction

    Click through to the Transaction record from the related list on the Bond.

    Your Transaction record should look like this:

    Transaction details:

    • Table: 'Incident [incident]'

    • Document: < Your Incident >

    • Integration: < Your Integration >

    • Connection: < Your Connection >

    Errors:

    • Error: (If there was a transactional error the Transaction state would show as 'Error' and the details would be captured here).

    • Process error: (If there was a process error the Process state would show as 'Rejected' and the details would be captured here)

    Stages:

    • Direction: 'Outbound' & 'Inbound'

    • Message: 'ResolveIncident' & 'Receipt'

    • Internal reference: < ServiceNow ticket reference > (Same as 'Document')

    • External reference: < External system's ticket reference >

    View the Stage

    Click through to the Outbound Stage record from the related list on the Transaction. (If you wish, you could also do the same for the Inbound Stage record.)

    Check the values in the fields match what you expect.

    Your Stage record should look like this:

    Stage details:

    • Direction: 'Outbound'

    • External reference: < External system's ticket reference >

    • Internal reference: < ServiceNow ticket reference >

    • Snapshot: < Snapshot record reference >

    Mapped Staged Data fields:

    • close_code: < Your Resolution code >

    • close_notes: < Your Resolution notes >

    • state: '6'

    View the HTTP Request

    Click through to the Outbound HTTP Request record from the related list on the Transaction. (If you wish, you could also do the same for the Inbound HTTP Request record.)

    Your HTTP Request record should look like this:

    HTTP Request details:

    • Integration: < Your Integration >

    • Connection: < Your Connection >

    • Transaction: < Your Transaction >

    • Message: 'ResolveIncident'

    Response details:

    • Status code: '200'

    • Response headers: < The header of the response being received >

    • Response payload: < The payload of the response being received >

    Compare with the External System's Incident

    Navigate to the corresponding Incident in the external system.

    Check the values in the fields match those you noted when you saved the Incident in the internal system.

    Your external system's Incident record should look like this (depending on the system you're integrating with, your record may look different; the important matter is that the values match):

    State: 'Resolved'

    Resolution code: < Your Resolution code >

    Resolution notes: < Your Resolution notes >

    Navigate to the Notes tab.

    Your Notes tab should look like this:

    Activities: < Your Resolution code/notes & State > (added by < your.external.system.user >)

    As when testing our previous scenarios, if completing this test after having integrated with the external system (as opposed to connecting to your own instance), it would be good to test the ResolveIncident Message in both directions.

    If you have completed this testing for the first time (sending to your own instance only), you are now ready to move on and look at running Build at the Integration level.

    Unifi 2.1 Release Notes

    Here you will find details of what's changed in this release, including new features & improvements, deprecated features and general fixes.

    Introduction

    Welcome to the release notes for Unifi - Version 2.1. Please have a read through to see new features and fixes that have been added.

    Reconfigure the Connections

    The next step in building the other half of the Integration is to reconfigure the connections.

    Now that both halves of the Integration are in place, we need to reconfigure each of the Connections to point to the other instance. Before doing that though, we need to create a new Inbound User for the external instance.

    Create an Inbound User (external instance)

    To configure our Integration user:

    In native ServiceNow, navigate to User Administration > Users. Click New.

    Connection Variables

    Connection Variables can be especially useful if you have multiple connection environments - e.g. Dev, Test, Prod - each containing different data.

    Although having multiple environments may not apply to this integration, we will create Connection Variables to contain certain data values which will be substituted into the Poll Processor scripts.

    Instead of scripting data values directly into the code of your Poll Processor scripts, it may be better practice to use Connection Variables in their place. Not only does it make those scripts cleaner, but it also means that changes in requirements can be more easily enacted by changing the values of the data in those variables, without having to change the code in the scripts.

    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    x_snd_eb.ws_console.checkpoint("MessageScript")
    
    x_snd_eb.ws_console.execute("Mapping incident.number [x_snd_eb_field.do?sys_id=d4dba3aadb7dbc501831aab35b961994]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $stage.number = '' + (source.number || default_value);
      } else if (source.number != '') {
        $stage.number = '' + source.number;
      }
    
    });
    
    var error = x_snd_eb.ws_console.findCheckpointError("MessageScript");
    if (error) throw error.message;
    
    //===== [ws] End Unifi Auto Generated Code =====//
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    x_snd_eb.ws_console.checkpoint("MessageScript")
    
    x_snd_eb.ws_console.execute("Mapping incident.number [x_snd_eb_field.do?sys_id=d4dba3aadb7dbc501831aab35b961994]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      var $payload = payload;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $payload.correlation_id = '' + $stage.number;
      } else if ($stage.number) {
        $payload.correlation_id = '' + $stage.number;
      }
    
    });
    
    var error = x_snd_eb.ws_console.findCheckpointError("MessageScript");
    if (error) throw error.message;
    
    //===== [ws] End Unifi Auto Generated Code =====//
    function identify(payload) {
    
      return (payload.message.name || '') + '';
    
    }
    Upgrade Notice

    Please note that, as with every release, there may be some changes that are not entirely compatible with your existing integrations. While we do everything we can to make sure you won't have to fix your integrations when upgrading, we strongly encourage all our customers to perform full end-to-end tests of their integrations before upgrading Unifi in Production.

    We also highly recommend aligning your Unifi upgrade with your ServiceNow upgrade. This means you only need to test your integrations one time rather than once for the ServiceNow upgrade and once for the Unifi upgrade.

    Feedback and Reviews

    We really appreciate feedback on what we're doing - whether it's right or wrong! We take feedback very seriously, so if you feel you'd give us anything less than a 5 star rating, we'd love to hear from you so we can find out what we need to do to improve!

    If you would rate us 5 stars, and haven't left a review on the ServiceNow Store yet, we'd be grateful if you would head over there to leave us your feedback. It only takes a few minutes and really does help us a lot. Go on, you know you want to leave a 5-star review on the Store!​

    Highlights

    Major Portal Update

    The biggest change in this release is the update to the Portal interface, now known as Unifi Integration Designer.

    The old operations dashboard has now been moved to the new Unifi Operations Portal, ready for lots of exciting updates around operations in the near future. It's been replaced with a brand new configuration dashboard, allowing you to view, create, copy and manage your processes and integrations with ease.

    There are lots of improvements across the board when configuring an integration, too, not least of all including support for all the components you need to build any Ticket Exchange integration together in an intuitive way.

    Integration Pause

    We've introduced a brand new capability to pause an integration. This allows you to temporarily prevent outbound messages from being sent, instead allowing them queue ready for sending in future. This is different to deactivating the integration, which would prevent message processing altogether. You might want to do this if you are having a lot of errors with the external system, or perhaps if it's gone down for maintenance. Once you know the system is back up and online, you can resume the integration with the click of a button and it will automatically start processing the queued messages.

    Event Actions

    The introduction of Event Actions is part of our ongoing strategy to improve operations management of integrations. By creating an Event Action, you can easily triage events such as transaction errors and perform actions to handle or report on those actions. For example, you might want to create an Incident record if you receive more than 5 transaction errors in 15 minutes.

    Notes

    Logged Attachments

    With the introduction of Activity Logs you no longer need to attach logs to requests/transactions. Activity Logs are present in related lists on all relevant Transaction stack records.

    The attached logs were previously controlled by the Attach logs and Attach payloads checkboxes on Integration, but they are now overridden off by a new Integration Enable Attachments system property. This property acts as the master switch and effectively disables the checkboxes on the Integration. Note: the checkboxes have been removed from the Integration form but can still be edited from the list view.

    Details

    New Features & Improvements

    • Admins can now force close a bond. [UN-106]

    • Description field added to Data Stores. [UN-123]

    • New option on Integration to send attachments with Create messages. [UN-184]

    • Activity Log now references the Target (e.g. Incident). [UN-288]

    • Added a cleaner job, controlled by system properties, to remove orphaned Transactions. [UN-544]

    • New Poll Request states (Retrieving, Processing) are set while a Poller is processing . [UN-293]

    • Field style added to Active field on Poller. [UN-298]

    • Activity Log is now able to show the table that called it. [UN-305]

    • Field style added to Poll Request state. [UN-313]

    • Queued Transactions are now ignored when the bond is closed. [UN-370]

    • Fields can now be copied. [UN-389]

    • The Integration field is now auto-populated when creating a Field from a Message. [UN-395]

    • The Table field is now auto-populated when creating a Field. [UN-396]

    • Added Domain field to Transaction stack forms (Bond, Transaction, Stage, and HTTP Request). [UN-401]

    • Copy Message now copies all its Fields. [UN-420]

    • Copying an Integration now copies all the Fields. [UN-421]

    • Copy Integration is now available in the Portal. [UN-422]

    • Connection is now shown on Transaction. [UN-426]

    • Integration Status (Up, Down, Awaiting) is now tracked on the Integration. [UN-427]

    • Integration State (Active, Paused, Off) is now tracked on the Integration. [UN-428]

    • Added option to Run Event Actions on an Integration. [UN-431]

    • Bond now references the Connection it was created for. [UN-438]

    • Dynamic Stage ($stage) now has a getValue() method. [UN-441]

    • Fields and Field Maps can now be configured in the Portal. [UN-443]

    • Message level Fields can inherit from Integration level Fields. [UN-449]

    • Pollers are now listed on Integration. [UN-456]

    • Bonded Attachment records now track direction (Inbound or Outbound). [UN-461]

    • Added console object to all scripts for ease of logging. [UN-477]

    • Updated Activity Logs on the bond so it shows all Activity Logs for the Document record. [UN-513]

    • Improved Activity Log titles. [UN-514]

    • Admins can now force re-open a closed Bond. [UN-517]

    • Improved Execute Now button for Pollers. [UN-521]

    • Added Activity Logs to Poll Requests. [UN-522]

    • Added Integration field to Poll Request. [UN-523]

    • Improved naming for Portal based Activity Logs. [UN-529]

    • HTTP Request and Transaction now shows the Response Action that was used. [UN-533]

    • Cascade delete now applies to Field Maps belonging to an Integration. [UN-545]

    • Cascade delete now applies to Fields belonging to an Integration. [UN-546]

    • Cascade delete now applies to Pollers belonging to an Integration. [UN-547]

    • Cascade delete now applies to Pollers belonging to an Poll Processor. [UN-547]

    • Added Description field to Connection. [UN-565]

    • Added Description field to Scheduled Scripts. [UN-570]

    • Added Hints to Field Map fields. [UN-571]

    • Added execution URL to Activity Log. [UN-574]

    • Modified security on Activity Logs so they are visible to Unifi Managers. [UN-586]

    • New Unifi REST service and integration role added to simplify REST API configuration. [UN-633]

    • Changed Integration Format and Message Service defaults to be REST/JSON. [UN-634]

    Changes

    • Bond closed field has been removed from Message. [UN-332]

    • The XML Template on Message no longer has a default value. [UN-398]

    • Changing the Integration on a Field now clears the Message. [UN-399]

    • Poll Processors are now copied when the Integration is copied. [UN-468]

    • Improved the Field "Depends on" logic. [UN-476]

    • Data Stores now inherit the domain from the parent document. [UN-481]

    • Message.processOutbound() will not send anything if the action on the current record has been aborted using setAbortAction(true). [UN-490]

    • Replay Request is now available to the Unifi manager role. [UN-494]

    • Most system properties are now Private and not transferrable by Update Set. [UN-652]

    • HTTP Request URL length limit increased to 2048 characters. [UN-118]

    • Transaction count on bond has been deprecated. [UN-141]

    • Number field has been removed from Messages and Message Scripts. [UN-208]

    • Modified Bond Reference Method field visibility on Message. [UN-292]

    • Ignore Transaction button now redirects to the Transaction being ignored. [UN-338]

    • Deprecated ECC Queue attachment support for attaching logs. [UN-405]

    • Deactivated the fix script x_snd_eb eBonding Upgrade. [UN-406]

    • Response is no longer mandatory on Message. [UN-439]

    • Integration properties which are numbers are now mandatory. [UN-440]

    • Endpoint URL is now visible on inbound requests. [UN-511]

    • Deprecated log attachments. [UN-540]

    • Bonded Attachment fields are now locked down. [UN-577]

    • Only Unifi Admins or Managers can replay HTTP Requests. [UN-581]

    General Fixes

    • Inbound Create messages are now rejected when a Bond with the same reference exists. [UN-136]

    • Inbound Bonded Attachments now reference the Transaction they came in on. [UN-151]

    • Fixed issue with connection name generation. [UN-159]

    • Replaying a Transaction with attachments will now replay the attachments as well. [UN-226]

    • The Bond state will now always reflect the overall status of its transactions. [UN-230]

    • Bond status is now updated correctly when processing numerous queued messages. [UN-273]

    • A new field Deferred count has been added to Bonded Attachment which tracks how many times the attachment was not sent and allows us to properly calculate attachment metrics on the Bond. [UN-287]

    • Bond numbers are no longer used unnecessarily. [UN-315]

    • Fixed issues with assigning headers in Stage to Request Message Scripts. [UN-333]

    • Fixed an issue where calling a Unifi endpoint with GET would throw an error. [UN-380]

    • UTF-8 encoded XML is now checked before processing to prevent parsing issues. [UN-382]

    • The Name value on Field is now set even when a not mapping to a real field. [UN-397]

    • Fixed an issue where the Field form would always show the alert for losing changes. [UN-451]

    • Fixed duplicate attachment messages when using ServiceNow Antivirus scanning. [UN-465]

    • Inbound transactions that are replayed are now executed as the integration instead of the current user. [UN-473]

    • Fixed an issue with Field Choice generation not having the table set. [UN-475]

    • Replaying an HTTP Request now increments the number correctly. [UN-478]

    • Errors thrown in Field Map scripts will now show up in the Transaction. [UN-479]

    • Fixed an issue with replaying Transactions created by system. [UN-482]

    • Fixed Bond History state logging. [UN-485]

    • Fixed an issue with false-positive updates from Transactions. [UN-505]

    • The "Generate field choices" action on Field now checks for existing Field Choice entries. [UN-516]

    • Reference fields in Messages are now correctly updated when copying an Integration. [UN-530]

    • Fixed an issue where full Activity Logs would be sent to system log. [UN-534]

    • Logging verbosity is now allowed at error level. [UN-535]

    • Fixed an issue where queued Transactions would not be processed. [UN-543]

    • Connection is now updated when the Integration name is changed. [UN-552]

    • API names are now allowed to use a zero (0). [UN-553]

    • Clicking the "Generate field choices" action on Field will save the record first to ensure choices are generated correctly. [UN-556]

    • Response Action user notifications now work. [UN-562]

    • Fixed undefined error with Ignore Transaction button [UN-592]

    • Fixed issue in generating messages without a Connection URL [UN-638]

    Integration Designer (Portal) Changes

    • Transactions are now ordered by date created in the live feed. [UN-452]

    • Side menu options are now highlighted when selected. [UN-453]

    • Reference links now navigate to the Portal pages instead of native ServiceNow. [UN-454]

    • Changed the style on inactive Boolean fields to differentiate them from read-only Boolean fields. [UN-564]

    • Embedded fonts/icons to improve page loading times. [UN-572]

    • Added Enable/Disable button to form headers for easy access. [UN-641]

    Integration Designer (Portal) Fixes

    • Fixed read error when attempting to view a record in Portal as a non-admin. [UN-403]

    • Fixed Portal font size for instances running Madrid onwards. [UN-404]

    • Fixed an issue with the operations dashboard truncating the live transaction feed when there are less than 20 transactions. [UN-407]

    • Attachment sending can now be controlled from the portal. [UN-415]

    • Condition widgets now work in Portal. [UN-434]

    • Fixed an issue with variables payload and headers not being assignable in Message Scripts. (Closures have been replaced with instructive comments.) [UN-463]

    • Outbound Attachment properties are no longer visible for inbound only messages. [UN-472]

    • Bond scripted condition type only shows once instead of twice. [UN-558]

    • Long text fields in Portal lists are now truncated to improve usability. [UN-569]

    • Fixed render issue with reference fields that have no value in portal [UN-578]

    • References in lists now show "(empty)" if there is no display value [UN-640]

    • Fixed issue with form appearing read-only in Portal view when directly navigation to the URL [UN-642]

    • Fixed issue with Portal form loads from an external link [UN-643]

    • Added support for day-of-week type fields. [UN-566]

    • Added support for time fields. [UN-567]

    • Added support for interval fields. [UN-568]

    • Lists and pages now update the title in Portal. [UN-637]

    This will facilitate this same connection being used for both the Table API and Attachment API (as per the
    ).

    The user profile used by the external system for authentication. An active connection must be found for the user to gain access.

    lookup: <Your Inbound user>

    User ID

    The id of the user (to be used by the external system for authentication).

    <your.integration_user>

    First name

    The integration user's first name.

    <Your First Name>

    Last name

    The integration user's last name.

    <Your Last Name>

    Password

    The user's password (to be used in basic authentication).

    <Your Password>

    Roles

    The role required for access to the integrated records.

    Environment

    The environment this connection applies to.

    'Development'

    Endpoint URL

    The external system's access URL.

    <External system Endpoint URL>

    Active

    Use this connection for the integration when true.

    <true>

    Authentication

    The authentication method to use for this connection.

    'Basic'

    User*

    The username used in basic authentication.

    <external.system.user>

    Password*

    The password used in basic authentication.

    <External system user password>

    'itil', 'x_snd_eb_integration'

    Inbound user**

    Incident Attachment Poller Guide

    Always ensure that your Inbound User is NOT used by anyone else for the same Process i.e. if you’re creating a Connection for an Integration on the Incident Process, your Inbound User has to be the only User used by an Integration within that Process.

    The user profile used by the external system for authentication. An active connection must be found for the user to gain access.

    lookup: <Your Inbound User>

    User ID

    The id of the user (to be used by the external system for authentication).

    <your.integration_user>

    First name

    The integration user's first name.

    <Your First Name>

    Last name

    The integration user's last name.

    <Your Last Name>

    Password

    The user's password (to be used in basic authentication).

    <Your Password>

    Roles

    The roles required for access to the integrated records.

    Environment

    The environment this connection applies to.

    'Development'

    Endpoint URL

    The external system's access URL.

    <External system Endpoint URL>

    Active

    Use this connection for the integration when true.

    <true>

    Authentication

    The authentication method to use for this connection.

    'Basic'

    User

    The username used in basic authentication.

    <external.system.user>

    Password

    The password used in basic authentication.

    <External system user password>

    'itil', 'x_snd_eb_integration'

    Inbound user

    Process this message when the bond state is Open.

    <true>

    Message name

    The message name that is unique for this integration.

    'UpdateIncident'

    Type

    The primary purpose of the message.

    'Update'

    Direction

    The direction(s) this message is configured to support.

    'Bidirectional'

    Response

    The immediate synchronous response to this message.

    lookup: 'Response'

    Async*

    Turn this option on if you want inbound processing to occur asynchronously or this message is the first of an asynchronous message pair.

    <true>

    Async receipt

    The asynchronous receipt to this message.

    lookup: 'Receipt'

    Bond ownership*

    Determine if the sender should own the bond or not in order for this message to be processed? Use 'Ignore' to process regardless of the owner flag. (Choices: Ignore, Must own, Must not own.)

    'Ignore'

    Bond condition type*

    The type of conditional check made on the bond. (None: no checks are made. State: checks against the state are made using the conditional checkboxes. Scripted: the 'Bond condition' script is used.)

    'State'

    Bond pending

    Process this message when the bond state is Pending.

    <true>

    Outbound condition*

    The condition that the ServiceNow record must meet to trigger this message being processed.

    Update the Outbound condition script field with the code below

    Bond reference method*

    Method of searching for and validating an existing bond for incoming messages.

    'Both'

    Reference lookup script

    The script containing functions for extracting internal and external references from the request payload.

    Update the code in the Reference lookup script field so that it looks like the code below

    Bond open

    Bond: < Your Bond >

  • Message: 'ResolveIncident'

  • Direction: 'Outbound'

  • Transaction state: 'Complete' (The data has been successfully transported)

  • Process state: 'Accepted' (The transaction was accepted as within the scope of the business logic that's in place)

  • Message: 'ResolveIncident'

  • Transaction: < Your Transaction >

  • Integration: < Your Integration >

  • Direction: 'Outbound'

  • Request state: 'OK' (There are no errors with the HTTP Request.)

  • Attempt number: < Number of HTTP Request attempts > (Failed requests are retried up to the maximum attempts number as configured on the Integration.)

  • Endpoint URL: < The external system’s access URL >

  • Action Method: 'POST'

  • Request headers: < The header of the request being sent >

  • Request payload: < The payload of the request being sent >

  • State

    The Incident lifecycle state.

    'Resolved'

    Resolution code

    The Incident resolution code.

    <Your Resolution code>

    Resolution notes

    The Incident resolution notes.

    <Your Resolution notes>

    The fields to be configured for the User record are as follows:
    Field
    Description
    Value

    User ID

    The id of the user (to be used by the external system for authentication).

    <your.integration.user>

    First name

    The integration user's first name.

    <Your First Name>

    Last name

    The integration user's last name.

    <Your Last Name>

    The x_snd_eb.integration role gives access to the Unifi web services. You may need to assign additional roles depending on the process functionality used i.e. things like gs.hasRole(‘itil’) in business rules/scripts etc.

    This Inbound user will become the Outbound user in the other instance. We will need to update the other instance accordingly.

    Edit the Connection (external instance)

    We are going to edit the existing 'Development' Connection so that it will become our 'Test' Connection and use the Inbound user just created.

    We will need to have our other instance point to this external one also (not only to itself). Therefore, we will create a new 'Test' Connection in the other instance to do that. (See the next section.)

    In Unifi Integration Designer, navigate to the 'Connections' icon.

    Click to open the previously created Development Connection to edit it.

    Edit the values in the Connection as follows:

    Field
    Description
    Value

    Environment

    The environment this connection applies to.

    'Test'

    Inbound user

    The user profile used by the external system for authentication.

    <Your Inbound user*>

    *Inbound user created above.

    Your Connection form should look like this

    We have not updated the Endpoint URL nor the Outbound User because they already contain the correct values (i.e. the internal instance's Endpoint & Inbound user).

    Save the Connection.

    At this stage you can carry our a basic Connection Test (as outlined on the Connection page of this guide).

    Create a Test Connection (internal instance)

    Back in the internal instance, navigate to the 'Connections' icon. Click New.

    We could have edited our existing 'Development' Connection to point to the external instance (instead of itself). We have chosen instead to create a new 'Test' Connection to do that. That way we have two Connections, a 'Development' Connection which points to itself and a 'Test' connection which points to the external instance.

    The fields to be configured for the New Connection modal are as follows:

    Field
    Description
    Value

    Environment

    The environment this connection applies to.

    'Test'

    Endpoint URL

    The external system's access URL.

    <External system Endpoint URL>

    Active

    Use this connection for the integration when true.

    <true>

    Outbound Connectivity

    The entire Endpoint URL for this Test environment Connection can be easily obtained from the automatically created Message Resource on the Unifi Scripted REST API (displayed in the widget at the top of the Connections page of the external instance - as shown above).

    For our Outbound User we will use the external system's Inbound User (as created above).

    Your New Connection modal should look like this:

    Submit and view to further configure the Connection.

    Clicking ‘Submit’ will redirect you to the list view of the record you’re creating. Clicking ‘Submit and view' will redirect you to the newly created record.

    Connection Details

    The fields to be configured for the Details form are as follows:

    Field
    Description
    Value

    Authentication

    The authentication method to use for this connection.

    'Basic'

    User*

    The username used in basic authentication.

    <external.system.user>

    Password*

    The password used in basic authentication.

    <External system user password>

    (External) User/Password: As created above & set in the external instance.*

    Your Details form should look like this:

    Save the Connection.

    As above, you can carry our a basic Connection Test (as outlined on the Connection page of this guide).

    View Connections

    There will now be both a Development and a Test Connection for your Integration. Only the Test Connection should be Active.

    These can be viewed by clicking the 'Connections' icon.

    We have completed building the other half of the Integration. We are now ready to go back and repeat the Testing for each of the scenarios we've built.

    See the following pages:

    Test CreateIncident
    Test UpdateIncident
    Test ResolveIncident
    We will use Connection Variables to identify which Assignment group to look for and which field elements to return data from when polling.

    Icons

    Before continuing we would like to draw your attention to some of the relevant icons that will be visible down the left hand navigation strip in the Unifi Integration Designer.

    The icons are:

    a) 'Integration' icon: Opens the current integration's Details page.

    b) 'Messages' icon: Opens the current integration's Messages page.

    c) 'Fields' icon: Opens the current integration's Fields page.

    d) 'Field Maps' icon: Opens the current integration's Field Maps page.

    e) 'Pollers' icon: Opens the current integration's Pollers page.

    f) 'Poll Processors' icon: Opens the current integration's Poll Processors page.

    g) 'Connections' icon: Opens the current integration's Connections page.

    Assignment Group

    It is necessary to identify which of the non-bonded records in the external instance (your PDI) are applicable to the integration. One way of doing this is to define a specific Assignment group to which all incidents will be assigned for the integration.

    We will create a new group which will be used only for this integration. We will then use the Sys ID of that group in a Connection Variable to pass into the Poll Processor scripts to enable Unifi to identify which records should be bonded.

    In your PDI, navigate to User Administration > Groups. Click New.

    The fields to be configured for the Group New record are as follows:

    Field
    Description
    Value

    Name

    Descriptive name, e.g. DBAs, Network, etc.

    <Your Name>

    Description

    The description of the Group.

    <Your Description>

    Your Group New record should look like this:

    Submit the record.

    Variable: external_group

    This variable will contain the sys id of the group created above. It will be used in the Poll Processor Setup script to identify which non-bonded Incidents to query.

    To open Unifi Integration Designer, navigate to [ws] Unifi > Unifi Integration Designer, then navigate to < Your Integration > (created following the Outbound Incident Guide).

    Click the 'Connections' icon, then navigate to and open < Your Connection >.

    From the Connection, navigate to Connection > Variables & click New.

    The 'external_group' New Connection Variable fields to be configured are as follows:

    Field
    Description
    Value

    Key

    A unique name that will be used to get the value.

    'external_group'

    Value

    The variable value to be used in the integration.

    <Your Value>*

    Description

    Describe what this connection variable is for and how it should be used.

    <Your Description>

    *Value: Value may vary. Use the sys id of the group created in your PDI.

    Your 'external_group' New Connection Variable modal should look like this:

    Click Submit.

    You will be redirected back to the Variables page of the Connection record.

    Variable: base_fields

    This variable will contain the minimum set of fields required to identify and select records in the remote system.

    Click New.

    The 'base_fields' New Connection Variable fields to be configured are as follows:

    Field
    Description
    Value

    Key

    A unique name that will be used to get the value.

    'base_fields'

    Value

    The variable value to be used in the integration.

    'sys_id,number,correlation_id,sys_updated_on,sys_updated_by'

    Description

    Describe what this connection variable is for and how it should be used.

    <Your Description>

    Your 'base_fields' New Connection Variable modal should look like this:

    Click Submit.

    You will be redirected back to the Variables page of the Connection record.

    Variable: data_fields

    This variable will contain fields which will be retrieved from the remote system, in addition to the required base_fields. We have chosen a sample selection of fields. You may choose different fields if you wish. However, the fields you select here must also be mapped with corresponding Field Records (more on that on the CreateIncidentInbound Fields page).

    Click New.

    The 'data_fields' New Connection Variable fields to be configured are as follows:

    Field
    Description
    Value

    Key

    A unique name that will be used to get the value.

    'data_fields'

    Value

    The variable value to be used in the integration.

    'caller_id,short_description,description,state,impact,urgency'

    Description

    Describe what this connection variable is for and how it should be used.

    <Your Description>

    Your 'data_fields' New Connection Variable modal should look like this:

    Click Submit.

    The following Connection Variables should now be in place for your Connection:

    Now let's move on and configure the Poll Processor.

    CreateIncident Message

    The CreateIncident Message will create a ticket on the target table of the integrated system.

    As previous, after clicking the 'Messages' icon, you will see the following screen (note: both the previously configured messages are now visible in the list):

    Click New.

    New Message Modal

    The fields to be configured for the CreateIncident New Message modal are as follows:

    Field
    Description
    Value

    Your CreateIncident New Message modal should look like this:

    Submit and view to further configure the Message.

    Response Fields

    Navigate to Message > Response.

    The Response fields to be configured are as follows:

    Field
    Description
    Value

    *This field is automatically defaulted to true.

    Your Response form should look like this:

    Navigate to Message > Bond.

    Bond Fields

    The Bond fields to be configured are as follows:

    Field
    Description
    Value

    *These fields are automatically populated.

    Your Bond form should look like this:

    Navigate to Outbound > Trigger.

    Outbound Trigger Fields

    The Outbound Trigger fields to be configured (as required)* are as follows:

    Field
    Description
    Value

    *Outbound condition (as required):

    It is not necessary for you to enter a condition. The value given is an example. You may create any condition (or not) to align with your business process requirements.

    The code in the 'Outbound condition' script field should look like this:

    This is an example of data-driving the trigger condition. This script checks whether the integration that this message belongs to is listed in a custom field on the assignment group which references the integration.

    Your Outbound Trigger form should look like this:

    Navigate to Outbound > Settings.

    Outbound Settings Fields

    The Outbound Settings fields to be configured are as follows:

    Field
    Description
    Value

    Your Outbound Settings form should look like this:

    Navigate to Inbound > Settings.

    Inbound Settings Fields

    The Inbound Settings fields to be configured are as follows:

    Field
    Description
    Value

    *This field is automatically populated & not editable.

    Bond reference method:

    Internal - lookup using the internal reference only.

    External - lookup using the external reference only.

    Both - lookup using both the internal and external references.

    Bond reference method: The perspective of the available choices is in relation to the receiving instance i.e. Internal (internal reference) means the bonded ticket in our instance and External (external reference) means the bonded ticket in their instance.

    Primarily used in relation to create and update type messages, these settings define which values to lookup against to search for and validate whether or not a bond already exists.

    In the case of a create type message, we use 'External' because there is not yet a bonded ticket in the receiving instance to reference (if we were to receive a create type message which referenced a bond that already existed it would be rejected because we don't want to create another bond for a record we've already seen ).

    The code in the 'Reference lookup script' field should look like this:

    Your Inbound Settings form should look like this:

    Click Save.

    We are now ready to configure the Fields for our CreateIncident Message.

    UpdateIncident Fields

    We will utilise the Field & Field Map records to configure the Message Scripts for the UpdateIncident Message.

    Field: message.message_header

    The 'message_header' (Integration level) Field record should already be in place (i.e. with Active set to false). We will now create its Message level counterpart.

    From the UpdateIncident Message, navigate to Message > Fields.

    Your UpdateIncident Fields page should look like this:

    Find the message.message_header (Integration level) Field & set Active to true.

    The 'Build Integration' button becomes visible in the banner and the empty circle icon next to the Field name turns green & contains a green 'check' (to indicate that Message level configuration exists for this Field). Note: the empty 'circle icon' indicates that the Integration level Field is available to add to the Message.

    As before, by setting the Active flag to true on the Integration level Field record listed on the Message, Unifi has automatically created the Message level counterpart.

    Next, repeat the process for the incident.short_description Field.

    Field: incident.short_description

    The 'incident.short_desccription' (Integration level) Field record should already be in place (i.e. with Active set to false). We will now create its Message level counterpart.

    Your UpdateIncident Fields page should look like this:

    Find the incident.short_description (Integration level) Field & set Active to true.

    The empty circle icon next to the Field name turns green & contains a green 'check' (to indicate that Message level configuration exists for this Field).

    We will now configure Field records for two other Incident record field elements.

    Fields & Field Maps

    As with the CreateIncident Message and depending on your requirements, you will need to create Field records for each of the relevant Incident record field elements (see the table in on the 'CreateIncident Fields' page for an example). For the sake of brevity, this Guide will focus on two of those. If you wish, however, you are free to configure other Field records as required.

    The table below lists the Incident record field elements we will map and the relevant Field Maps required to configure each Field record.

    Incident Field
    Field Map

    Copy Field Maps

    If you haven't already, you will need to copy the relevant additional Field Maps for the UpdateIncident Field records as follows:

    • Journal field

    See (on the 'CreateIncidentReceipt Fields' page) for details.

    Field: incident.comments

    From the UpdateIncident Message, navigaate to Message > Fields & click New.

    The fields to be configured for our incident.comments New Field modal are as follows:

    Field
    Description
    Value

    *These fields are automatically defaulted to true, or automatically populated.

    **Field map: Value may vary. Choose the copy Field Map you created for your Integration.

    Your 'incident.comments' New Field modal should look like this:

    Submit the record.

    You will be redirected back to the Fields page of the UpdateIncident Message.

    Field: incident.work_notes

    Because the incident.work_notes Field record is the same 'type' (IG Journal field) & the majority of the settings are the same as the previously configured Field, it will be quicker to copy the incident.comments Field & make a few minor changes.

    Click the ellipsis next to the incident.comments Field record & click Copy.

    The fields to edit for the Copy Field modal are as follows:

    Field
    Description
    Value

    *This field is automatically populated.

    Your Copy Field modal should look like this:

    Click Copy.

    You will be redirected to the Details page of the newly created incident.work_notes Field record.

    Build

    Now that we’ve configured the Field records for the UpdateIncident message, we are ready to build our message scripts.

    To quickly navigate to the UpdateIncident Message from the Details page of the newly created incident.work_notes Field record…

    ...click the 'Preview' icon to the left of the Message field.

    From the UpdateIncident message, navigate to Message > Fields.

    The following Field records should now be in place for your UpdateIncident messsage:

    Click on Build Message.

    You will see the 'Message build successful' Info Message.

    Navigate to Advanced > Script Editor to view the auto-generated code.

    Your Script Editor fields should look like this:

    Message Scripts

    The newly auto-generated code will appear between a Begin & End Comment immediately prior to any code that may already be there (pre-existing code will be retained).

    We are now ready to Test our UpdateIncident Message.

    !current.state.changes()
    var answer = {};
    
    answer.getExternalMessageID = function (payload, request) {
      return '' + (payload.message.source_id || '');
    };
    
    answer.getInternalMessageID = function (payload, request) {
      return '' + (payload.message.target_id || '');
    };

    Set the Bond State when receiving this message. Use 'None' to leave the Bond State alone or to modify it via a Message/Field Stage to Target script. (Choices: None, Pending, Open, Suspended, Vendor suspended, Closed)

    'Open'

    In the case of an update type message, we use 'Both' because it's a more accurate method of validating updates are being sent to/received from the correct bonded records.

    Message name

    The message name that is unique for this integration.

    'CreateIncident'

    Type

    The primary purpose of the message.

    'Create'

    Direction

    The direction(s) this message is configured to support.

    'Bidirectional'

    Response

    The immediate synchronous response to this message.

    lookup: 'Response'

    Async*

    Turn this option on if you want inbound processing to occur asynchronously or this message is the first of an asyncronous message pair.

    <true>

    Async receipt

    The asynchronous receipt to this message.

    lookup: 'CreateIncidentReceipt'

    Bond ownership*

    Determine if the sender should own the bond or not in order for this message to be processed? Use 'Ignore' to process regardless of the owner flag. (Choices: Ignore, Must own, Must not own.)

    'Ignore'

    Bond condition type*

    The type of conditional check made on the bond. (None: no checks are made. State: checks against the state are made using the conditional checkboxes. Scripted: the 'Bond condition' script is used.)

    'State'

    Bond new

    Process this message when a new bond is required.

    <true>

    Outbound condition*

    The condition that the ServiceNow record must meet to trigger this message being processed.

    Update the Outbound condition script field with the code below

    Action method

    The SOAP Action or the REST Method to use for this message. If this field is empty the SOAP Action will default to the message name and the REST Method will default to POST.

    'POST'

    Bond reference method*

    Method of searching for and validating an existing bond for incoming messages.

    'External'

    Reference lookup script

    The script containing functions for extracting internal and external references from the request payload.

    Update the code in the Reference lookup script field so that it looks like the code below

    Set bond state inbound

    The Field Map this Field record is linked with.

    'IG - Journal field'**

    Map to field*

    Use this Field record to represent a field on a source/target table.

    <true>

    Table*

    The primary source/target table that this Field record is mapped to.

    'Incident' [incident]

    Element

    The field on the source/target table this Field record is mapped to.

    'Additional comments'

    Path

    Where in the payload the data will be placed.

    'detail'

    Property*

    The property in the payload the data will be written to.

    Automatically populated

    Inbound*

    Set to true to use for inbound Messages.

    <true>

    Outbound*

    Set to true to use for outbound Messages.

    <true>

    comments

    Journal field

    work_notes

    Journal field

    Message*

    The Message this Field record is linked with.

    'UpdateIncident'

    Description

    Describe what this field is for and any specific details that might help you in future.

    'The incident's comments'

    Active*

    Set to true to use this Field record for processing.

    <true>

    Element

    The field on the source/target table this Field record is mapped to.

    'Work notes'

    Property*

    The property in the payload the data will be written to.

    Automatically populated

    Description

    Describe what this field is for and any specific details that might help you in future.

    'The incident's work notes'

    Fields & Field Maps
    Copy Field Maps

    Field map

    Password

    The user's password (to be used in basic authentication).

    <Your Password>

    Roles

    The role required for access to the integrated records.

    x_snd_eb_integration

    Inbound user

    The user profile used by the external system for authentication. An active connection must be found for the user to gain access.

    lookup: <Your Inbound User>

    CreateIncidentReceipt Fields

    We will utilise the Field & Field Map records to configure the Message Scripts for the CreateIncidentReceipt Message.

    Copy Field Maps

    It is worth copying all relevant OOTB Field Maps as are necessary for your integration before using any of them in your Field Records - thereby mitigating the risk of any potential issues with future upgrades.

    The Field Maps we shall use for our CreateIncidentReceipt Field records are:

    • Message Header

    • Receipt Status

    To copy the Message Header Field Map, navigate to the 'Field Maps' icon.

    Click on the ellipsis to the right of the Message Header Field Map & then click Copy.

    Copy Field Map Modal

    The fields to edit for the Copy Field Map modal are as follows:

    Field
    Description
    Value

    *This field is automatically populated.

    Name: We have chosen to prefix the existing Field Map Name with the initials of our Integration (you are free to choose any appropriate means of identifying/differentiating).

    Your Copy Field Map modal should look like this:

    Click Copy.

    You will be redirected to the Details page of the newly created Field Map.

    Repeat the process for the Receipt Status Field Map.

    Field: message.message_header

    From the CreateIncidentReceipt Message, navigate to Message > Fields. Click New.

    The fields to be configured for our message_header New Field modal are as follows:

    Field
    Description
    Value

    *These fields are automatically defaulted to true, or automatically populated.

    **Field map: Value may vary. Choose the copy Field Map you created for your Integration.

    Your 'message_header' New Field modal should look like this:

    Submit the record.

    You will be redirected back to the Fields page of the CreateIncidentReceipt Message.

    Field: message.transaction_details

    Click New.

    The fields to be configured for our transaction_details New Field modal are as follows:

    Field
    Description
    Value

    *These fields are automatically defaulted to true, or automatically populated.

    **Field map: Value may vary. Choose the copy Field Map you created for your Integration.

    Your 'transaction_details' New Field modal should look like this:

    Submit the record.

    You will be redirected back to the Fields page of the CreateIncidentReceipt Message.

    Build

    Now that we’ve configured the Field records for the CreateIncidentReceipt message, we are ready to build our message scripts.

    The following Field records should now be in place for your CreateIncidentReceipt messsage:

    Feature Alert: In the picture above you will notice that a 'Build Integration' button has appeared in the banner at the top of the page. Whenever a change is made to a Field record that is associated to a Message (whether that is being created, updated, or deleted) the button will be available and acts as a visual reminder that changes have been made and Message Script(s) need to be built. We will talk more about this feature in the page.

    Navigate to Advanced > Script Editor.

    When you first open the Script Editor, you will see the following:

    Having visibility of your message scripts in the one pane makes scripting so much more efficient.

    Click on Build Message.

    You will see the 'Message build successful' Info Message.

    Your Script Editor fields should now look like this:

    You can click View to adjust the layout and change the view to show various combinations of, or individual script fields.

    Message Scripts

    The newly auto-generated code will appear between a Begin & End Comment immediately prior to any code that may already be there (pre-existing code will be retained).

    Once you have finished examining the code, click 'Close' to navigate back to the Fields page of the CreateIncidentReceipt Message.

    We are now ready to configure our CreateIncident Message.

    Poll Processor

    The Poll Processor contains the logic that will be applied when polling a remote system for data.

    The Poll Processor is a configuration record which contains the logic that will be applied when polling a remote system for data. There are three main scripts which are used to setup, execute and process the Poll Requests. The scripts given here are examples of how you might configure your Poll. The details of yours may differ depending on your requirements.

    Icons

    Before continuing we would like to draw your attention to some of the relevant icons that are visible down the left hand navigation strip of the Unifi Integration Designer portal page.

    The icons are:

    a) 'Integration' icon: Opens the current integration's Details page.

    b) 'Messages' icon: Opens the current integration's Messages page.

    c) 'Fields' icon: Opens the current integration's Fields page.

    d) 'Field Maps' icon: Opens the current integration's Field Maps page.

    e) 'Pollers' icon: Opens the current integration's Pollers page.

    f) 'Poll Processors' icon: Opens the current integration's Poll Processors page.

    New Poll Processor

    In Unifi Integration Designer, navigate to & open < Your Integration > (created following the Outbound Incident Guide).

    Click the 'Poll Processors' icon & then New.

    The fields to be configured for the New Poll Processor modal are as follows:

    Field
    Description
    Value

    Your New Poll Processor modal should look like this:

    Submit and view to further configure the Poll Processor.

    Setup Script

    The Setup Script is the first script to run (it runs at the point in time the Poll Request is created). It is used to build the environment for the poll and define what it will do. We will use it to setup the URL that will be called.

    Navigate to Scripts > Setup Script.

    The Setup script field is to be configured as follows:

    Field
    Description
    Value

    The code in the Setup script field should look like this:

    Setup script: The parameters for which data to return are contained in the endpoint url.

    fields: The table API will return all the data by default, so we choose to deliberately limit what is returned to the fields listed in this variable.

    query: Instead of querying all the records on the remote instance, we deliberately limit the records to those where the correlation id is not empty (i.e. it's bonded), that haven't been updated by the Authentication user (our system) and that were updated since either since the last update time (if one exists), or in the last 30 minutes.

    Endpoint URL: The value used in the poll_request.endpoint_url was initially generated using the ServiceNow REST API Explorer, substituting variables in for the uri query and fields. This value is appended to the existing endpoint url in the active connection before being added to the Poll Request.

    Your Setup Script form should look like this:

    Navigate to Request Script.

    Request Script

    The Request Script is used to reach into the remote system and execute the request. We will use the ServiceNow RESTMessageV2() web service to make a REST call to the URL defined in the Setup Script.

    The Request script field is to be configured as follows:

    Field
    Description
    Value

    The code in the Request script field should look like this:

    Request script: This script uses the ServiceNow RESTMessageV2() web service to make a REST call to the endpoint url created in the Setup script. It returns the body of the request as the answer which it passes to the Response script

    Your Request Script form should look like this:

    Navigate to Response Script.

    Response Script

    The Response Script is used to process the information returned from the remote system. We will pass this data to Unifi to process.

    The Response script field is to be configured as follows:

    Field
    Description
    Value

    The code in the Response script field should look like this:

    Response script: This script parses the response into a body object to contain the result, (returning if it doesn't contain anything). It then sets up some objects to help us (including the essential PollHelper() function which we initialise from the poll_request). After that it loops through each of the returned tickets; for each it sets up a payload object and the options for submitting it to Unifi before calling the processInbound() method. It then checks whether the ticket was updated later than the last update time; if so, it sets and stores the last update time as that 'sys_updated_on' value (this 'last_update_time' is what the Setup script checks against when defining what the Poll will do).

    After looping through all the records, the results are logged to the Response status field of the Poll Request.

    Essential code: the following lines of code must be included in the response script to send the data to Unifi

    Your Response Script form should look like this:

    Save the Poll Processor.

    Now let's move on and configure the Poller.

    Test CreateIncident

    Follow these steps to test the CreateIncident Message.

    Because we have configured Unifi to connect to itself, we don't need to wait until we've connected to the external system before we test. We can test both sending and receiving Messages in the one instance. It goes without saying that these tests should be repeated once we have connected to the external instance.

    To test, we will create an incident in our instance and then follow the data as it flows through the Unifi transport stack and on to the newly created ticket (whether that be in our instance, or in the external system we are integrating with).

    Assignment Group

    We have data-driven the trigger for our Create Message so that it fires when a ticket is assigned to an assignment group which has the integration referenced on it. In order to test then, we’ll need to add our integration to the Unifi Integrations field on the assignment group that triggers our incidents. We will create a new assignment group as an example.

    In native ServiceNow, navigate to User Administration > Groups. Click New.

    The Group fields to be configured are as follows:

    Field
    Description
    Value

    *Unifi Integrations: This field may need to be created/added to the Group [sys_user_group] record.

    Your Group record should look like this:

    Submit the record.

    Create an Incident

    In native ServiceNow, navigate to Incident > Create New.

    The Incident fields to configure are as follows:

    Field
    Description
    Value

    *Note: We have chosen these fields as these were the ones we mapped when creating our Field records for the CreateIncident Message. Your choices may differ depending on which Field records you created.

    Your Incident form should look like this:

    Right-click & Save.

    Note the values entered (including State), so that you can check them against the mapped fields on the corresponding record in the instance being integrated to.

    You should see an Info Message, confirming the CreateIncident Message is being sent to your Integration:

    When you scroll down to the 'Unifi Integrations' related list (you may have to configure the related lists to add it to your Incident form), notice:

    A Bond has been created. The External reference is populated & the State has changed to 'Open'. Click the Bond Number link to open the Bond record.

    Note: You may need to refresh the list by clicking the Bonds breadcrumb to view the changes.

    View the Bond

    Your Bond record should look like this:

    Bond details:

    • Integration: < Your Integration >

    • Connection: < Your Connection >

    • Table: 'Incident [incident]'

    • Document: < Your Incident >

    Transaction:

    • Message ID: Internal system's unique Transaction identifier

    • External Message ID: External system's unique Transaction identifier

    • Message: 'Createincident'

    • Direction: 'Outbound'

    You are able to view the logs in the 'Unifi Activity Logs' related list.

    Transaction process next queued: Logs from checking whether there are any other transactions queued and processing those.

    Transaction receive message: Logs from processing the inbound asynchronous receipt.

    Transaction sending: Logs from taking the Stage data, building the Request record & sending the Request to the integrated system.

    Business rule: < Your Trigger >: Logs from the Business Rule that triggered Unifi.

    View the Transaction

    Click through to the Transaction record from the related list on the Bond.

    Your Transaction record should look like this:

    Transaction details:

    • Table: 'Incident [incident]'

    • Document: < Your Incident >

    • Integration: < Your Integration >

    • Connection: < Your Connection >

    Errors:

    • Error: (If there was a transactional error the Transaction state would show as 'Error' and the details would be captured here).

    • Process error: (If there was a process error the Process state would show as 'Rejected' and the details would be captured here)

    Stages:

    • Direction: 'Outbound' & 'Inbound'

    • Message: 'CreateIncident' & 'CreateIncidentReceipt'

    • Internal reference: < ServiceNow ticket reference > (Same as 'Document')

    • External reference: < External system's ticket reference >

    View the Stage

    Click through to the Outbound Stage record from the related list on the Transaction. (If you wish, you could also do the same for the Inbound Stage record.)

    Check the values in the fields match what you expect.

    Your Stage record should look like this:

    Stage details:

    • Direction: 'Outbound'

    • Internal reference: < ServiceNow ticket reference >

    • Snapshot: < Snapshot record reference >

    • Message: 'CreateIncident'

    Mapped Staged Data fields (yours may differ depending on which Field records you created):

    • caller_id: < Your caller.id >

    • short_description: < Your Short description >

    • state: '1'

    View the HTTP Request

    Click through to the outbound HTTP Request record from the related list on the Transaction. (If you wish, you could also do the same for the Inbound HTTP Request.)

    This is where you will find details of the data that was transported between the systems being integrated. (These records are extremely useful for developing and debugging integrations because of the immediate availability and contextual relevance to the integration you are developing.)

    Your HTTP Request record should look like this:

    HTTP Request details:

    • Integration: < Your Integration >

    • Connection: < Your Connection >

    • Transaction: < Your Transaction >

    • Message: 'CreateIncident'

    Response details:

    • Status code: '200'

    • Response headers: < The header of the response being received >

    • Response payload: < The payload of the response being received >

    Compare with the External System's Incident

    Navigate to the corresponding Incident in the external system.

    Check the values in the fields match those you noted when you saved the Incident in the internal system.

    Your external system's Incident record should look like this (depending on the system you're integrating with, your record may look different; the important matter is that the values match):

    Caller: < Your Caller >

    State: < Your State >

    Short description: < Your Short description >

    Activities: < Note showing activity on the Incident > (Opened by < your.external.system.user > configured in the Connection)

    Bond: Note that a bond exists in the external system in an 'Open' state and the 'Internal reference' & 'External reference' are reversed

    If completing this test after having integrated with the external system (as opposed to connecting to your own instance), it would be good to test the CreateIncident Message in both directions.

    We are now ready to move to the Update Scenario.

    CreateIncidentResponse Fields

    We will utilise the Field & Field Map records to configure the Message Scripts for the CreateIncidentResponse Message.

    Copy Field Maps

    It is worth copying all relevant OOTB Field Maps as are necessary for your integration before using any of them in your Field Records - thereby mitigating the risk of any potential issues with future upgrades.

    The Field Map we shall use for our CreateIncidentResponse Field record is:

    • Source Reference

    To copy the Source Reference Field Map, navigate to the 'Field Maps' icon.

    Click on the ellipsis to the right of the Source Reference Field Map & click Copy.

    Copy Field Map Modal

    The fields to edit for the Copy Field Map modal are as follows:

    Field
    Description
    Value

    *Name: We have chosen to prefix the existing Field Map Name with the initials of our Integration (you are free to choose any appropriate means of identifying/differentiating your copy).

    Your Copy Field Map modal should look like this:

    Integration should be automatically populated.

    Click Copy.

    You will be redirected to the Details page of the newly created Field Map.

    Field: result.sys_id

    In Unifi Integration Designer, from the CreateIncidentResponse page, navigate to Message > Fields. Click New.

    The fields to be configured for the sys_id New Field modal are as follows:

    Field
    Description
    Value

    *These fields are automatically defaulted to true, or automatically populated.

    **Field map: Value may vary. Choose the copy Field Map you created for your Integration.

    Property: We are setting 'sys_id' as the property because that is what is required by the table API. If it were possible, it would better to use something more meaningful, like the Number of the ticket integrated with, as this aids in debugging.

    The 'result.sys_id' New Field modal should look like this:

    Submit the record.

    You will be redirected back to the Fields page of the CreateIncidentResponse Message.

    Build

    Now that we’ve configured the Field records for the CreateIncidentResponse message, we are ready to build our message scripts.

    The following Field record should now be in place for your CreateIncidentResponse messsage:

    Feature Alert: In the picture above you will notice that a 'Build Integration' button has appeared in the banner at the top of the page. Whenever a change is made to a Field record that is associated to a Message (whether that is being created, updated, or deleted) the button will be available and acts as a visual reminder that changes have been made and Message Script(s) need to be built. We will talk more about this feature in the page.

    Navigate to Advanced > Script Editor.

    When you first open the Script Editor, you will see the following:

    Having visibility of your message scripts in the one pane makes scripting so much more efficient.

    Click on Build Message.

    You will see the 'Message build successful' Info Message.

    Your Script Editor fields should now look like this:

    You can click View to adjust the layout and change the view to show various combinations of, or individual script fields.

    Message Scripts

    The newly auto-generated code will appear between a Begin & End Comment immediately prior to any code that may already be there (pre-existing code will be retained).

    We will now examine our new, auto-generated Message Script.

    Payload to Stage:

    Both the stage & bond external reference are being set to the sys id only because we are integrating with the table API and that's what it requires. If possible, it is better to use something more meaningful, like the Number of the ticket integrated with, as this aids in debugging.

    Once you have finished examining the code, click 'Close' to navigate back to the Fields page of the CreateIncidentResponse Message.

    Next, we will configure the CreateIncident Message.

    Unifi 2.0 Release Notes

    Here you will find details of what's changed in this release, including new features & improvements, deprecated features and general fixes.

    Introduction

    Welcome to the release notes for Unifi - Version 2.0. Please have a read through to see new features and fixes that have been added.

    Test CreateIncident

    We will test our CreateIncident Message.

    Create an Incident

    Navigate to Incident > Create New.

    The Incident fields to configure are as follows:

    Field
    Description
    Value
    current.assignment_group && String(current.assignment_group.u_unifi_integrations).indexOf(message.integration) != -1
    var answer = {};
    
    answer.getExternalMessageID = function (payload, request) {
      return '' + (payload.message.source_id || '');
    };
    
    answer.getInternalMessageID = function (payload, request) {
      return '' + (payload.message.target_id || '');
    };
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    (New auto-generated code will appear here)
    
    //===== [ws] End Unifi Auto Generated Code =====//
    
    (Old pre-existing code will appear here)

    The Field Map this Field record is linked with.

    'IG - Message Header'**

    Map to field*

    Use this Field record to represent a field on a source/target table.

    <false>

    Path

    Where in the payload the data will be placed.

    'message'

    Property

    The property in the payload the data will be written to.

    'message_header'

    Inbound*

    Set to true to use for inbound Messages.

    <true>

    Outbound*

    Set to true to use for outbound Messages.

    <true>

    The Field Map this Field record is linked with.

    'IG - Receipt Status'**

    Map to field*

    Use this Field record to represent a field on a source/target table.

    <false>

    Path

    Where in the payload the data will be placed.

    'message'

    Property

    The property in the payload the data will be written to.

    'transaction_details'

    Inbound*

    Set to true to use for inbound Messages.

    <true>

    Outbound*

    Set to true to use for outbound Messages.

    <true>

    Name

    The name of your field map. (If left unedited, it will append the word 'Copy' to the existing name.)

    <Your Name>

    Integration*

    The integration this field map is associated with.

    <Your Integration>

    Message*

    The Message this Field record is linked with.

    'CreateIncidentReceipt'

    Description

    Describe what this field is for and any specific details that might help you in future.

    'The protocol message header'

    Active*

    Set to true to use this Field record for processing.

    <true>

    Message*

    The Message this Field record is linked with.

    'CreateIncidentReceipt'

    Description

    Describe what this field is for and any specific details that might help you in future.

    'Used to send and receive transaction process errors'

    Active*

    Set to true to use this Field record for processing.

    <true>

    Build Integration Level

    Field map

    Field map

    Note: We have included the /table/incident element of the endpoint url because we used the truncated url in the Connection when following the Outbound Incident Guide. If you have used the full url there, then this element can be excluded here.

    (We have also chosen to limit the number of records returned to 10.)

    params: The params object is passed through to the subsequent scripts (and on to further Pollers, if required).

    processInbound()
    : Having the 'poll_helper.processInbound(opts);' inside the loop means that an update message will be generated for each updated ticket.

    Payload object: We have chosen to structure the payload object (var pl) as we have. There is no obligation to keep the same structure. Yours can be defined to suit your requirements.

    Payload options: In the payload options (var opts), we have commented out //message_name: 'UpdateIncidentInbound',. This is because we have chosen to include the message name in the structure of the payload object.

    Message name: Unifi needs to know the message name in order to know how to process the inbound request. We can either set it in the payload (as we have), or in the options (as per the commented out line).

    Name

    The name of the Processor.

    <Your Name>

    Setup script

    The script to setup the Poll Request record.

    Update the code in the Setup script field so that it looks like the code below

    Request script

    The script that executes the request.

    Update the code in the Request script field so that it looks like the code below

    Response script

    The script that processes the response to the request.

    Update the code in the Response script field so that it looks like the code below

    A brief description of the incident.

    <Your Short description>

    State: 'Open' (Message exchange is available)

  • Status: 'OK' (All transactions have completed)

  • Internal reference: < ServiceNow ticket reference > (Same as 'Document')

  • External reference: < External system's ticket reference >

  • Transaction state: 'Complete' (The data has been successfully transported)

  • Process state: 'Accepted' (The transaction was accepted as within the scope of the business logic that's in place)

  • Bond: < Your Bond >

  • Message: 'CreateIncident'

  • Direction: 'Outbound'

  • Transaction state: 'Complete' (The data has been successfully transported)

  • Process state: 'Accepted' (The transaction was accepted as within the scope of the business logic that's in place)

  • Transaction: < Your Transaction >

  • Integration: < Your Integration >

  • Direction: 'Outbound'

  • Request state: 'OK' (There are no errors with the HTTP Request.)

  • Attempt number: < Number of HTTP Request attempts > (Failed requests are retried up to the maximum attempts number as configured on the Integration.)

  • Endpoint URL: < The external system’s access URL >

  • Action Method: 'POST'

  • Request headers: < The header of the request being sent >

  • Request payload: < The payload of the request being sent >

  • Name

    Descriptive name, e.g. DBAs, Network, etc.

    <Your Name>

    Type

    Types of this group.

    'itil', 'eBonding'

    Unifi Integrations*

    Glide List referencing the Integration [x_snd_eb_integration] table.

    <Your Integration>

    Caller*

    Person who reported or is affected by this incident.

    <Your Caller>

    State*

    The Incident lifecycle state.

    'New' - Default (Automatically populated)

    Assignment group

    The group which triggers the Integration.

    <Your Group>

    Short description*

    The Field Map this Field record is linked with.

    'PI - Source Reference'**

    Map to field*

    Use this Field record to represent a field on a source/target table.

    <false>

    Path

    Where in the payload the data will be placed.

    'result'

    Property

    The property in the payload the data will be written to.

    'sys_id'

    Inbound*

    Set to true to use for inbound Messages.

    <true>

    Outbound

    Set to true to use for outbound Messages.

    <false>

    Name*

    The name of your field map. (If left unedited, it will append the word 'Copy' to the existing name.)

    <Your Name>

    Message*

    The Message this Field record is linked with.

    'CreateIncidentResponse'

    Description

    Describe what this field is for and any specific details that might help you in future.

    'Extract returned sys_id & store in stage.external_reference'

    Active*

    Set to true to use this Field record for processing.

    <true>

    Build Integration Level

    Field map

    Upgrade Notice

    Please note that this is a major release which may not be entirely compatible with your existing integrations. While we do everything to make sure you won't have to fix your integrations when upgrading, we strongly encourage all our customers to perform full end-to-end tests of their integrations before upgrading Unifi in Production.

    Feedback and Reviews

    We really appreciate feedback on what we're doing - whether it's right or wrong! We take feedback very seriously, so if you feel you'd give us anything less than a 5 star rating, we'd love to hear from you so we can find out what we need to do to improve!

    If you would rate us 5 stars, and haven't left a review on the ServiceNow Store yet, we'd really appreciate you heading over there to leave us your feedback. It only takes a few minutes and really does help us a lot. Go on, you know you want to leave a 5-star review on the Store!

    Release Overview

    The following items are the major talking points for this release.

    Service Portal Interface

    Now that Unifi has a solid and proven foundation for building and running integrations, we have built a new Service Portal interface to make it simpler and easier than ever to build an integration. This new interface has been developed from the ground up to be scalable, intuitive and capable of supporting advanced features.

    Unifi version 2.0 marks the first release of the portal, with the ability to build Processes, Integrations and Messages, but we will be adding to it in future releases.

    Also of importance is the new Dashboard which gives a clear overview of what is happening in your instance right now. A live view of the last 20 transactions to be processed and the bonds that have been worked on today really helps you to see what's going on.

    Madrid Ready

    Unifi is tested to be compatible with all current ServiceNow releases: Kingston, London and Madrid.

    Queue Management

    A lot of effort has been put into upgrading the queue management options that are available. Things like replaying Transactions and Requests now use brand new technology which allows them to be much more robust and as close to a clone of the original as possible. It's also now possible to repair all the outstanding Transactions directly from the Integration with the click of a button.

    Field Mapping

    This release introduces the concept of Field Maps. These allow you to configure your messages with Fields and reusable Field Maps which then automatically generate all your scripts, so you don't need to write any code.

    Field Maps have no negative performance impact - in fact, they might be slightly faster - because all the logic to be executed is copied into the Message Scripts when the integration is built. Any existing code in your Message Scripts is retained so you always have the option of doing things manually.

    Activity Logs

    Anyone that's used Unifi knows that a major benefit of building integrations in Unifi is the logging and profiling capability. We've now expanded this capability to make it more easily and widely accessible, so even background processes have complex logs available to see.

    With the introduction of the Activity Log table, this becomes your first port of call when trying to looking for issues.

    Features

    [UN-124] - Add description to connection variables to allow explanation of their use

    It is now possible to add a description to the Connection Variable (up to 4000 characters) so notes or explanations can be stored.

    [UN-127] - Replay All errored transactions

    The Integration record now features a 'Repair' button which will automatically batch process all errored transactions. A background process is executed and with status being displayed through a progress bar.

    [UN-152] - Sending attachments

    • This is a breaking change

    Some improvements have been made to the attachment sending.

    Two new fields are now available on Message:

    • Send attachments [true/false]

    • Send attachments max [Integer - default 1]

    In addition to these new fields, the method AttachmentHandler#getAttachmentsToSend(message, transaction) now takes two arguments where previously it took one. It is this method modification that may break some existing installations that manually call this method (e.g. in a UI Macro or Script Include). Please check usage of this before upgrading.

    [UN-170] - Add reprocess/resend to HTTP requests

    Replaying an HTTP Request now works properly for both inbound and outbound requests. Previously, complexities with the process prevented this from being fully implemented.

    [UN-178] - Activity Log

    Unifi has a very smart profiling and logging tool called console which allows detailed logs to be attached to contextually relevant records. While this has been incredibly useful it fell short in two areas. The first is that it would add lots of attachments to the database over time, and the second is that it wasn't easily possible to log non-record generating processes, such as background clean-up jobs.

    This update addresses both of these issues through the addition of a new table called Activity Log. The table means that attachments are no longer needed because all transactions are automatically logged. It also means that background processes can be tracked because they do not need a record to belong to. The logs are stored in the table and rendered without needing to download or open an attachment.

    Activity Logs will also track (where possible) the integration they belong to and the contextual record it is about. Related lists have been added in places like Bond, Transaction and Request so that Activity Logs can be easily referenced.

    By default, Activity Logs are stored for 7 days.

    [UN-210] - Dynamic Stage object so we don’t need to extend

    Traditionally, local staging tables have been required for each process to capture data at a point in time. This data would then be available to process accurately, but it was also providing a log for future reference. The problem was a new Stage table would need to be created before the Process could be created. Then, any time a data point was needed, a new field would have to be added to the custom stage table.

    Dynamic Stage does away with the need for custom stages per process and removes the need to create fields by storing data dynamically as you use it. New Processes only need to reference the Unifi Stage table, and Dynamic Stage will take care of everything else.

    • This change is fully backwards compatible with the traditional one stage table per process.

    Start using Dynamic Stage in your Message Scripts by assigning to and from the $stage object instead of stage. It is possible to add not only strings to $stage, but also complex objects and arrays. Just make sure that things like field objects are coerced to strings (or use getValue()) otherwise you'll see something like [object Object] instead of the string value you expect.

    • Custom stage tables will work with Dynamic Stage, but you will need to add the Stage Data Render formatter to the form layout.

    [UN-266] - Clone cleanup should disable all non-instance specific connections

    By default, the Integrations Enabled system property (x_snd_eb.active) is disabled when an instance is cloned. This update also disables all Connections to prevent accidental connection to the wrong endpoint.

    [UN-268] - Add automatic domain setting for Bond and Transaction stack

    The domain field is now automatically set for transactional records using the following logic:

    • Bond domain comes from Target domain (e.g. Incident).

    • Transaction domain comes from Bond domain.

    • Stage domain comes from Transaction domain.

    • HTTP Request domain comes from Transaction domain.

    • Bonded Attachment domain comes from Bond domain.

    [UN-269] - Modify response action override message

    The response action error message has been modified to be more descriptive.

    e.g. Socket timeout handled by response action "Default 0 Script Errors"

    [UN-272] - Add indexes

    All tables have been indexed according to the data and queries being used. This should improve performance, especially when loading/searching lists.

    [UN-276] - Allow multiple ignore and ignore from right click (Transaction)

    Transactions can now be ignored from the list context menu and by a list button.

    [UN-299] - Add description fields to configuration records

    Add description field to all configuration type records.

    • Process

    • Integration

    • Message

    • Response Action

    • Poller

    • Poll Processor

    [UN-304] - Break out GlideRecord#operation() to Model method

    It is now possible to check the record operation from the Unifi Model class.

    [UN-307] - Add link to app log

    The System Log module has been updated to point to the scoped log rather than the system log.

    [UN-309] - Update sync overdue transaction job BR on integration

    The business rule that generates the overdue transaction jobs for each integration is now wrapped so it appears in the Activity Log.

    [UN-317] - Refine Message.processOutbound

    The Message.processOutbound() method has been improved to be more efficient and provide better visibility of processing.

    [UN-318] - Add method to console for executing a function

    A new method ws_console.execute() wraps an inline function in console logic and prevents errors from leaking (as errors are captured by the Activity Log and automatically put in gs.error()).

    It should be used in all business rules and scheduled jobs, and anywhere else a script runs in Unifi.

    [UN-320] - Add cleanup job for pollers

    A scheduled job has been added run every hour and uses a new cleanup field on the Poller record to determine how many days to keep Poll Requests for.

    [UN-326] - Poll Requests module should filter by created on today

    Viewing Poll Requests from the application navigator will now filter to show only those created today.

    [UN-340] - Sync responses do not have automatic access to internal reference

    When an inbound sync request was made, the internal stage did not get auto populated with the internal_reference field for use by the response message (e.g. to give the Incident number that was created). Unifi now checks if it has a value and if not, auto-populates it.

    [UN-352] - Copy message

    A Copy action is now available on the Message form which copies the Message and its Scripts.

    [UN-353] - Copy connection

    A Copy action is now available on the Connection form which copies the Connection and its Variables.

    [UN-354] - Add support for streaming an attachment over REST

    Unifi now supports sending a whole attachment as the request instead of having it sent as part of the body. This method streams the attachment rather than embedding it which means attachments larger than the string limit (5MB) can now be sent.

    To use this feature, simply set the payload of the request to be sys_attachment:<sys_id> and Unifi will automatically sent the specified attachment.

    [UN-355] - Improve environment objects for identify_message script

    The Identify message script on the Integration is now provided with integration and connection GlideRecord objects. The objects now available are payload, headers, integration, connection and variables.

    [UN-361] - Add link parsing to console

    Console logs now replace text in the format table.sys_id with a link to the record in HTML format. If the record is found then the table label and record display value are also shown. This allows users to easily open records used during the process.

    [UN-363] - Add link to broken transactions on integration

    A View broken transactions related link is now available on the integration to easily view all transactions that are errored or timed out.

    [UN-366] - Process stage table should be default to x_snd_eb_stage.

    With the introduction of Dynamic Stage, new Process records default to use the Unifi Stage table.

    UN-367] - Allow request error to show in Transaction instead of 'Final retry failed.'

    The "Final retry failed" error shown in transactions was not helpful and has now been replaced with the error generated by the latest request that failed.

    [UN-368] - If transaction is ignored, prevent in flight request from sending

    Ignoring a transaction midway through a request being processed would not prevent the request from being sent. Requests now check if the transaction is cancelled just before sending and will automatically cancel themselves if the transaction is cancelled.

    [UN-374] - Remove irrelevant debug statements

    Irrelevant debug statements have been tidied up so they either do not show or only show when trace logging is enabled.

    [UN-376] - Replace snd_console with ws_console

    When Unifi was first created, snd_console was also created to be used for profiling and debugging. With the company transitioning from the old name SN Developer to Whitespace Studios, we have replaced snd_console with ws_console. You might even see ws_console become available for your own apps in future!

    • This change is backwards compatible. snd_console still exists in Unifi so any code in your instance that uses this method will still work.

    [UN-377] - Message path should allow ${} variable format

    The Path on Message would only allow inline scripts using the {} format, but this is inconsistent with the rest of ServiceNow so it now accepts ${} or {} to define inline scripts. e.g.

    /upload?id={variables.uid}

    or

    /upload?id=${variables.uid}

    Fixes

    [UN-150] - Replay request/transaction needs to run as the original creator.

    When replaying requests or transactions, the replay would run as the logged in user instead of the original user. It now runs as the original user to allow functionality that relies on the identity of the user to run correctly.

    [UN-228] - Overhaul pending transactions counter

    It is possible for Pending transactions counter on the Bond record to get out of sync. Pending transactions are now calculated differently to try to prevent this from happening.

    [UN-257] - Message processOutbound is processing messages for inactive integrations

    Integrations that were inactive were still being processed for messages to send when an insert/update was made to a record. This fix prevents inactive integrations from having their messages processed.

    [UN-260] - Payload object is not automatically converted to JSON for Stage to Request

    Integrations using JSON payloads had to manually stringify the payload object in the Stage to Request script. You can now just set the global variable payload to your payload object and it will automatically convert it to JSON.

    [UN-274] - Poller doesn't check for integration off property

    Pollers would still run even if the integration was disabled. This fix means Pollers will not run if the integration is disabled.

    [UN-275] - RestHelper wraps with 'result'

    • This is a breaking change

    When using a scripted REST API with the Unifi RestHelper, ServiceNow automatically wrap any non-streamed response in a result object which makes it difficult to integrate with other systems that have specific response requirements. This fix uses the streaming method to send the response payload which means the message controls the whole response and no result wrapper is added.

    [UN-283] - ITIL users cannot see the message names when viewing bond/transactions.

    Security rules have been created to allow ITIL users to see the names of the messages that have been used when viewing from transactional data such as bonds and transactions.

    [UN-285] - Attachment added can only be true on one message

    Previously, only one message per integration could be configured with the 'Attachment added' trigger condition. This update allows one message per table per integration instead.

    [UN-289] - Attachment business rule does not run on update

    Some processes will update attachment records and these updates were not captured by Unifi. This fix addresses that so updates to attachments will check integrations.

    [UN-290] - REST XML does not work

    This fix allows XML to work properly with scripted REST API's using the Unifi RestHelper.

    [UN-303] - When getting the bond need to order by created at ascending

    This fix addresses issues finding the correct bond for integrations that can create more than one bond per ticket and see transactions spread between different (incorrect) bonds.

    [UN-306] - ITIL users cannot see the integration names when viewing bond/transactions.

    Security rules have been created to allow ITIL users to see the names of the integrations that have been used when viewing from transactional data such as bonds and transactions.

    [UN-308] - Data Store checkOrphans method causing errors for empty table name

    The scheduled orphan record checker for Data Stores would cause errors when the record that owner the data store was deleted. This would cause the getRefRecord() method to fail.

    [UN-314] - Receiving errors in processing poll requests due to string being too big

    Pollers that return strings that are outside the string size limit (usually > 5MB for scoped applications) will generate an exception. A try/catch has been added to help avoid the exception and allow the script to keep running and gracefully exit.

    [UN-319] - Repeating an inbound create request causes multiple bonds

    When replaying an inbound create request, it would run as the user who replayed the request. Unifi saw this as a new create as it wasn't created by the Integration User. This has been fixed by replaying using a scheduled job that runs as the user that created the original request.

    [UN-328] - Outbound attachment sending loop

    Sending an outbound attachment that is rejected could result in the attachment being picked up with the next transaction which could also fail, thus causing an infinite loop. Bonded attachments are now only picked up in the Ready state where previously it was Ready or Rejected.

    [UN-334] - Sync integration doesn't update bond external reference from stage, but async does.

    The External reference on the Bond had to be written to manually for a synchronous message, where it happened automatically for an asynchronous message. It now works automatically for both types of message.

    [UN-343] - Multi-table attachment processing

    If an integration belonged to a process which pointed to a different table to the attachment sending message, the attachment listener on sys_attachment would not find the message. This is fixed with an option being passable to Message.processOutbound so the table hierarchy will be searched.

    [UN-348] - Affected CI logic updating incident is causing double updates

    A caching issue meant it was possible for a work note to be added to the Incident whenever a CI was added/removed from the form. This has been fixed with a more intelligent mechanism of referencing the target record.

    [UN-350] - Unifi message name header needs to be case insensitive

    Message identification can be done by the request passing a specific header that Unifi recognises rather than adding the message name to the payload. However, headers in ServiceNow Scripted REST are always converted to lowercase which meant the Unifi header name, which used uppercase characters, did not work. This has been fixed by using case-insensitive matching on the Unifi message name header.

    [UN-351] - Inbound user should not be mandatory

    The Inbound user field on Connection is no longer mandatory. This is important for outbound-only integrations which do not require or permit any inbound requests.

    [UN-356] - Add condition to the sys_attachment Unifi trigger

    There were scenarios where Unifi log attachments could be sent by Unifi via the integration. Additional conditions on the sys_attachment business rule now prevent this from happening.

    [UN-375] - Request URL's have duplicate host

    If an integration required two endpoints (such as a ServiceNow Table API integration which also uses the Attachment API), the secondary host defined in a connection variable would not replace the host defined on the connection. The resulting URL had the connection endpoint followed by the variable endpoint.

    e.g. Connection URL: https://test.service-now.com/api/now/table Connection Variable value (attachment_api): https://test.service-now.com/api/now/attachment Message path: {variables.attachment_api} Resulting URL: https://test.service-now.com/api/now/tablehttps://test.service-now.com/api/now/attachment

    The workaround was to put both hosts in variables, but it has now been fixed so that the message path is pre-processed first and then the connection path is prepended if the resulting URL does not contain a schema (i.e. ://).

    [UN-379] - Inbound attachment does not trigger outbound attachments for other bonds

    In the multi-bond scenario where one ticket is bonded to many integrations, an inbound attachment will automatically create Bonded Attachment records for all the other Bonds. The problem was it didn't trigger the outbound message processing so those attachments didn't get sent automatically. This is now fixed so the outbound messages are processed when the bonded attachments are created.

    Caller*

    Person who reported or is affected by this incident.

    <Your Caller>

    State*

    The Incident lifecycle state.

    'New' - Default (Automatically populated)

    Short description*

    A brief description of the incident.

    <Your Short description>

    *Note: We have chosen these fields as these were the ones we mapped when creating our Field records for the CreateIncident Message. Your choices may differ depending on which Field records you created.

    Your Incident form should look like this:

    Right-click & Save.

    Note the values entered (including State & Priority), so that you can check them against the mapped fields on the corresponding record in the instance being integrated to.

    You should see an Info Message, confirming the CreateIncident Message is being sent to your Integration:

    You should also see a note in the Activities stream:

    When you scroll down to the 'Unifi Integrations' related list (you may have to configure the related lists to add it to your Incident form), notice:

    A Bond has been created. The State remains 'Pending' until the list is refreshed.

    Refresh the list by clicking Bonds.

    You should see the External reference populated & the State changed to 'Open':

    We are using a sys_id for the External reference in our example because we are integrating with the table API. If possible, it is better to use something more meaningful, like the Number of the ticket integrated with, as this aids in debugging.

    Click the Bond Number link to open the Bond record.

    View the Bond

    Your Bond record should look like this:

    Bond details:

    • Integration: < Your Integration >

    • Connection: < Your Connection >

    • Table: 'Incident [incident]'

    • Document: < Your Incident >

    • State: 'Open' (Message exchange is available)

    • Status: 'OK' (All transactions have completed)

    • Internal reference: < ServiceNow ticket reference > (Same as 'Document')

    • External reference: < External system's ticket reference >

    Transaction:

    • Message: 'Createincident'

    • Direction: 'Outbound'

    • Transaction state: 'Complete' (The data has been successfully transported)

    • Process state: 'Accepted' (The transaction was accepted as within the scope of the business logic that's in place)

    You are able to view the logs in the 'Unifi Activity Logs' related list.

    Transaction process next queued: Logs from checking whether there are any other transactions queued and processing those.

    Transaction sending: Logs from taking the Stage data, building the Request record & sending the Request to the integrated system.

    Business rule: < Your Trigger >: Logs from the Business Rule that triggers Unifi.

    View the Transaction

    Click through to the Transaction record from the related list on the Bond.

    Your Transaction record should look like this:

    Transaction details:

    • Table: 'Incident [incident]'

    • Document: < Your Incident >

    • Integration: < Your Integration >

    • Connection: < Your Connection >

    • Bond: < Your Bond >

    • Message: 'CreateIncident'

    • Direction: 'Outbound'

    • Transaction state: 'Complete' (The data has been successfully transported)

    • Process state: 'Accepted' (The transaction was accepted as within the scope of the business logic that's in place)

    Errors:

    • Error: (If there was a transactional error the Transaction state would show as 'Error' and the details would be captured here).

    • Process error: (If there was a process error the Process state would show as 'Rejected' and the details would be captured here)

    Stage:

    • Direction: 'Outbound'

    • Message: 'CreateIncident'

    • Internal reference: < ServiceNow ticket reference > (Same as 'Document')

    • External reference: < External system's ticket reference >

    View the Stage

    Click through to the Stage record from the related list on the Transaction.

    Check the values in the fields match what you expect.

    Your Stage record should look like this:

    Stage details:

    • Direction: 'Outbound'

    • External reference: < External system's ticket reference >

    • Internal reference: < ServiceNow ticket reference >

    • Snapshot: < Snapshot record reference >

    • Message: 'CreateIncident'

    • Transaction: < Your Transaction >

    • Integration: < Your Integration >

    Mapped Staged Data fields (yours may differ depending on which Field records you created):

    • Caller ID: < Your caller.id >

    • Short description: < Your Short description >

    • State: '1'

    View the HTTP Request

    Click through to the HTTP Request record from the related list on the Transaction.

    This is where you will find details of the data that was transported between the systems being integrated. (These records are extremely useful for developing and debugging integrations because of the immediate availability and contextual relevance to the integration you are developing.)

    Your HTTP Request record should look like this:

    HTTP Request details:

    • Integration: < Your Integration >

    • Connection: < Your Connection >

    • Transaction: < Your Transaction >

    • Message: 'CreateIncident'

    • Direction: 'Outbound'

    • Request state: 'OK' (There are no errors with the HTTP Request.)

    • Attempt number: < Number of HTTP Request attempts > (Failed requests are retried up to the maximum attempts number as configured on the Integration.)

    • Endpoint URL: < The external system’s access URL >

    • Action Method: 'POST'

    • Request headers: < The header of the request being sent >

    • Request payload: < The payload of the request being sent >

    Response details:

    • Status code: '200'

    • Response headers: < The header of the response being received >

    • Response payload: < The payload of the response being received >

    Compare with the External System's Incident

    Navigate to the corresponding Incident in the external system.

    Check the values in the fields match those you noted when you saved the Incident in the internal system.

    Your external system's Incident record should look like this (depending on the system you're integrating with, your record may look different; the important matter is that the values match):

    Caller: < Your Caller >

    State: < Your State >

    Short description: < Your Short description >

    Activities: < Note showing activity on the Incident > (Opened by < your.external.system.user > configured in the Connection)

    We are now ready to move on to the Update Scenario.

    Poll Processor

    The Poll Processor contains the logic that will be applied when polling a remote system for data.

    The Poll Processor is a configuration record which contains the logic that will be applied when polling a remote system for data. There are three main scripts which are used to setup, execute and process the Poll Requests. The scripts given here are examples of how you might configure your Poll. The details of yours may differ depending on your requirements.

    New Poll Processor

    In Unifi Integration Designer, click the 'Poll Processors' icon & then New.

    The fields to be configured for the New Poll Processor modal are as follows:

    Field
    Description
    Value

    Your New Poll Processor modal should look like this:

    Submit and view to further configure the Poll Processor.

    Setup Script

    The Setup Script is the first script to run (it runs at the point in time the Poll Request is created). It is used to build the environment for the poll and define what it will do. We will use it to setup the URL that will be called.

    Navigate to Scripts > Setup Script.

    The Setup script field is to be configured as follows:

    Field
    Description
    Value

    The code in the Setup script field should look like this:

    Setup script: The parameters for which data to return are contained in the endpoint url.

    fields: The table API will return all the data by default, so we choose to deliberately limit what is returned to the fields listed in this variable. Instead of hardcoding them into the script, we have chosen to substitute Connection Variables containing those values.

    query: Instead of querying all the records on the remote instance, we deliberately limit the query to those active records where the correlation id is empty (i.e. it's not bonded), that have been assigned to a specific Assignment group and haven't been updated by the Authentication user (i.e. not created by our system), and that were also updated since either since the last update time (if one exists), or in the last 30 minutes.

    Endpoint URL: The value used in the poll_request.endpoint_url was initially generated using the ServiceNow REST API Explorer, substituting variables in for the uri query and fields. This value is appended to the existing endpoint url in the active connection before being added to the Poll Request.

    Your Setup Script form should look like this:

    Navigate to Request Script.

    Request Script

    The Request Script is used to reach into the remote system and execute the request. We will use the ServiceNow RESTMessageV2() web service to make a REST call to the URL defined in the Setup Script.

    The Request script field is to be configured as follows:

    Field
    Description
    Value

    The code in the Request script field should look like this:

    Request script: This script uses the ServiceNow RESTMessageV2() web service to make a REST call to the endpoint url created in the Setup script. It returns the body of the request as the answer which it passes to the Response script

    Your Request Script form should look like this:

    Navigate to Response Script.

    Response Script

    The Response Script is used to process the information returned from the remote system. We will pass this data to Unifi to process.

    The Response script field is to be configured as follows:

    Field
    Description
    Value

    The code in the Response script field should look like this:

    Response script: This script parses the response into a body object to contain the result, (returning if it doesn't contain anything). It then sets up some objects to help us (including the essential PollHelper() function which we initialise from the poll_request). After that it loops through each of the returned tickets; for each it sets up a payload object and the options for submitting it to Unifi before calling the processInbound() method. It then checks whether the ticket was updated later than the last update time; if so, it sets and stores the last update time as that 'sys_updated_on' value (this 'last_update_time' is what the Setup script checks against when defining what the Poll will do).

    After looping through all the records, the results are logged to the Response status field of the Poll Request.

    Essential code: the following lines of code must be included in the Response script to send the data to Unifi

    Your Response Script form should look like this:

    Save the Poll Processor.

    Now let's move on and configure the Poller.

    UpdateIncident Fields

    We will utilise the Field & Field Map records to configure the Message Scripts for the UpdateIncident Message.

    Field: incident.short_description

    The 'incident.short_desccription' (Integration level) Field record should already be in place (i.e. with Active set to false). Creating the Message level counterpart is now easier than ever.

    ResolveIncident Fields

    We will utilise the Field & Field Map records to configure the Message Scripts for the ResolveIncident Message.

    The 'message_header', 'incident.comments', 'incident.work_notes' and 'incident.short_description' Field records are already be in place because they were also copied when we copied the Message. We can choose to include, or exclude as many of those and the Integration level ones that are available depending on our requirements (by either activating or deactivating the relevant Fields). We have chosen not to include 'incident.short_description' in our mappings, so we'll delete that.

    In Unifi Integration Designer, from the ResolveIncident Message, navigate to Message > Fields.

    Click on the ellipsis to the right of the incident.short_description Field & click Delete.

    Confirm Delete.

    CreateIncident Message

    The CreateIncident Message will create a ticket on the target table of the integrated system.

    After clicking the 'Messages' icon, you will see the following screen (note: the previously configured message is visible in the list):

    Click New.

    New Message Modal

    The fields to be configured for the CreateIncident New Message modal are as follows:

    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    (New auto-generated code will appear here)
    
    //===== [ws] End Unifi Auto Generated Code =====//
    
    (Old pre-existing code will appear here)
    // Configure the new Poll Request record
    (function(poll_request, poller, params) {
    
        var gdt = new GlideDateTime();
        gdt.addSeconds(-1800);
    
        var connection = poller.getIntegration().getActiveConnection();
        var user = connection.getBasicAuthUser();
        var time = connection.getData('last_update_time', (gdt + ''));
    
        var fields = 'sys_id,number,correlation_id,short_description,description,sys_updated_on,sys_updated_by';
    
        var query = [
            'correlation_idISNOTEMPTY',
            'sys_updated_by!=' + user,
            'sys_updated_on>' + time
        ];
    
        var uri_query = query.map(function(c) {
            return encodeURIComponent(c);
        }).join('%5E');
    
        poll_request.endpoint_url += '/table/incident?sysparm_query=' + uri_query +
            '&sysparm_fields=' + encodeURIComponent(fields) + '&sysparm_limit=10';
    
    })(poll_request, poller, params);
    // Process the request e.g. by executing a web service and returning the response
    (function(poll_request, poller, connection, params) {
    
        var rm = new sn_ws.RESTMessageV2();
        rm.setEndpoint(poll_request.endpoint_url);
        rm.setHttpMethod('GET');
        rm.setRequestHeader('Accept', 'application/json');
        rm.setRequestHeader('Content-type', 'application/json');
        rm.setBasicAuth(connection.getBasicAuthUser(), connection.getBasicAuthPassword());
    
        // rm.setRequestBody(JSON.stringify(body));
        var resp = rm.execute();
    
        answer = resp.getBody() + '';
    
    })(poll_request, poller, connection, params);
    // Process the response returned by the request script
    // The 'answer' variable from the request script is passed in here as the 'response' parameter 
    (function (poll_request, poller, response, params) {
    
        var body = JSON.parse(response);
    
        // Process the result
        var conn = poller.getIntegration().getActiveConnection();
        var cvars = conn.getVariables();
    
        var poll_helper = new x_snd_eb.PollHelper(poll_request);
        var info = [];
    
        if ( body.result.length == 0 ) {
            status = 'No Incident found';
            poll_request.response_status = status + '\n\n' + JSON.stringify(body,null,2);
            return;
        }
    
        body.result.forEach(function(inc){
    
            // Set up the payload object
            var pl = {
                message : {
                    name: 'UpdateIncidentInbound',
                    source_reference: inc.sys_id
                },
                detail : {
                    short_description : inc.short_description,
                    description : inc.description
                }
            };
    
            // Set up the options object for message submission
            var opts = {
                //message_name: 'UpdateIncidentInbound',
                payload : JSON.stringify(pl)
            };
    
            poll_helper.processInbound(opts);
    
            var inc_time = inc.sys_updated_on;
            info.push('Incident : ' + inc.number + ' (' + inc_time + ')');
    
            // Set last update time (if later)
            var conn_time = conn.getData('last_update_time');
            if ( inc_time > conn_time ) {
                conn.setData('last_update_time',inc_time);
            }
    
        });
    
        poll_request.response_status = info.join('\n') + '\n\n' + JSON.stringify(body,null,2);
    
    })(poll_request, poller, response, params);
    var poll_helper = new x_snd_eb.PollHelper(poll_request);
    poll_helper.processInbound(opts);
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    (New auto-generated code will appear here)
    
    //===== [ws] End Unifi Auto Generated Code =====//
    
    (Old pre-existing code will appear here)
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    x_snd_eb.ws_console.checkpoint("MessageScript")
    
    x_snd_eb.ws_console.execute("Mapping result.sys_id [x_snd_eb_field.do?sys_id=a163e73e1b11b81090dfdb9ebd4bcbdc]", function () {
      log.debug("Field map: PI - Source Reference [x_snd_eb_field_map.do?sys_id=eca02f3e1b11b81090dfdb9ebd4bcb63]");
      payload = payload || {};
      payload.result = payload.result || {};
      var $payload = payload.result;
      
      stage.external_reference = '' + ($payload.sys_id || '');
    
    });
    
    var error = x_snd_eb.ws_console.findCheckpointError("MessageScript");
    if (error) throw error.message;
    
    //===== [ws] End Unifi Auto Generated Code =====//
    ws_console.execute('Business rule: Do something', function () {
     // run some code
     // errors will be caught and logged in the Activity Log and System Log
    });
    Message.processOutbound(current, {parent_tables: true});

    Note: We have included the /table/incident element of the endpoint url because we used the truncated url in the Connection when following the Outbound Incident Guide. If you have used the full url there, then this element can be excluded here.

    &sysparm_display_value=true: Adding this parameter means that reference data will return an object containing the 'display_value' element instead of the 'value' element. We will talk more about the relevance of this when mapping the caller_id field on the 'CreateIncidentInbound Fields' page.

    (We have also chosen to limit the number of records returned to 10.)

    params: The params object is passed through to the subsequent scripts (and on to further Pollers, if required).

    processInbound()
    : Having 'poll_helper.processInbound(opts);' inside the loop means that an update message will be generated for each updated ticket.

    Payload object: We have chosen to structure the payload object (var pl) as we have. There is no obligation to keep the same structure. Yours can be defined to suit your requirements.

    Payload options: In the payload options (var opts), we have commented out //message_name: 'UpdateIncidentInbound',. This is because we have chosen to include the message name in the structure of the payload object.

    Message name: Unifi needs to know the message name in order to know how to process the inbound request. We can either set it in the payload (as we have), or in the options (as per the commented out line).

    Name

    The name of the Processor.

    <Your Name>

    Setup script

    The script to setup the Poll Request record.

    Update the code in the Setup script field so that it looks like the code below

    Request script

    The script that executes the request.

    Update the code in the Request script field so that it looks like the code below

    Response script

    The script that processes the response to the request.

    Update the code in the Response script field so that it looks like the code below

    From the UpdateIncident page, navigate to Message > Fields.

    Find the incident.short_description (Integration level) Field & set Active to true.

    The 'Build Integration' button becomes visible in the banner and the empty circle icon next to the Field name turns green & contains a green 'check' (to indicate that Message level configuration exists for this Field).

    By simply setting the Active flag to true on the Integration level Field record listed on the Message, Unifi has automatically created the Message level counterpart. The Integration level record still exists (and can be seen when you click on the 'Fields' icon to navigate to the Fields page), but is no longer visible in the list view on the Message because the Message level record has been created.)

    Hints & Tips: Unifi automatically creates Integration level Fields when we first create the Message level equivalent records; those Integration level Fields are visible on the Fields list of the Messages we subsequently create. Therefore, if a Field is required for multiple Messages, create it once for the first Message and then simply set active to true for its Integration level counterpart from the Fields list of each of the relevant Messages that Field is required on.

    We will now configure Field records for two other Incident record field elements.

    Fields & Field Maps

    The table below lists the Incident fields above and the relevant Field Maps required to configure each Field record.

    Incident Field
    Field Map

    comments

    'PI - String'*

    work_notes

    'PI - String'*

    We have chosen String type here because we are integrating with the table API. This will return the contents of those fields as a string value. If we were integrating Unifi to Unifi we may use a Journal field type which would return an array of comments objects with "text", "created_on", "created_by" & "published" elements.

    *Field map: Values may vary (dependent on your configuration of the copies). Choose the copy Field Maps you created earlier.

    Field: incident.comments

    Because the incident.comments Field record is the same 'type' (IS - String) & the majority of the settings are the same as the previously configured Field, it will be quicker to copy the incident.short_description Field & make a few minor changes.

    Click the ellipsis next to the incident.short_description Field record & click Copy.

    The fields to edit for the Copy Field modal are as follows:

    Field
    Description
    Value

    Element

    The field on the source/target table this Field record is mapped to.

    Additional comments

    Property*

    The property in the payload the data will be written to.

    Automatically populated

    Description

    Describe what this field is for and any specific details that might help you in future.

    'The incident's comments'

    *This field is automatically populated.

    Your Copy Field modal should look like this:

    Click Copy.

    You will be redirected to the Details page of the newly created incident.comments Field record.

    Field: incident.work_notes

    It will again be quicker to copy the previously configured incident.comments Field & make a few minor changes.

    To quickly navigate back to the UpdateIncident Message, click the 'Preview' icon next to the Message field on the Details page of newly created incident.comments Field record.

    Navigate to Message > Fields.

    Click the ellipsis next to the incident.comments Field record & click Copy.

    The fields to edit for the Copy Field modal are as follows:

    Field
    Description
    Value

    Element

    The field on the source/target table this Field record is mapped to.

    'Work notes'

    Property*

    The property in the payload the data will be written to.

    Automatically populated

    Description

    Describe what this field is for and any specific details that might help you in future.

    'The incident's work notes'

    *This field is automatically populated.

    Your Copy Field modal should look like this:

    Click Copy.

    You will be redirected to the Details page of newly created incident.work_notes Field record.

    Build

    Now that we’ve configured the Field records for the UpdateIncident message, we are ready to build our message scripts.

    Navigate to the UpdateIncident Message, then navigate to Message > Fields.

    The following Field records should now be in place for your UpdateIncident messsage:

    Click on Build Message.

    You will see the 'Message build successful' Info Message.

    Navigate to Advanced > Script Editor to view the auto-generated code.

    Your Script Editor fields should look like this:

    Message Scripts

    The newly auto-generated code will appear between a Begin & End Comment immediately prior to any code that may already be there (pre-existing code will be retained).

    We will now examine our new, auto-generated Message Scripts.

    Source to Stage:

    Stage to Request:

    We are now ready to Test the UpdateIncident Message.

    Deleting here only deletes the Field record for this message. The integration level record and any other message level ones remain in place.

    Field: incident.state (Message level)

    Unifi created the incident.state (Integration level) Field record earlier. It is, therefore, displayed in the list with Active set to false.

    The fields to be changed to configure the incident.state (Message level) Field record are as follows:

    Field
    Description
    Value

    Active

    Set to true to create a Message level Field record from its Integration level counterpart.

    <true>

    By simply setting the Active flag to true on the Integration level Field record listed on the Message, Unifi has created the Message level counterpart.

    Your ResolveIncident Message Fields page should look like this:

    The empty circle icon next to the Field name turns green & contains a green ‘check’ (to indicate that Message level configuration exists for this Field).

    We will now configure Field records for the two remaining Incident record field elements which are required.

    Fields & Field Maps

    The table below lists the Incident record field elements we will map and the relevant Field Maps required to configure each Field record.

    Incident Field
    Field Map

    close_code

    'IG - Choice'*

    close_notes

    'IG - String'*

    *Field map: Values may vary (dependent on your configuration of the copies). Choose the copy Field Maps you created earlier.

    Field: incident.close_code (Message level)

    There is no need to ‘Generate field choices’ for Message level Field records because the Field Map always looks for them on an Integration level Field which has the same name.

    As with 'incident.state' the 'incident.close_code' Field record is a Choice 'type' Field. We will, therefore, configure the choices once at the Integration level. We’ll first configure the Message level Field and then move on to configure the choices on its Integration level counterpart.

    From the ResolveIncident Message, navigate to Message > Fields. Click New.

    The fields to be configured for our incident.close_code (Message level) New Field modal are as follows:

    Field
    Description
    Value

    Message*

    The Message this Field record is linked with.

    'ResolveIncident'

    Description

    The description of this Field record.

    'The incident's Resolution code (Close code in ServiceNow)'

    Active*

    Set to true to use this Field record for processing.

    <true>

    *These fields are automatically defaulted to true, or automatically populated.

    **Field map: Value may vary. Choose the copy Field Map you created for your Integration.

    Your 'incident.close_code' (Message level) New Field modal should look like this:

    Submit the record.

    You will be redirected back to the Fields page of the ResolveIncident Message.

    Field: incident.close_code (Integration level)

    You will need to 'Generate field choices' for this Integration level Choice 'type' Field.

    Navigate to the 'Fields' icon to open the Fields page.

    Click to open the incident.close_code (Integration level) Field record (the one where Message is empty).

    The incident.close_code Field record opens to the Details page.

    Navigate to Field > Field Choices.

    Click Generate field choices.

    Click Generate on the 'Generate field choices' modal which displays.

    The Field Choices are generated & now visible in the list.

    Field: incident.close_notes

    From the ResolveIncident Message, navigate to Message > Fields. Click New.

    The fields to be configured for the incident.close_notes New Field modal are as follows:

    Field
    Description
    Value

    Message*

    The Message this Field record is linked with.

    'ResolveIncident'

    Description

    The description of this Field record.

    'The incident's Resolution notes (Close notes in ServiceNow)'

    Active*

    Set to true to use this Field record for processing.

    <true>

    *These fields are automatically defaulted to true, or automatically populated.

    **Field map: Value may vary. Choose the copy Field Map you created for your Integration.

    Your 'incident.close_notes' New Field modal should look like this:

    Submit the record.

    You will be redirected back to the Fields page of the ResolveIncident Message.

    Build

    Now that we’ve configured the Field records for the ResolveIncident message, we are ready to build our message scripts.

    To quickly navigate to the ResolveIncident message from the Details page of the newly created incident.close_notes Field record…

    ...click the 'Preview' icon to the left of the Message field.

    From the ResolveIncident message, navigate to Message > Fields.

    The following Field records should now be in place for your ResolveIncident messsage:

    Click on Build Message.

    You will see the 'Message build successful' Info Message.

    Navigate to Advanced > Script Editor to view the auto-generated code.

    Your Script Editor fields should look like this:

    Message Scripts

    The newly auto-generated code will appear between a Begin & End Comment immediately prior to any code that may already be there (pre-existing code will be retained).

    We are now ready to Test our ResolveIncident Message.

    Field
    Description
    Value

    Message name

    The message name that is unique for this integration.

    'CreateIncident'

    Type

    The primary purpose of the message.

    'Create'

    Direction

    The direction(s) this message is configured to support.

    'Outbound'

    Your CreateIncident New Message modal should look like this:

    Submit and view to further configure the Message.

    Response Fields

    Navigate to Message > Response.

    The Response fields to be configured are as follows:

    Field
    Description
    Value

    Response

    The immediate synchronous response to this message.

    lookup: 'CreateIncidentResponse'

    Async*

    Turn this option on if you want inbound processing to occur asynchronously or this message is the first of an asynchronous message pair.

    <false>

    *This field is automatically defaulted to true.

    Your Response form should look like this:

    Navigate to Message > Bond.

    Bond Fields

    The Bond fields to be configured are as follows:

    Field
    Description
    Value

    Bond ownership*

    Determine if the sender should own the bond or not in order for this message to be processed? Use 'Ignore' to process regardless of the owner flag. (Choices: Ignore, Must own, Must not own.)

    'Ignore'

    Bond condition type*

    The type of conditional check made on the bond. (None: no checks are made. State: checks against the state are made using the conditional checkboxes. Scripted: the 'Bond condition' script is used.)

    'State'

    Bond new

    Process this message when a new bond is required.

    <true>

    *These fields are automatically populated.

    Your Bond form should look like this:

    Navigate to Outbound > Trigger.

    Outbound Trigger Fields

    The Outbound Trigger fields to be configured (as required)* are as follows:

    Field
    Description
    Value

    Outbound condition*

    The condition that the ServiceNow record must meet to trigger this message being processed.

    <Your condition> e.g. 'Short description contains Push-Pull Integration'

    *Outbound condition (as required):

    It is not necessary for you to enter a condition. The value given is an example. You may create any condition (or not) to align with your business process requirements.

    Your Outbound Trigger form should look like this:

    Navigate to Outbound > Settings.

    Outbound Settings Fields

    The Outbound Settings fields to be configured are as follows:

    Field
    Description
    Value

    Path*

    A path to append to the URL defined in the connection. Specify a full URL to override the connection. Define inline scripts to reference Stage to Request script variables by wrapping code in braces {}, e.g. /{transaction.message_id}.

    '/table/incident'

    Action method

    The SOAP Action or the REST Method to use for this message. If this field is empty the SOAP Action will default to the message name and the REST Method will default to POST.

    'POST'

    *Path

    Only add this value if you have used the truncated Endpoint URL in the Connection. If you have used the full Endpoint URL, this step can be skipped.

    Your Outbound Settings form should look like this:

    Click Save.

    We are now ready to configure the Fields for our CreateIncident Message.

    // Configure the new Poll Request record
    (function(poll_request, poller, params) {
    
        var gdt = new GlideDateTime();
        gdt.addSeconds(-1800);
    
        var connection = poller.getIntegration().getActiveConnection();
        var cvar = connection.getVariables();
    
        var user = connection.getBasicAuthUser();
        var time = connection.getData('last_update_time', (gdt + ''));
        var group = cvar.external_group + ''; //Poller Integration Support 
        var fields = cvar.base_fields + ',' + cvar.data_fields;
    
        var query = [
            'active=true',
            'correlation_idISEMPTY',
            'assignment_group=' + group,
            'sys_updated_by!=' + user,
            'sys_updated_on>' + time,
            'ORDERBYsys_updated_on'
        ];
    
        var uri_query = query.map(function(c) {
            return encodeURIComponent(c);
        }).join('%5E');
    
        poll_request.endpoint_url += '/table/incident?sysparm_query=' + uri_query +
            '&sysparm_fields=' + encodeURIComponent(fields) + '&sysparm_display_value=true' + '&sysparm_limit=10';
    
    })(poll_request, poller, params);
    // Process the request e.g. by executing a web service and returning the response
    (function(poll_request, poller, connection, params) {
    
        var rm = new sn_ws.RESTMessageV2();
        rm.setEndpoint(poll_request.endpoint_url);
        rm.setHttpMethod('GET');
        rm.setRequestHeader('Accept', 'application/json');
        rm.setRequestHeader('Content-type', 'application/json');
        rm.setBasicAuth(connection.getBasicAuthUser(), connection.getBasicAuthPassword());
    
        // rm.setRequestBody(JSON.stringify(body));
        var resp = rm.execute();
    
        answer = resp.getBody() + '';
    
    })(poll_request, poller, connection, params);
    // Process the response returned by the request script
    // The 'answer' variable from the request script is passed in here as the 'response' parameter 
    (function(poll_request, poller, response, params) {
    
        var body = JSON.parse(response);
    
        // Process the result
        var conn = poller.getIntegration().getActiveConnection();
        var cvars = conn.getVariables();
    
        var poll_helper = new x_snd_eb.PollHelper(poll_request);
        var info = [];
    
        if (body.result.length == 0) {
            status = 'No Incident found';
            poll_request.response_status = status + '\n\n' + JSON.stringify(body, null, 2);
            return;
        }
    
        body.result.forEach(function(inc) {
    
            // Set up the payload object
            var pl = {
                message: {
                    name: 'CreateIncidentInbound',
                    source_reference: inc.sys_id
                },
                detail: {
                    caller_id: inc.caller_id,
                    short_description: inc.short_description,
                    description: inc.description,
                    state: inc.state,
                    impact: inc.impact,
                    urgency: inc.urgency
                }
            };
    
            // Set up the options object for message submission
            var opts = {
                //message_name: 'CreateIncidentInbound',
                payload: JSON.stringify(pl)
            };
    
            poll_helper.processInbound(opts);
    
            var inc_time = inc.sys_updated_on;
            info.push('Incident : ' + inc.number + ' (' + inc_time + ')');
    
            // Set last update time (if later)
            var conn_time = conn.getData('last_update_time', "");
            info.push('Conn Time : ' + conn_time);
            if (inc_time > conn_time) {
                conn.setData('last_update_time', inc_time);
            }
    
        });
    
        poll_request.response_status = info.join('\n') + '\n\n' + JSON.stringify(body, null, 2);
    
    })(poll_request, poller, response, params);
    var poll_helper = new x_snd_eb.PollHelper(poll_request);
    poll_helper.processInbound(opts);
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    (New auto-generated code will appear here)
    
    //===== [ws] End Unifi Auto Generated Code =====//
    
    (Old pre-existing code will appear here)
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    x_snd_eb.ws_console.checkpoint("MessageScript")
    
    x_snd_eb.ws_console.execute("Mapping incident.short_description [x_snd_eb_field.do?sys_id=a70b854b1b15b81090dfdb9ebd4bcbb2]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $stage.short_description = '' + (source.short_description || default_value);
      } else if (source.short_description != '') {
        $stage.short_description = '' + source.short_description;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.comments [x_snd_eb_field.do?sys_id=1a5efe331b953c1090dfdb9ebd4bcbfc]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $stage.comments = '' + (source.comments || default_value);
      } else if (source.comments != '') {
        $stage.comments = '' + source.comments;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.work_notes [x_snd_eb_field.do?sys_id=99ffb6371b953c1090dfdb9ebd4bcb22]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $stage.work_notes = '' + (source.work_notes || default_value);
      } else if (source.work_notes != '') {
        $stage.work_notes = '' + source.work_notes;
      }
    
    });
    
    var error = x_snd_eb.ws_console.findCheckpointError("MessageScript");
    if (error) throw error.message;
    
    //===== [ws] End Unifi Auto Generated Code =====//
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    x_snd_eb.ws_console.checkpoint("MessageScript")
    
    x_snd_eb.ws_console.execute("Mapping incident.short_description [x_snd_eb_field.do?sys_id=a70b854b1b15b81090dfdb9ebd4bcbb2]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      var $payload = payload;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $payload.short_description = '' + $stage.short_description;
      } else if ($stage.short_description) {
        $payload.short_description = '' + $stage.short_description;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.comments [x_snd_eb_field.do?sys_id=1a5efe331b953c1090dfdb9ebd4bcbfc]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      var $payload = payload;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $payload.comments = '' + $stage.comments;
      } else if ($stage.comments) {
        $payload.comments = '' + $stage.comments;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.work_notes [x_snd_eb_field.do?sys_id=99ffb6371b953c1090dfdb9ebd4bcb22]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      var $payload = payload;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $payload.work_notes = '' + $stage.work_notes;
      } else if ($stage.work_notes) {
        $payload.work_notes = '' + $stage.work_notes;
      }
    
    });
    
    var error = x_snd_eb.ws_console.findCheckpointError("MessageScript");
    if (error) throw error.message;
    
    //===== [ws] End Unifi Auto Generated Code =====//
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    (New auto-generated code will appear here)
    
    //===== [ws] End Unifi Auto Generated Code =====//
    
    (Old pre-existing code will appear here)

    Field map

    The Field Map this Field record is linked with.

    'IG - Choice'**

    Map to field*

    Use this Field record to represent a field on a source/target table.

    <true>

    Table*

    The primary source/target table that this Field record is mapped to.

    'Incident' [incident]

    Element

    The field on the source/target table this Field record is mapped to.

    'Resolution code'

    Path

    Where in the payload the data will be placed.

    'detail'

    Property*

    The property in the payload the data will be written to.

    Automatically populated

    Inbound*

    Set to true to use for inbound Messages.

    <true>

    Outbound*

    Set to true to use for outbound Messages.

    <true>

    Mandatory

    Set to true to make mandatory.

    <true>

    Field map

    The Field Map this Field record is linked with.

    'IG - String'**

    Map to field*

    Use this Field record to represent a field on a source/target table.

    <true>

    Table*

    The primary source/target table that this Field record is mapped to.

    'Incident' [incident]

    Element

    The field on the source/target table this Field record is mapped to.

    'Resolution notes'

    Path

    Where in the payload the data will be placed.

    'detail'

    Property*

    The property in the payload the data will be written to.

    Automatically populated

    Inbound*

    Set to true to use for inbound Messages.

    <true>

    Outbound*

    Set to true to use for outbound Messages.

    <true>

    Mandatory

    Set to true to make mandatory.

    <true>

    Poll Processor

    The Poll Processor contains the logic that will be applied when polling a remote system for data.

    The Poll Processor is a configuration record which contains the logic that will be applied when polling a remote system for data. There are three main scripts which are used to setup, execute and process the Poll Requests. The scripts given here are examples of how you might configure your Poll. The details of yours may differ depending on your requirements.

    Icons

    Before continuing we would again like to remind you of the relevant icons that are visible down the left hand navigation strip of the Unifi Integration Designer.

    The icons are:

    a) 'Integration' icon: Opens the current integration's Details page.

    b) 'Messages' icon: Opens the current integration's Messages page.

    c) 'Fields' icon: Opens the current integration's Fields page.

    d) 'Field Maps' icon: Opens the current integration's Field Maps page.

    e) 'Pollers' icon: Opens the current integration's Pollers page.

    f) 'Poll Processors' icon: Opens the current integration's Poll Processors page.

    New Poll Processor

    In Unifi Integration Designer, navigate to & open < Your Integration > (created following the Outbound Incident Guide & Incident Update Poller Guide).

    Click the 'Poll Processors' icon & then New.

    The fields to be configured for the New Poll Processor modal are as follows:

    Field
    Description
    Value

    Your New Poll Processor modal should look like this:

    Submit and view to further configure the Poll Processor.

    Setup Script

    The Setup Script is the first script to run (it runs at the point in time the Poll Request is created). It is used to build the environment for the poll and define what it will do. We will use it to setup the URL that will be called.

    Navigate to Scripts > Setup Script.

    The initial Poll Processor fields to be configured are as follows:

    Field
    Description
    Value

    The code in the Setup script field should look like this:

    Setup script: The parameters for which data to return are contained in the endpoint url.

    fields: The table API will return all the data by default, so we choose to deliberately limit what is returned to the fields listed in this variable.

    query: Instead of querying all the records on the remote instance, we deliberately limit the records to those where the correlation id is not empty (i.e. it's bonded), that haven't been updated by the Authentication user (our system) and that were updated since either since the last update time (if one exists), or in the last 30 minutes.

    Endpoint URL: The value used in the poll_request.endpoint_url was initially generated using the ServiceNow REST API Explorer, substituting variables in for the uri query and fields. This value is appended to the existing endpoint url in the active connection before being added to the Poll Request.

    Your Setup Script form should look like this:

    Navigate to Request Script.

    Request Script

    The Request Script is used to reach into the remote system and execute the request. We will use the ServiceNow RESTMessageV2() web service to make a REST call to the URL defined in the Setup Script.

    The next Poll Processor field to be configured is as follows:

    Field
    Description
    Value

    The code in the Request script field should look like this:

    Request script: This script uses the ServiceNow RESTMessageV2() web service to make a REST call to the endpoint url created in the Setup script. It returns the body of the request as the answer which it passes to the Response script

    Your Request Script form should look like this:

    Navigate to Response Script.

    Response Script

    The Response Script is used to process the information returned from the remote system. We will pass this data to Unifi, telling it which Message to use to process the data.

    The last Poll Processor field to be configured is as follows:

    Field
    Description
    Value

    The code in the Response script field should look like this:

    Response script: This script parses the response into a body object to contain the result, (returning if it doesn't contain anything).

    It then sets up some objects to help us; these include the essential PollHelper() function (which we initialise from the poll_request) along with two other functions: get_bond() to find the Bond for an Incident & get_message_name() to work out the message type to send to Unifi based upon the change of state.

    After that it loops through each of the returned tickets. For each ticket, it logs the incident number & time, finds the bond & returns any previous data stored on the bond, decides which Message to use, sets up a payload object and submits it to Unifi by calling the processInbound() method. It then saves the current incident as the previous incident for the next poll & checks whether the ticket was updated later than the last update time; if so, it sets and stores the last update time as that 'sys_updated_on' value (this 'last_update_time' is what the Setup script checks against when defining what the Poll will do).

    Your Response Script form should look like this:

    Save the Poll Processor.

    Now let's move on and configure the Poller.

    Note: We have included the /table/incident element of the endpoint url because we used the truncated url in the Connection when following the Outbound Incident Guide. If you have used the full url there, then this element can be excluded here.

    (We have also chosen to limit the number of records returned to 10.)

    params: The params object is passed through to the subsequent scripts (and on to further Pollers, if required).

    After looping through all the records (processing each result), the results are logged to the Response status field of the Poll Request.

    Essential code: the following lines of code must be included in the response script to enable Unifi

    processInbound(): Having the 'poll_helper.processInbound()' function inside the loop means that an update message will be generated for each updated ticket.

    Payload object: We have chosen to structure the payload object (var payload) as we have. There is no obligation to keep the same structure. Yours can be defined to suit your requirements.

    Message name: Unifi needs to know the message name in order to know how to process the inbound request. We can either set it in the payload (as we have), or declare a variable that sets it which is passed into the processInbound() function along with the payload. (Unifi will always check processInbound() first. If no Message name is set here it will use the 'Identify message script' on the Integration).

    Name

    The name of the Processor.

    <Your Name>

    Setup script

    The script to setup the Poll Request record.

    Update the code in the Setup script field so that it looks like the code below

    Request script

    The script that executes the request.

    Update the code in the Request script field so that it looks like the code below

    Response script

    The script that processes the response to the request.

    Update the code in the Response script field so that it looks like the code below

    Edit CreateIncident Message

    Here we will deal with the configuration changes that need to be made to our CreateIncident Message to facilitate identifying and returning data from bonded records.

    CreateIncident Message

    Now that we've configured the remote system's Incident form to display our bonded ticket number as the correlation id, we need to update our CreateIncident Message to send it.

    To ensure that our CreateIncident Message is sending the relevant data we need to configure a new Field record that will send the Incident number as the correlation id. We will make use of the previously copied String Field Map record.

    Field: incident.number

    In Unifi Integration Designer, from the CreateIncident Message, navigate to Message > Fields. Click New.

    The fields to be configured for our incident.number New Field modal are as follows:

    Field
    Description
    Value

    *These fields are automatically defaulted to true, or automatically populated.

    **Field map: Value may vary. Choose the copy Field Map you created for your Integration.

    Your 'incident.number' New Field modal should look like this:

    Submit the record.

    You will be redirected back to the Fields page of the CreateIncident Message.

    Field: incident.description

    It is not necessary to configure this Field record to facilitate identifying and returning data from bonded records. It is only included here to facilitate the sending of data in the Description field of the Incident when testing our Integration. You may choose to ignore this if you wish. Similarly, if you had already configured the incident.description Field record for the CreateIncident Message (when completing the 'Outbound incident' Guide), you can ignore this.

    The ‘incident.description’ (Integration level) Field record should already be in place (i.e. with Active set to false). This was automatically created by Unifi when we created the Message level record when configuring the Fields for the UpdateIncidentInbound Message. We will now create its Message level counterpart for the CreateIncident Message.

    From the CreateIncident Message, navigate to Message > Fields.

    Your CreateIncident Fields page should look like this:

    Find the incident.description (Integration level) Field & set Active to true.

    The empty circle icon next to the Field name turns green & contains a green ‘check’ (to indicate that Message level configuration exists for this Field) when we set Active to true. (The ‘Build Integration’ button became visible in the banner when we created the 'incident.number' Field record.)

    By setting the Active flag to true on the Integration level Field record listed on the Message, Unifi has automatically created the Message level counterpart.

    Click to open the incident.description (Message level) Field to make a few minor changes.

    The incident.description Field record opens to the Details page.

    To edit, set Inherit to False.

    Save the record (the fields now become editable).

    Navigate to Field > Settings.

    Edit the incident.description Field record as follows:

    Field
    Description
    Value

    Your 'incident.description' Field record should look like this:

    Save the record.

    Build

    Now that we’ve configured the Field records for the CreateIncident message, we are ready to build our message scripts.

    To quickly navigate to the CreateIncident Message from the Details page of the newly created incident.description Field record...

    ...click the 'Preview' icon to the left of the Message field.

    The following Field records should now be in place for your CreateIncident Message:

    Click on Build Message.

    You will see the 'Message build successful' Info Message.

    Navigate to Advanced > Script Editor > View > Outbound to view the auto-generated code.

    Your Script Editor fields should look like this:

    Message Scripts

    The new auto-generated code (mapping the incident number to the correlation id & mapping the Incident description) will appear between the Begin & End Comment along with the code that was already there (which we had previously created using the Outbound Incident Guide). Your code may differ, depending on which Field records you created to satisfy your mapping requirements.

    Source to Stage:

    Stage to Request:

    We have now completed the configuration and are ready to move on to Test our Update Scenario.

    CreateIncident Fields

    We will utilise the Field & Field Map records to configure the Message Scripts for the CreateIncident Message.

    Field: message.message_header

    The ‘message.message_header’ Field record is visible and inactive. It is an Integration level Field which was automatically created by Unifi at the time we created the Message level record (as per the 'CreateIncidentReceipt Fields' page). We’ll talk more about Integration level & Message level Fields in the '

    // Configure the new Poll Request record
    (function(poll_request, poller, params) {
    
        var gdt = new GlideDateTime();
        gdt.addSeconds(-1800);
    
        var connection = poller.getIntegration().getActiveConnection();
        var user = connection.getBasicAuthUser();
        var time = connection.getData('last_update_time', (gdt + ''));
    
        var fields = 'sys_id,number,correlation_id,short_description,description,state,close_code,close_notes,sys_updated_on,sys_updated_by';
    
        var query = [
            'correlation_idISNOTEMPTY',
            'sys_updated_by!=' + user,
            'sys_updated_on>' + time
        ];
    
        var uri_query = query.map(function(c) {
            return encodeURIComponent(c);
        }).join('%5E');
    
        poll_request.endpoint_url += '/table/incident?sysparm_query=' + uri_query +
            '&sysparm_fields=' + encodeURIComponent(fields) + '&sysparm_limit=10';
    
    })(poll_request, poller, params);
    // Process the request e.g. by executing a web service and returning the response
    (function(poll_request, poller, connection, params) {
    
        var rm = new sn_ws.RESTMessageV2();
        rm.setEndpoint(poll_request.endpoint_url);
        rm.setHttpMethod('GET');
        rm.setRequestHeader('Accept', 'application/json');
        rm.setRequestHeader('Content-type', 'application/json');
        rm.setBasicAuth(connection.getBasicAuthUser(), connection.getBasicAuthPassword());
    
        // rm.setRequestBody(JSON.stringify(body));
        var resp = rm.execute();
    
        answer = resp.getBody() + '';
    
    })(poll_request, poller, connection, params);
    // Process the response returned by the request script
    // The 'answer' variable from the request script is passed in here as the 'response' parameter 
    (function (poll_request, poller, response, params) {
    
        var body = JSON.parse(response);
    
        // Nothing to do if no results were returned
        if ( body.result.length == 0 ) {
            poll_request.response_status = 'No Incidents returned\n\n' + JSON.stringify(body,null,2);
            return;
        }
    
        // Sample result
    /*
    {
      "result": [
        {
          "sys_id": "0ecc4865db734010c3ebde82ca961960",
          "number": "INC0010107",
          "correlation_id": "INC0010345",
          "short_description": "Demo two - Fixing request",
          "description": "A long description",
          "state":"2",
          "sys_updated_on": "2020-04-02 14:00:00",
          "sys_updated_by": "a.user"
        },
        {
          ... next Incident
        }
      ]
    }    
    */
    
        // Establish the environment
        var integration = poller.getIntegration();
        var config = integration.getConfig();
        var conn   = integration.getActiveConnection();
        var cvars  = conn.getVariables();
    
        var poll_helper = new x_snd_eb.PollHelper(poll_request);
        var info = [];
    
        // Use Unifi code to find the Bond for an Incident
        function get_bond(inc) {
            var bond = new x_snd_eb.Bond(config);
            bond.locateReference(integration,inc.correlation_id,inc.sys_id);
            if ( !bond.isValidRecord() ) { return null; }
            return bond; 
        }
    
        // Work out the message type to send to Unifi based upon the change of state
        function get_message_name(curr,prev) {
    
            // Default message type is an update
            var message_name = 'UpdateIncidentInbound';
    
            // Use the default type if we have no previous state
            if ( !prev || !prev.state ) { 
                return message_name; 
            }
    
            // Use the default type if there is no change in state
            if ( curr.state == prev.state ) { 
                return message_name; 
            }
    
            // We know the state has changed, check if it is Resolved (6)
            if ( curr.state == '6' ) {
                message_name = 'ResolveIncidentInbound';
            }
    
            return message_name;
        }
    
        function process_incident(inc) {
    
            // Log the incident number and time
            var inc_time = inc.sys_updated_on;
            info.push('Incident : ' + inc.number + ' (' + inc_time + ')');
    
            // Find the bond on which the previous data is stored
            var bond = get_bond(inc);
    
            // If no bond was found, ignore this incident
            if ( !bond ) {
                info.push('- Bond not found - Incident ignored');
                return;
            }
    
            // Get the data stored for the incident by a previous poll
            var previous_inc = bond.getDataObject('previous_inc',{ state : '2' });
    
            // Work out the message type to send into Unifi 
            var message_name = get_message_name(inc,previous_inc);
            info.push('- Message name: ' + message_name);
    
            // Set up the payload object for passing into Unifi
            var payload = {
                message : {
                    name: message_name,
                    source_reference: inc.sys_id,
                },
                detail : {
                    short_description : inc.short_description,
                    description : inc.description,
                    state : inc.state,
                    close_code : inc.close_code,
                    close_notes : inc.close_notes
                }
            };
    
            // Submit the message into Unifi
            poll_helper.processInbound({
                payload : JSON.stringify(payload)
            });
    
            // Save the current incident as the previous incident for the next poll
            bond.setDataObject('previous_inc',inc);
    
            // Update last update time (if later)
            var conn_time = conn.getData('last_update_time');
            if ( inc_time > conn_time ) {
                conn.setData('last_update_time',inc_time);
            }
    
        }
    
        // Process each result
        body.result.forEach(function(inc){
            process_incident(inc);
        });
    
        poll_request.response_status = info.join('\n') + '\n\n' + JSON.stringify(body,null,2);
    
    })(poll_request, poller, response, params);
    var poll_helper = new x_snd_eb.PollHelper(poll_request);
    poll_helper.processInbound({
                payload : JSON.stringify(payload)
            });

    The Field Map this Field record is linked with.

    'PI - String'**

    Map to field*

    Use this Field record to represent a field on a source/target table.

    <true>

    Table*

    The primary source/target table that this Field record is mapped to.

    'Incident' [incident]

    Element

    The field on the source/target table this Field record is mapped to.

    'Number'

    Property*

    The property in the payload the data will be written to.

    'correlation_id'

    Inbound*

    Set to true to use for inbound Messages.

    <false>

    Outbound*

    Set to true to use for outbound Messages.

    <true>

    Message*

    The Message this Field record is linked with.

    'CreateIncident'

    Description

    The description of this Field record.

    'The incident number sent as the correlation id'

    Active*

    Set to true to use this Field record for processing.

    <true>

    Path

    Where in the payload the data will be placed.

    [Blank]

    Inbound

    Set to true to use for inbound Messages.

    <false>

    Outbound

    Set to true to use for outbound Messages.

    <true>

    Field map

    ' section.

    It is now easier than ever to create a Message level Field record for its Integration level counterpart.

    From the CreateIncident Message, navigate to Message > Fields.

    Find the message.message_header (Integration level) Field & set Active to true.

    Feature Alert: The ‘Build Integration’ button becomes visible in the banner and the empty 'circle icon' (next to the Field name) turns green & contains a green ‘check’ (to indicate that Message level configuration exists for this Field). Note: the empty 'circle icon' indicates that the Integration level Field is available to add to the Message.

    By simply setting the Active flag to true on the Integration level Field record listed on the Message, Unifi has automatically created the Message level counterpart. The Integration level record still exists (and can be seen when you click on the ‘Fields’ icon to navigate to the Fields page), but is no longer visible in the list view on the Message because the Message level record has been created.)

    Hints & Tips: Unifi automatically creates Integration level Fields when we first create the Message level equivalent records; those Integration level Fields are visible on the Fields list of the Messages we subsequently create. Therefore, if a Field is required for multiple Messages, create it once for the first Message and then simply set active to true for its Integration level counterpart from the Fields list of each of the relevant Messages that Field is required on.

    We will now configure Field records for a select few Incident record field elements.

    Fields & Field Maps

    Depending on your requirements, you will need to create Field records for each of the relevant Incident record field elements (see the table below for an example). For the sake of brevity, this Guide will focus on a select few. If you wish, however, you are free to continue & configure the remaining Field records. The table below lists an example of the Incident record field elements you may wish to map and the relevant Field Maps required to configure each Field record. For a fuller definition of available Field Maps, please see the relevant page in our technical documentation.

    Incident Field
    Field Map

    caller_id

    Reference

    short_description

    String

    description

    String

    category

    Choice

    impact

    Choice

    The Field records we will focus on will be for Caller (Reference), Short description (String) and State (Choice).

    Copy Field Maps

    If you haven't already, you will need to copy the relevant additional Field Maps for the CreateIncident Field records as follows:

    • Reference

    • String

    • Choice

    See Copy Field Maps (on the 'CreateIncidentReceipt Fields' page) for details.

    Field: incident.caller_id

    From the CreateIncident Message, navigate to Message > Fields. Click New.

    The fields to be configured for the incident.caller_id New Field modal are as follows:

    Field
    Description
    Value

    Message*

    The Message this Field record is linked with.

    'CreateIncident'

    Description

    Describe what this field is for and any specific details that might help you in future.

    'The caller on this incident'

    Active*

    Set to true to use this Field record for processing.

    <true>

    *These fields are automatically defaulted to true, or automatically populated.

    **Field map: Value may vary. Choose the copy Field Map you created for your Integration.

    Your 'incident.caller_id' New Field modal should look like this:

    Submit the record.

    You will be redirected back to the Fields page of the CreateIncident Message.

    Field: incident.short_description

    Click New.

    The fields to be configured for the incident.short_description New Field modal are as follows:

    Field
    Description
    Value

    Message*

    The Message this Field record is linked with.

    'CreateIncident'

    Description

    Describe what this field is for and any specific details that might help you in future.

    'The short description of the incident'

    Active*

    Set to true to use this Field record for processing.

    <true>

    *These fields are automatically defaulted to true, or automatically populated.

    **Field map: Value may vary. Choose the copy Field Map you created for your Integration.

    Your 'incident.short_description' New Field modal should look like this:

    Submit the record.

    You will be redirected back to the Fields page of the CreateIncident Message.

    Field: incident.state

    Field records can exist at both the Integration and the Message level (a Field record exists at the Integration level if it isn't linked to a Message i.e. the 'Message' field element is left blank). We noted previously that an Integration level Field record is automatically created when we first create one at the Message level. We will utilise and configure both when mapping 'incident.state'.

    The 'incident.state' Field record is a Choice 'type' Field. These are used when you’re mapping choice field elements with static values that don't change per Message (e.g. State, Impact, Urgency) i.e. you're not going to have one set of choices/values for create and another for update.

    Rather than configure choices for each Message, configure choices once at the Integration level. This means you only need define them once. The Field Map will take care of it and any 'incident.state' Field records that are set at the Message level (i.e. with a value in the 'Message' field) would use the choices configured at the Integration level.

    We'll first configure the Message level Field and then move on to configure the choices on its Integration level counterpart.

    Field: incident.state (Message level)

    There is no need to 'Generate field choices' for Message level Field records because the Field Map always looks for them on an Integration level Field which has the same name.

    From the CreatIncident Message, navigate to Message > Fields. Click New.

    The fields to be configured for our incident.state (Message level) New Field modal are as follows:

    Field
    Description
    Value

    Message*

    The Message this Field record is linked with.

    'CreateIncident'

    Description

    Describe what this field is for and any specific details that might help you in future.

    'The incident lifecycle state'

    Active*

    Set to true to use this Field record for processing.

    <true>

    *These fields are automatically defaulted to true, or automatically populated.

    **Field map: Value may vary. Choose the copy Field Map you created for your Integration.

    Your 'incident.state' (Message level) New Field modal should look like this:

    Submit the record.

    You will be redirected back to the Fields page of the CreateIncident Message.

    Field: incident.state (Integration level)

    We will need to 'Generate field choices' for this Integration level Choice 'type' Field.

    Navigate to the 'Fields' icon to open the Fields page.

    Click to open the incident.state (Integration level) Field record (the one where Message is empty).

    The incident.state Field record opens to the Details page.

    Navigate to Field > Field Choices.

    Click Generate field choices.

    Click Generate on the 'Generate field choices' modal which displays.

    The Field Choices are generated & now visible in the list.

    At this stage, you could carry on and configure any remaining Field records for the rest of the Incident record field elements (as per your requirements - see the Fields & Field Maps table at the top of this section). However, we will now run the Build process to auto-generate our Message Scripts.

    Build

    Now that we’ve configured the Field records for the CreateIncident message, we are ready to build our message scripts.

    From the CreateIncident message, navigate to Message > Fields.

    The following Field records should now be in place for your CreateIncident messsage:

    Click on Build Message.

    You will see the 'Message build successful' Info Message.

    Navigate to Advanced > Script Editor to view the auto-generated code.

    Your Script Editor fields should look like this:

    Message Scripts

    The newly auto-generated code will appear between a Begin & End Comment immediately prior to any code that may already be there (pre-existing code will be retained).

    We are now ready to Test our CreateIncident Message.

    Before we do, let's view the Trigger which Unifi automatically created when we ran 'Build Message'.

    Field: incident.state

    UpdateIncidentInbound Fields

    We will utilise the Field & Field Map records to configure the Message Scripts for the UpdateIncidentInbound Message.

    Copy Field Maps

    It is worth copying all relevant OOTB Field Maps as are necessary for your integration before using any of them in your Field Records - thereby mitigating the risk of any potential issues with future upgrades.

    Some Field Maps should already have been copied for this Integration whilst following the Outbound Incident Guide. Those that aren't will need to be copied. The Field Maps we shall use for our UpdateIncidentInbound Field records are:

    • Message Header

    • String

    To copy the Message Header Field Map, navigate to the 'Field Maps' icon.

    Click on the ellipsis to the right of the Message Header Field Map & then click Copy.

    Copy Field Map Modal

    The fields to edit for the Copy Field Map modal are as follows:

    Field
    Description
    Value

    *Name: We have chosen to prefix the existing Field Map Name with the initials of our Integration (you are free to choose any appropriate means of identifying/differentiating).

    Your Copy Field Map modal should look like this:

    Click Copy.

    You will be redirected to the Details page of the newly created Field Map.

    If necessary, repeat the process for the String Field Map.

    Field records can represent the handling of two categories of data: either a data object which carries transaction specific data (e.g. name, time stamp, source id etc.), or a field element on the bonded record (e.g. Short description). We will begin by configuring a Field record to deal with the transaction specific data.

    Field: message.header

    Back in the UpdateIncidentInbound Message, navigate to Message > Fields. Click New.

    The fields to be configured for our message_header New Field modal are as follows:

    Field
    Description
    Value

    *These fields are automatically defaulted to true, or automatically populated.

    **Field map: Value may vary. Choose the copy Field Map you created for your Integration.

    Your 'message.header' New Field modal should look like this:

    Submit the record.

    You will be redirected back to the Fields page of the UpdateIncidentInbound Message.

    Fields & Field Maps

    Depending on your requirements, you will need to create Field records for each of the relevant Incident record field elements you wish to map. As we have only chosen to include the short_description & description elements in both the Setup script & Response script of the Poll Processor, this Guide will focus on those two. If you wish, however, you are free to configure other Field records as required (ensuring you also define them in both the Setup Script & Response script of the Poll Processor).

    For a full description of the available Field Maps, please see the relevant page in our .

    The table below lists the Incident record field elements we will map and the relevant Field Maps required to configure each Field record.

    Incident Field
    Field Map

    *Field map: Values may vary (dependent on your configuration of the copies). Choose the copy Field Maps you created earlier.

    Field: incident.short_description

    The ‘incident.short_description’ (Integration level) Field record should already be in place (i.e. with Active set to false). This was automatically created by Unifi when we first created the Message level record when completing the Outbound Incident Guide. We will now create its Message level counterpart.

    From the UpdateIncidentInbound Message, navigate to Message > Fields.

    Your UpdateIncidentInbound Fields page should look like this:

    Find the incident.short_description (Integration level) Field & set Active to true.

    The empty circle icon next to the Field name turns green & contains a green ‘check’ (to indicate that Message level configuration exists for this Field) when we set Active to true. (The ‘Build Integration’ button became visible in the banner when we created the 'message.header' Field).

    By setting the Active flag to true on the Integration level Field record listed on the Message, Unifi has automatically created the Message level counterpart.

    Click to open the incident.short_description (Message level) Field to make a few minor changes.

    The incident.short_description Field record opens to the Details page.

    The following info message is also displayed (which can be closed):

    Field inheritance is set to true by default. This means the record will be updated with integration-level Field values when saved (except for Active, Inherit and Message values).

    You can either uncheck the Inherit field to configure locally, or edit the integration-level Field record. We will choose to uncheck the Inherit field and configure locally, because we want this inbound Field to be different to the outbound one (and the integration-level Field which was automatically created at that time).

    For more information on Field Inheritance click .

    Set Inherit to False.

    Save the record (the fields now become editable).

    Navigate to Field > Settings.

    Edit the incident.short_description Field record as follows:

    Field
    Description
    Value

    Your incident.short_description Field record should look like this:

    Save the record.

    Field: incident.description

    Because the incident.description Field record is the same ‘type’ (PI - String) & the majority of the settings are the same as the previously configured Field, it will be quicker to copy the incident.short_description Field & make a few minor changes.

    To quickly navigate to the UpdateincidentInbound Message from the Details page of the incident.short_description Field record...

    ...click the 'Preview' icon to the left of the Message field.

    From the UpdateIncidentInbound Message, navigate to Message > Fields.

    Click the ellipsis next to the incident.short_desscription Field record & click Copy.

    The fields to edit for the Copy Field modal are as follows:

    Field
    Description
    Value

    *This field is automatically populated.

    Your 'incident.description' Copy Field modal should look like this:

    Click Copy.

    You will be redirected to the Details page of the newly created incident.description Field record.

    Build

    Now that we’ve configured the Field records for the UpdateIncidentInbound message, we are ready to build our message scripts.

    To quickly navigate to the UpdateIncidentInbound message from the Details page of the newly created incident.description Field record…

    ...click the 'Preview' icon to the left of the Message field.

    The following Field records should now be in place for your UpdateIncidentInbound messsage:

    Click on Build Message.

    You will see the 'Message build successful' Info Message.

    Navigate to Advanced > Script Editor.

    Your Script Editor fields should initially look like this:

    Navigate to View > Inbound to view the auto-generated code.

    Your Script Editor fields should now look like this:

    Message Scripts

    The Message Scripts reflect the mappings as per this Guide. Your scripts might differ depending on which Fields you chose to map (& defined in the payload). We will look at the Message Scripts in turn.

    Payload to Stage:

    Your Payload to Stage Message Script should look like this:

    Stage to Target:

    Your Stage to Target Message Script should look like this:

    Before we test, we need to make a few changes. The first is to our Integration - to allow for inbound Message Identification.

    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    x_snd_eb.ws_console.checkpoint("MessageScript")
    
    x_snd_eb.ws_console.execute("Mapping incident.number [x_snd_eb_field.do?sys_id=997a766c1be1bc1090dfdb9ebd4bcbb7]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $stage.number = '' + (source.number || default_value);
      } else if (source.number != '') {
        $stage.number = '' + source.number;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.caller_id [x_snd_eb_field.do?sys_id=3a5cbbbe1b51b81090dfdb9ebd4bcb66]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $stage.caller_id = '' + (source.caller_id || default_value);
      } else if (source.caller_id != '') {
        $stage.caller_id = '' + source.caller_id;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.short_description [x_snd_eb_field.do?sys_id=49debf3e1b51b81090dfdb9ebd4bcba5]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $stage.short_description = '' + (source.short_description || default_value);
      } else if (source.short_description != '') {
        $stage.short_description = '' + source.short_description;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.description [x_snd_eb_field.do?sys_id=618a766c1be1bc1090dfdb9ebd4bcb91]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $stage.description = '' + (source.description || default_value);
      } else if (source.description != '') {
        $stage.description = '' + source.description;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.state [x_snd_eb_field.do?sys_id=f32e8cc31b91b81090dfdb9ebd4bcb09]", function () {
      log.debug("Field map: PI - Choice [x_snd_eb_field_map.do?sys_id=c7b97f7a1b51b81090dfdb9ebd4bcb62]");
      
      var default_value = (function () {
        return '';
      })();
      
      var field_choice;
      var is_mandatory = false;  
      
      if (!source.state.nil()) {
        field_choice = new GlideRecord('x_snd_eb_field_choice');
        field_choice.addQuery('table',         '=', 'incident');
        field_choice.addQuery('element',       '=', 'state');
        field_choice.addQuery('integration',   '=', '27be43a91b9db41090dfdb9ebd4bcb2e');
        field_choice.addQuery('field.message', '=', '');
        field_choice.addQuery('direction',     '=', 'Outbound');
        field_choice.addQuery('value',         '=', source.state);
        field_choice.addQuery('active',        '=', 'true');
        field_choice.query();
      
        if (field_choice.next()) {
          $stage.state = '' + field_choice.external_value;
        }
      } 
      
      if (!$stage.state) {
        $stage.state = '' + (source.state || '');
      }
      
      if (is_mandatory) {
        $stage.state = '' + (source.state || '');
      }
    
    });
    
    var error = x_snd_eb.ws_console.findCheckpointError("MessageScript");
    if (error) throw error.message;
    
    //===== [ws] End Unifi Auto Generated Code =====//
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    x_snd_eb.ws_console.checkpoint("MessageScript")
    
    x_snd_eb.ws_console.execute("Mapping incident.number [x_snd_eb_field.do?sys_id=997a766c1be1bc1090dfdb9ebd4bcbb7]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      var $payload = payload;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $payload.correlation_id = '' + $stage.number;
      } else if ($stage.number) {
        $payload.correlation_id = '' + $stage.number;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.caller_id [x_snd_eb_field.do?sys_id=3a5cbbbe1b51b81090dfdb9ebd4bcb66]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      var $payload = payload;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $payload.caller_id = '' + $stage.caller_id;
      } else if ($stage.caller_id) {
        $payload.caller_id = '' + $stage.caller_id;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.short_description [x_snd_eb_field.do?sys_id=49debf3e1b51b81090dfdb9ebd4bcba5]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      var $payload = payload;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $payload.short_description = '' + $stage.short_description;
      } else if ($stage.short_description) {
        $payload.short_description = '' + $stage.short_description;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.description [x_snd_eb_field.do?sys_id=618a766c1be1bc1090dfdb9ebd4bcb91]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      var $payload = payload;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $payload.description = '' + $stage.description;
      } else if ($stage.description) {
        $payload.description = '' + $stage.description;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.state [x_snd_eb_field.do?sys_id=f32e8cc31b91b81090dfdb9ebd4bcb09]", function () {
      log.debug("Field map: PI - Choice [x_snd_eb_field_map.do?sys_id=c7b97f7a1b51b81090dfdb9ebd4bcb62]");
      payload = payload || {};
      var $payload = payload;
      
      var is_mandatory = false;  
      
      if (is_mandatory) {
        $payload.state = $stage.state;
      } else if ($stage.state) {
        $payload.state = $stage.state;
      }
    
    });
    
    var error = x_snd_eb.ws_console.findCheckpointError("MessageScript");
    if (error) throw error.message;
    
    //===== [ws] End Unifi Auto Generated Code =====//
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    (New auto-generated code will appear here)
    
    //===== [ws] End Unifi Auto Generated Code =====//
    
    (Old pre-existing code will appear here)

    The Field Map this Field record is linked with.

    'IS - Message Header'**

    Map to field*

    Use this Field record to represent a field on a source/target table.

    <false>

    Path

    Where in the payload the data will be placed.

    'message'

    Property

    The property in the payload the data will be written to.

    'header'

    Inbound*

    Set to true to use for inbound Messages.

    <true>

    Outbound*

    Set to true to use for outbound Messages.

    <false>

    Name*

    The name of your field map. (If left unedited, it will append the word 'Copy' to the existing name.)

    <Your Name>

    Message*

    The Message this Field record is linked with.

    'UpdateIncidentInbound'

    Description

    Describe what this field is for and any specific details that might help you in future.

    ‘The protocol message header’

    Active*

    Set to true to use this Field record for processing.

    <true>

    short_description

    'PI - String'*

    description

    'PI - String'*

    Path

    Where in the payload the data will be placed.

    ‘detail’

    Inbound

    Set to true to use for inbound Messages.

    <true>

    Outbound

    Set to true to use for outbound Messages.

    <false>

    Element

    The field on the source/target table this Field record is mapped to.

    'Description'

    Property*

    The property in the payload the data will be written to.

    Automatically populated

    Description

    Describe what this field is for and any specific details that might help you in future.

    'The incident's description'

    technical documentation
    here

    Field map

    urgency

    Choice

    state

    Choice

    comments

    Journal field

    work_notes

    Journal field

    Field map

    The Field Map this Field record is linked with.

    'IG - Reference'**

    Map to field*

    Use this Field record to represent a field on a source/target table.

    <true>

    Table*

    The primary source/target table that this Field record is mapped to.

    'Incident' [incident]

    Element

    The field on the source/target table this Field record is mapped to.

    'Caller'

    Path

    Where in the payload the data will be placed.

    'detail'

    Property*

    The property in the payload the data will be written to.

    Automatically populated

    Inbound*

    Set to true to use for inbound Messages.

    <true>

    Outbound*

    Set to true to use for outbound Messages.

    <true>

    Field map

    The Field Map this Field record is linked with.

    'IG - String'**

    Map to field*

    Use this Field record to represent a field on a source/target table.

    <true>

    Table*

    The primary source/target table that this Field record is mapped to.

    'Incident' [incident]

    Element

    The field on the source/target table this Field record is mapped to.

    'Short description'

    Path

    Where in the payload the data will be placed.

    'detail'

    Property*

    The property in the payload the data will be written to.

    Automatically populated

    Inbound*

    Set to true to use for inbound Messages.

    <true>

    Outbound*

    Set to true to use for outbound Messages.

    <true>

    Field map

    The Field Map this Field record is linked with.

    'IG - Choice'**

    Map to field*

    Use this Field record to represent a field on a source/target table.

    <true>

    Table*

    The primary source/target table that this Field record is mapped to.

    'Incident' [incident]

    Element

    The field on the source/target table this Field record is mapped to.

    'State'

    Path

    Where in the payload the data will be placed.

    'detail'

    Property*

    The property in the payload the data will be written to.

    Automatically populated

    Inbound*

    Set to true to use for inbound Messages.

    <true>

    Outbound*

    Set to true to use for outbound Messages.

    <true>

    CreateIncident Fields

    We will utilise the Field & Field Map records to configure the Message Scripts for the CreateIncident Message.

    Fields & Field Maps

    Depending on your requirements, you will need to create Field records for each of the relevant Incident record field elements (see the table below for an example). For the sake of brevity, this Guide will focus on a select few. If you wish, however, you are free to continue & configure the remaining Field records. The table below lists an example of the Incident record field elements you may wish to map and the relevant Field Maps required to configure each Field record. For a fuller definition of available Field Maps, please see the relevant page in our technical documentation.

    Incident Field
    Field Map

    *caller_id: we have chosen String type here because we are integrating with the table API. This will return the sys id of the caller as a string value. Note: If we were integrating Unifi to Unifi we may use a Reference type which would return the caller as an object with "value", "link" & "display_value" elements.

    The Field records we will focus on will be for Caller (String), Short description (String) and State (Choice).

    Copy Field Maps

    If you haven't already, you will need to copy the relevant additional Field Maps for the CreateIncident Field records as follows:

    • String

    • Choice

    See (on the 'CreateIncidentResponse Fields' page) for details.

    Field: incident.caller_id

    In Unifi Integration Designer, from the CreateIncident page, navigate to Message > Fields. Click New.

    The fields to be configured for the 'incident.caller_id' New Field modal are as follows:

    Field
    Description
    Value

    *These fields are automatically defaulted to true, or automatically populated.

    **Field map: Value may vary. Choose the copy Field Map you created for your Integration.

    Your 'incident.caller_id' New Field modal should look like this:

    Submit the record.

    You will be redirected back to the Fields page of the CreateIncident Message.

    Field: incident.short_description

    Because the incident.short_description Field record is the same 'type' (PI - String) & the majority of the settings are the same as the previously configured Field, it will be quicker to copy the incident.caller_id Field & make a few minor changes.

    Feature Alert: The 'result.sys_id' Field is visible and inactive. It is an integration level Field which was automatically created by Unifi at the time we created the Message level record (in CreateIncidentResponse Fields). We'll talk in more detail about this feature in the following section.

    Click the ellipsis next to the incident.caller_id Field record & click Copy.

    The fields to edit for the Copy Field modal are as follows:

    Field
    Description
    Value

    *This field is automatically populated.

    Your Copy Field modal should look like this:

    Click Copy.

    You will be redirected to the Details page of the newly created incident.short_description Field record.

    The following info message is also displayed (which can be closed):

    Field inheritance is set to true by default. This means the record will be updated with integration-level Field values when saved (except for Active, Inherit and Message values). Uncheck the Inherit field to configure locally. For more information on Field Inheritance click .

    Field: incident.state

    Field records can exist at both the Integration and the Message level (a Field record exists at the Integration level if it isn't linked to a Message i.e. the 'Message' field element is left blank). We noted previously that an Integration level Field record is automatically created when we create one at the Message level. We will utilise and configure both when mapping 'incident.state'.

    The 'incident.state' Field record is a Choice 'type' Field. These are used when you’re mapping choice field elements with static values that don't change per Message (e.g. State, Impact, Urgency) i.e. you're not going to have one set of choices/values for create and another for update.

    Rather than configure choices for each Message, configure choices once at the Integration level. This means we only need define them once. The Field Map will take care of it and any 'incident.state' Field records that are set at the Message level (i.e. with a value in the 'Message' field) would use the choices configured at the Integration level.

    We'll first configure the Message level Field and then move on to configure the choices on its Integration level counterpart.

    Field: incident.state (Message level)

    There is no need to 'Generate field choices' for Message level Field records because the Field Map always looks for them on an Integration level Field which has the same name.

    To quickly navigate to the CreateIncident Message from the Details page of the newly created incident.short_description Field record...

    ...click the 'Preview' icon to the left of the Message field.

    From the CreatIncident Message, navigate to Message > Fields. Click New.

    The fields to be configured for our 'incident.state' (Message level) New Field modal are as follows:

    Field
    Description
    Value

    *These fields are automatically defaulted to true, or automatically populated.

    **Field map: Value may vary. Choose the copy Field Map you created for your Integration.

    Your 'incident.state' (Message level) New Field modal should look like this:

    Submit the record.

    You will be redirected back to the Fields page of the CreateIncident Message.

    Field: incident.state (Integration level)

    We will need to 'Generate field choices' for this Integration level Choice 'type' Field.

    Navigate to the 'Fields' icon to open the Fields page.

    Click to open the incident.state (Integration level) Field record (the one where Message is empty).

    The incident.state Field record opens to the Details page.

    Navigate to Field > Field Choices.

    Click Generate field choices.

    Click Generate on the 'Generate field choices' modal which displays.

    The Field Choices are generated & now visible in the list.

    At this stage, you could carry on and configure the remaining Field records for the rest of the Incident fields (as per the table at the top of this section). However, we will now run the Build process to auto-generate our Message Scripts.

    Build

    Now that we’ve configured the Field records for the CreateIncident message, we are ready to build our message scripts.

    From the CreateIncident Message, navigate to Message > Fields.

    The following Field records should now be in place for your CreateIncident messsage:

    Click on Build Message.

    You will see the 'Message build successful' Info Message.

    Navigate to Advanced > Script Editor to view the auto-generated code.

    Your Script Editor fields should look like this:

    Message Scripts

    The newly auto-generated code will appear between a Begin & End Comment immediately prior to any code that may already be there (pre-existing code will be retained).

    We will now examine our new, auto-generated Message Scripts.

    Source to Stage:

    Stage to Request:

    We are now ready to Test our CreateIncident Message.

    Before we do, let's view the Trigger which Unifi automatically created when we ran 'Build Message'.

    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    x_snd_eb.ws_console.checkpoint("MessageScript")
    
    x_snd_eb.ws_console.execute("Mapping message.header [x_snd_eb_field.do?sys_id=ca3a65dc1ba57c1090dfdb9ebd4bcb90]", function () {
      log.debug("Field map: PI - Message Header [x_snd_eb_field_map.do?sys_id=a225651c1ba57c1090dfdb9ebd4bcbeb]");
      payload = payload || {};
      payload.message = payload.message || {};
      var $payload = payload.message;
      
      // Messge identifiers
      $stage.$message_name = $payload.name;
      $stage.$time_stamp   = $payload.time_stamp;
      
      // Task references
      stage.internal_reference = $payload.target_reference || '';
      stage.external_reference = $payload.source_reference || '';
      
      // Transaction identifiers
      transaction.external_message_id = $payload.source_id || '';
      
      
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.short_description [x_snd_eb_field.do?sys_id=168aa99c1ba57c1090dfdb9ebd4bcbee]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      payload.detail = payload.detail || {};
      var $payload = payload.detail;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory && $payload.short_description == undefined) {
        throw 'Mandatory field short_description was not provided';
      } else {
        $stage.short_description = $payload.short_description;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.description [x_snd_eb_field.do?sys_id=6178b5181be57c1090dfdb9ebd4bcbb1]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      payload.detail = payload.detail || {};
      var $payload = payload.detail;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory && $payload.description == undefined) {
        throw 'Mandatory field description was not provided';
      } else {
        $stage.description = $payload.description;
      }
    
    });
    
    var error = x_snd_eb.ws_console.findCheckpointError("MessageScript");
    if (error) throw error.message;
    
    //===== [ws] End Unifi Auto Generated Code =====//
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    x_snd_eb.ws_console.checkpoint("MessageScript")
    
    x_snd_eb.ws_console.execute("Mapping incident.short_description [x_snd_eb_field.do?sys_id=168aa99c1ba57c1090dfdb9ebd4bcbee]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory && $stage.short_description == '') {
        throw 'Mandatory field short_description was not provided';
      } else {
        target.short_description = '' + ($stage.short_description || default_value);
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.description [x_snd_eb_field.do?sys_id=6178b5181be57c1090dfdb9ebd4bcbb1]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory && $stage.description == '') {
        throw 'Mandatory field description was not provided';
      } else {
        target.description = '' + ($stage.description || default_value);
      }
    
    });
    
    var error = x_snd_eb.ws_console.findCheckpointError("MessageScript");
    if (error) throw error.message;
    
    //===== [ws] End Unifi Auto Generated Code =====//

    comments

    String

    worknotes

    String

    The Field Map this Field record is linked with.

    'PI - String'**

    Map to field*

    Use this Field record to represent a field on a source/target table.

    <true>

    Table*

    The primary source/target table that this Field record is mapped to.

    'Incident '[incident]

    Element

    The field on the source/target table this Field record is mapped to.

    'Caller'

    Property*

    The property in the payload the data will be written to.

    Automatically populated

    Inbound*

    Set to true to use for inbound Messages.

    <false>

    Outbound*

    Set to true to use for outbound Messages.

    <true>

    The Field Map this Field record is linked with.

    'PI - Choice'**

    Map to field*

    Use this Field record to represent a field on a source/target table.

    <true>

    Table*

    The primary source/target table that this Field record is mapped to.

    'Incident' [incident]

    Element

    The field on the source/target table this Field record is mapped to.

    'State'

    Property*

    The property in the payload the data will be written to.

    Automatically populated

    Inbound*

    Set to true to use for inbound Messages.

    <false>

    Outbound*

    Set to true to use for outbound Messages.

    <true>

    caller_id*

    String

    short_description

    String

    description

    String

    category

    Choice

    impact

    Choice

    urgency

    Choice

    state

    Message*

    The Message this Field record is linked with.

    'CreateIncident'

    Description

    Describe what this field is for and any specific details that might help you in future.

    'The caller on this incident'

    Active*

    Set to true to use this Field record for processing.

    <true>

    Element

    The field on the source/target table this Field record is mapped to.

    'Short description'

    Property*

    The property in the payload the data will be written to.

    Automatically populated

    Description

    Describe what this field is for and any specific details that might help you in future.

    'The short description of this incident'

    Message*

    The Message this Field record is linked with.

    'CreateIncident'

    Description

    Describe what this field is for and any specific details that might help you in future.

    'The incident lifecycle state'

    Active*

    Set to true to use this Field record for processing.

    <true>

    Copy Field Maps
    here

    Choice

    Field map

    Field map

    ResolveIncidentInbound Fields

    We will utilise the Field & Field Map records to configure the Message Scripts for the ResolveIncidentInbound Message.

    Field records can represent the handling of two categories of data: either a data object which carries transaction specific data (e.g. name, time stamp, source id etc.), or a field element on the bonded record (e.g. Short description).

    The 'message.header', 'incident.description' and 'incident.short_description' Field records are already be in place because they were also copied when we copied the Message. We will now configure Field records for the remaining field elements we have chosen to map.

    Fields & Field Maps

    Depending on your requirements, you will need to create Field records for each of the relevant Incident record field elements you wish to map. As we have chosen to include the state, close_notes & close_code elements in both the Setup script & Response script of the Poll Processor, this Guide will focus on those three only. If you wish, however, you are free to configure other Field records as required (ensuring you also define them in both the Setup Script & Response script of the Poll Processor).

    For a full description of the available Field Maps, please see the relevant page in our .

    The table below lists the Incident record field elements we will map and the relevant Field Maps required to configure each Field record.

    Incident Field
    Field Map

    *Field map: Values may vary (dependent on your configuration of the copies). Choose the copy Field Maps you created earlier.

    Field: incident.state (Message level)

    Unifi created the incident.state (Integration level) Field when we first created the Message level record whilst following the Outbound Incident Guide. It is, therefore, displayed in the Fields list on the ResolveIncidentInbound Message with Active set to false.

    From the ResolveIncidentInbound Message, navigate to Message > Fields.

    Your ResolveIncident Message Fields page should look like this:

    Find the incident.state (Integration level) Field & set Active to true.

    The empty circle icon next to the Field name turns green & contains a green ‘check’ (to indicate that Message level configuration exists for this Field) when we set Active to true. (The ‘Build Integration’ button became visible in the banner when we copied the UpdateIncidentInbound Message).

    By simply setting the Active flag to true on the Integration level Field record listed on the Message, Unifi has created the Message level counterpart.

    Click to open the newly created incident.state (Message level) Field record for further editing.

    The incident.state Field record opens to the Details page.

    To edit, set Inherit to False.

    Save the record (the fields now become editable).

    Field inheritance is set to true by default. This means the record will be updated with integration-level Field values when saved (except for Active, Inherit and Message values).

    You can either uncheck the Inherit field to configure locally, or edit the integration-level Field record. We will choose to uncheck the Inherit field and configure locally, because we want this inbound Field to be different to the outbound one (and the integration-level Field which was automatically created at that time).

    For more information on Field Inheritance click .

    Navigate to Field > Settings.

    The fields to be changed to configure the incident.state (Message level) Field record are as follows:

    Field
    Description
    Value

    Your incident.state (Message level) Settings form should look like this:

    Save the record.

    Field: incident.close_notes

    As with incident.state, Unifi created the incident.close_notes (Integration level) Field when we first created the Message level record whilst following the Outbound Incident Guide. We will now create the Message level counterpart for the ResolveIncidentInbound Message.

    To quickly navigate to the ResolveIncidentInbound Message from the Details page of the incident.state Field record...

    ...click the ‘Preview’ icon to the left of the Message field.

    From the ResolveIncidentInbound Message, navigate to Message > Fields.

    Find the incident.close_notes (Integration level) Field & set Active to true.

    Click to open the newly created incident.close_notes (Message level) Field record for further editing.

    The incident.close_notes Field record opens to the Details page.

    To edit, set Inherit to False.

    Save the record (the fields now become editable).

    Navigate to Field > Settings.

    The fields to be changed to configure the incident.close_notes (Message level) Field record are as follows:

    Field
    Description
    Value

    *Mandatory should already be set to true.

    Your 'incident.close_notes' (Message level) Settings form should look like this:

    Save the record.

    Field: incident.close_code

    Again, Unifi created the incident.close_code (Integration level) Field when we first created the Message level record whilst following the Outbound Incident Guide. We will also create the Message level counterpart for the ResolveIncidentInbound Message.

    As with 'incident.state' the 'incident.close_code' Field record is a Choice 'type' Field. We have already configured the choices at the Integration level, so there's no need to 'Generate field choices' for this Message level record because the Field Map always looks for them on an Integration level Field which has the same name.

    From the ResolveIncidentInbound Message, navigate to Message > Fields.

    Find the incident.close_code (Integration level) Field & set Active to true.

    Click to open the newly created incident.close_code (Message level) Field record for further editing.

    The incident.close_code Field record opens to the Details page.

    To edit, set Inherit to False.

    Save the record (the fields now become editable).

    Navigate to Field > Settings.

    The fields to be changed to configure the incident.close_code (Integration level) Field record are as follows:

    Field
    Description
    Value

    *Mandatory should already be set to true.

    Your ‘incident.close_code’ (Message level) Field record should look like this:

    Save the record.

    Build

    Now that we’ve configured the Field records for the ResolveIncidentInbound message, we are ready to build our message scripts.

    From the ResolveIncidentInbound message., navigate to Message > Fields.

    The following Field records should now be in place for your ResolveIncidentInbound messsage:

    Click on Build Message.

    You will see the 'Message build successful' Info Message.

    Navigate to Advanced > Script Editor > View > Inbound to view the auto-generated code.

    Your Script Editor fields should look like this:

    Message Scripts

    The Message Scripts reflect the mappings as per this Guide. Your scripts might differ depending on which Fields you chose to map (& defined in the payload). We will look at the Message Scripts in turn.

    Payload to Stage:

    Your Payload to Stage Message Script should look like this:

    Stage to Target:

    Your Stage to Target Message Script should look like this:

    Because we have already made a few changes to allow for inbound Message & Bond Identification in our earlier 'Incident Update Poller' Guide, we can now move on to Testing.

    ResolveIncident Fields

    We will utilise the Field & Field Map records to configure the Message Scripts for the ResolveIncident Message.

    The 'incident.comments', 'incident.work_notes' and 'incident.short_description' Field records are already in place because they were also copied when we copied the Message. We can choose to include, or exclude as many of those and the Integration level ones that are available depending on our requirements (by either activating or deactivating the relevant Fields). We will choose to keep the existing Message level Fields and add the available incident.state (Integration level) Field.

    Field: incident.state (Message level)

    By simply setting the Active flag to true on the Integration level Field record listed on the Message, Unifi will automatically create the Message level counterpart.

    Navigate to Message > Fields.

    Your ResolveIncident Message Fields page should look like this:

    Find the incident.state (Integration level) Field & set Active to true.

    The empty circle icon next to the Field name turns green & contains a green 'check' (to indicate that Message level configuration exists for this Field).

    We will now configure Field records for the two remaining Incident record field elements which are required.

    Fields & Field Maps

    The table below lists the Incident record field elements we will map and the relevant Field Maps required to configure each Field record.

    Incident Field
    Field Map

    *Field map: Values may vary (dependent on your configuration of the copies). Choose the copy Field Maps you created earlier.

    Field: incident.close_code (Message level)

    There is no need to 'Generate field choices' for Message level Field records because the Field Map always looks for them on an Integration level Field which has the same name.

    As with 'incident.state' the 'incident.close_code' Field record is a Choice 'type' Field. We will, therefore, configure the choices once at the Integration level. We'll first configure the Message level Field and then move on to configure the choices on its Integration level counterpart.

    From the Fields page, click New.

    The fields to be configured for our incident.close_code (Message level) New Field modal are as follows:

    Field
    Description
    Value

    *These fields are automatically defaulted to true, or automatically populated.

    **Field map: Value may vary. Choose the copy Field Map you created for your Integration.

    Your 'incident.close_code' (Message level) New Field modal should look like this:

    Submit the record.

    You will be redirected back to the Fields page of the ResolveIncident Message.

    Field: incident.close_code (Integration level)

    We will need to 'Generate field choices' for this Integration level Choice 'type' Field.

    Navigate to the 'Fields' icon to open the Fields page.

    Click to open the incident.close_code (Integration level) Field record (the one where Message is empty).

    The incident.close_code Field record opens to the Details page.

    Navigate to Field > Field Choices.

    Click Generate field choices.

    Click Generate on the 'Generate field choices' modal which displays.

    The Field Choices are generated & now visible in the list.

    Field: incident.close_notes

    Because the incident.close_notes Field record is the same 'type' (PI - String) & the majority of the settings are the same as the incident.work_notes Field, it will be quicker to copy that Field & make a few minor changes.

    From the ResolveIncident Message, navigate to Message > Fields.

    Click the ellipsis next to the incident.work_notes Field record & click Copy.

    The fields to edit for the Copy Field modal are as follows:

    Field
    Description
    Value

    *This field is automatically populated.

    Your 'incident.close_notes' Copy Field modal should look like this:

    Click Copy.

    You will be redirected to the Details page of the newly created incident.close_notes Field record.

    The "This message inherits its configuration from the integration-level field..." info message is also displayed (which can be closed).

    Field inheritance is set to true by default. This means the record will be updated with integration-level Field values when saved (except for Active, Inherit and Message values).

    You can either uncheck the Inherit field to configure locally, or edit the integration-level Field record. We will choose to edit the integration-level because it makes more sense to have the same settings for each message-level incident.close_notes Field (i.e. each will be mandatory).

    For more information on Field Inheritance click .

    Navigate to the 'Fields' icon to open the Fields page.

    Click to open the incident.close_notes (Integration level) Field record (the one where Message is empty).

    The incident.close_notes Field record opens to the Details page.

    Navigate to Field > Settings.

    Set Mandatory to true.

    Click Save.

    Build

    Now that we’ve configured the Field records for the ResolveIncident message, we are ready to build our message scripts.

    Navigate to the ResolveIncident message, then navigate to Message > Fields.

    The following Field records should now be in place for your ResolveIncident messsage:

    Click on Build Message.

    You will see the 'Message build successful' Info Message.

    Navigate to Advanced > Script Editor to view the auto-generated code.

    Your Script Editor fields should look like this:

    Message Scripts

    The newly auto-generated code will appear between a Begin & End Comment immediately prior to any code that was already there.

    We will now examine our new, auto-generated Message Scripts.

    Source to Stage:

    Stage to Request:

    We are now ready to Test the ResolveIncident Message.

    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    (New auto-generated code will appear here)
    
    //===== [ws] End Unifi Auto Generated Code =====//
    
    (Old pre-existing code will appear here)
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    x_snd_eb.ws_console.checkpoint("MessageScript")
    
    x_snd_eb.ws_console.execute("Mapping incident.caller_id [x_snd_eb_field.do?sys_id=3a5cbbbe1b51b81090dfdb9ebd4bcb66]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $stage.caller_id = '' + (source.caller_id || default_value);
      } else if (source.caller_id != '') {
        $stage.caller_id = '' + source.caller_id;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.short_description [x_snd_eb_field.do?sys_id=49debf3e1b51b81090dfdb9ebd4bcba5]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $stage.short_description = '' + (source.short_description || default_value);
      } else if (source.short_description != '') {
        $stage.short_description = '' + source.short_description;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.state [x_snd_eb_field.do?sys_id=f32e8cc31b91b81090dfdb9ebd4bcb09]", function () {
      log.debug("Field map: PI - Choice [x_snd_eb_field_map.do?sys_id=c7b97f7a1b51b81090dfdb9ebd4bcb62]");
      
      var default_value = (function () {
        return '';
      })();
      
      var field_choice;
      var is_mandatory = false;  
      
      if (!source.state.nil()) {
        field_choice = new GlideRecord('x_snd_eb_field_choice');
        field_choice.addQuery('table',         '=', 'incident');
        field_choice.addQuery('element',       '=', 'state');
        field_choice.addQuery('integration',   '=', '27be43a91b9db41090dfdb9ebd4bcb2e');
        field_choice.addQuery('field.message', '=', '');
        field_choice.addQuery('direction',     '=', 'Outbound');
        field_choice.addQuery('value',         '=', source.state);
        field_choice.addQuery('active',        '=', 'true');
        field_choice.query();
      
        if (field_choice.next()) {
          $stage.state = '' + field_choice.external_value;
        }
      } 
      
      if (!$stage.state) {
        $stage.state = '' + (source.state || '');
      }
      
      if (is_mandatory) {
        $stage.state = '' + (source.state || '');
      }
    
    });
    
    var error = x_snd_eb.ws_console.findCheckpointError("MessageScript");
    if (error) throw error.message;
    
    //===== [ws] End Unifi Auto Generated Code =====//
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    x_snd_eb.ws_console.checkpoint("MessageScript")
    
    x_snd_eb.ws_console.execute("Mapping incident.caller_id [x_snd_eb_field.do?sys_id=3a5cbbbe1b51b81090dfdb9ebd4bcb66]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      var $payload = payload;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $payload.caller_id = '' + $stage.caller_id;
      } else if ($stage.caller_id) {
        $payload.caller_id = '' + $stage.caller_id;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.short_description [x_snd_eb_field.do?sys_id=49debf3e1b51b81090dfdb9ebd4bcba5]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      var $payload = payload;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $payload.short_description = '' + $stage.short_description;
      } else if ($stage.short_description) {
        $payload.short_description = '' + $stage.short_description;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.state [x_snd_eb_field.do?sys_id=f32e8cc31b91b81090dfdb9ebd4bcb09]", function () {
      log.debug("Field map: PI - Choice [x_snd_eb_field_map.do?sys_id=c7b97f7a1b51b81090dfdb9ebd4bcb62]");
      payload = payload || {};
      var $payload = payload;
      
      var is_mandatory = false;  
      
      if (is_mandatory) {
        $payload.state = $stage.state;
      } else if ($stage.state) {
        $payload.state = $stage.state;
      }
    
    });
    
    var error = x_snd_eb.ws_console.findCheckpointError("MessageScript");
    if (error) throw error.message;
    
    //===== [ws] End Unifi Auto Generated Code =====//

    Set to true to make mandatory.

    <true>

    Set to true to make mandatory.

    <true>

    state

    'PI - Choice'*

    close_notes

    'PI - String'*

    close_code

    'PI - Choice'*

    Path

    Where in the payload the data will be placed.

    'detail'

    Inbound

    Set to true to use for inbound Messages.

    <true>

    Outbound

    Set to true to use for outbound Messages.

    <false>

    Path

    Where in the payload the data will be placed.

    'detail'

    Inbound

    Set to true to use for inbound Messages.

    <true>

    Outbound

    Set to true to use for outbound Messages.

    <false>

    Path

    Where in the payload the data will be placed.

    'detail'

    Inbound

    Set to true to use for inbound Messages.

    <true>

    Outbound

    Set to true to use for outbound Messages.

    <false>

    technical documentation
    here

    Mandatory*

    Mandatory*

    The Field Map this Field record is linked with.

    'PI - Choice'**

    Map to field*

    Use this Field record to represent a field on a source/target table.

    <true>

    Table*

    The primary source/target table that this Field record is mapped to.

    'Incident' [incident]

    Element

    The field on the source/target table this Field record is mapped to.

    'Resolution code'

    Property*

    The property in the payload the data will be written to.

    Automatically populated

    Inbound*

    Set to true to use for inbound Messages.

    <false>

    Outbound*

    Set to true to use for outbound Messages.

    <true>

    Mandatory

    Set to true to make mandatory.

    <true>

    close_code

    'PI - Choice'*

    close_notes

    'PI - String'*

    Message*

    The Message this Field record is linked with.

    'ResolveIncident'

    Description

    The description of this Field record.

    'The incident's Resolution code (Close code in ServiceNow)'

    Active*

    Set to true to use this Field record for processing.

    <true>

    Element

    The field on the source/target table this Field record is mapped to.

    'Resolution notes'

    Property*

    The property in the payload the data will be written to.

    Automatically populated

    Description

    The description of this Field record.

    'The incident's Resolution notes (Close notes in ServiceNow)'

    here

    Field map

    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    x_snd_eb.ws_console.checkpoint("MessageScript")
    
    x_snd_eb.ws_console.execute("Mapping message.header [x_snd_eb_field.do?sys_id=0f7216b21be9f05090dfdb9ebd4bcb22]", function () {
      log.debug("Field map: PI - Message Header [x_snd_eb_field_map.do?sys_id=a225651c1ba57c1090dfdb9ebd4bcbeb]");
      payload = payload || {};
      payload.message = payload.message || {};
      var $payload = payload.message;
      
      // Messge identifiers
      $stage.$message_name = $payload.name;
      $stage.$time_stamp   = $payload.time_stamp;
      
      // Task references
      stage.internal_reference = $payload.target_reference || '';
      stage.external_reference = $payload.source_reference || '';
      
      // Transaction identifiers
      transaction.external_message_id = $payload.source_id || '';
      
      
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.short_description [x_snd_eb_field.do?sys_id=077216b21be9f05090dfdb9ebd4bcb1c]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      payload.detail = payload.detail || {};
      var $payload = payload.detail;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory && $payload.short_description == undefined) {
        throw 'Mandatory field short_description was not provided';
      } else {
        $stage.short_description = $payload.short_description;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.description [x_snd_eb_field.do?sys_id=0f7216b21be9f05090dfdb9ebd4bcb20]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      payload.detail = payload.detail || {};
      var $payload = payload.detail;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory && $payload.description == undefined) {
        throw 'Mandatory field description was not provided';
      } else {
        $stage.description = $payload.description;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.state [x_snd_eb_field.do?sys_id=daba16b21be9f05090dfdb9ebd4bcb4e]", function () {
      log.debug("Field map: PI - Choice [x_snd_eb_field_map.do?sys_id=c7b97f7a1b51b81090dfdb9ebd4bcb62]");
      payload = payload || {};
      payload.detail = payload.detail || {};
      var $payload = payload.detail;
      
      var is_mandatory = false;  
      
      if (is_mandatory && $payload.state == undefined) {
        throw 'Mandatory field state was not provided';
      } else {
        $stage.state = $payload.state;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.close_code [x_snd_eb_field.do?sys_id=bdfa22be1be9f05090dfdb9ebd4bcb9b]", function () {
      log.debug("Field map: PI - Choice [x_snd_eb_field_map.do?sys_id=c7b97f7a1b51b81090dfdb9ebd4bcb62]");
      payload = payload || {};
      payload.detail = payload.detail || {};
      var $payload = payload.detail;
      
      var is_mandatory = true;  
      
      if (is_mandatory && $payload.close_code == undefined) {
        throw 'Mandatory field close_code was not provided';
      } else {
        $stage.close_code = $payload.close_code;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.close_notes [x_snd_eb_field.do?sys_id=c9532af61be9f05090dfdb9ebd4bcbb4]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      payload.detail = payload.detail || {};
      var $payload = payload.detail;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = true;
      
      if (is_mandatory && $payload.close_notes == undefined) {
        throw 'Mandatory field close_notes was not provided';
      } else {
        $stage.close_notes = $payload.close_notes;
      }
    
    });
    
    var error = x_snd_eb.ws_console.findCheckpointError("MessageScript");
    if (error) throw error.message;
    
    //===== [ws] End Unifi Auto Generated Code =====//
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    x_snd_eb.ws_console.checkpoint("MessageScript")
    
    x_snd_eb.ws_console.execute("Mapping incident.short_description [x_snd_eb_field.do?sys_id=077216b21be9f05090dfdb9ebd4bcb1c]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory && $stage.short_description == '') {
        throw 'Mandatory field short_description was not provided';
      } else {
        target.short_description = '' + ($stage.short_description || default_value);
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.description [x_snd_eb_field.do?sys_id=0f7216b21be9f05090dfdb9ebd4bcb20]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory && $stage.description == '') {
        throw 'Mandatory field description was not provided';
      } else {
        target.description = '' + ($stage.description || default_value);
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.state [x_snd_eb_field.do?sys_id=daba16b21be9f05090dfdb9ebd4bcb4e]", function () {
      log.debug("Field map: PI - Choice [x_snd_eb_field_map.do?sys_id=c7b97f7a1b51b81090dfdb9ebd4bcb62]");
      
      var default_value = (function () {
        return '';
      })();
      
      var is_mandatory = false;  
      
      if (is_mandatory && $stage.state == undefined) {
        throw 'Mandatory field state was not provided';
      } else {
        var field_choice;
        
        field_choice = new GlideRecord('x_snd_eb_field_choice');
        field_choice.addQuery('table',          '=', 'incident');
        field_choice.addQuery('element',        '=', 'state');
        field_choice.addQuery('integration',    '=', '27be43a91b9db41090dfdb9ebd4bcb2e');
        field_choice.addQuery('field.message',  '=', '');
        field_choice.addQuery('direction',      '=', 'Inbound');
        field_choice.addQuery('external_value', '=', $stage.state);
        field_choice.addQuery('active',         '=', 'true');
        field_choice.query();
      
        if (field_choice.next()) {
          target.state = field_choice.value;
        } else {
          target.state = $stage.state;
        }
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.close_code [x_snd_eb_field.do?sys_id=bdfa22be1be9f05090dfdb9ebd4bcb9b]", function () {
      log.debug("Field map: PI - Choice [x_snd_eb_field_map.do?sys_id=c7b97f7a1b51b81090dfdb9ebd4bcb62]");
      
      var default_value = (function () {
        return '';
      })();
      
      var is_mandatory = true;  
      
      if (is_mandatory && $stage.close_code == undefined) {
        throw 'Mandatory field close_code was not provided';
      } else {
        var field_choice;
        
        field_choice = new GlideRecord('x_snd_eb_field_choice');
        field_choice.addQuery('table',          '=', 'incident');
        field_choice.addQuery('element',        '=', 'close_code');
        field_choice.addQuery('integration',    '=', '27be43a91b9db41090dfdb9ebd4bcb2e');
        field_choice.addQuery('field.message',  '=', '');
        field_choice.addQuery('direction',      '=', 'Inbound');
        field_choice.addQuery('external_value', '=', $stage.close_code);
        field_choice.addQuery('active',         '=', 'true');
        field_choice.query();
      
        if (field_choice.next()) {
          target.close_code = field_choice.value;
        } else {
          target.close_code = $stage.close_code;
        }
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.close_notes [x_snd_eb_field.do?sys_id=c9532af61be9f05090dfdb9ebd4bcbb4]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = true;
      
      if (is_mandatory && $stage.close_notes == '') {
        throw 'Mandatory field close_notes was not provided';
      } else {
        target.close_notes = '' + ($stage.close_notes || default_value);
      }
    
    });
    
    var error = x_snd_eb.ws_console.findCheckpointError("MessageScript");
    if (error) throw error.message;
    
    //===== [ws] End Unifi Auto Generated Code =====//
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    (New auto-generated code will appear here)
    
    //===== [ws] End Unifi Auto Generated Code =====//
    
    (Old pre-existing code will appear here)
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    x_snd_eb.ws_console.checkpoint("MessageScript")
    
    x_snd_eb.ws_console.execute("Mapping incident.short_description [x_snd_eb_field.do?sys_id=06fe6b771b193c1090dfdb9ebd4bcbe0]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $stage.short_description = '' + (source.short_description || default_value);
      } else if (source.short_description != '') {
        $stage.short_description = '' + source.short_description;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.state [x_snd_eb_field.do?sys_id=f2db33f71b193c1090dfdb9ebd4bcbc5]", function () {
      log.debug("Field map: PI - Choice [x_snd_eb_field_map.do?sys_id=c7b97f7a1b51b81090dfdb9ebd4bcb62]");
      
      var default_value = (function () {
        return '';
      })();
      
      var field_choice;
      var is_mandatory = false;  
      
      if (!source.state.nil()) {
        field_choice = new GlideRecord('x_snd_eb_field_choice');
        field_choice.addQuery('table',         '=', 'incident');
        field_choice.addQuery('element',       '=', 'state');
        field_choice.addQuery('integration',   '=', '27be43a91b9db41090dfdb9ebd4bcb2e');
        field_choice.addQuery('field.message', '=', '');
        field_choice.addQuery('direction',     '=', 'Outbound');
        field_choice.addQuery('value',         '=', source.state);
        field_choice.addQuery('active',        '=', 'true');
        field_choice.query();
      
        if (field_choice.next()) {
          $stage.state = '' + field_choice.external_value;
        }
      } 
      
      if (!$stage.state) {
        $stage.state = '' + (source.state || '');
      }
      
      if (is_mandatory) {
        $stage.state = '' + (source.state || '');
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.comments [x_snd_eb_field.do?sys_id=79fe6b771b193c1090dfdb9ebd4bcbcd]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $stage.comments = '' + (source.comments || default_value);
      } else if (source.comments != '') {
        $stage.comments = '' + source.comments;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.work_notes [x_snd_eb_field.do?sys_id=4efe6b771b193c1090dfdb9ebd4bcbd1]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $stage.work_notes = '' + (source.work_notes || default_value);
      } else if (source.work_notes != '') {
        $stage.work_notes = '' + source.work_notes;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.close_code [x_snd_eb_field.do?sys_id=eaaff7bb1b193c1090dfdb9ebd4bcb6f]", function () {
      log.debug("Field map: PI - Choice [x_snd_eb_field_map.do?sys_id=c7b97f7a1b51b81090dfdb9ebd4bcb62]");
      
      var default_value = (function () {
        return '';
      })();
      
      var field_choice;
      var is_mandatory = true;  
      
      if (!source.close_code.nil()) {
        field_choice = new GlideRecord('x_snd_eb_field_choice');
        field_choice.addQuery('table',         '=', 'incident');
        field_choice.addQuery('element',       '=', 'close_code');
        field_choice.addQuery('integration',   '=', '27be43a91b9db41090dfdb9ebd4bcb2e');
        field_choice.addQuery('field.message', '=', '');
        field_choice.addQuery('direction',     '=', 'Outbound');
        field_choice.addQuery('value',         '=', source.close_code);
        field_choice.addQuery('active',        '=', 'true');
        field_choice.query();
      
        if (field_choice.next()) {
          $stage.close_code = '' + field_choice.external_value;
        }
      } 
      
      if (!$stage.close_code) {
        $stage.close_code = '' + (source.close_code || '');
      }
      
      if (is_mandatory) {
        $stage.close_code = '' + (source.close_code || '');
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.close_notes [x_snd_eb_field.do?sys_id=0bd508401b693c1090dfdb9ebd4bcb5a]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      
      var default_value = (function () {
        return '';
      })();
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = true;
      
      if (is_mandatory) {
        $stage.close_notes = '' + (source.close_notes || default_value);
      } else if (source.close_notes != '') {
        $stage.close_notes = '' + source.close_notes;
      }
    
    });
    
    var error = x_snd_eb.ws_console.findCheckpointError("MessageScript");
    if (error) throw error.message;
    
    //===== [ws] End Unifi Auto Generated Code =====//
    //===== [ws] Begin Unifi Auto Generated Code =====//
    
    /*
     * This code (between the Begin and End comments) is generated from the
     * Field and Field mapping records which are configured as part of the integration.
     *
     * All code either above or below the comments will be automatically maintained
     * through the build cycle.
     *
     * WARNING: Do not edit the Begin or End comments.
     */
    
    x_snd_eb.ws_console.checkpoint("MessageScript")
    
    x_snd_eb.ws_console.execute("Mapping incident.short_description [x_snd_eb_field.do?sys_id=06fe6b771b193c1090dfdb9ebd4bcbe0]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      var $payload = payload;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $payload.short_description = '' + $stage.short_description;
      } else if ($stage.short_description) {
        $payload.short_description = '' + $stage.short_description;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.state [x_snd_eb_field.do?sys_id=f2db33f71b193c1090dfdb9ebd4bcbc5]", function () {
      log.debug("Field map: PI - Choice [x_snd_eb_field_map.do?sys_id=c7b97f7a1b51b81090dfdb9ebd4bcb62]");
      payload = payload || {};
      var $payload = payload;
      
      var is_mandatory = false;  
      
      if (is_mandatory) {
        $payload.state = $stage.state;
      } else if ($stage.state) {
        $payload.state = $stage.state;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.comments [x_snd_eb_field.do?sys_id=79fe6b771b193c1090dfdb9ebd4bcbcd]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      var $payload = payload;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $payload.comments = '' + $stage.comments;
      } else if ($stage.comments) {
        $payload.comments = '' + $stage.comments;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.work_notes [x_snd_eb_field.do?sys_id=4efe6b771b193c1090dfdb9ebd4bcbd1]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      var $payload = payload;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = false;
      
      if (is_mandatory) {
        $payload.work_notes = '' + $stage.work_notes;
      } else if ($stage.work_notes) {
        $payload.work_notes = '' + $stage.work_notes;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.close_code [x_snd_eb_field.do?sys_id=eaaff7bb1b193c1090dfdb9ebd4bcb6f]", function () {
      log.debug("Field map: PI - Choice [x_snd_eb_field_map.do?sys_id=c7b97f7a1b51b81090dfdb9ebd4bcb62]");
      payload = payload || {};
      var $payload = payload;
      
      var is_mandatory = true;  
      
      if (is_mandatory) {
        $payload.close_code = $stage.close_code;
      } else if ($stage.close_code) {
        $payload.close_code = $stage.close_code;
      }
    
    });
    
    
    x_snd_eb.ws_console.execute("Mapping incident.close_notes [x_snd_eb_field.do?sys_id=0bd508401b693c1090dfdb9ebd4bcb5a]", function () {
      log.debug("Field map: PI - String [x_snd_eb_field_map.do?sys_id=da997f7a1b51b81090dfdb9ebd4bcb5e]");
      payload = payload || {};
      var $payload = payload;
      
      // Determines whether this instance of the field map is for a mandatory field
      var is_mandatory = true;
      
      if (is_mandatory) {
        $payload.close_notes = '' + $stage.close_notes;
      } else if ($stage.close_notes) {
        $payload.close_notes = '' + $stage.close_notes;
      }
    
    });
    
    var error = x_snd_eb.ws_console.findCheckpointError("MessageScript");
    if (error) throw error.message;
    
    //===== [ws] End Unifi Auto Generated Code =====//