この記事の内容で何ができるのか
- ウェブページのソースコードに差分があったら検知できる
- 定期的にチェックを実行できる(最高頻度で毎時)
何ができないのか
- スクリプトからのアクセス拒否しているページには使えない
- どのような差分かは分からない
- 即時の検知はできない
はじめに
RSSフィードの無いウェブページの更新を検知する必要があったのでGoogle Apps Script(GAS)でスクリプトを作成しました。
同じようなニーズを持つ方の参考になれば幸いです。
スクリプト
前提
スプレッドシートをデータ保管に使いたいので、
新規のスプレッドシートから「拡張機能」→「App Script」の順でスクリプト作成を開始する。
(スプレッドシートとの連携が楽なので)
コード
スプレッドシートのA1のアドレスを、チェック用のハッシュ保管エリアとして使います。
function myFunction() {
const CHECK_URL = "https://~~~"; // チェックしたいURL
const sheet = SpreadsheetApp.getActiveSheet();
let oldHash = sheet.getRange('A1').getValue();
let response = UrlFetchApp.fetch(CHECK_URL);
let text = response.getContentText();
let hashBin = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_512, text);
let hash = Utilities.base64Encode(hashBin);
if (hash === oldHash) { // ハッシュ値に変化がなければ変更なし
return;
}
sheet.getRange('A1').setValue(hash); // ハッシュ値を更新
/* 通知を送信したり、外部のAPIを実行したり、
* 変更があったときに行いたいことを記述
*/
return;
}
定期実行
デバッグ実行して問題が無さそうであれば、トリガーのメニューから「トリガーを追加」を選び、
必要な頻度での実行を指定する。
カスタマイズ例
先のコードはコア機能のみなので、必要に応じて機能を足してください。
例えば以下のカスタマイズコードは、下記の要件を満たすよう改造した場合です。
- 複数のURLを対象にする
- スプレッドシートでURLを管理する
- 通知用にタイトルの項目を追加する
スプレッドシートのA列をタイトル、B列をURL、そしてC列をチェック用のハッシュ保管エリアとして使います。
function myFunction() {
const COLUMN_TITLE = 0;
const COLUMN_URL = 1;
const COLUMN_HASH = 2;
const sheet = SpreadsheetApp.getActiveSheet();
const allData = sheet.getDataRange();
const rows = allData.getValues();
let results = [];
rows.forEach(function(row, i) {
let title = row[COLUMN_TITLE];
let url = row[COLUMN_URL];
let oldHash = row[COLUMN_HASH];
let response = UrlFetchApp.fetch(url);
let text = response.getContentText();
let hashBin = Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_512, text);
let hash = Utilities.base64Encode(hashBin);
if (hash === oldHash) {
return;
}
results.push([title, url]);
sheet.getRange(i + 1 , COLUMN_HASH + 1).setValue(hash);
});
if (results.length === 0) {
// 更新がなかったときの処理
return;
}
// 更新があったときの処理
return;
}
おわりに
GASからのfetchがタイムアウトになってしまうページについては無力で、他のサーバサイド言語などで対応する必要があります。
ただ、お手軽にサクッと更新チェックを定期実行するのであれば、魅力的な選択肢だと思います。