Google Apps ScriptでRSSを配信する【GAS】
社内でちょっとしたRSS配信が必要になり、それは既存のRSSを取得してまとめた内容から一定のフィルタをした内容を再度RSSとして配信するという仕組みで、既存のRSSリーダーのデータを拝借しつつ、RSS配信をする仕組みを作ってみました。
元のコードを掲載していたサイトが消滅していたのと、現代風に少し直して構築してみました。スプレッドシートに必要な項目が揃っていればどんなものでも配信が可能です。
目次
今回利用するスプレッドシート等
- RSS配信 - Google Spreadsheet
- Feeder
- 出力したRSSのサンプル
これまでもRSS関係としてはRSSリーダーを作ってみたり、Google Sites上でRSSを受信する仕組みを作ったりしてきましたが、今回は逆にスプシのデータに基づいてRSSとして配信をする仕組みです。XML形式で所定のフォーマットに整えて出力する必要性があります。
事前準備
スプレッドシートの準備
スプシ側は4列のみで構成しています。サイト名、タイトル、URL、日付の4列で構成しています。前述のRSSリーダーでこれらの項目を取得するよう構築しトリガーで仕掛けておけばデータは自動的に毎日洗い替えされていきます。
後述のGASで空行はスルーされるので空であっても問題ありません。
このような形式であればRSSだけじゃなく、報告書データといったものであってもスプシで整えて社内配信することが出来るので、管理者向けの日次情報報告の基盤として利用しても良いのではないかと思います。
図:このようなデータを整備します
ウェブアプリケーションとしてデプロイ
スプシを整備して「ウェブアプリケーションとしてデプロイ」をしなければRSSとして配信できません。また、このウェブアプリケーションとしてデプロイはいくつかのハマりポイントがありますので注意が必要です。公開の仕方は以下の手順。
- スクリプトエディタを開く
- 右上のデプロイをクリック
- 新しいデプロイをクリック
- 種類の選択ではウェブアプリを選択し、次のユーザとしてアプリケーションを実行で誰の権限で動かすかを指定する。自分か?アクセスしてるユーザの二択。
- アプリケーションにアクセスできるユーザを指定する。今回は公開配信ですのでアクセスできるユーザは「全員」である必要性があります。
- 最後に導入すると、ウェブアプリケーションのURLが取得できます。このURLでアクセスをします。URLの最後がexecがRSSとしての配信用のURLになります。
- 次回以降コードを編集して再デプロイ時はデプロイを管理から同じURLにて、新しいバージョンを指定して発行することが出来ます。
図:ウェブアプリとして出力します
セットアップの実行
次項のソースコードが入っていますので使う場合は、スプシを開いたら以下の手順でセットアップします。
- メニューにでてるプログラム→セットアップを実行
- 初回認証を求められるので認証を許可します。
- 完了したらもう一回同じ作業をします。
- するとスクリプトプロパティにスプシのIDが記録されて、これで配信準備完了です。
ソースコード
GAS側
前述の準備にてスプシのIDがスクリプトプロパティに格納されていれば、配信が出来ます。doGetでスプシのデータをRSSに組み立てて出力してくれます。HTML側からの要求でスプシデータを返すgetRecordData関数が最も重要な関数で、空行などはフィルタされます。日付だけはJSTに変換して配列に格納し直しています。
RSSはXMLであるので、ContentService.createTextOutputにてMimetypeをXMLで指定してテキスト出力しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
function onOpen(e) { let ui = SpreadsheetApp.getUi(); ui.createMenu('▶プログラム') .addItem('セットアップ', 'getMySheetId') .addToUi(); } //自分自身のIDを取得するコード function getMySheetId(){ let sheet = SpreadsheetApp.getActiveSpreadsheet(); let myid = sheet.getId(); let prop = PropertiesService.getScriptProperties(); prop.setProperty("sheetid", myid); //メッセージ出力 SpreadsheetApp.getUi().alert("セットアップ完了") } //RSS出力 function doGet() { //HTML出力 let output = HtmlService.createTemplateFromFile('template'); let result = output.evaluate(); //XML出力 return ContentService.createTextOutput(result.getContent()).setMimeType(ContentService.MimeType.XML); } //RSSデータを取得して返す function getRecordData(){ //スプシのIDを取得する let prop = PropertiesService.getScriptProperties(); let ssid = prop.getProperty("sheetid"); // スプレッドシート取得 let sheet = SpreadsheetApp.openById(ssid); let ss = sheet.getSheetByName("rssdata").getRange("A2:D").getValues(); //取得データを回して空行はスルーする let array = []; for(let i = 0;i < ss.length; i++){ //レコードを一個取り出す let rec = ss[i]; //空だった場合スルーする if(rec[0] == "" || rec[0] == undefined){ continue; } //日付データは変換する rec[3] = datechanger(rec[3]); //レコードデータをpushする array.push(rec); } //値をHTML側に返却する return array; } //日付列のデータを変換して返す function datechanger(dateman) { var date = new Date(dateman) return Utilities.formatDate(date, 'JST', 'EEE, d MMM yyyy HH:mm:ss Z'); } // シートのタイトル取得 function sheetTitle() { let prop = PropertiesService.getScriptProperties(); let ssid = prop.getProperty("sheetid"); let ss = SpreadsheetApp.openById(ssid).getName(); return ss; } // シートのリンク取得 function sheetLink() { let prop = PropertiesService.getScriptProperties(); let ssid = prop.getProperty("sheetid"); let ss = SpreadsheetApp.openById(ssid).getUrl(); return ss; } |
HTML側(template.html)
オリジナルのコードよりも簡素にしています。可能な限りGAS側で整形を完了させて、HTML側での処理はforループで当てはめるだけにしています。スクリプトレットによってHTML側から直接GAS側の関数を叩いてデータを1度だけ取得。あとはループで配列データを回してはめ込んでいくので処理は早いです。
タイトル、リンク、出力日、作成者の4つが最低限必要な項目なのでスプシもそれに対応するデータとしています。HTMLを使ってXMLを整形するのにこのようなスクリプトレットとループだけで簡単に構築できるテクニックというのがこの手法の一番のポイントと言えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/"> <channel> <title><?= sheetTitle() ?></title> <link><?= sheetLink() ?></link> <? var rowdata = getRecordData(); for(let i = 0; i < rowdata.length; i++){ let rec = rowdata[i]; ?> <item> <title><?= rec[1] ?></title> <link><?= rec[2] ?></link> <pubDate><?= rec[3] ?></pubDate> <dc:creator><?= rec[0] ?></dc:creator> </item> <? } ?> </channel> </rss> |
RSSリーダーで読み込んでみる
Google Chromeの拡張機能も存在するFeeder.coというサイトのRSSリーダーサービスにログインして、出力したexecのURLを読み込ませてみました。
フィードを追加から追加し無事に読み込めると真ん中のパネルにフィードの内容が列挙されます。クリックするとリンク先の記事が左側のパネルに表示されるという仕組みです。
見ているウェブページにRSSフィードがあった場合、拡張機能から追加も出来る為、枯れた技術ですが最近見直されても来ている古き良き仕組みであるRSSの仕組みを使って情報配信出来ます。GASで色々とフィルタしたり色々なサイトの情報を1つにまとめてから配信など活用方法も多々あるので、使い所はあるのではないかと思います。
図:Feederサービスでフィードを読み込ませてみた