Google docsのスプレッドシートに特定フィードの更新内容を追記する

業務でふと必要になって時々似た様なGoogle App Script書いているのですが、毎回書き始めるときに「えーっと、どうだったかな」となることが2回続いたのでエントリとして追加。

以下の様な形で書いてみた。そんなに大したことはやっていないのだけれども少し調整したところは、

  • フィード内のアイテムのプロパティで示されるリンク先URLの重複をシートに記録した中に一致したものが無いかの確認をする様にした
    • やり方としてはスプレッドシートの情報をまるっと取得して素朴にループさせてという愚直な方法にした(プレッドシート呼び出しのAPIを繰り返して叩かない)
  • リンク先のURLのバリデーションを入れる
    • RSSフィードが発行されていないページを外部のサービスを使ってRSS化したときに、更新対象以外の要素がフィードに含まれていたとき*1にそれを除外するため

ぐらい。 あとはSlackに通知させる必要があれば、sheet.appendRow([title, url, description]); と書いている辺りで併せて通知させれば良いかと思う。

下のスクリプトを追加して、定期的に呼び出す設定すればRSSが更新される度にシートの最終行に追記されていく様になる。

function parseNewsFeed() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var sheetData = sheet.getDataRange().getValues();
  
  var feedURL = "(走査対象のフィードのURL)";
  var response = UrlFetchApp.fetch(feedURL);

  var xml = XmlService.parse(response.getContentText());
  var items = xml.getRootElement().getChildren('channel')[0].getChildren('item');
  
  for(var i = 0; i < items.length; i++) {
    var title = items[i].getChild("title").getText();
    var url = items[i].getChild("link").getText();
    var description = items[i].getChild("description").getText().replace(/<("[^"]*"|'[^']*'|[^'">])*>/g,'').replace(/(\s+)/g, '');
    
    var urlValidate = /(フィード内のURLのバリデーション用正規表現を書く)/;
    
    if (urlValidate.test(url)) {
      if (!isExist(sheetData, 1, url)) {
        sheet.appendRow([title, url, description]);
      }
    }
  }
}

function isExist(sheetData, targetCol, value) {
  for(var i=0; i<sheetData.length; i++) {
    if (sheetData[i][targetCol] == value) {
      return true;
    }
  }
  return false;
}

*1:ページサイドにあるカテゴリなどの要素がフィードのアイテムとして更新されてしまうことがあるため