概要
Slack Bot と Google Apps Script を用いて,特定の Web ページが更新されたことを通知する簡易な機能を実装してみる.
詳細
ふと東方我楽多叢誌の更新頻度を知りたくなったので
- 1日おきに Web ページの情報を取ってくる
- 取ってきた情報と,以前のページ情報を比較する
- 2で比較したものが異なる場合は通知し,そうでない場合は通知しない
という流れの機能を作る.
簡単な流れ図
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
東方我楽多叢誌 strange article of the outer world
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
情報の取得 ↑ ↓ 情報の保存
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
Google Apps Script + Google スプレッドシート
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
更新通知 ↓
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
Slack Bot
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
Slack Bot の作成
- https://api.slack.com/apps にアクセスし Create New App をクリック
- アプリ名とワークスペースを設定し Create App をクリック
- 左側のメニューから Bot Users をクリック
- Add a Bot User をクリック
- 表示名とデフォルトユーザー名を設定し Add Bot User をクリック1
- 左側のメニューから Install App をクリック
- Install App to Workspace をクリック
- アプリがワークスペースへのアクセス権限をリクエストしてくるので,許可する
- 表示されるトークンのうち Bot User OAuth Access Token をメモしておく
スプレッドシートの作成
- Google ドライブ上にスプレッドシートを作成しておく
- スプレッドシート ID をメモしておく(下記参照)
https://docs.google.com/spreadsheets/d/[スプレッドシートID]/edit
GAS でのコーディング
- 作成したスプレッドシートのメニューバーから ツール>スクリプト エディタ をクリック
- エディタ画面の リソース>ライブラリ からこちらのライブラリを追加する
- 次のコードを入力して保存する
コード.gs
function updateCheck() {
// 東方我楽多叢誌のページ情報を取得
var targetUrl = "https://touhougarakuta.com/";
var response = UrlFetchApp.fetch(targetUrl);
var hash = Utilities.computeDigest(Utilities.DigestAlgorithm.MD5, response.getContentText()).toString();
// データベース(スプレッドシート)の情報を取得
var sheet = SpreadsheetApp.openById("スプレッドシートID");
var data = sheet.getRange("A1").getValue();
// Slack API でメッセージ送信
var slack_token = "xoxb-******"; // Bot User OAuth Access Token
var slackApp = SlackApp.create(slack_token);
var channelId = "ABCDE1234";
var message = "東方我楽多叢誌に更新があるようです。\n" + targetUrl;
var result = "Not Posted";
if(data != hash) {
sheet.getRange("A1").setValue(hash);
result = slackApp.chatPostMessage(channelId, message, {});
}
Logger.log(result);
}
テスト
- スクリプトエディタの画面で 実行ボタン をクリック
- Google アカウントへのアクセスをリクエストされるので,許可する2
- スクリプトが実行され,Slack Bot に通知が来たら成功
運用開始
- スクリプトエディタの画面で 編集>現在のプロジェクトのトリガー をクリック
- トリガーを追加 をクリック
- イベントのソースを 時間主導型 にし,例えば1日おきに更新確認を行いたい場合は,トリガーのタイプを 日付ベースのタイマー にして時刻を選択する
東方我楽多叢誌に更新があれば,下記のように通知がなされる.
発展編: 更新内容も一緒に通知する
上記の機能では「Web ページが更新された」ということしか通知されない.なぜなら,更新通知の際に Web ページ全体をハッシュ値に変換して比較しており,差分の検出を行うことができないからである.そこで以下では,具体的な更新内容も併せて通知させてみたい.
スプレッドシートの書き換え
前節のスプレッドシートの作成で既に作成したスプレッドシートに以下の通り記入する3.
- セル A1 に
=IMPORTXML("https://touhougarakuta.com", "//a[contains(@class, 'card')]/@href")
を記入 - セル B1 に
=IMPORTXML("https://touhougarakuta.com" & A4, "//h2")
を記入
GAS コードの書き換え
前節の GAS でのコーディングの手順に従ってスクリプトエディタを開き,コードを次のように書き換える.
コード.gs
function updateCheck() {
// データベース(スプレッドシート)の情報を取得
var sheet = SpreadsheetApp.openById("スプレッドシートID");
var url = "https://touhougarakuta.com";
var oldtitle = sheet.getRange("E4").getValue();
var href = url + sheet.getRange("A4").getValue();
var title = sheet.getRange("B1").getValue();
// Slack API でメッセージを送信する準備
var slack_token = "xoxb-******"; // Bot User OAuth Access Token
var slackApp = SlackApp.create(slack_token);
var channelId = "ABCDE1234";
var message = "新着情報:\n" + title + "\n" + href;
var result = "Not Posted";
// 更新されていたらメッセージ送信&スプレッドシート書き換え
if(oldtitle != title) {
result = slackApp.chatPostMessage(channelId, message, {});
sheet.getRange("E4").setValue(title);
}
Logger.log(result);
}
テスト・運用開始
前節のテストや運用開始と同様である.
東方我楽多叢誌に更新があれば,下記のように通知がなされる.
参考
- Google Apps Script で Slack Botを作ってみた。(お勉強編) - Qiita
- 【GAS】エラー「ArrayをObject[][]に変換できません。」に遭遇したら・・・ - Qiita
- クローラ作成に必須!XPATHの記法まとめ - Qiita
- XPath Cheat Sheet