かかりつけ医院のWebサイトに更新があったらメールで通知するシステム
はじめに
インフルエンザワクチンの予防接種を我が家の私以外の家族(妻、子供)は近所のかかりつけ医院で受けています。こちらの医院はインフルエンザワクチンの予防接種は予約制となっていますが、今年は予約希望者が多いらしく、ワクチンの在庫が無くなると予約が出来なくなります。
ワクチンの入荷はホームページでお知らせされますが、依然として希望者が多いので見つけたらすぐ電話して予約しないと在庫切れとなってしまいます。
という事で、Webサイトを定期的にチェックして更新があったらメールでお知らせするシステムを用意する事にしました。
しました、と書きましたが、以前、全日本合唱連盟の合唱名曲シリーズ(全日本合唱コンクール課題曲集)の発表が行われたら検知してメールで通知する仕組みを作ったことがあるので、それを転用しました。
動作の概要
プログラムについて
メインプログラム
「メインプログラム」と表現するのもおこがましいbashスクリプトです。
check_Kakarituke.sh
#!/bin/bash -x export LC_ALL="ja_JP.UTF-8" TAG="Kakarituke_Clinic" URL='http://example.com/cgi-bin/general/topics.cgi' WORKDIR='/home/bata64/sh/check_Kakarituke' OUT='/home/bata64/sh/check_Kakarituke/output.html' InfoFile="/home/bata64/sh/check_Kakarituke/messages.txt" RcptTo="hoge@example.com,hoge2@example.com" MD5SUM=md5sum.txt MD5SUMPRE=md5sum_pre.txt date cd $WORKDIR curl $URL -o $OUT md5sum $OUT > $MD5SUM diff $MD5SUM $MD5SUMPRE > /dev/null 2>&1 if [ $? -eq 0 ]; then logger -i -p 6 -t $TAG "No Change at $URL " else cd /home/bata64/py/; python3.6 ./mailsend.py $TAG $InfoFile $RcptTo logger -i -p 6 -t $TAG "Some Change Occuerd at $URL " fi cd $WORKDIR rm $OUT cp -p $MD5SUM $MD5SUMPRE
メール送信プログラム
以前ならPerlでNet::SMTP、あるいはEmail::Senderなどを使って書いていましたが、日本語でSubjectや本文を書く時に色々考慮が必要でした。
Pythonだとsmtplibという標準のモジュールでサクッと書けました。すばらしい・・・。
mailsend.py [件名] [メッセージ本文記載のテキストファイルのパス] [宛先メールアドレス(複数の場合はカンマ区切り)]
という感じで動作します。
import smtplib import sys from email.message import EmailMessage # コマンドライン引数取得 args = sys.argv subject = args[1] msgtxt = args[2] rcptto = args[3] with open(msgtxt,'r') as fp: # Create a textplain message msg = EmailMessage() msg.set_content(fp.read()) msg['Subject'] = 'お知らせ about ' + subject msg['From'] = 'bata64@example.ne.jp' msg['To'] = rcptto # Send the message via our own SMTP server. s = smtplib.SMTP('smtp.example.ne.jp',587) s.ehlo('example.ne.jp') s.login('bata64@example.ne.jp', 'password') s.send_message(msg) s.quit()
メッセージ本文記載テキストファイル
ホームページが更新されていたらお知らせするメールに記載する文章です。
HTMLファイルの中身を記載しようかとも思いましたが、受け取った人が実際にアクセスしてみる形が実装上の手間、確実に確認するプロセスとして良いなと思ったので以下のようにしました。
messages.txt
○○クリニックのページに更新があります http://example.com/
定期的に実行する仕組み
メインプログラム、メール送信プログラムを実行するパーミッションがあり、それぞれ実際に実行してみて想定する動作をする事が確認出来たら、定期的に実行するように設定します。設定には、LinuxやUnix系OSで用意されているcronを利用し、7時から20時の間、30分間隔で実行する事にしました。さくらのVPSで契約しているCentOSサーバに設定した内容は以下の通りです。
/etc/cron.d/bata64
## かかりつけ医院のお知らせページの更新確認(2020年度下期のインフルエンザワクチン入荷状況チェック) 07,37 7-20 * * * bata64 ( /home/bata64/sh/check_Kakarituke/check_Kakarituke.sh > /home/kawabata/sh/check_Kakarituke/check_Kakarituke.sh.log 2>&1 )
動作確認
CentOSサーバにSSHでアクセスして各ファイルを所定の場所に格納したのち、
% tail -f /var/log/cron
で、時間になったらcronに設定したスクリプトが起動しているかを確認しましょう。起動していたら以下のようなメッセージが出力されます。
Nov 22 20:37:01 www6057uj CROND[22339]: (bata64) CMD (( /home/bata64/sh/check_Kakarituke/check_Kakarituke.sh > /home/kawabata/sh/check_Kakarituke/check_Kakarituke.sh.log 2>&1 2>&1 ))
初回実行時は前回実施ファイルが無いので「差分無しではない」という判定になりメールが届きます。
ちょっとした解説
アクセス先URL
(以下URLは全てダミーです)
かかりつけ医院のホームページのURLは
http://example.com/
ですが、お知らせページはフレームの中にあり、URLは
http://example.com/cgi-bin/general/topics.cgi
であることがわかりましたので、こちらに直接アクセスしてチェックする事にしました。
なお、フレームのURLはChromeでホームページにアクセスしたのちフレームにマウスカーソルを合わせて右クリックメニューから「フレームのソースを表示」を実行して表示される
view-source:http://example.com/cgi-bin/general/topics.cgi
から「view-source:」を取り除く事で確認しました。
syslogに通知
メインプログラムにて
TAG="Kakarituke_Clinic" logger -i -p 6 -t $TAG "No Change at $URL " logger -i -p 6 -t $TAG "Some Change Occuerd at $URL "
と記述し、メールだけでなくsyslogにもメッセージを残すことにしました。syslog監視をすれば検知も可能ですが実施は今後考えます。