電通総研 テックブログ

電通総研が運営する技術ブログ

TypeScript × axios × Backlog APIで課題登録!

はいどーもー!

早いもので新卒入社から丸3年、コミュニケーションIT事業部の宮澤響です!

本記事では、Backlog APIを利用したBacklogへの課題の登録方法について、私が実際にハマったポイントを交えながらご紹介します。

背景・前提

Backlogとは

Backlogとは、株式会社ヌーラボが提供している課題管理・プロジェクト管理のサービスです。
シンプルで直感的に使えるデザインが特長であり、GitリポジトリWikiとしての機能も有しています。

どうしてAPIで課題登録を?

弊社では同種のサービスとしてJiraが全社展開されています。
そのため、私自身もこれまではJiraの利用経験しかありませんでした。

しかしこの度、チームの都合によりBacklogを利用することになり、利用方法を調査していたところ、BacklogにはJiraのように標準機能で自動化できる項目はあまりないことが分かりました。
そこで、Backlog APIを利用することで一部の処理を自動化できないかと考え、手始めに基本となるであろう課題の登録をやってみることにしました。

サンプルコードについて

本記事のサンプルコードにはTypeScriptaxiosを利用しています。
それぞれのインストール方法などについては本記事内では解説していませんので、適宜リンク先をご参照ください。

下準備

まずは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

なお、issueTypeIdpriorityIdは、登録先のプロジェクトの課題ページの高度な検索タブや、プロジェクト設定の当該種別の編集ページのURLから確認するのが最も簡単です。

もちろん、課題情報の取得種別一覧の取得優先度一覧の取得、などのAPIを利用して確認することも可能です。

注意点として、Backlog APIを利用する際はContent-Typeapplication/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_xxxxxxxxxxはカスタム属性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-Typeapplication/x-www-form-urlencoded
  • カスタム属性の値は選択肢名ではなく選択肢IDで指定
  • 標準機能でパラメータに複数の値を指定するには、append()メソッドで1つ目の選択肢と2つ目の選択肢を分けて指定

少しでもBacklog APIの利用を検討している方々の参考になれば幸いです。

最後までお読みいただき、本当にありがとうございました!


執筆:@miyazawa.hibiki、レビュー:Ishizawa Kento (@kent)
Shodoで執筆されました