Edited at

【Jiraお勧めアドオン】 ScriptRunner の使い方( Script Listeners & REST Endpoint 編)

More than 1 year has passed since last update.


はじめに

個人的に熱いScriptRunnerの使い方をご紹介します。

「こんな使い方もできるよ!」って言う紹介記事みたいなもんです。

この記事で取り上げるのは Hipchat Datacenter 3.x.x との連携です。

標準の連携機能ではできない、細かい制御がしたくて作りました。

image.png

個人的に意識しているポイントは、以下2点です。

1. ScriptListnerは簡単な処理!

2. REST Endpointでやや面倒な処理!


バージョン

ScriptRunner 5.0.14

Hipchat Datacenter 3.x.x


ScriptListeners

Endpointで処理するための情報を幾つか付与した上で、AsyncHTTPBuilderを使って非同期通信します。

あまりゴテゴテ処理は書かないようにしてます。

途中、postHeadersに入れているBasic認証については、Jira BASIC認証を参照ください。

※コード例は、「fred:fred」をbase64でエンコードした文字列になります。

※base64のエンコードは「base64 エンコード」でググるとWEBサイトいっぱいでてくるので、そこでやりましょう。

import groovyx.net.http.AsyncHTTPBuilder

import groovy.json.JsonBuilder
import static groovyx.net.http.ContentType.*

String baseurl = "https://ホスト名/jira/rest/scriptrunner/latest/custom/notificationToHipchat";
String queryParams = "eventName=Assign";
String url = baseurl + "?" + queryParams;
def http = new AsyncHTTPBuilder(poolSize: 5, uri: url)
def postBody = event.getIssue().getId().toString();
def postHeaders= [Authorization: 'Basic ZnJlZDpmcmVk']; //Jira Basic Authentication

http.post( body: postBody, headers : postHeaders, requestContentType : JSON , contentType : JSON)


REST Endpoint

以下のことやってます。

1. データを受け取る

2. メッセージ生成

3. hipchatに送信

実際に運用しているソースでは、条件に応じてpostするroomを分けているため、hipchatにpostするところを関数化してます。

//for endpoint

import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.transform.BaseScript
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

//for RestAPI
import groovyx.net.http.RESTClient
import groovyx.net.http.HttpResponseException
import static groovyx.net.http.ContentType.URLENC

//for json
import groovy.json.JsonOutput
import groovy.json.JsonBuilder
import java.util.HashMap

//for process
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventTypeManager
import com.atlassian.jira.event.type.EventType
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.IssueManager

//url&token
String baseurl = "https://ホスト名/"

@BaseScript CustomEndpointDelegate delegate

//define a method
def post(RESTClient https, String path, String token, messagejson, Issue issue) {
try {
def resp = https.post(
path: path,
query:['auth_token': token],
requestContentType: URLENC,
headers: ['Content-Type': 'application/json'],
body: JsonOutput.toJson(messagejson),
)
} catch(HttpResponseException e) {
def r = e.response
log.error(issue.key.toString());
log.error(issue.summary.toString());
log.error("Success: $r.success");
log.error("Status: $r.status");
log.error("Reason: $r.statusLine.reasonPhrase");
log.error("Content: \n${JsonOutput.prettyPrint(JsonOutput.toJson(r.data))}");
}
}

//main process
notificationToHipchat(httpMethod: "POST", groups: ["jira-software-users"]) { MultivaluedMap queryParams, String body ->
//get request
String id = body;
IssueManager issueManager = ComponentAccessor.getIssueManager();
Issue issue = issueManager.getIssueObject((Long)id.toInteger());
String eventName = queryParams.getFirst("eventName") ?: "";

log.info(eventName);

//message generate
String messageValue = "";
String colorValue = "red";
String notifyValue = "false";
def messagejson = [:];

messageValue = "【" + eventName + "】"
//generic event
if (eventName=="Transition") {
messageValue = messageValue + " to " + issue.status.name;
colorValue = "yellow";
}
messageValue = messageValue + "\r\nsummary: " + issue.summary
messageValue = messageValue + "\r\ntype: " + issue.getIssueType().getName();
messageValue = messageValue + "\r\nlink: https://ホスト名/jira/browse/" + issue.key
messageValue = messageValue + "\r\nassignee: @" + issue.assignee?.displayName?.replaceAll(" ","");
messagejson = [
message: messageValue,
color: colorValue,
notify: notifyValue,
message_format: 'text'
]

//post
String path = "v2/room/20/notification"; //test room
String token = "hipchatトークン"; //test room
def https = new RESTClient(baseurl);

post(https, path, token, messagejson, issue);

return Response.ok(new JsonBuilder(body).toString()).build();
}

メンションしたい場合、JIRAのフルネームがhipchatのメンション対象になります。

ただし、hipchat側で空白をカットされているので、そこを補正してあげる必要があります。

上記コードの中にも記載されていますが、抜き出すと以下コードです。

messageValue = messageValue + "\r\nassignee: @" + issue.assignee?.displayName?.replaceAll(" ","");


最後に

個人的にこの使い方便利だなーと感じつつも、まとまって記載された記事を見かけなかったので、作った感じです。

ScriptRunner:本当に便利なので、ぜひご活用下さい。

以上です。