Originally asked by Kaleigh Garcia on 25 October 2024 (original question)
Hello Exalate Community,
I’m working on a sync configuration between Salesforce and Azure DevOps (ADO) with the goal of syncing Salesforce Chatter posts to the discussion section in ADO. I’m currently using the BasicHubComment
object in my script to map Chatter comments from Salesforce to workItem.comments
in ADO. However, these comments are not appearing in ADO’s discussion section as expected.
I’ve referred to Exalate’s resource for syncing Chatter posts to Jira comments, hoping to adapt this approach to work with ADO’s discussion section. Here’s a breakdown of my current configuration for both the outgoing and incoming scripts across Salesforce and ADO.
Any guidance on this would be helpful!
Salesforce Outgoing (from Exalate resource ):
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
}
Salesforce Incoming (from Exalate resource ):
def commentMap = [
"mathieu.lepoutre@idalko.com" : "0058d000004df3DAAQ",
"syed.majid.hassan@idalko.com" : "0057Q000006fOOOQA2"
]
def flag = 0
// Loop through added comments
replica.addedComments.collect { comment ->
def matcher = comment.body =~ /([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)/ // Regex to find email addresses
def newCommentBody = comment.body
matcher.each { matchedEmail ->
newCommentBody = newCommentBody.replace(matchedEmail[0], "") // Remove the email from the comment body
// Post the comment with mention
def res = httpClient.post("/services/data/v54.0/chatter/feed-elements",
"{\"body\":{\"messageSegments\":[{\"type\":\"Text\", \"text\":\"${newCommentBody} \" },{\"type\":\"Mention\", \"id\":\"${commentMap[matchedEmail[0]]}\"}]},\"feedElementType\":\"FeedItem\",\"subjectId\":\"${entity.Id}\"}")
flag = 1
}
}
// If no email mentions were found, sync the comments normally
if (flag == 0) {
entity.comments = commentHelper.mergeComments(entity, replica)
}
ADO Outgoing:
replica.chatterPosts.each { chatterPost ->
def newComment = [
"text": chatterPost.body.messageSegments.collect { it.text }.join(" ")
]
def discussionUrl = "/_apis/wit/workItems/${workItem.id}/comments?api-version=6.0-preview.3"
def res = httpClient.post(discussionUrl, newComment)
if (res.status != 200) {
logger.error("Failed to post comment to ADO Discussion: ${res.body}")
}
}
ADO Incoming:
if (!workItem.comments) {
workItem.comments = []
}
if (replica.chatterPosts) {
replica.chatterPosts.each { chatterPost ->
def adoComment = new com.exalate.basic.domain.hubobject.v1.BasicHubComment()
adoComment.body = chatterPost.messageSegments.collect { it.text }.join(" ")
adoComment.author = nodeHelper.getUserByEmail(chatterPost.author.email) ?: chatterPost.author.displayName
adoComment.created = chatterPost.createdDate
workItem.comments += adoComment
}
}