ソースコード
#!/bin/bash
LAST_MODIFIED="Thu, 17 Oct 2019 07:18:26 GMT"
URL="https://example.com"
DISCORD_WEBHOOK_ADDRESS=""
LM=$( \
curl -I -s ${URL} \
| grep --ignore-case "Last-Modified" \
| sed -e "s/Last-Modified: //i" -e "s/\r//" \
)
if [ ! "$LAST_MODIFIED" = "$LM" ]; then
curl -X POST -H "Content-Type: application/json" \
-d '{"content": "Last-Modified is changed at <t:'$(date -d "$LM" +%s)'>. ('"$LM"')"}' \
${DISCORD_WEBHOOK_ADDRESS}
fi
実行結果
解説
変数宣言
LAST_MODIFIED="Thu, 17 Oct 2019 07:18:26 GMT"
URL="https://example.com"
DISCORD_WEBHOOK_ADDRESS=""
LAST_MODIFIED
手動で最終更新日を入れておく
URL
更新をチェックしたいサイトのアドレス
DISCORD_WEBHOOK_ADDRESS
WEBページに更新があったときに通知するwebhookのアドレス
Last-Modifiedの取得
LM=$( \
curl -I --silent ${URL} \
| grep --ignore-case "Last-Modified" \
| sed -e "s/Last-Modified: //i" -e "s/\r//" \
)
curl -I -s ${URL}
URLのヘッダのみを取得する.サイレントモードで実行する
grep --ignore-case "Last-Modified"
大文字小文字を無視して “Last-Modified” の文字列を探す.サイトによって “Last-Modified” だったり “last-modified”だったりしたので
sed -e "s/Last-Modified: //i" -e "s/\r//"
”Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT”という文字列を受け取り日時のみを返す.ついでにCR文字を消す
if
取得したLast-Modified
の値が手動で入力した値と同じか単純に比較しているだけ.
webhookのポスト
curl -X POST -H "Content-Type: application/json" \
-d '{"content": "Last-Modified is changed at <t:'$(date -d "$LM" +%s)'>. ('"$LM"')"}' \
${DISCORD_WEBHOOK_ADDRESS}
<t:'$(date -d "$LM" +%s)'>
Last-ModifiedはGMTらしいのでローカル時間に変換してあげる.
グリニッジ標準時。 HTTP における時刻は常にグリニッジ標準時で表され、ローカル時刻になることはありません。
Last-Modified - HTTP | MDN
discordでは <t:TIMESTAMP>
の形式でUnix Timestampを送ると良い感じにユーザのロケールとタイムゾーンにしてくれる.
Discord Developer Portal - API Docs for Bots and Developers
date
コマンドに-dオプションで変換したい時間を入れて+%sでUnix Timestamp で出力する.
"$LM"
Last-Modifiedの値にスペースが入っているのでスペース込みで1つの文字列扱いにするためにダブルクォーテーションで囲んでおく.
curl
の-dオプションの引数をjson形式にする関係でシングルクォーテーションで囲んでいるが,これだとコマンド置換や変数展開ができない.そこで変数展開が必要な前後で文字列を区切っている(Python だと 'str1' + 'str2'
と書くような感じ.).Bashだと+が不要なのでそのままつなげればよい('str1''str2'
).このときに見やすくするために '
と $
の間にスペースを入れると当然ながら別の引数として認識されてしまう.
実行方法
crontabやsystemd timerを利用して何分かおきに走らせたりするといいのではないでしょうか.
# crontab -e
*/5 * * * * PATH_TO_SCRIPT
おわりに
いかがでしたか.RSSなどが無いサイトで更新をチェックしたいときに使えるTipsでした.
変数を配列で持てば複数サイトにも対応できそうですね.
Last-Modified
をヘッダに入れてないサイトに対しては無力ですが(笑).そんな時はETag
とか見たら良いんじゃないでしょうか.
しらんけど