App Storeのアプリがバージョンアップされたかを検知するpythonスクリプトを作成してみた
こんな需要があるのかわかりませんが、自分が欲しかったので試行錯誤しながらつくってみました。
なんでこんなものをつくったのか
MDMツールとしてLanscope Anを導入しているのですが、このMDMは自動アップデートに対応していません。
ユーザーにやらせればいいじゃん。と思ったそこのあなた!ユーザーにはインストール権限もなければアンインストール権限もないという、DEP + VPP + MDM + 機能制限というとても豪華な構成なのです(笑)
で、某アプリがですね。バージョンアップしてくださいますと最新版以外はログインできなくなるというクソ素晴らしい仕様なのです。
Lanscope Anからアップデート配信をすることは可能なのですが、バージョンアップ自体にそもそも気づかないためユーザーからの申告で把握することが多く面倒だなと思っていました。
そこで、pythonを利用したらスクレイピング簡単にできるって聞いたことあるしいけるんじゃね?と思い立ちやってみました。
必要なパッケージのインストール
pip install bs4 pip install requests pip install json pip install urllib2 pip install filecmp
バージョンアップ確認Pythonスクリプト
下記のようなスクリプトを作成しました。こちらのスクリプトはPython2.7で確認しています。
スクリプトを配置した場所と同じ階層にtmpディレクトリを作成してください。
# coding: UTF-8 import os,sys import argparse import urllib2 import requests,json import filecmp from bs4 import BeautifulSoup parser = argparse.ArgumentParser() parser.add_argument('-u', '--url', type=str, required=True, nargs=1, help="Store url.") parser.add_argument('-txt', type=str) args = parser.parse_args() url = args.url[0] outfile = args.txt webhook_url = "https://outlook.office.com/webhook/" def updateTxt(txtpath): f = open(txtpath,'w') f.write(app_version.encode('utf_8') ) f.close() def teamsPost(): source = 'がバージョンアップしました' strTxt = unicode(source, 'utf-8') body = {'text': title + " " + strTxt} headers = {'content-type': 'application/json'} requests.post(webhook_url,data = json.dumps(body), headers=headers) html = urllib2.urlopen(url) soup = BeautifulSoup(html,"html.parser") title = soup.title.string p_tag = soup.find_all("time") app_version = "" for tag in p_tag: try: string_ = tag.get("class").pop(0) if string_ in "version-history__item__release-date": app_version = tag.string break except: pass before_file_path = './tmp/before_date_' + outfile + '.txt' after_file_path = './tmp/after_date_' + outfile + '.txt' updateTxt(after_file_path) if os.path.exists(before_file_path): if not (filecmp.cmp( before_file_path , after_file_path )): updateTxt(before_file_path) teamsPost() else: updateTxt(before_file_path)
内容としては、
更新日付のタグを取得し、テキストファイルとして保存
before afterで保存したファイル内容を比較し、内容が一致していなければバージョンアップがされたものとみなしています。
App Store側の仕様が変わった場合にはそれにあわせてスクリプトの修正が必要になります。
スクリプト実行方法
下記のように引数をつけて実行します。(引数名適当すぎた・・・)
urlには、AppSotreのアプリページのURLをtxtにはこの実行結果を保存するための識別名をつけます。
#python appvercheck.py -u 'https://itunes.apple.com/jp/app/microsoft-teams/id1113153706?mt=8' -txt teams
通知結果
バージョンアップしていた場合には、TeamsのWebhookを呼び出し通知用チャットへ通知するようにしています。
こんな感じで通知がきます。
テスト的にZabbixと同じwebhookを使ったのこうなってますが気にしないでください(笑)
Titleタグをそのままもってきているため、「Microsoft Teams]をApp Storeで までが入ってきています。
ここは、「」だけを抜いてくるとかの処理を追加するともっと綺麗になりそうですね。
Google Playも少し応用すれば同じ形で通知できそうですね。
おまけ。Python3の場合のスクリプト
個人で契約しているVPS環境にはPython3をインストールしていたので、Python3でも動くようにいじってみました。
# coding: UTF-8 import os,sys import argparse #import urllib2 import urllib3 import requests,json import filecmp import certifi from bs4 import BeautifulSoup parser = argparse.ArgumentParser() parser.add_argument('-u', '--url', type=str, required=True, nargs=1, help="Store url.") parser.add_argument('-txt', type=str , required=True) args = parser.parse_args() url = args.url[0] outfile = args.txt webhook_url = "https://outlook.office.com/webhook/*****" def updateTxt(txtpath): f = open(txtpath,'wb') f.write(app_version.encode('utf_8') ) f.close() def teamsPost(): source = 'がバージョンアップしました' strTxt = source body = {'text': title + " " + strTxt} headers = {'content-type': 'application/json'} requests.post(webhook_url,data = json.dumps(body), headers=headers) http = urllib3.PoolManager( cert_reqs='CERT_REQUIRED', ca_certs=certifi.where()) r = http.request('GET',url) soup = BeautifulSoup(r.data,"html.parser") title = soup.title.string p_tag = soup.find_all("time") app_version = "" for tag in p_tag: try: string_ = tag.get("class").pop(0) if string_ in "version-history__item__release-date": app_version = tag.string break except: pass before_file_path = './tmp/before_date_' + outfile + '.txt' after_file_path = './tmp/after_date_' + outfile + '.txt' print(app_version) updateTxt(after_file_path) if os.path.exists(before_file_path): if not (filecmp.cmp( before_file_path , after_file_path )): updateTxt(before_file_path) teamsPost() else: updateTxt(before_file_path)
urllib3になってurlopenがなくなっていたりcertifiが必要になったりとちょこちょこ変更されています。
意味不明な代入している箇所がありますが、Python2をそのままいじった名残です。
参考URL
http://loudspeaker.sakura.ne.jp/devblog/2015/04/26/python-encoding-problem/