【GAS編】QiitaAPIで投稿記事ごとのviews数、LGTM数、ストック数、コメント数を取得し一覧で表示

以前投稿した「[【JavaScript初心者】QiitaAPIで投稿記事ごとのviews数、LGTM数、ストック数、コメント数を取得し一覧で表示](https://qiita.com/Pell/items/82cdc7ad199f32d964b7)」のGoogleAppsScript(GAS)版です。
各投稿記事のviews数、LGTM数、ストック数等を一覧で確認できるようにします。QiitaAPI(api/v2/authenticated_user/items、api/v2/items/[記事のID])を使用して投稿記事ごとのviews数、LGTM数、ストック数を取得、表示しました。

# 本記事の環境

※PCに環境構築を行う必要はありません。
WEBブラウザ(Google Chome)
Googleアカウント

# 使用技術

GoogleAppsScriptのみ。

# 事前準備

[以前の投稿](https://qiita.com/Pell/items/82cdc7ad199f32d964b7)の「事前準備」を参照してください。

# 使用方法

* 以下の成果物をGoogleスプレッドシート/拡張機能/Apps Scriptにコピー&ペーストし、「ユーザーID」と「アクセストークン」を書き換える。
* 「実行」ボタンを選択して、実行が終わるまで少し待つ。
  * 初回は、承認、Googleアカウントへのログイン、リクエストの許可が求められる。
* 実行が終わったら実行ログを確認する。
* 実行ログに問題がなければスプレッドシート側の出力結果を確認する。

# 成果物(画面)

![09_結果確認3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1009061/66b44aa1-4a7c-1101-83c9-47e605d9d57b.png)

# 所感

* JavaScript版の成果物を参考にできたため以前よりスムーズに作成できた。
* GAS版では、定期実行や、Qiita記事への自動投稿・更新も手軽に可能かと思われるため今後試してみる。

# 成果物(ソースコード)

```javascript
// ユーザーID
const USER_ID = "[ユーザーID]";
// 閲覧権限トークン
const TOKEN = "[アクセストークン]";
// 見出し行
const TITLES = [
  "No","作成日","タイトル","views","LGTM","ストック","コメント",
];
// データ整形用
const COLUMNS = [
  "created_at", "title", "page_views_count", "likes_count", "stock_count", "comments_count",
];

// メイン処理
function qiitaMain() {
  // 処理対象スプレッドシートを取得する。
  let spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  let sheet = spreadsheet.getSheets()[0];

  // シート全体をクリアする。
  sheet.clear();

  // 見出し行を出力する。
  for (let indexY = 0; indexY < TITLES.length; indexY++) {
    sheet.getRange(1,indexY + 1).setValue(TITLES[indexY]);
  }

  // 記事一覧取得処理を呼び出す。
  let qiita_data = getQiita();
  // 記事一覧を出力する。
  for (let indexX = 0; indexX < qiita_data.length; indexX++) {
    // No列は個別に出力する。
    sheet.getRange(indexX + 2, 1).setValue(qiita_data.length - indexX);  
    for (let indexY = 0; indexY < TITLES.length; indexY++) {
      // 各記事を出力する。
      sheet.getRange(indexX + 2, indexY + 2).setValue(qiita_data[indexX][indexY]);  
    }
  }

  // 合計行を出力する。
  sheet.getRange(qiita_data.length + 3, 1).setValue("計");
  sheet.getRange(qiita_data.length + 3, 2).setValue("ー");
  sheet.getRange(qiita_data.length + 3, 3).setValue("ー");
  sheet.getRange(qiita_data.length + 3, 4).setFormula("SUM(D2:D" + (qiita_data.length + 1) + ")");
  sheet.getRange(qiita_data.length + 3, 5).setFormula("SUM(E2:E" + (qiita_data.length + 1) + ")");
  sheet.getRange(qiita_data.length + 3, 6).setFormula("SUM(F2:F" + (qiita_data.length + 1) + ")");
  sheet.getRange(qiita_data.length + 3, 7).setFormula("SUM(G2:G" + (qiita_data.length + 1) + ")");

  // 実行日時を出力する。
  sheet.getRange(qiita_data.length + 5, 1).setValue("実行日時：" + Utilities.formatDate(new Date(),"JST", "yyyy/MM/dd HH:mm"));
}

// 記事一覧取得処理
function getQiita() {
  let result = [];
  let apiUrl = "https://qiita.com/api/v2/users/" + USER_ID + "/items";
  let response = UrlFetchApp.fetch(apiUrl);
  let total = response.getHeaders()['total-count'];
  let page = 1;
  let index_result = 0;
  while (index_result < total) {
    // ページャーごとに分けて記事を取得する。
    // 記事を全件取得するまで処理を続ける。
    let response = UrlFetchApp.fetch(apiUrl + "?page=" + page);
    let json = response.getContentText();
    let jsonData = JSON.parse(json);
    for (let index_json in jsonData) {
      // 取得した記事ごとに処理を行う。
      let work = [];
      // 記事詳細取得処理を呼び出す。
      let detail = getQiitaDetail(jsonData[index_json]['id']);
      // ストック数取得処理を呼び出す。
      let stock_count = getQiitaStock(jsonData[index_json]['id']);
      for(let column of COLUMNS) {
        switch (column){
          case "page_views_count":
            work.push(detail['page_views_count']);
            break;
          case "created_at":
            // 日付のフォーマットを変更する。
            work.push(Utilities.formatDate(new Date(jsonData[index_json][column]),"JST", "yyyy/MM/dd"));
            break;
          case "stock_count":
            work.push(stock_count);
            break;
          case "title":
            work.push('=HYPERLINK("' + jsonData[index_json]['url'] + '","' + jsonData[index_json][column] + '")');
            break;
          default:
            work.push(jsonData[index_json][column]);
            break;
        }
      }
      result[index_result] = work;
      index_result++;
    }
    page++;
  }
  // Logger.log(result);
  return result;
}

// 記事詳細取得処理(views数)
function getQiitaDetail(id) {
  let apiUrl = "https://qiita.com/api/v2/items";
  let headers = {'Authorization' : 'Bearer ' + TOKEN};
  let params = {'headers' : headers};
  let detail = UrlFetchApp.fetch(apiUrl + "/" + id, params);
  let jsonDetail = JSON.parse(detail.getContentText());
  return jsonDetail;
}

// ストック数取得処理
function getQiitaStock(id) {
  let result = 0;
  let apiUrl = "https://qiita.com/api/v2/items/"　+ id + "/stockers";
  let headers = {'Authorization' : 'Bearer ' + TOKEN};
  let params = {'headers' : headers};
  let page = 1;
  let flg = true;
  while (flg) {
    // ページャーごとに分けてストック情報を取得する。
    // ストック情報を全件取得するまで処理を続ける。
    let response = UrlFetchApp.fetch(apiUrl + "?page=" + page + "&per_page=100");
    let json = response.getContentText();
    let jsonData = JSON.parse(json);
    result += jsonData.length;
    if (jsonData.length < 100) {
      // 次のページャーがないと判断して処理終了。
      flg = false;
    }
    page++;
  }
  // Logger.log(result);
  return result;
}
```