A Jira Salesforce integration use case can be an interesting one, an amalgamation of business and technical teams.
In this article, we’ll discuss an advanced comment use case that allows syncing threads of comments and user mentions between these 2 platforms so that they speak the same language.
The use case is implemented between a Jira Cloud and a Salesforce instance.
The following are the key requirements:
Exalate is a one-way or two-way synchronization solution that supports multiple platforms like Jira, Salesforce, Azure DevOps, GitHub, Zendesk, etc.
Its intuitive Groovy-based scripting engine allows you to implement advanced use cases. The Sync rules can be modified to set up deeper integrations. In addition to this, you can use Triggers and set up advanced automatic synchronization too.
Note: The Exalate Academy is a great way to learn more about Exalate. Give it a try!
Note: You can learn more about setting up a connection between Jira and Salesforce through the Getting Started guide or read this complete Jira Salesforce Integration guide.
Once the Connection has been created, you need to configure the Sync Rules.
These rules are Groovy-based scripts that control what information to send and receive between the 2 platforms.
You can click on the “Configure Sync” button after the Connection has been set up to configure these rules or you can also edit the Connection in the “Connections” tab in the Exalate Console.
Rules are present at both ends of the synchronization. The “Outgoing Sync” on the Jira side decides what information must be sent from Jira to Salesforce and the “Incoming Sync” decides what and how information must be received from Salesforce.
The same exists in the Salesforce instance.
The scripts you see are generated by default when the Connection has been created. So common fields like summary, description, comments, etc are already there and can be synchronized out-of-the-box.
Now, we need to edit them to accommodate our sync requirements.
replica.key = issue.key
replica.type = issue.type
replica.assignee = issue.assignee
replica.reporter = issue.reporter
replica.summary = issue.summary
replica.description = issue.description
replica.labels = issue.labels
replica.comments = issue.comments.collect {
comment ->
def matcher = comment.body =~ /\[~accountid:([\w:-]+)\]/
def newCommentBody = comment.body
matcher.each {
target = nodeHelper.getUser(it[1])?.email
newCommentBody = newCommentBody.replace(it[0],target)
}
comment.body = newCommentBody
comment
}
replica.resolution = issue.resolution
replica.status = issue.status
replica.parentId = issue.parentId
replica.priority = issue.priority
replica.attachments = issue.attachments
replica.project = issue.project
//Comment these lines out if you are interested in sending the full list of //versions and components of the source project.
replica.project.versions = []
replica.project.components = []
The Outgoing sync looks like this
Here’s what happens in the script:
Note: Replica works as a payload to pass information between the two applications.
Salesforce: Outgoing Sync
if(entity.entityType == "Case") {
replica.key = entity.Id
replica.summary = entity.Subject
replica.description = entity.Description
replica.attachments = entity.attachments
replica.Status = entity.Status
replica.comments = entity.comments.inject([]) { result, comment ->
def res = httpClient.get("/services/data/v54.0/query/?q=SELECT+Name+from+User+where+id=%27${comment.author.key}%27")
comment.body = nodeHelper.stripHtml(res.records.Name[0] + " commented: " + comment.body)
result += comment
def feedResponse = httpClient.getResponse("/services/data/v54.0/chatter/feed-elements/${comment.idStr}")
def js = new groovy.json.JsonSlurper()
def feedJson = groovy.json.JsonOutput.toJson(feedResponse.body)
feedResponse.body.capabilities.comments.page.items.collect {
res = httpClient.get("/services/data/v54.0/query/?q=SELECT+Name+from+User+where+id=%27${it.user.id}%27")
def c = new com.exalate.basic.domain.hubobject.v1.BasicHubComment()
c.body = res.records.Name[0] + " commented: " + it.body.text
c.id = it.id
result += c
}
result
}
}
The Outgoing Sync script looks like this.
Here’s what happens in the script:
if(firstSync){
entity.entityType = "Case"
}
if(entity.entityType == "Case"){
entity.Subject = replica.summary
entity.Description = replica.description
entity.Origin = "Web"
entity.Status = "New"
entity.attachments = attachmentHelper.mergeAttachments(entity, replica)
def commentMap = [
"mathieu.lepoutre@idalko.com" : "0058d000004df3DAAQ",
"syed.majid.hassan@idalko.com" : "0057Q000006fOOOQA2"
]
def flag = 0
replica.addedComments.collect {
comment ->
def matcher = comment.body =~ /([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)/
def newCommentBody = comment.body
matcher.each {
newCommentBody = newCommentBody.replace(it[0],"")
def res = httpClient.post("/services/data/v54.0/chatter/feed-elements", \
"{\"body\":{\"messageSegments\":[{\"type\":\"Text\", \"text\":\"${newCommentBody} \" },{\"type\":\"Mention\", \"id\":\"${commentMap[it[0]]}\"}]},\"feedElementType\":\"FeedItem\",\"subjectId\":\"${entity.Id}\"}")
flag = 1
}
}
if (flag == 0)
entity.comments = commentHelper.mergeComments(entity, replica)
}
The Incoming Sync script looks like this.
Here’s what happens in the script:
There is no need to modify this since the default behavior is sufficient for our use case.
Once the code is inserted into the respective outgoing and incoming syncs, comments, and threaded replies will automatically be reflected in Jira.
So when you insert a threaded comment in Salesforce.
All of them get reflected in Jira.
Also, user mentions in Jira will tag the corresponding user in Salesforce, if he/ she exists.
So mention a user in Jira.
And see the corresponding user being tagged in Salesforce.
In this article we just saw an example of an advanced comment sync between Jira and Salesforce. A lot of other advanced sync requirements can also be implemented using Exalate because of its support for Groovy-based scripts.
Book a demo with Exalate to learn more about how it can be customized for your specific scenario.
Syed Majid Hassan -Exalate-
0 comments