15
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AirpodsProが欲しいので入荷したらLINEに通知する

Last updated at Posted at 2019-11-15

ことの始まり

AirpodsProの波に乗り遅れた。
先月末発売されたAirpodsProですが、Sonyの例のノイキャンと比較レビューとか見てから買おうと思ってたが、自分が記事を読んだ頃には完売してた、やらかした。
__たまに直営のAppleStoreに入荷が入るらしい__のでそれを監視して、入荷が入り次第自分の__LINEに通知__を送る。

下調べ

どうやって入庫情報を取得するか問題
どうやら毎朝入荷があった場合ちゃんと更新されているらしい
スクリーンショット 2019-11-15 13.19.36.png

受け取れる日を確認をクリックするとこの画面が出る。
郵便番号入れると近くのショップ情報が取得できる
スクリーンショット 2019-11-15 13.25.15.png

この感じだとGETとかPOSTで取れそうなので、ネットワーク見る
68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3235363139362f30656336353930312d353739382d383336632d343739332d3334663038623530363361362e706e67.png

めっちゃこれじゃねえかみたいなのがある

デベロッパーツールでResponse見れますが
見た目わかりやすくしたいのでGETとかPOSTしてくれるアプリで情報取ってみる
スクリーンショット 2019-11-15 13.36.28.png
めっちゃ来た

partsが品番でlocationが郵便番号

レスポンスをちゃんと見る

さっき返ってきたレンスポンスは一店舗でこれだけ返ってくる。

response
{
  "head": {
    "status": "200",
    "data": {}
  },
  "body": {
    "stores": [
      {
        "storeEmail": "shinsaibashi@apple.com",
        "storeName": "心斎橋",
        "reservationUrl": "http://www.apple.com/jp/retail/shinsaibashi",
        "makeReservationUrl": "http://www.apple.com/jp/retail/shinsaibashi",
        "state": "大阪府",
        "storeImageUrl": "https://rtlimages.apple.com/cmc/dieter/store/4_3/R091.png?resize=828:*&output-format=jpg",
        "country": "JP",
        "city": "大阪市",
        "storeNumber": "R091",
        "partsAvailability": {
          "MWP22J/A": {
            "storePickEligible": true,
            "storeSearchEnabled": true,
            "storeSelectionEnabled": true,
            "storePickupQuote": "土 2019/12/07 Apple 心斎橋",
            "pickupSearchQuote": "受け取れる日:<br/>土 2019/12/07",
            "storePickupLabel": "受取日:",
            "partNumber": "MWP22J/A",
            "purchaseOption": "",
            "ctoOptions": "",
            "storePickupLinkText": "受け取れる日を確認",
            "storePickupProductTitle": "AirPods Pro",
            "pickupDisplay": "ships-to-store"
          }
        },
        "phoneNumber": "06-4963-4500",
        "address": {
          "address": "Apple 心斎橋",
          "address3": "アーバンBLD心斎橋",
          "address2": "中央区西心斎橋1-5-5",
          "postalCode": "542-0086"
        },
        "hoursUrl": "http://www.apple.com/jp/retail/shinsaibashi",
        "storeHours": {
          "storeHoursText": "営業時間",
          "bopisPickupDays": "日数",
          "bopisPickupHours": "時間",
          "hours": [
            {
              "storeTimings": "10:00~21:00",
              "storeDays": "月~日:"
            }
          ]
        },
        "storelatitude": 34.672,
        "storelongitude": 135.50007,
        "storedistance": 3.44,
        "storeDistanceWithUnit": "3.44 km",
        "storeDistanceVoText": "542-0086からの距離:3.44 km",
        "storelistnumber": 1,
        "storeListNumber": 1
      }

----------------いっぱい下に続く----------------

storePickupQuoteだけ取得できれば問題なさそう

Python で書いてく

GETするだけならrequestsだけで実装できるので適当に書く

在庫情報の取得
def get_store_status(_parts, _location):
    arrival = []
    url =  "https://www.apple.com/jp/shop/retail/pickup-message"
    param = {"parts.0": _parts, "location": _location}

    response = requests.get(url, params=param)
    json_data = json.loads(response.text)

    stores = json_data['body']['stores']
    for store in stores:
        store_pickup = store['partsAvailability'][_parts]['storePickupQuote']

        if '本日' in store_pickup:
            arrival.append({'店舗':store['address']['address'],
                            '郵便番号':store['address']['postalCode']})

    return arrival

とりあえず書いた、適当に解説すると
帰ってきたjsonを辞書に入れて
入荷が入った店舗は日付ではなく本日が入っているのでそういう判定をして
本日があれば通す

実際に在庫情報がいつ更新されるかはわからないので、
6時〜10時の間に1分に1回リクエストさせる。

def start_job():
    parts = {'AirpodsPro':'MWP22J/A', 'Airpods':'MV7N2J/A'}
    location = '530-0000'

    end_stamp = datetime.now().timestamp() + (60 * 60 * 4)

    while True:
        now = datetime.now().timestamp()
        arrival = get_store_status(parts['AirpodsPro'], location)

        if arrival or now > end_stamp:
            line_notif(arrival)
            break

        time.sleep(60)

def trigger():
    schedule.every().day.at('06:00').do(start_job)
    while True:
        schedule.run_pending()
        time.sleep(1)

在庫があればループ抜けて通知
なければ10時までオリョクル

LINEに通知する

LINEはNotifyののやつ登録して自分に送る
これを参考にさせて頂く - PythonでLINEに通知を送る

def line_notify(stores):
    line_notify_token = 'アクセストークン'
    line_notify_api = 'https://notify-api.line.me/api/notify'

    if stores:
        strings=''
        for s in stores:
            strings += f'''
            店舗: {s['店舗']}
            郵便番号: {s['郵便番号']}\n'''

        message = f'''
        AirpodsProが入荷されました。
        対象店舗:{strings}
        ショッピングカート:https://www.apple.com/jp/shop/bag
        '''

        payload = {'message': message}
        headers = {'Authorization': 'Bearer ' + line_notify_token}
        requests.post(line_notify_api, data=payload, headers=headers)

とりあえず入荷があればこれでLINEに通知くる
ショッピングカートのURL貼っておけばそのまま購入できる。
(前もって購入する端末とブラウザでショッピングカートに入れておく必要はある)

入荷されているのに来なかったら悲しいので動くのか試しておく

airpodsはあるのでこいつで試す
さっきの辞書にAirpodsの情報入れといたのでそれを使う

arrival = get_store_status(parts['Airpods'], location)

これで実行する。

25521.jpg

通知が来たのでオッケー

最後に

LINE Notify めっちゃ便利ですね、これ今後もめっちゃ使えそう。

一番の問題は朝起きているかなんですけどね

15
9
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?