Mapping the serviceNow story number (with date/time stamp) to Jira activity tab?

snow_beginner
Mega Guru

Hi, 

I have a requirement to map the servicenow story number with date time stamp to the jira activity tab, how would I do that?

The business rule which connects snow > jira is below. it is an after business rule which runs on insert, update or delete.

Screenshot 2025-02-18 105100.png

 

script include it points to has this code:

 

var AgileJiraUtils = Class.create();
AgileJiraUtils.prototype = {
    initialize: function() {
        this._logger = new sn_int_common.DebugLogManager();
    },

    updateWorkitemsGroup: function(project, assignmentGroup) {
        var tableMapGr = this._getAllTableMapsByProject(project);
        while (tableMapGr.next()) {
            var internalTable = tableMapGr.getValue('internal_table');
            var workitemGr = new GlideRecord(internalTable);
            var externalIdGr = workitemGr.addJoinQuery("sn_int_common_external_identifiers", "sys_id", "reference_value");
            externalIdGr.addCondition('external_project', project.sys_id);
            workitemGr.setValue('assignment_group', assignmentGroup);
            workitemGr.updateMultiple();
        }
    },

    _getAllTableMapsByProject: function(project) {
        var tableMapGr = new GlideRecord('sn_int_common_table_map');
        tableMapGr.addQuery('map_config', project.mapping_config.sys_id);
        tableMapGr.addQuery('is_valid', true);
        tableMapGr.query();

        return tableMapGr;
    },

    fetchJiraProjectFromGroup: function(groupId) {
        var gr = new GlideRecord('sn_agile_jira_int_import_settings');
        if (gr.get('assignment_group', groupId))
            return gr.getValue('jira_project');
        else
            return "";
    },

    isSynchEnabled: function(jiraProject, syncFlow) {
        var flagFields = {
            "import": "enable_import",
            "export": "enable_export"
        };
        var gr = new GlideRecord('sn_agile_jira_int_import_settings');
        if (gr.get('jira_project', jiraProject) && !gs.nil(flagFields[syncFlow]))
            return gr[flagFields[syncFlow]];
        else
            return false;
    },

    exportCurrentRecordToJira: function(sourceGr,previousGr, jiraProjectGr) {
        var jiraProject_GR = new GlideRecord('sn_jira_int_project');
        var integrationTypeGR = new sn_agile_int_cmns.AgileIntCommonUtil().getIntegrationType();
        if (gs.nil(jiraProjectGr)) {
            jiraProject_GR = this._getJiraProjectForExport(sourceGr, integrationTypeGR);
        } else {
            jiraProject_GR.get(jiraProjectGr);
        }
        if (jiraProject_GR.isValidRecord()) {
            var instanceGR = jiraProject_GR.instance.getRefRecord();
            var isExportEnabled = jiraProject_GR.enable_export;
            var payloadObject = '';
            if (instanceGR.isValidRecord() && instanceGR.getValue('state') == 'connected' && isExportEnabled) {
                if (sourceGr.operation() != "delete") {
                    payloadObject = new sn_agile_jira_int.AgileJiraExportUtils().preparePayloadForEntity(sourceGr.getTableName(),
                        sourceGr.getUniqueValue(), jiraProject_GR, sourceGr);
                    payloadObject['payload'] = payloadObject['payload'].join("^");
                }
                if (payloadObject || sourceGr.operation() === "delete") {
                    this._logger.log("Exporting from: " + sourceGr.getTableName() + " to Jira Project: " + jiraProject_GR.getUniqueValue() + " with data", payloadObject);
                    new sn_jira_int.JiraExportUtils().synchSNRecordWithJira(integrationTypeGR, sourceGr, jiraProject_GR, payloadObject, previousGr);
                }
            } else
                gs.info('Export criteria is not satisfied. Reason: Enable Export property of this project is false or instance is not in connected state.');
        }
    },

    _getJiraProjectForExport: function(sourceGr, integrationTypeGR) {
        var jiraProject_GR = new GlideRecord('sn_jira_int_project');
        if (!gs.nil(sourceGr.assignment_group)) {
            jiraProject_GR.get(this.fetchJiraProjectFromGroup(sourceGr.assignment_group));
        }
        if (!jiraProject_GR.isValidRecord()) {
            var externalIDHelper = new sn_agile_jira_int.JiraExternalIDHelper(integrationTypeGR);
            var externalIDs_GR = externalIDHelper.fetchExternalIDRecord(sourceGr.getTableName(), '', "reference_value", sourceGr.sys_id);
            if (!gs.nil(externalIDs_GR) && externalIDs_GR.isValidRecord() && !gs.nil(externalIDs_GR.external_project)) {
                jiraProject_GR = externalIDs_GR.external_project.getRefRecord();
            }
        }
        return jiraProject_GR;
    },

    exportAttachmentFromTaskToExternalSystem: function(attachmentGr) {
        var exportUtil = new sn_jira_int.exportAttachmentUtil();
        if (exportUtil.validateIfAttachmentAddedFromImportRequest(attachmentGr)) //cyclic case
            return;
        var integrationTypeGR = new sn_agile_int_cmns.AgileIntCommonUtil().getIntegrationType();
        var externalIDHelper = new sn_agile_jira_int.JiraExternalIDHelper(integrationTypeGR);
        var externalIDRecord = externalIDHelper.fetchExternalIDRecord(attachmentGr.table_name, '', "reference_value", attachmentGr.table_sys_id);
        var issueID;
        var jiraProject_Gr;
        if (externalIDRecord && !gs.nil(externalIDRecord.getValue('external_project'))) {
            issueID = externalIDRecord.getValue("external_id");
            jiraProject_Gr = this._getJiraProject(externalIDRecord);
        }
        if (!gs.nil(jiraProject_Gr) && jiraProject_Gr.isValidRecord() && jiraProject_Gr.enable_export && !gs.nil(issueID)) {
            var instance = jiraProject_Gr.instance.getRefRecord();
            if (instance.isValidRecord() && instance.getValue('state') == 'connected') {
                var connectionAlias = instance.connection_alias.getRefRecord();
                if (connectionAlias.isValidRecord())
                    var response = exportUtil.exportAttachment(instance, issueID, attachmentGr.sys_id, attachmentGr.table_name, attachmentGr.table_sys_id, attachmentGr.file_name);
            } else {
                this._logger.log("Cannot export attachment, Please check if the associated Jira instance is in connected state.");
            }
        } else
            this._logger.log("Cannot export attachment, Please check if the associated Jira Project has Export Enabled");
    },

    _getJiraProject: function(externalIdGr) {
        var jiraProjectGr = new GlideRecord('sn_jira_int_project');
        var externalProjectSysId = externalIdGr.getValue('external_project');
        if (jiraProjectGr.get(externalProjectSysId))
            return jiraProjectGr;
        return jiraProjectGr;
    },

    deleteAttachmentFromExternalSystem: function(taskId, externalId) {
        var integrationTypeGR = new sn_agile_int_cmns.AgileIntCommonUtil().getIntegrationType();
        var issueGr;
        var exportUtil = new sn_jira_int.exportAttachmentUtil();
        var taskGr = new GlideRecord("task");
        if (!taskGr.get(taskId))
            return;
        issueGr = new GlideRecord(taskGr.getValue("sys_class_name"));
        if (!issueGr.get(taskId))
            return;
        var externalIDHelper = new sn_agile_jira_int.JiraExternalIDHelper(integrationTypeGR);
        var externalIDRecord = externalIDHelper.fetchExternalIDRecord(issueGr.table_name, '', "reference_value", issueGr.sys_id);
        var jiraProject_Gr;
        if (externalIDRecord && !gs.nil(externalIDRecord.getValue('external_project'))) {
            jiraProject_Gr = externalIDRecord.external_project.getRefRecord();
        }
        if (gs.nil(jiraProject_Gr) || !jiraProject_Gr.isValidRecord() || !jiraProject_Gr.enable_export)
            return;
        var instance = jiraProject_Gr.instance.getRefRecord();
        if (instance.isValidRecord()) {
            exportUtil.deleteAttachment(instance, externalId);
        }
    },

    exportSprintToJira: function(sprintGr, operation) {
        var importSettingGR = new GlideRecord('sn_agile_jira_int_import_settings');
        if (!importSettingGR.get('assignment_group', sprintGr.getValue("assignment_group")))
            return;
        if (gs.nil(importSettingGR.getValue('jira_board')))
            return;
        var jiraBoardGr = importSettingGR.jira_board.getRefRecord();
        if (!gs.nil(jiraBoardGr.getValue('type')) && jiraBoardGr.getValue('type') === 'kanban')
            return;
        var jiraProjectGR = importSettingGR.jira_project.getRefRecord();
        if (operation === 'update' && !this.hasFieldChanged(sprintGr, jiraProjectGR))
            return;

        var jiraInstanceGR = importSettingGR.jira_instance.getRefRecord();
        var externalSystemVersion = jiraInstanceGR.external_system_version.getRefRecord();
        var externalSystem = externalSystemVersion.external_system.getRefRecord();
        var connectionAlias = jiraInstanceGR.connection_alias.getRefRecord();
        var integrationTypeGR = new sn_agile_int_cmns.AgileIntCommonUtil().getIntegrationType();
        var commonItegrationUtil = new sn_int_common.CommonIntegrationUtils(integrationTypeGR);
        var payloadObject = '';

        if (jiraInstanceGR.getValue('state') == 'connected' && jiraProjectGR.enable_export) {
            payloadObject = new sn_agile_jira_int.AgileJiraExportUtils().preparePayloadForEntity(sprintGr.getTableName(),
                sprintGr.getUniqueValue(), jiraProjectGR, sprintGr);
            var input = {};
            var payload = {};
            payload.source_table = sprintGr.getTableName();
            payload.source_sys_id = sprintGr.getValue("sys_id");
            payload.external_system = externalSystem;
            payload.integration_type = integrationTypeGR;
            payload.external_project = jiraProjectGR;
            payload.operation = operation;
            if (operation !== 'insert') {
                var externalIDRecord = commonItegrationUtil.getExternalIDRecord(sprintGr.getTableName(), jiraProjectGR, "reference_value", sprintGr.getValue("sys_id"));
                if (externalIDRecord)
                    payload.sprint_id = externalIDRecord.getValue("external_id");
            }
            payload.connection_alias = connectionAlias;
            payload.board_id = importSettingGR.jira_board.getRefRecord().id;
            if (!gs.nil(payloadObject)) {
                var fieldValuesFromMap = payloadObject["payload"];
                for (i = 0; i < fieldValuesFromMap.length; i++) {
                    var pos = fieldValuesFromMap[i].indexOf("=");
                    var field = fieldValuesFromMap[i].substr(0, pos);
                    var value = fieldValuesFromMap[i].substr(pos + 1, fieldValuesFromMap[i].length);
                    if (field == "startDate") {
                        var startDate = new GlideDateTime(value);
                        payload.start_date = startDate;
                    } else if (field == "endDate") {
                        var endDate = new GlideDateTime(value);
                        payload.end_date = endDate;
                    } else {
                        payload[field] = value;
                    }
                }
            }
            if (payload) {
                this._logger.log("Exporting Sprint", payload);
                new sn_agile_jira_int.ExportSprintUtil().exportSprintToJira(payload);
            }
        }
    },

    hasFieldChanged: function(tableGr, projectGR) {
        var integrationTypeGR = new sn_agile_int_cmns.AgileIntCommonUtil().getIntegrationType();
        var fieldMapConfig = new sn_int_common.FieldMapConfig();
        var fieldMapping = fieldMapConfig.getFieldMapByInternalTableAsJsonObject(projectGR.mapping_config.getRefRecord(), tableGr.getTableName(), integrationTypeGR);
        for (var snowColumn in fieldMapping) {
            if (tableGr.isValidField(snowColumn)) {
                var fieldElement = tableGr.getElement(snowColumn);
                if (fieldElement != null && fieldElement.changes())
                    return true;
            }
        }
        return false;
    },

    canImportIssues: function(project) {
        if (!gs.nil(project.mapping_config) && project.enable_import) {
            return new sn_jira_int.JiraIntegrationUtils().isThereAnyTableMaps(project);
        } else {
            gs.info("Please enable import in project or create a map configuration to import issues for the project " + project.name);
            return false;
        }
    },

    type: 'AgileJiraUtils'
};

 

Any help would be very appreciated. Thanks.

1 REPLY 1

Ankur Bawiskar
Tera Patron
Tera Patron

@snow_beginner 

we don't know how the fields are mapped. I believe you can check that in your script how it's done.

Is this a custom script or you have used any plugin which provided this script

we could see some scoped apps script include such as sn_agile_int_cmns, sn_jira_int

If my response helped please mark it correct and close the thread so that it benefits future readers.

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader