REST APIを使ってJira Service Managementの複数サービスプロジェクトへチケット操作をしてみた

REST APIを使ってJira Service Managementの複数サービスプロジェクトへチケット操作をしてみた

Clock Icon2025.06.09

こんにちは。たかやまです。

Jira Service Managementではサービス プロジェクトとして複数のプロジェクトを作成することができます。

基本的にこのサービスプロジェクト単位でチケットをやりとりすることになりますが、ケースによってプロジェクトを横断してチケットを作成したいケースがあるかもしれません。

ただ、Jira ではプロジェクトを横断して一括でチケットを作成する機能をコンソール上から提供されていません。

そこで今回は、Jira Service ManagementのAPIを使ってチケットを作成する方法を試してみたのでご紹介します。

やってみる

やってみる前に、手順の中でJira Cloud APIとJira Service Managementの二つのAPIを使用するので簡単に説明します。

Jira Service Management APIはJira Cloud APIと階層的な関係にあり、JSMプロジェクトでは両方のAPIを組み合わせて使用することになります。

基本的なJira Service Management APIでJira Cloud APIの操作を代替することが可能ですが、後述するエージェント側でのトランジション操作のようにJira Service Management API側で操作できないものもあるので、そういった場合にはJira Cloud APIを利用する必要があります。

事前準備と前提条件

事前準備

APIを使用するには、以下の情報が必要です:

前提条件

  • サービスプロジェクトごとに同名のリクエストタイプが存在すること
  • サービスプロジェクトごとに同一のワークフローが提供されていること

環境設定

まずはAPIを叩くための環境変数を設定します。

JIRA_USERJIRA_TOKEN には実行者のメールアドレスとAPIトークンを設定してください

# 認証情報を環境変数に設定(セキュリティ対策)
export JIRA_USER="<your-email@domain.com>"
export JIRA_TOKEN="<your-api-token>"
export JIRA_BASE_URL="https://your-domain.atlassian.net"

プロジェクト一覧の取得

次に、利用可能なサービスデスクプロジェクトの一覧を取得します。

# プロジェクト情報の表示
curl --request GET \
  --url "${JIRA_BASE_URL}/rest/servicedeskapi/servicedesk" \
  --user "${JIRA_USER}:${JIRA_TOKEN}" \
  --header 'Accept: application/json' \
  --silent | jq -r '.values[] | "ID: \(.id), Name: \(.projectName), Key: \(.projectKey)"'
レスポンス例
ID: 1, Name: 開発環境, Key: DEV
ID: 2, Name: 本番環境, Key: PROD

リクエストタイプIDの取得

次に、チケット作成に必要なリクエストタイプIDを取得します。

ここが若干ハマリどころで、リクエストタイプはサービスデスクごとに存在するため、各サービスデスクから個別に取得する必要があります。

プロジェクトのリクエストタイプIDは rest/servicedeskapi/requesttype で取得できます。

curl --request GET \
  --url "${JIRA_BASE_URL}/rest/servicedeskapi/servicedesk/<PROJECT_ID>/requesttype" \
  --user "${JIRA_USER}:${JIRA_TOKEN}" \
  --header 'Accept: application/json' \
  --silent | \
  jq -r '.values[] | "ID: \(.id) - \(.name)"' | \
  sort -V

プロジェクトごとに以下のように同じリクエストタイプでも、サービスデスクごとに異なるIDが付与されていることがわかります。

プロジェクトID 1の場合 :

ID: 1 - インシデント
ID: 2 - リクエスト
ID: 3 - その他

プロジェクトID 2の場合 :

ID: 101 - インシデント
ID: 102 - リクエスト
ID: 103 - その他

そのためこのあとチケット作成時には、プロジェクトIDに対応するリクエストタイプIDを指定するために事前にリクエストタイプのIDを取得しておく必要があります。

さきほど取得したプロジェクト情報をもとに、チケットを作成したいプロジェクトのIDを指定します。

# 対象プロジェクトIDを配列で設定
TARGET_PROJECT_IDS=(1 2)

# 取得したいリクエストタイプ名を指定
REQUEST_TYPE_NAME="インシデント"

以下のスクリプトで、各プロジェクトの指定したリクエストタイプIDを自動取得できます。

# 各プロジェクトのリクエストタイプIDを取得
declare -A PROJECT_REQUEST_TYPE_IDS

echo "=== ${REQUEST_TYPE_NAME} リクエストタイプID取得開始 ==="

for project_id in "${TARGET_PROJECT_IDS[@]}"; do
    echo "プロジェクトID: $project_id のリクエストタイプを確認中..."

    # 指定したリクエストタイプIDを取得
    request_type_id=$(curl --request GET \
      --url "${JIRA_BASE_URL}/rest/servicedeskapi/servicedesk/${project_id}/requesttype" \
      --user "${JIRA_USER}:${JIRA_TOKEN}" \
      --header 'Accept: application/json' \
      --silent | jq -r --arg type_name "$REQUEST_TYPE_NAME" '.values[] | select(.name | test($type_name; "i")) | .id' | head -n 1)

    if [ -n "$request_type_id" ] && [ "$request_type_id" != "null" ]; then
        PROJECT_REQUEST_TYPE_IDS[$project_id]=$request_type_id
        echo "  ✓ プロジェクトID $project_id: ${REQUEST_TYPE_NAME}ID = $request_type_id"
    else
        echo "  ✗ プロジェクトID $project_id: ${REQUEST_TYPE_NAME}が見つかりません"
        echo "  利用可能なリクエストタイプ:"
        curl --request GET \
          --url "${JIRA_BASE_URL}/rest/servicedeskapi/servicedesk/${project_id}/requesttype" \
          --user "${JIRA_USER}:${JIRA_TOKEN}" \
          --header 'Accept: application/json' \
          --silent | jq -r '.values[] | "    - \(.name) (ID: \(.id))"'
    fi
done

# 取得結果の確認
echo ""
echo "=== 取得したリクエストタイプID ==="
for project_id in "${TARGET_PROJECT_IDS[@]}"; do
    if [ -n "${PROJECT_REQUEST_TYPE_IDS[$project_id]}" ]; then
        echo "  プロジェクト $project_id: ${PROJECT_REQUEST_TYPE_IDS[$project_id]}"
    else
        echo "  プロジェクト $project_id: 取得失敗"
    fi
done
レスポンス例
=== インシデント リクエストタイプID取得開始 ===
プロジェクトID: 1 のリクエストタイプを確認中...
  ✓ プロジェクトID 1: インシデントID = 1
プロジェクトID: 2 のリクエストタイプを確認中...
  ✓ プロジェクトID 2: インシデントID = 101

=== 取得したリクエストタイプID ===
  プロジェクト 1: 1
  プロジェクト 2: 101

チケット作成の実行

取得したプロジェクトIDとリクエストタイプIDを使用して、複数プロジェクトに同じ内容のチケットを一括作成します。

以下のスクリプトでは、指定したプロジェクトIDの配列をループして、各プロジェクトにチケットを作成します。

TICKET_SUMMARYTICKET_DESCRIPTIONには、作成したいチケットの件名と内容を設定します。

# チケット内容を設定
TICKET_SUMMARY="【ここに件名を入力してください】"
TICKET_DESCRIPTION="【ここに詳細な説明を入力してください】\n\n ←改行する場合はこちらを使用してください。"

# 複数プロジェクトへのチケット作成
declare -a CREATED_TICKETS
declare -A TICKET_KEYS
declare -A TICKET_IDS

for project_id in "${TARGET_PROJECT_IDS[@]}"; do
    request_type_id="${PROJECT_REQUEST_TYPE_IDS[$project_id]}"

    # チケット作成API実行
    response=$(curl --request POST \
      --url "${JIRA_BASE_URL}/rest/servicedeskapi/request" \
      --user "${JIRA_USER}:${JIRA_TOKEN}" \
      --header 'Accept: application/json' \
      --header 'Content-Type: application/json' \
      --silent \
      --data "{
        \"serviceDeskId\": \"$project_id\",
        \"requestTypeId\": \"$request_type_id\",
        \"requestFieldValues\": {
          \"summary\": \"$TICKET_SUMMARY\",
          \"description\": \"$TICKET_DESCRIPTION\"
        }
      }")

    # チケット情報の抽出と格納
    ticket_key=$(echo "$response" | jq -r '.issueKey // empty')
    ticket_id=$(echo "$response" | jq -r '.issueId // empty')

    if [ -n "$ticket_key" ]; then
        CREATED_TICKETS+=("$ticket_key")
        TICKET_KEYS[$project_id]="$ticket_key"
        TICKET_IDS[$project_id]="$ticket_id"
    fi
done

# 作成結果の確認
for project_id in "${TARGET_PROJECT_IDS[@]}"; do
    if [ -n "${TICKET_KEYS[$project_id]}" ]; then
        echo "プロジェクト $project_id: ${TICKET_KEYS[$project_id]}"
    fi
done
レスポンス例
プロジェクト 1: DEV01-2223
プロジェクト 2: PROD01-133

コメント追加

作成したチケットに対してコメントを追加する場合は、 /rest/servicedeskapi/request/{issueIdOrKey}/comment を使用します。

# コメント内容
COMMENT_TEXT="追加のコメント内容"

# 作成したチケットにコメントを追加
for project_id in "${TARGET_PROJECT_IDS[@]}"; do
    if [ -n "${TICKET_KEYS[$project_id]}" ]; then
        response=$(curl --request POST \
          --url "${JIRA_BASE_URL}/rest/servicedeskapi/request/${TICKET_KEYS[$project_id]}/comment" \
          --user "${JIRA_USER}:${JIRA_TOKEN}" \
          --header 'Accept: application/json' \
          --header 'Content-Type: application/json' \
          --silent \
          --data "{
            \"body\": \"$COMMENT_TEXT\",
            \"public\": true
          }")

        comment_id=$(echo "$response" | jq -r '.id // empty')
        if [ -n "$comment_id" ]; then
            echo "プロジェクト $project_id: コメント追加完了 (ID: $comment_id)"
        fi
    fi
done

トランジション

作成したチケットのステータスを変更する場合は、トランジションAPIを使用します。

こちらのAPIは、Jira REST APIの /issue/{issueIdOrKey}/transitions です。

Jira Service Management側にも /rest/servicedeskapi/request/{issueIdOrKey}/transition というAPIがありますが、こちらはカスタマー権限でのステータスを変更するためのAPIになるため、管理者権限のステータスを変更する場合にはJira CloudのAPIを使用します。

まずは以下のコマンドで、チケットのトランジション一覧を取得します。

# 利用可能なトランジションを確認(最初のチケットで確認)
first_ticket_key=$(echo "${CREATED_TICKETS[0]}")
curl --request GET \
  --url "${JIRA_BASE_URL}/rest/api/3/issue/${first_ticket_key}/transitions" \
  --user "${JIRA_USER}:${JIRA_TOKEN}" \
  --header 'Accept: application/json' \
  --silent | jq '.transitions[] | {id: .id, name: .name}'
{
  "id": "11",
  "name": "進行中"
}
{
  "id": "21",
  "name": "完了"
}
{
  "id": "31",
  "name": "解決済み"
}
{
  "id": "41",
  "name": "再オープン"
}
{
  "id": "51",
  "name": "クローズ"
}
{
  "id": "131",
  "name": "キャンセル済み"
}
{
  "id": "141",
  "name": "回復"
}

取得したトランジションIDをTRANSITION_IDに指定して、以下のコマンドで、チケットのステータスを変更します。

# トランジション実行
TRANSITION_ID=""

for project_id in "${TARGET_PROJECT_IDS[@]}"; do
    if [ -n "${TICKET_KEYS[$project_id]}" ]; then
        response=$(curl --request POST \
          --url "${JIRA_BASE_URL}/rest/api/3/issue/${TICKET_KEYS[$project_id]}/transitions" \
          --user "${JIRA_USER}:${JIRA_TOKEN}" \
          --header 'Accept: application/json' \
          --header 'Content-Type: application/json' \
          --silent \
          --data "{
            \"transition\": {
              \"id\": \"$TRANSITION_ID\"
            }
          }")

        echo "プロジェクト $project_id: トランジション実行完了"
    fi
done
レスポンス例
プロジェクト 1: トランジション実行完了
プロジェクト 2: トランジション実行完了

最後に

今回は、Jira Service ManagementのAPIを使ったチケット作成方法をご紹介しました。

WebUIでの手動作業と比べて、APIを使うことで複数環境への一括チケット作成や自動化が可能になります。

特に、障害対応やメンテナンス告知など、同じ内容を複数のプロジェクトに展開する必要がある場合には、APIを使うことで効率化が図れます。

この記事がどなたかの参考になれば幸いです。

以上、たかやま(@nyan_kotaroo)でした。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.