Unable to Sync Comments From RITMs to and from custom field

Hi there,

While comments are flying nicely between ServiceNow INCs and JIRA, the same can not be said of the comments from our RITMs. We have a custom field for our IT Work Notes, a Journal Entry field named u_journal_2. No matter what I try it seems to throw up an error of some kind, either a type mismatch (String instead of List) or, and currently, No such property: issue for class: Script355.

I have followed the guide on " How to Sync Comments in Jira Cloud", trying replacing the “replica.comments” to “replica.u_journal_2” but it either doesn’t work or there is an error.

I feel like I have tried everything but it might be that I am not understanding what it is trying to do properly. Any help would be much appreciated!

Hi Iain,

I manage to sync comments from RITM to JSM using a journal field named “u_journal_2” and this is how I did it.

The Incoming sync from Jcloud was left as is
issue.comments = commentHelper.mergeComments(issue, replica)

and for the Outgoing script on SNOW inside the table for RITM I used
replica.u_journal_2 = requestItem.u_journal_2

So my RITM outgoing sync looks something like this

if(entity.tableName == "sc_req_item") {
  replica.summary = requestItem.short_description
  replica.description = requestItem.description
  replica.comments = requestItem.comments
  replica.attachments = requestItem.attachments
  // journal field
  replica.u_journal_2 = requestItem.u_journal_2
}

let me know if this works for you too.

Hi there Kevin,

Sadly that didn’t seem to work for me. I left the Incoming Sync on Jira as is and added the new line into the Outgoing Sync on ServiceNow as you mentioned. The sync does stay active on both sides and doesn’t throw up an error but when I try to add a new comment into the u_journal_2 field, it doesn’t appear in the ticket on Jira. However, updates to the Summary happen without an issue.

I noticed you used “requestItem” before the field names on all of the variables. I have the others as “entity” but that seems to be working perfectly. I am assuming that wouldn’t be the issue?

Also, I was looking for this to happen from Jira to ServiceNow as well. I tried throwing some mud at the wall to see if it would stick with:

issue.u_journal_2        = commentHelper.addComment(replica.comments, issue.u_journal_2)

but I am getting the error “No such property: issue for class: Script647”. Are you able to help with this too?

Hi iain,

Could you please share the outgoing script from SNOW and the incoming from Jcloud that are currently using?

I will work on syncing from Jcloud to SNOW too and share the script for both :slight_smile:

Hi again Kevin,

Can do indeed!

Outgoing Sync from SNow:

if (entity.tableName == "incident") {
replica.key            = entity.key
replica.summary        = "SN Incident - " + entity.short_description
replica.description    = "*Caller Name:* " + entity.caller_id.display_value + "\r*SN Priority:* " + entity.priorityValue.name + "\r\r-------------------------- [update below line]\r" + entity.description
replica.attachments    = entity.attachments
replica.comments       = entity.comments
replica.state          = entity.state
replica.priority       = entity.priorityValue

//if(!(entity.assigned_to instanceof String)){
//replica.assigned_to = entity.assigned_to.display_value 
//}
}

if (entity.tableName == "sc_req_item") {
replica.key            = entity.key
replica.summary        = "SN Request (" + entity.cat_item.display_value + ") - " + entity.short_description
replica.description    = "*Requested For:* " + entity.requested_for.name + "\r\r*For more information on this ticket please see:*\r \r[https://hestest.service-now.com/now/nav/ui/classic/params/target/sc_req_item.do%3Fsys_id%3D" + entity.sys_id + "|https://hestest.service-now.com/now/nav/ui/classic/params/target/sc_req_item.do%3Fsys_id%3D" + entity.sys_id + "|smart-link]"
replica.attachments    = entity.attachments
replica.u_journal_2    = requestItem.u_journal_2
replica.comments = requestItem.comments

Incoming Sync from JIRA:

if (firstSync) {
issue.projectKey  = "SNOW"
// Set the same issue type as the source issue. If not found, set a default.
issue.typeName    = nodeHelper.getIssueType(replica.type?.name, issue.projectKey)?.name ?: "ServiceNow"
issue.description = replica.description
}

issue.summary      = replica.summary
issue.comments     = commentHelper.mergeComments(issue, replica)
issue.attachments  = attachmentHelper.mergeAttachments(issue, replica)

if (!issue.summary.startsWith("SN Request")) {
  issue.description  = replica.description

  if (replica.state == "Resolved" || replica.state == "Closed" || replica.state == "Canceled") {
def statusMap = [
    //"New"   : "In Progress",
    //"Reviewed (Service Desk only)" : "In Progress",
    //"In Progress" : "In Progress",
    "Resolved"  : "Done",
    "Closed"  : "Done",
    "Canceled"  : "Done",
  ]
def remoteStatusName = replica.state
issue.setStatus(statusMap[remoteStatusName] ?: "In Progress")
  }

  def priorityMapping = [
    // remote side priority <-> local side priority             
      "1 - Critical" : "Highest",
      "2 - High" : "High",
      "3 - Moderate" : "Medium",
      "4 - Low" : "Low"
]
  def priorityName = priorityMapping[replica.priority?.name] ?: "Low" // set default priority in case the proper urgency could not be found
  issue.priority = nodeHelper.getPriority(priorityName)

} else {
  def statusMap = [
    "New"   : "In Progress",
    "Triage (Service Desk Only)" : "In Progress",
    "Pending" : "In Progress",
    "Work In Progress" : "In Progress",
    "Closed Complete"  : "Done",
    "Closed Incomplete" : "Done",
  ]
  def remoteStatusName = replica.state
  issue.setStatus(statusMap[remoteStatusName] ?: "In Progress")
  issue.summary      = replica.summary

}

On the SNOW outgoing you are using:
replica.u_journal_2 = requestItem.u_journal_2
replica.comments = requestItem.comments

And that means that you are populating the standard comments object in exalate, and also a custom object called replica.u_journal_2, but if you look at the incoming on Jira, I do not think you are utilizing the u_journal_2 field at all (or am I missing something).

Thanks
Majid

Hi there Majid,

Ah yes! This must have been from a time I had to remove it as it was breaking the rest of the script and I didn’t notice I had not put it back in. This is what I have currently:

Outgoing Sync from SNow:

if (entity.tableName == "incident") {
    replica.key            = entity.key
    replica.summary        = "SN Incident - " + entity.short_description
    replica.description    = "*Caller Name:* " + entity.caller_id.display_value + "\n*SN Priority:* " + entity.priorityValue.name + "\n\n-------------------------- [update below line]\n" + entity.description
    replica.attachments    = entity.attachments
    replica.comments       = entity.comments
    replica.state          = entity.state
    replica.priority       = entity.priorityValue

    //if(!(entity.assigned_to instanceof String)){
    //replica.assigned_to = entity.assigned_to.display_value 
    //}
}

// If the synced ticket is an Request, send the following fields with updated Short Description
if (entity.tableName == "sc_req_item") {
    
    replica.key            = entity.key
    replica.summary        = "SN Request (" + entity.cat_item.display_value + ") - " + entity.short_description
    replica.description    = "*Requested For:* " + entity.requested_for.name + "\r\r*For more information on this ticket please see:*\r \r[https://hestest.service-now.com/now/nav/ui/classic/params/target/sc_req_item.do%3Fsys_id%3D" + entity.sys_id + "|https://hestest.service-now.com/now/nav/ui/classic/params/target/sc_req_item.do%3Fsys_id%3D" + entity.sys_id + "|smart-link]"
replica.attachments    = entity.attachments
replica.customFields.u_journal_2       = entity.customFields.u_journal_2

Incoming Sync from JIRA:

if (firstSync) {
    issue.projectKey  = "SNOW"
    // Set the same issue type as the source issue. If not found, set a default.
    issue.typeName    = nodeHelper.getIssueType(replica.type?.name, issue.projectKey)?.name ?: "ServiceNow"
    
    // The Description sync lives in "firstSync" as, if it is a RITM, this will be the only time it syncs
    issue.description = replica.description
}

issue.summary      = replica.summary
issue.comments     = commentHelper.mergeComments(issue, replica)
issue.attachments  = attachmentHelper.mergeAttachments(issue, replica)

// Append content from 'u_journal_2' to the comments
if (replica.customFields?.u_journal_2) {
    issue.comments += "\n" + replica.customFields.u_journal_2
}

// If the synced ticket comes from an Incident
if (!issue.summary.startsWith("SN Request")) {
  issue.description  = replica.description

  // Unless ServiceNow ticket has been closed, leave State alone. If it is, then close JIRA ticket
  if (replica.state == "Resolved" || replica.state == "Closed" || replica.state == "Canceled") {
    def statusMap = [
        "Resolved"  : "Done",
        "Closed"  : "Done",
        "Canceled"  : "Done",
      ]
    def remoteStatusName = replica.state
    issue.setStatus(statusMap[remoteStatusName] ?: "In Progress")
  }

  // Updates Priority from ServiceNow ticket
  def priorityMapping = [
        // remote side priority <-> local side priority             
          "1 - Critical" : "Highest",
          "2 - High" : "High",
          "3 - Moderate" : "Medium",
          "4 - Low" : "Low"
    ]
      def priorityName = priorityMapping[replica.priority?.name] ?: "Low" // set default priority in case the proper urgency could not be found
      issue.priority = nodeHelper.getPriority(priorityName)

// If ticket is a Request Item
} else {
    // Unless ServiceNow ticket has been closed, leave State alone. If it is, then close JIRA ticket
    if (replica.state == "Closed Complete" || replica.state == "Closed Incomplete") {
      def statusMap = [
        "Closed Complete"  : "Done",
        "Closed Incomplete" : "Done",
      ]
      def remoteStatusName = replica.state
      issue.setStatus(statusMap[remoteStatusName] ?: "In Progress")
      issue.summary      = replica.summary
    }

}

Currently this solution does sync/stay active but doesn’t put the information into the JIRA ticket. Also, the other way around (JIRA to ServiceNow) is probably more important. I can give the script for that too if/when needed.