At a recent ScriptRunner Champion Hour, I talked about how to respond to events in Confluence to update Jira.
The path we demonstrated was to use a combination of an Event Listener in Confluence and REST Endpoint in Jira. The details of using the App Links API are detailed in our documentation for ScriptRunner for Confluence (and for ScriptRunner for Jira, if you need to go the other direction). Here is the code I used.
The basic idea is that if a page in Confluence has a Jira Issue macro in it, then when someone likes that page, they should also automatically vote for the corresponding issue in Jira. Complexities like handling multiple issue macros or doing completely different operations in Jira & Confluence are left as exercises to the reader. :)
Set up a listener in ScriptRunner for Confluence
import com.atlassian.applinks.api.ApplicationLinkResponseHandler import com.atlassian.applinks.api.ApplicationLinkService import com.atlassian.applinks.api.application.jira.JiraApplicationType import com.atlassian.confluence.event.events.like.LikeEvent import com.atlassian.sal.api.component.ComponentLocator import com.atlassian.sal.api.net.Request import com.atlassian.sal.api.net.Response import com.atlassian.sal.api.net.ResponseException import groovy.json.JsonSlurper LikeEvent event = event def content = event.content def xmlStorageFormat = content.bodyAsString def document = new XmlSlurper(false, false) .parseText(xmlStorageFormat) .declareNamespace([ac: "http://atlassian.com/content"]) def macros = document.'ac:structured-macro' def issueKey = macros.children().find { element -> element.'@ac:name' == "key" }?.text() log.debug "Found link to issue key ${issueKey} in page ${content.title}" if (issueKey) { /* For more details on using the App Links API, see https://docs.adaptavist.com/sr4js/latest/integrations/atlassian-products/via-app-links https://docs.adaptavist.com/sr4c/latest/integrations/atlassian/connect-to-atlassian-via-app-links */ def appLinkService = ComponentLocator.getComponent(ApplicationLinkService) def appLink = appLinkService.getPrimaryApplicationLink(JiraApplicationType) def applicationLinkRequestFactory = appLink.createAuthenticatedRequestFactory() def request = applicationLinkRequestFactory.createRequest( Request.MethodType.PUT, "/rest/scriptrunner/latest/custom/voteForIssue?issueKey=${issueKey}" ) def handler = new ApplicationLinkResponseHandler() { @Override Map credentialsRequired(Response response) throws ResponseException { return null } @Override Map handle(Response response) throws ResponseException { assert response.statusCode == 200 new JsonSlurper().parseText(response.getResponseBodyAsString()) as Map } } request.execute(handler) }
Then a REST Endpoint in Jira:
import com.atlassian.jira.component.ComponentAccessor import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate import groovy.transform.BaseScript import javax.ws.rs.core.MultivaluedMap import javax.ws.rs.core.Response @BaseScript CustomEndpointDelegate customEndpointDelegate voteForIssue( httpMethod: 'PUT', groups: ['jira-software-users'] ) { MultivaluedMap queryParams -> def voteManager = ComponentAccessor.voteManager def issueService = ComponentAccessor.issueService def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser def issueKey = queryParams.getFirst('issueKey')?.toString() def issue = issueService.getIssue(loggedInUser, issueKey).getIssue() voteManager.addVote(loggedInUser, issue) return Response.ok("Successfully voted for issue ${issueKey}").build() }
Jonny Carter
Engineering Team Lead
Adaptavist
Springfield, MO
55 accepted answers
0 comments