はいどーもー! 早いもので新卒入社から丸3年、コミュニケーションIT事業部の宮澤響です! 本記事では、 Backlog API を利用した Backlog への課題の登録方法について、私が実際にハマったポイントを交えながらご紹介します。 背景・前提 Backlogとは どうしてAPIで課題登録を? サンプルコードについて 下準備 APIキーの発行 プロジェクトIDの確認 スペースのURLの確認 やってみる 必要なモジュールのインポートと変数の定義 課題の登録〜基本編〜 課題の登録〜カスタム属性編〜 課題の登録〜複数選択編〜 おまけで検証してみた まとめ 背景・前提 Backlogとは Backlogとは、株式会社 ヌーラボ が提供している課題管理・プロジェクト管理のサービスです。 シンプルで直感的に使えるデザインが特長であり、Git リポジトリ や Wiki としての機能も有しています。 どうして API で課題登録を? 弊社では同種のサービスとして Jira が全社展開されています。 そのため、私自身もこれまではJiraの利用経験しかありませんでした。 しかしこの度、チームの都合によりBacklogを利用することになり、利用方法を調査していたところ、BacklogにはJiraのように標準機能で自動化できる項目はあまりないことが分かりました。 そこで、Backlog API を利用することで一部の処理を自動化できないかと考え、手始めに基本となるであろう課題の登録をやってみることにしました。 サンプルコードについて 本記事のサンプルコードには TypeScript と axios を利用しています。 それぞれのインストール方法などについては本記事内では解説していませんので、適宜リンク先をご参照ください。 下準備 まずはBacklog API を利用するための下準備です。 API キーの発行 個人設定 > API から、 API キーを発行します。 必要に応じて メモ 欄に文字列を入力し、 登録 ボタンを押下します。 なお、Backlog API ではOAuth 2.0を利用した認証・認可方式も提供されていますが、Nulabアカウントを作成した上で開発するアプリケーションの登録を行う必要があるため、本記事では事前準備が不要な API キーを利用した方式を採用します。( 参考 ) プロジェクトIDの確認 課題の登録先となるプロジェクトのプロジェクトIDを確認します。 プロジェクトIDは、当該プロジェクトの 課題 ページや、 プロジェクト設定 ページのURLから確認できます。 プロジェクト情報の取得 の API を利用して確認することもできますが、今回は少し楽をしています。 スペースのURLの確認 課題の登録先となるプロジェクトが所属しているスペースのURLを確認します。 スペースやプロジェクトのあらゆる画面のURLの先頭にある https://xx.backlog.jp または https://xx.backlog.com の部分です。 xx の部分にはそれぞれのスペースのスペースIDが入ります。 やってみる 実際に API リク エス トのための ソースコード を記述していきます。 必要なモジュールのインポートと変数の定義 まずは必要なモジュールをインポートするとともに、ここまでに確認してきた内容から以下の変数を定義します。 // 必要なモジュールをインポートします import axios , { AxiosResponse } from "axios" ; // 右辺の""の中に先ほど発行したAPIキーの値を入力します const apiKey = "abcdefghijklmn" ; // 右辺の""の中に先ほど確認したプロジェクトIDの値を入力します const projectId = "123456" ; // 右辺の""の中に先ほど確認したスペースのURLの値の末尾に「/api/v2」を追加したものを入力します const baseUrl = "https://xx.backlog.jp/api/v2" ; なお、本記事では簡素化のために API キーを ソースコード 内に直接記載していますが、実際に運用をする際、特に GitHub などを利用して ソースコード を共有、公開する際は、 API キーのような認証情報は ソースコード 内に直接記載しない ことを強く推奨します。 (対応例: .gitignore で指定した .env ファイルに記載した値を dotenv を利用して読み込む、など) 課題の登録〜基本編〜 課題の追加 の API を利用します。 手始めに、必須とされている以下のパラメータのみを指定して、POSTリク エス トを送信してみます。 パラメータ名 型 内容 projectId 数値 課題を登録するプロジェクトのID summary 文字列 課題の件名 issueTypeId 数値 課題の種別のID priorityId 数値 課題の優先度のID なお、 issueTypeId や priorityId は、登録先のプロジェクトの 課題 ページの 高度な検索 タブや、 プロジェクト設定 の当該種別の編集ページのURLから確認するのが最も簡単です。 もちろん、 課題情報の取得 、 種別一覧の取得 、 優先度一覧の取得 、などの API を利用して確認することも可能です。 注意点として、Backlog API を利用する際は Content-Type が application/x-www-form-urlencoded である必要がある ため、 URLSearchParams を利用します。( 参考 ) const createIssue1 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = new URLSearchParams ( { apiKey , projectId , summary: "テスト1" , issueTypeId: "123456" , priorityId: "2" , } ); return await axios.post ( url + params ); } ; createIssue1 (); 無事に登録されました。 課題の登録〜カスタム属性編〜 続いて、以下のカスタム属性の値を指定してみます。 カスタム属性名 選択形式 選択肢 単一選択カスタム属性 単一選択(リスト形式) 選択肢1、選択肢2、選択肢3 複数選択カスタム属性 複数選択(リスト形式) 選択肢1、選択肢2、選択肢3 カスタム属性のパラメータ名は customField_xxxxx ( xxxxx はカスタム属性ID)です。 カスタム属性IDの確認方法は、これまでのものと同様、登録先のプロジェクトの 課題 ページの 高度な検索 タブのURL、 プロジェクト設定 の当該カスタム属性の編集ページのURL、 カスタム属性一覧の取得 の API などです。 注意点として、カスタム属性の値は、 選択肢名ではなく選択肢IDで指定 します。 課題の追加 の API リファレンスにはこのことが書かれていないので、若干のハマりポイントです。 const createIssue2 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = new URLSearchParams ( { apiKey , projectId , summary: "テスト2" , issueTypeId: "123456" , priorityId: "2" , // 「customField_12345: "選択肢1"」とすると400エラーになります customField_12345: "1" , // 同上 customField_67890: "1" , } ); return await axios.post ( url + params ); } ; createIssue2 (); 無事にカスタム属性の値が設定されました。 課題の登録〜複数選択編〜 続いて、複数選択が可能なカスタム属性に複数の値を指定してみます。 イメージとしては以下のような ソースコード なのですが、このままでは customField_67890 に複数の値を指定する部分で コンパイル エラー( Type 'string[]' is not assignable to type 'string'. )が発生してしまいます。 const createIssue3 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = new URLSearchParams ( { apiKey , projectId , summary: "テスト3" , issueTypeId: "123456" , priorityId: "2" , customField_12345: "1" , // これはコンパイルエラーになります customField_67890: [ "1" , "2" ] , } ); return await axios.post ( url + params ); } ; createIssue3 (); そのため、標準機能で対応する場合には、少し不格好ではありますが、 append() メソッドを利用して、1つ目の選択肢と2つ目の選択肢を分けて指定 します。 const createIssue3 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = new URLSearchParams ( { apiKey , projectId , summary: "テスト3" , issueTypeId: "123456" , priorityId: "2" , customField_12345: "1" , customField_67890: "1" , } ); params.append ( "customField_67890" , "2" ); return await axios.post ( url + params ); } ; createIssue3 (); 或いは、コンスト ラク タでは値を指定せず、 append() メソッドのみで全ての値を指定することも可能です。 const createIssue3 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = new URLSearchParams (); params.append ( "apiKey" , apiKey ); params.append ( "projectId" , projectId ); params.append ( "summary" , "テスト3" ); params.append ( "issueTypeId" , "123456" ); params.append ( "priorityId" , "2" ); params.append ( "customField_12345" , "1" ); params.append ( "customField_67890" , "1" ); params.append ( "customField_67890" , "2" ); return await axios.post ( url + params ); } ; createIssue3 (); なお、上述のサンプルコードはいずれも標準機能のみを用いてクエリパラメータを生成していましたが、外部ライブラリを利用すると、カスタム属性に複数の値を指定する部分を一行ですっきり記述できます。 例えば、 qs を利用すると、以下のようになります。 import qs from "qs" ; const createIssue3 = async () : Promise < AxiosResponse > => { const url = ` ${ baseUrl } /issues?` ; const params = qs.stringify ( { apiKey , projectId , summary: "テスト3" , issueTypeId: "123456" , priorityId: "2" , customField_12345: "1" , customField_67890: [ "1" , "2" ] , } , { indices: false } ); return await axios.post ( url + params ); } ; createIssue3 (); 無事に複数の値が設定されました。 これでひとまず課題登録に関する一連の試みは完了です。 おまけで検証してみた ちょっとしたおまけです。 上述のとおり、Backlog API では application/x-www-form-urlencoded でリク エス トを送信しますが、 application/json でのリク エス トに変更したらどうなるのでしょうか。 課題の登録には不要な検証ですが、気になったので試してみました。 const createIssue4 = async () : Promise < AxiosResponse > => { // apiKeyをdataに含めると401エラーになります const url = ` ${ baseUrl } /issues?apiKey= ${ apiKey } ` ; const data = { projectId , summary: "テスト4" , issueTypeId: "123456" , priorityId: "2" , customField_12345: "1" , customField_67890: [ "1" , "2" ] , } ; return await axios.post ( url , data ); } ; createIssue4 (); 結果としては、課題の登録自体はできるものの、カスタム属性の値が反映されませんでした。 (中途半端に成功する理由については不明です…もしご存知の方がいらっしゃれば、ぜひ本記事を引用して記事を執筆してみてください…!笑) まとめ 本記事では、Backlog API を利用したBacklogへの課題の登録方法について、サンプルコードとともにご紹介しました。 その際の主な注意点は以下です。 API キーのような認証情報は ソースコード 内に直接記載しない(Backlog API に限らず) Content-Type は application/x-www-form-urlencoded カスタム属性の値は選択肢名ではなく選択肢IDで指定 標準機能でパラメータに複数の値を指定するには、 append() メソッドで1つ目の選択肢と2つ目の選択肢を分けて指定 少しでもBacklog API の利用を検討している方々の参考になれば幸いです。 最後までお読みいただき、本当にありがとうございました! 私たちは同じ事業部で共に働いていただける仲間を募集しています! 私自身は対顧客のセキュリティに関する業務に従事していますので、そのような業務にご興味がありましたら、応募の際にお問い合わせください! みなさまのご応募、お待ちしています! クラウドアーキテクト アプリケーションアーキテクト 電通グループ向け基幹システムプロジェクトマネージャ 戦略的IT プロジェクトマネージャ/ITコンサルタント 執筆: @miyazawa.hibiki 、レビュー: Ishizawa Kento (@kent) ( Shodo で執筆されました )