やりたいこと
Googleマイマップにラーメン屋の感想を入力し、Slackに内容を通知して共有したい
調べた限り、マイマップには更新を検知するためのwebhook設定などはない。
今回はGoogle Apps Script, Fusion Tablesを利用して実現する。
※Fusion Tablesは2019年12月でサービス終了のアナウンスが流れているため注意してください
各種利用するサービスについて
マイマップ
自分専用のGoogle Mapを作り、メモとかピンができる
Fusion Tables
About Fusion Tables – Fusion Tables Help
スプレッドシートをRDBMSのようにSQLで編集することができる。
実装
既存マイマップをFusion Tablesに落とし込む
マイマップはkmlというxml形式でエクスポートすることができる。
ダウンロードしたkmlファイルを開いてURLをたどっていくと以下のような形式のkmlがダウンロードできるリンクにたどり着く
<?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://www.opengis.net/kml/2.2"> <Document> <name>hogehogeマップ</name> <description>hogehoge</description>
上記kmlをダウンロードし、新規作成したFusion Tablesにインポートする
正しくインポートされたら name
, description
カラムが追加される
Google Apps Scriptでkmlを監視する
以下に全文ソース記載。やっていることは
- 現在のFusion Tablesのデータを取得
- 現在のkmlのデータを取得
- kmlからpinデータのみを抽出
- Fusion Tablesのデータと比較
- Fusion Tablesにないものは新規レビューとしてFusion Tablesに追加、Slackに通知
function myFunction() { // table id を入力 var tableId = '*****************************************'; var selectSql = 'SELECT name, description FROM ' + tableId; var res = FusionTables.Query.sql(selectSql); // fusion tableのデータをハッシュに var fusionTable = {}; for(var i = 0; i < res.rows.length; i++) { var name = res.rows[i][0]; var description = res.rows[i][1]; fusionTable[name] = fusionTable[name] || []; fusionTable[name].push(description); } // kml urlを入力 var kmlUrl = 'https://www.google.com/maps/d/kml?forcekml=1&mid=******************************'; var kmlResponse = UrlFetchApp.fetch(kmlUrl); var xml = XmlService.parse(kmlResponse.getContentText()); // ハードコーディングしているが取得したほうが安全 var namespace = XmlService.getNamespace('http://www.opengis.net/kml/2.2') // kmlのFolder Elementの中にデータあり var folders = xml.getRootElement().getChildren()[0].getChildren('Folder', namespace); for(var i = 0; i < folders.length; i++) { var folder = folders[i]; // name, descriptionのみを取り出す var placemarks = folder.getChildren("Placemark", namespace); for(var j = 0; j < placemarks.length; j++) { var nameElement = placemarks[j].getChild("name", namespace); var descriptionElement = placemarks[j].getChild("description", namespace); var name = ''; var description = ''; if(nameElement) name = nameElement.getValue().trim(); if(descriptionElement) description = descriptionElement.getValue().trim(); // 現在のFusion Tablesとの比較 if(!fusionTable[name] || fusionTable[name].indexOf(description) == -1) { Logger.log(name + ": false"); Logger.log("name") Logger.log(name); Logger.log("description"); Logger.log(description); Logger.log("fusionTable"); Logger.log(fusionTable[name]); var insertSql = 'INSERT INTO ' + tableId + '(name, description) VALUES (\'' + name + '\', \'' + description + '\');'; FusionTables.Query.sql(insertSql); sendSlackMessage(name, description); } } } } function sendSlackMessage(name, description) { // Slack incoming webhook URLを入力 var slackWebhook = 'https://hooks.slack.com/services/****************************; var options = { "method": "post", "contentType": "application/json", "payload": JSON.stringify({ "text": "*" + name + "*\n" + description }) }; UrlFetchApp.fetch(slackWebhook, options); }
定期的に実行する
GASを定期実行するトリガーを設定する
Done
参考URL
Fusion Tables×Google Apps Script(Webアプリケーション作成編1) – Qiita