Skip to content
  • There are no suggestions because the search field is empty.

Adding Device Data to Proactive Surveys in HappySignals

Extend proactive survey context in HappySignals by adding device data via ServiceNow script includes. Detailed technical steps, best practices, and troubleshooting.

Adding Device Data to Proactive Surveys in HappySignals

Purpose

This article is designed for Proactive IT Experience 2.x and explains how to extend the context data of proactive surveys to include device information (e.g., Laptops and Computers) using the HappyProactiveCustomConfig script and ServiceNow CMDB.

Prerequisites
  • Scripted Extension Points are enabled in the HappySignals application
  • Access to the relevant asset or CMDB tables in ServiceNow
  • IT Experience Administrator or Administrator role

Implementation Steps

1. Identify the Correct Table

  • Confirm which table contains your device records. In most cases, this is alm_asset, but it can vary.
  • If your organization uses CMDB CI Computer, copy the table name from the URL and replace alm_asset in the script accordingly.

Performance considerations

  • Ensure commonly queried fields, such as assigned_to and install_status are indexed in your asset table.
  • If only the most recently assigned device is required, consider limiting the query after ordering results to reduce processing overhead.

2. Add Logic to HappyProactiveCustomConfig

Insert a condition and function to fetch device details and attach them as URL parameters for the survey:

if (obj.survey_id.toString() == "computer") {
var asset = this.__getAssetDetails(obj.user.toString());
if (!gs.nil(asset)) {
for (key in asset) {
conf[key] = asset[key];
}
}
}
The survey_id value refers to the proactive survey type.

3. Function to Retrieve Device Details

Update the function based on your table and field names:

__getAssetDetails: function(user) {
var assetDetails = { "devices": 0 };
if (gs.nil(user)) return null;
try {
var assets = new GlideRecord('alm_asset'); // Replace if using CMDB CI Computer
assets.addQuery('model_category.name', 'Computer'); // Adjust if using custom category
assets.addQuery('install_status', '101'); // Use numeric value for "in use"
assets.addQuery('assigned_to', user);
assets.orderByDesc('assigned'); // Ensures latest assigned device is selected
assets.query();
while (assets.next()) {
if (assetDetails.devices == 0) {
assetDetails.pc_type = this.__getFieldValue(assets, 'model_category');
assetDetails.pc_model = this.__getFieldValue(assets, 'model.name');
assetDetails.pc_manuf = this.__getFieldValue(assets, 'model.manufacturer');
assetDetails.pc_os = this.__getFieldValue(assets, 'ci.os');
assetDetails.pc_insdate = this.__getFieldValue(assets, 'install_date', 'time');
assetDetails.pc_age = this.__getAssetAgeRange(assets, 'install_date');
}
assetDetails.devices++;
}
} catch (e) {
gs.error("Error collecting asset details: " + e);
}
return assetDetails;
}

For thepc_age you still need to define the helper function by adding it to the very end of the script:

    __getAssetAgeRange: function(asset, dateField) {

        if (gs.nil(asset) || !asset.isValid()) {
            gs.warn("HappyItExCustomConfig - __getAssetAgeRange: Invalid asset passed, could not determine age range.");
            return "";
        }

        if (gs.nil(dateField) || gs.nil(asset[dateField])) {
            gs.warn("HappyItExCustomConfig - __getAssetAgeRange: Invalid date field passed, could not determine age range.");
            return "";
        }

        // key is the range name passed to HappySignals
        // value is the cut-off age in years for that range
        // DO NOT ADJUST THIS RANGE MAP
        var ageRanges = {
            "0-2 months": 0.16667,
            "2-6 months": 0.5,
            "6 months - 1 year": 1,
            "1-2 years": 2,
            "2-3 years": 3,
            "3-4 years": 4,
            ">4 years": 1000 // this is the last range, it will catch everything older than 4 years
        };

        var installed = new GlideDateTime(asset[dateField].toString()),
            currentDate = new GlideDateTime(),
            deviceAgeYears = GlideDateTime.subtract(installed, currentDate).getDayPart() / 365;

        for (range in ageRanges) {
            if (deviceAgeYears < ageRanges[range]) {
                return range; // return the first range that the device age falls into
            }
        }
        return "";
  },

Make sure the snippets above come before the line:

type: "HappyProactiveCustomConfig",

Device context fields

The following fields are added dynamically to the survey context:

Field name Description
devices Number of active devices assigned to the user
pc_type Device category
pc_model Device model
pc_manuf Manufacturer
pc_os Operating system
pc_insdate Installation date
pc_age Device age 

4. Mobile Device Surveys

Create a similar function for mobile devices:

assets.addQuery('model_category.name', 'Mobile phone');
assets.addQuery('install_status', 'in use'); // or numeric equivalent

Rename fields to avoid duplication:

assetDetails.mobile_type = this.__getFieldValue(assets, 'model_category');
assetDetails.mobile_model = this.__getFieldValue(assets, 'model.name');
``

Best Practices

  • Preserve existing logic: Do not remove existing scripts (e.g., Laptop and Computers). Add new ones alongside.
  • Use clear field names: Examples: pc_model, mobile_model.
  • Ensure data security: Do not include personally identifiable information (PII).
  • Test before production: Validate with a test survey.
  • Document changes: Add comments in the script and update internal documentation.

Troubleshooting

  • Device table mismatch: If alm_asset does not exist, check your CMDB structure. Common alternatives include cmdb_ci_computer or custom asset tables.
  • Field names differ: Use Show XML or Dictionary in ServiceNow to confirm exact field names (e.g., install_status, assigned_to).
  • Install status values: If “in use” is not recognized, verify numeric codes (commonly 101 for active/in use).
  • Multiple devices per user: The script uses orderByDesc('assigned') to select the most recently assigned device.
  • Script errors: Check system logs for gs.error messages and confirm that the Scripted Extension Point is active.