Bloggerの投稿一覧をGASで自動記入する

GoogleAppsScriptが面白そうだったので遊んでみた。

やってみたこと

今回は、ブログのサイトマップの一覧をGoogleAppsScriptを使用してGoogleスプレットシートに記載する。

  1. サイトマップを取得する
  2. スプレットシートに保存してあるデータを取得する
  3. データとサイトマップから新規/更新/削除を行う
    • 新規/更新の場合、BloggerAPIを使用して詳細情報を取得する
  4. スプレットシートに更新したデータを適用する

補足(BloggerAPIで投稿一覧を取得)

BloggerAPIは、投稿一覧を取得可能です。ただし、BloggerAPIの投稿一覧取得は、取得数が大量(例:50件以上)となる場合、エラーを返すことがあります。そのため、投稿一覧の取得はサイトマップを使用して取得しています。(投稿の詳細情報取得は、安定しており失敗は確認できていません。ただし、複数回行うため、時間がかかります)

ソースコード

posts.gsvar bloggerid = '{BloggerID}';
var key = '{BloggerAPIキー}';
var sheetid = '{スプレッドシートID}';
// www.bugbugnow.netのドメインを要変更

// ブロガーの投稿情報を取得
function updateBloggerPost(value) {
  var fetchOptions = {
    method:'GET',
    headers:{
      Referer:'https://www.bugbugnow.net/',
    }
  };

  var m = value[0].match(/^https?:\/\/www.bugbugnow.net(\/.*$)/);
  if (m != null) {
    var request = 'https://www.googleapis.com/blogger/v3/blogs/'+bloggerid+'/posts/bypath'+'?path='+m[1]+'&key='+key;
    var response = UrlFetchApp.fetch(request, fetchOptions);
    Utilities.sleep(5*1000);//5s
    var content = response.getContentText();
    try {
      var json = JSON.parse(content);
      value[2] = json.published;
      value[3] = json.title;
      if (json.labels) {
        value[4] = json.labels.join(',');
      } else {
        // タグなし対策
        value[4] = '';
      }
    } catch (e) {
      Logger.log('json err.');
    }
  }
}

function updatePostList() {
  // サイトマップの取得
  var ret = 0;
  var response = UrlFetchApp.fetch('https://www.bugbugnow.net/sitemap.xml');
  var xml = XmlService.parse(response.getContentText());
  var root = xml.getRootElement();
  var ns = XmlService.getNamespace('http://www.sitemaps.org/schemas/sitemap/0.9');

  // サイトマップの解析
  var urls = root.getChildren('url', ns);
  Logger.log('sitemap: '+urls.length);

  // スプレットシートの取得
  var sheetApp = SpreadsheetApp.openById(sheetid);
  var sheet = sheetApp.getSheetByName('posts');

  var list = [];
  var values = [[],[],[],[],[]];
  var row = sheet.getLastRow();
  if (row > 1) {
    values = sheet.getRange(1+1, 1, row-1, 5).getValues();
  }

  // 更新/追加
  for (var i=0; i<urls.length; i++) {
    var url = urls[i].getChildText('loc', ns);
    var mod = urls[i].getChildText('lastmod', ns);
    var insert = true;
    for (var k=0; k<values.length; k++) {
      if (values[k][0] == url) {
        if (values[k][1] != mod) {
          values[k][1] = mod;
          updateBloggerPost(values[k]);
          ret++;
          Logger.log('update: '+values[k][0]);
        }
        list[k] = true;
        insert = false;
        break;
      }
    }
    if (insert) {
      values.push([url, mod]);
      updateBloggerPost(values[values.length-1]);
      list[values.length-1] = true;
      ret++;
      Logger.log('insert: '+values[values.length-1][0]);
    }
    if (ret >= 10) {
      break;
    }
  }

  // 削除
  for (var i=values.length-1; i>=0; i--) {
    if (list[i] !== true) {
      Logger.log('delete: '+values[i][0]);
      values.splice(i, 1);
      ret++;
    }
  }

  // 更新
  values.sort(function(a, b) {
    return new Date(a[2]).getTime() - new Date(b[2]).getTime();
  });
  if (row > 1) {
    sheet.getRange(2, 1, row-1, 5).clear();
  }
  sheet.getRange(2, 1, values.length, values[0].length).setValues(values);
}

// 投稿一覧更新
function updatePost() {
  updatePostList();
}

完成品

Bloggerのページ一覧を下記のようにGoogleスプレットシートに記入できました。

posts

変更履歴

更新日内容
2018/02/23初版
2018/08/12[fix] ラベルのない投稿がある場合、エラーする問題を修正

参考