Multi-response output controls

  • Release version: Zurich
  • Updated July 31, 2025
  • 2 minutes to read
  • Summarize
    Summarized using AI
    This content was generated using new OpenAI-powered functionality. Results are provided on an as is basis and are not guaranteed to be accurate or complete.

    Summary of Multi-response output controls

    This feature enables configuration of multi-step user input controls within ServiceNow virtual agent interactions. It allows you to implement controls that require several sequential inputs, such as paginated pickers or stepwise date selection (year, month, day). This functionality is particularly useful for managing complex user input flows by maintaining context across multiple interactions.

    Show full answer Show less

    Key Features

    • Context Data Management APIs: Four primary APIs are provided to set, get, and remove user-specific context data related to multi-response controls. These APIs are used exclusively within inbound and outbound transformers:
      • setProviderUserContext(key, contextData, providerAppId, providerUserId)
      • getProviderUserContext(key, providerAppId, providerUserId)
      • removeProviderUserContext(key, providerAppId, providerUserId)
      • removeAllProviderUserContext(providerAppId, providerUserId)
    • Pagination Example: The outbound transformer stores the current pagination state (such as page index and page length) in the user context. The inbound transformer reads this context to determine which page of options to present or process.
    • Picker Control Implementation: Example code demonstrates how to paginate options in the outbound transformer by slicing the options list according to current page index and length, and how to navigate between pages using “prev” and “next” commands.
    • Inbound Transformer Logic: Shows how to interpret user input for pagination commands or option selection, update pagination context accordingly, and return the selected option value.

    Practical Application for ServiceNow Customers

    By using these multi-response output controls, ServiceNow customers can enhance virtual agent dialogs to support complex input flows that span multiple user interactions. This improves user experience by allowing navigation through large sets of options in manageable pages, or guiding users step-by-step through input sequences like date picking.

    Implementing these controls requires creating inbound and outbound transformers that utilize the provided APIs to maintain and update user-specific context data. This context-aware design ensures that the virtual agent can remember user choices and control states across multiple conversational turns.

    Implement controls that involve multiple steps to get user input.

    Use the following API to configure context data for multi-output controls.

    Common use cases

    1. To achieve pagination of pickers: page_no, pagination_length updated in inbound based on next/previous button is read in outbound.
    2. Step by step response of date picker like first year, then month, and then date selection.
    The following APIs are only available in inbound and outbound transformers.
    sn_cs.VASystemObject.setProviderUserContext( key, contextData, providerAppId, providerUserId);
    sn_cs.VASystemObject.getProviderUserContext(key, providerAppId, providerUserId);
    sn_cs.VASystemObject.removeProviderUserContext(key, providerAppId, providerUserId);
    sn_cs.VASystemObject.removeAllProviderUserContext(providerAppId, providerUserId)
    The outbound transformer of the picker control can store current page details in user contextData.
     var paginationData = {
              "page_index": 1,
              "pagination_length": 2
        }
    };
    sn_cs.VASystemObject.setProviderUserContext("picker_pagination", paginationData, providerAppId, providerUserId, );
    The inbound transformer of picker control can get current page details from user contextData.
    var paginationData = sn_cs.VASystemObject.getProviderUserContext("picker_pagination", providerAppId, providerUserId);

    Example code for picker control outbound transformer

    (function execute(inputs, outputs) {
        var control = inputs.rich_control;
        var payload = inputs.payload;
        var appId = payload.appId;
        var userId = payload.userId;
    
        var paginationData = sn_cs.VASystemObject.getProviderUserContext('picker_control', appId, userId);
        paginationData = JSON.parse(paginationData);
        //First time when the outbound picker is called when selecting the topic.
        if (paginationData == null) {
            paginationData = {
                'page_index': 1,
                'pagination_length': 5
            };
            sn_cs.VASystemObject.setProviderUserContext('picker_control', paginationData, appId, userId);
        }
    
        var page_index = paginationData['page_index'];
        var pagination_length = paginationData['pagination_length'];
        var start = (page_index - 1) * pagination_length;
        var end = page_index * pagination_length;
    
        if (control['options']) {
            var options = control['options'];
            var optionsLength = options.length;
            if (end > optionsLength)
                end = optionsLength;
            var picker = control["label"] + ":";
            if (start > 0)
                picker += "\n" + "*" + ": " + "prev";
            for (var x = start; x < end; x++) {
                gs.log("here " + x + " : " + options[x]);
                picker += "\n" + (x + 1) + ": " + options[x].label;
            }
            if (end < optionsLength)
                picker += "\n" + "#" + ": " + "next";
        }
        outputs.text_message = picker;
    })(inputs, outputs);
    Example Picker Control Inbound Tranformer
    (function execute(inputs, outputs) {
    
        var request_context = inputs.request_context;
        var rich_control = inputs.rich_control;
        var appId = request_context.appId;
        var userId = request_context.userId;
    
        var selectedValue = request_context["typed_value"];
        var result = {};
        result["value"] = "";
        result["search_text"] = selectedValue;
    
        var options = rich_control['options'];
    
        var paginationData = sn_cs.VASystemObject.getProviderUserContext('picker_control', appId, userId);
        paginationData = JSON.parse(paginationData);
    
        switch (selectedValue) {
            case 'prev': {
                --paginationData["page_index"];
                result["send_prev_control"] = true;
            }
            break;
        case 'next': {
            ++paginationData["page_index"];
            result["send_prev_control"] = true;
        }
        break;
        default: {
            var selectedIndex = Number(selectedValue) - 1;
            if (paginationData["page_index"] != undefined && paginationData["pagination_length"] != undefined) {
                var highestOptionInPage = paginationData["page_index"] * paginationData["pagination_length"];
                if (selectedIndex >= 0 && selectedIndex < highestOptionInPage) {
                    var selectedOption = options[selectedIndex];
                    result["value"] = selectedOption.value;
                    result["search_text"] = "";
                }
            } else {
                var selectedOption = options[selectedIndex];
                result["value"] = selectedOption.value;
                result["search_text"] = "";
            }
        }
        }
        sn_cs.VASystemObject.setProviderUserContext('picker_control', paginationData, appId, userId);
        outputs.result = result;
    })(inputs, outputs);