【PHP】BacklogのAPIを使って課題を取得＆更新してみる

業務でBacklogの課題を一括更新する要件があったので、APIを使って行った対応内容をまとめます。

一括作成に関してはAPIでもできますが、スプレッドシートを使う方法が楽なのでそちらを参考にしてください。

[Google スプレッドシートを使って、Backlogに課題を一括登録しよう | Backlog](https://support-ja.backlog.com/hc/ja/articles/360042820873-Google-%E3%82%B9%E3%83%97%E3%83%AC%E3%83%83%E3%83%89%E3%82%B7%E3%83%BC%E3%83%88%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6-Backlog%E3%81%AB%E8%AA%B2%E9%A1%8C%E3%82%92%E4%B8%80%E6%8B%AC%E7%99%BB%E9%8C%B2%E3%81%97%E3%82%88%E3%81%86)

## 環境
PHP 7.3.11
Backlog API v2

## 前準備
BacklogのAPIを使うにはいくつか準備が必要です。
まずは下記の情報をメモしておきましょう。

1. スペース名
2. プロジェクトID
3. APIキー

##### スペース名
`https://◯◯◯.backlog.com/` の◯◯◯の部分です。

##### プロジェクトID
`https://xxx.backlog.com/ListIssueType.action?project.id=◯◯◯`の〇〇〇の部分です。

##### APIキー
発行方法はBacklogの公式サイトを確認してください。簡単です。

[APIの設定 | Backlog](https://support-ja.backlog.com/hc/ja/articles/360035641754-API%E3%81%AE%E8%A8%AD%E5%AE%9A)

新しく発行するでもいいですし、すでに発行済であればそちらを利用してもOKです。

## 課題の取得
まずは更新対象の課題を取得します。

```PHP:backlog_get.php
$sname = "xxxx";
$akey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$projectId = 999999;

$params = array(
      'apiKey' => $akey,
      'projectId[]' => $projectId,
  );
  $url = 'https://' . $sname . '.backlog.com/api/v2/issues?'.http_build_query($params, '','&');

  $headers = array('Content-Type:application/x-www-form-urlencoded');
  $context = array(
      'http' => array(
          'method' => 'GET',
          'header' => $headers,
          'ignore_errors' => true,
      )
  );
  $response = file_get_contents($url, false, stream_context_create($context));

  # レスポンスを変数で扱えるように変換
  $json = mb_convert_encoding($response, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
  $json = json_decode($json, true);
```

これでレスポンスが返ってこればOKです。
json形式で返却されるので、それをjson_decodeして配列で扱えるようにしています。

ただし、これだと課題が最大20件までしか取得できていないと思いますので、while文を使ってループするように変更します。

```php:backlog_get.php
//-- 追加開始 --//
$cnt = 0;
while(1){
  $offset = $cnt * 100;
//-- 追加終了 --//
  $params = array(
      'apiKey' => $akey,
      'projectId[]' => $projectId,
　　　　//-- 追加開始 --//
      'count' => 100,       // 取得上限(1-100) 指定が無い場合は20
      'offset' => $offset,
　　　　//-- 追加終了 --//
  );
  $url = 'https://' . $sname . '.backlog.com/api/v2/issues?'.http_build_query($params, '','&');

  $headers = array('Content-Type:application/x-www-form-urlencoded');
  $context = array(
      'http' => array(
          'method' => 'GET',
          'header' => $headers,
          'ignore_errors' => true,
      )
  );
  $response = file_get_contents($url, false, stream_context_create($context));
  # レスポンスを変数で扱えるように変換
  $json = mb_convert_encoding($response, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
  $json = json_decode($json, true);

//-- 追加開始 --//
  if(count($json) == 0){
    echo "取得0件なので終了";
    break;
  }else{
    foreach ($json as $value) {
      echo $value["issueKey"] . ":" . $value["summary"] . "\n";
    }
  }
  $cnt++;
}
//-- 追加終了 --//
```
取得した課題が0件の場合はループから抜けるようにしました。

下記のような結果が出力されたはずです。

```bash
PROJECT-1:テスト1
PROJECT-3:テスト3
PROJECT-5:テスト5
︙
```

### 取得条件
課題の取得条件はいろいろ指定できますので、上記のコードでいう`$params`の配列を必要に応じて変更してください。

検索パラメータとして利用できるものの一覧はBacklog公式サイトにありますので確認してみてください。

[課題一覧の取得 | Backlog](https://developer.nulab.com/ja/docs/backlog/api/2/get-issue-list/#)

```php:検索条件例
$params = array(
      'apiKey' => $akey,
      'projectId[]' => $projectId,
      'categoryId[]' => 99999,   // カテゴリID
      'parentChild' => 2,        // 親子課題条件（0: すべて, 1: 子課題以外, 2: 子課題, 3: 親課題でも子課題でもない課題, 4: 親課題）
      'statusId' => array(1 => 1, 2 => 2, 3 => 3, 4 => 4),  // 状態（1: 未対応, 2: 処理中, 3: 処理済み, 4: 完了）
      'sort' => 'created',
      'order' => 'asc',
      'count' => 100,       // 取得上限(1-100) 指定が無い場合は20
      'priorityId[]' => 4   // 優先度"低"のものを取得
  );
```

## 課題の更新
では次に課題の更新です。

といっても、取得の処理とほとんど変わりません。

先程取得した`issueKey`に対して更新を行います。
課題を「優先度：中」「状態：完了」にしてみます。

```php:backlog_patch.php
function backlog_patch($issueKey){
    $params = array(
        'apiKey' => $akey,
        'priorityId' => '3',   // 課題の優先度（3:中）
        'statusId' => '4'      // 状態（4:完了）
    );

    $url = 'https://' . $sname . '.backlog.com/api/v2/issues/' . $issueKey .'?'.http_build_query($params, '','&');

    $headers = array('Content-Type:application/x-www-form-urlencoded');
    $context = array(
        'http' => array(
            'method' => 'PATCH',
            'header' => $headers,
            'ignore_errors' => true,
        )
    );
    $response = file_get_contents($url, false, stream_context_create($context));
}
```

[課題情報の更新 | Backlog](https://developer.nulab.com/ja/docs/backlog/api/2/update-issue/#)

## 課題の取得＆更新
取得した課題を一気に更新したいので、これまで紹介した２つの処理をまとめてみます。

`backlog_get.php`のforeachの処理内に更新の関数を差し込みます。

```php
    foreach ($json as $value) {
      backlog_patch($value["issueKey"]);
    }
```

これでOKです。

## まとめ
意外と面倒だけど、一回作っちゃえば今後繰り返し使えるので良きです。

自分で作ってから公式ライブラリが配布されていることに気づいたので、ぶっちゃけこっちを使った方がいいかもしれませんｗ

[ライブラリ | Backlog](https://developer.nulab.com/ja/docs/backlog/libraries/#)