2018年9月14日金曜日

Python スクリプトから IIJmio クーポンスイッチを操作する (4)

IIJmio のクーポンスイッチするスクリプトをラズベリーパイにコピーして cron から定時にスクリプトを実行するようにしたんだけど、結構な確率で失敗してしまう現象が起きています。(1日に1回づつON/OFFするんだけど、1回は失敗する感じ) 手元の ubuntu 環境だとそんなエラーにはならないので困ってしまいました。

ちなみに IIJmio のサーバーからステータスコード 400 で BAD REQUEST というエラーが戻ってきます。IIJmio のリクエストの書き方を変えたら安定するようになりました。理由はわからん。やっぱりネットワークプログラムは難しい。

元々のコード
req = urllib.request.Request(iijmio_url)
req.data = json.dumps(params).encode("utf-8")
req.headers = iijmio_headers
req.method = 'PUT'
新しいコード
data = json.dumps(params).encode("utf-8")
req = urllib.request.Request(iijmio_url, data=data, headers=iijmio_headers, method="PUT")
そんなわけで cron にも登録して、自動的に昼にスイッチ ON、寝る時間にはスイッチ OFF にして、今のところは動いています。

pi@raspberrypi:~ $ crontab -e
# m h  dom mon dow   command
0 12 * * * /usr/bin/python3 /home/pi/iijmio-coupon-on.py
0 22 * * * /usr/bin/python3 /home/pi/iijmio-coupon-off.py

エラーが起きてきた時の処理とかどうやるのが適切なんだろうなぁ。プログラムって難しい。
#coding: utf-8
import urllib.request
import urllib.parse
import json
from slacker import Slacker

iijmio_url = "https://api.iijmio.jp/mobile/d/v2/coupon/"
iijmio_token = "IIJmio のトークン"
iijmio_devid = "IIJmio のデベロッパID"
iijmio_headers = {
    "X-IIJmio-Developer" : iijmio_devid,
    "X-IIJmio-Authorization" : iijmio_token,
    "Content-Type" : "application/json"
}

slack_token = "Slack Bot App のトークン"
couponUse = False
params = {
    "couponInfo": [
        {
            "hdoInfo": [
                {"hdoServiceCode": "hdoxxxxxxxx","couponUse": couponUse},
                {"hdoServiceCode": "hdoxxxxxxxx","couponUse": False}
            ],
            "hduInfo": []
        }
    ]
}

data = json.dumps(params).encode("utf-8")
print(data)
req = urllib.request.Request(iijmio_url, data=data, headers=iijmio_headers, method="PUT")

try:
    res = urllib.request.urlopen(req)
except urllib.error.HTTPError as e:
    # Return code error (e.g. 404, 501, ...)
    message = "HTTPError: {}".format(e.code)
except urllib.error.URLError as e:
    # Not an HTTP-specific error (e.g. connection refused)
    message = "URLError: {}".format(e.reason)
else:
    # 200
    if couponUse:
        message = "クーポンを ON にしました"
    else:
        message = "クーポンを OFF にしました"

slack = Slacker(slack_token)
slack.chat.post_message("general",message,"IIJmio")