5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ConfluenceでJiraを操作するページを作る

Last updated at Posted at 2019-07-21

JiraとConfluenceを連携させて使っていると、Jiraでかゆいところに手が届かないのをREST APIで何とかしたいと思うことがある。個人的に作業するだけならcurlでも良いが、慣れていない人も含め、複数の人が同じことをしやすいようにしたいので、UIが欲しい。

定型的なチケット作成や、テンプレートチケットのクローン程度であれば簡単にできるので、Confluenceページ上のHTMLマクロ内にスクリプトを少し書くだけで実現できる。

HTML部分

AUIでは色々なコンポーネントが用意されているが、まずはフォームがあればそれらしい画面が作れそうだった。AUIのフォームの説明ページでは基本的なフォームの形が紹介されている。

例えば、ボタンを押したら何かするようにしたければ、以下のようにする。

<form ... class="aui">
    <div class="field-group">...</div>
    <div class="field-group">...</div>
    <div class="buttons-container">
        <div class="buttons" onclick="onClick()">...</div>
    </div>
</form>

<script type="text/javascript">
(function () {
const API_BASE="<JIRAサーバ>/rest/api/2"

async function onClick() {
    ...
}

})();
</script>

テキストボックスでEnterキーを押したり、Submitボタンをクリックしたりすると、意図しないSubmitアクションが実行されてしまった。ボタンはtype="submit"の代わりにtype="button"にすることでSubmitアクションを止められたが、テキストボックスは一工夫いるらしい。「Enterキーを無効にする方法」がうまく使えるか試してみる。

Jiraチケットを取得する

チケットを取得するときは、/rest/api/2/issue/<KEY or ID>GETする。HTTPリクエストを出すにはAJS.$.ajax()(jQueryの機能)を使う。

async function getIssue( key ) {
    var issue;
    await AJS.$.ajax( {
        url: API_BASE + '/issue/' + key,
        type: 'get',
        successs: function( data ) {
            issue = data;
        }
    } );
    return issue;
}

JiraとConfluenceを連動して使っているのであれば多分Originが同じになるのでCORSを気にすることはないが、同一PCで動かしていてポートが違うような場合、Jiraサーバ側に特定のOriginを許可する設定が必要になる。

Jiraチケットを作成する

チケットを作成するときは、{ fields: { field: value } }という形のJSONを/rest/api/2/issuePOSTする。以下では、戻り値(issue)のfieldsだけ取り出して返している。

async function postIssue( fields ) {
    var resultFields;
    await AJS.$.ajax( {
        url: API_BASE + '/issue',
        type: 'post',
        data: JSON.stringify( { 'fields': fields } ),
        headers: {
            'Content-Type': 'application/json'
        },
        success: function( data ) {
            resultFields = data.fields;
        }
    } );
    return resultFields;
}

Jiraチケットを複製する

チケットを作る際のルール・テンプレートが柔らかく、暫定的にチーム内で統一して作りたい場合があると思う。そんなとき、ベースとなるチケットを複製するという手段がある。

以下は、srcKey(string)で指定したチケットをparentKey(string)以下にコピーする関数。コピーする対象のフィールドはfields(string[])で指定する。

function extractFields( src, fieldNames ) {
    let fields = {};

    for( let fieldName of fieldNames ) {
        let tmp = src[ fieldName ];

        // null, undefined を受け付けない場合があるので除外しておく
        if( tmp ) {
            fields[ fieldName ] = tmp;
        }
    }
}

async function cloneIssue( srcKey, parentKey, fieldNames ) {
    const src = await getIssue( srcKey );
    const parent = await getIssue( parentKey );

    if( !src || !parent ) {
        throw new Error( 'Invalid Key.' ); // 適当   
    }

    const projectKey = parent.fields.project.key;

    let fields = extractFields( src.fields, fieldNames );
    fields[ 'project' ] = { key: projectKey };
    fields[ 'parent' ] = { key: parentKey };

    await postIssue( fields );
}

UIと繋ぐ

先ほどのcloneIssue関数をUIと繋ぐ場合、ボタン操作などをトリガとして実行する関数(ここではonClick)で、設定値を持つinput要素等からval()関数で設定値を取得し、cloneIssue関数をコールする。成功・失敗を通知する機能もあると良いかもしれないが、基本は以下のようなイメージ。

const API_BASE="<JIRAサーバ>/rest/api/2"
const src = AJS.$('#src');         // コピーしたいチケットのキーを入力するinput要素のID
const parent = AJS.$('#parent');   // コピー先の親チケットのキーを入力するinput要素のID
const FIELDNAMES = [
    'custom_field_xxxxx', 
    'custom_field_yyyyy', 
    'custom_field_zzzzz', 
    'description',
    'issuetype',
    'summary'
];  // コピーしたいフィールド

// イベント処理の関数…UIのボタンから呼ぶようにする。
async function onClick() {
    try {
        const srcKey = src.val();
        const parentKey = parent.val();
        await cloneIssue( srcKey, parentKey, FIELDNAMES );
    } catch( err ) {
        console.log( err ); // 適当
    }
}

参考情報

Confluence

ConfluenceのHTMLマクロでは、AUI(Atlassian User Interface)で提供されるUI部品やヘルパ関数AJSを使うことができる。AJSにはjQueryが含まれていて、AJS.$で利用できる。また、ページのメタ情報をAJS.paramsで取得することもできる。

AUIのコードサンプルには「Edit in codepen」や「Edit in jsfiddle」と書かれたリンクがあり、AJSも含めどんな結果になるかを確認しながらコードを書くことができるようになっている。

Jira

REST API資料

JiraのREST APIについては、サーバ版とCloud版で異なるらしい。どちらが使えるか調べて、リンク先からREST APIの資料を参照する。

400 Bad Requestが返ってくる

REST APIでチケットを作ろうとすると、fieldsメンバ内に必ず設定しなくてはならない項目が不足するか、設定してはいけない項目があることで、400応答が返ってくることがある。そんな時は応答に含まれるエラーメッセージ(error.responseText)から、何がダメだったかが分かるようになっている。例えばissuetypeが無い、親チケットが無い、エピックにエピック名が無いなどがある。

401 Unauthorizedが返ってくる

ConfluenceとJiraでユーザの情報を共有して連携している場合(大抵はこれ)、ブラウザでJiraにログインすることで解消する。

415 Unsupported Media Typeが返ってくる

HTTPリクエスト時に、dataの中身をJSON.stringifyし忘れるか、Content-Typeヘッダを忘れるかのどちらかで起きる。

カスタムフィールドと設定値を調べる

チケットのカスタムフィールドはcustom_field1234のような名前なので、何を示すか分からない。また、priorityのような選択式のメンバについても、設定値がid:10500のようになっていて、何を示すか分からない。これらは、以下APIで調べることができる。

  • カスタムフィールド: /rest/api/2/customFields
  • フィールドの選択肢: /rest/api/2/customFieldOption/{id}

フィールドの選択肢customFieldOptionは、idが分かってからでないと呼び出せないので、用途としてはidに対応する文字列を取得する程度にしか使えない。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?