FFⅦリメイク完全に買い忘れたので監視プログラムを配備した

#はじめに
昨日FFⅦリメイクが出ましたね！

FFⅦといえば自分が学生の頃に発売されてえらい話題性があったので、完全なミーハー心で買いました。
地味に初めて買ったFFシリーズです。いい思い出です。
当時はエアリスが好きでした（今はティファです）。

そんな思い出があったので、発売されること自体は知ってましたが、
まかさ昨日出たなんて全然知らなったし、予約するのも忘れてた・・・。

家で話したところ妻もFFⅦを結構やり込んでいたので、夫婦で話し合った結果買おうという話になりました。

でも、そもそもPS4持ってないで・・・


#ちょうどいいのが見つかった！
少し調べると、PS4+FFⅦリメイクのセットがあるじゃないですか！！
パッケージ版ではあるけど、ソフト代が実質なしという超絶お得なセット。
これは買うしかない！！

<img src="https://media.playstation.com/is/image/SCEA/final-fantasy-vii-remake-pack-playstation-4-box-art-01-ps4-09mar20-ja-jp?$native_xl_t$" width="50%" height="50%"></img>


#いざ購入！？
こんなご時世だし実店舗よりもネットで買おうと色々探したけども、どこのサイトも売り切れ・・・。
そもそも数量限定みたいだしFFⅦ自体人気あるしそりゃそうか・・・。
Amazonや楽天市場などの大手なとこでは売ってるけど、既に値段が高騰している。
何としても欲しいし、でも高値なんかで買いたくない。


#入荷される可能性を信じて
各店舗の状況を見ると、一部サイトで**入荷待ち**や**在庫切れ**の文字が。
かなり絶望的な状況ではありますが、もしかするとどこかのタイミングで入荷されて買えるようになるのでは！？という淡い期待を持ちながら、暇な時に店舗サイトをちょいちょいチェックしていました。


#自動化しよう
暇な時にチェックすると、タイミングによっては入荷しても見逃してしまい買えなくなる可能性もありますし、そもそも面倒くさい・・・。
一応エンジニアなので、自動化しようと思い立ちプログラミングすることにしました。


#Let'sプログラミング
実現するにあたって、わざわざお金かけたくないですし、馴染みない言語を今から勉強するのも少し時間かかりそう。
ということで、以前少しかじったことがある[GoogleAppsScript（GAS）](https://developers.google.com/apps-script/)を使うことにしました。

##GASとは？
ご存知の方もいるかもしれませんが、GASとはGoogleが提供するスクリプト言語で、JavaScript書ける人だったら多分読めるし書けると思います。
Googleが提供しているということもあって、GmailやスプレッドシートなどGoogleが提供するサービスとの親和性がよいです。
それ以外にもWebAPI公開やスケジュール実行などサーバ構築不要で実現することができるのでサーバレスっぽい。
あと、何と言っても嬉しいのが環境面とか色々含めて**無償**で使えるということ！ ほんとGoogle様様です。

 - JavaScriptでできることは大体できる
 - Google系サービスを色々操作することができる
 - Googleアカウントさえあれば無償ですぐに使える
 - 作成したコードはWebAPIとして公開することができる
 - スケジュールなどのトリガーでJob実行が可能


##作ったもの
すごく単純で、GASプログラムから定期的に店舗サイトを探りに行き、入荷していたらLINE通知するというだけです。

![ff7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206972/aa5f57f7-7168-41c7-d4fd-49704f62cf3f.png)

プログラムはこんな感じ。先に言っときますが、スクレイピングの部分とか結構雑です。
あと、対象の店舗サイトはとりあえず3つだけです。
他にもいくつか試しましたが、プログラムからのアクセスだと弾かれたりしたので断念しました。


```Javascript

/*********************
各ショップで在庫をチェックし入荷されたらLINE通知する
*********************/
function check_zaiko(shop) {
  var msg = "";
  var html = UrlFetchApp.fetch(shop.url,{muteHttpExceptions:true}).getContentText(shop.charset);
  var parser = Parser.data(html).from(shop.tag_start).to(shop.tag_end).build();
  var result = String(parser);
  
  if(result.indexOf(shop.word) === -1) {
    msg = shop.name + "で入荷された！！\n" + shop.url;
    console.log(msg);
    sendLine(msg);
  } else {
    msg = shop.name + "品切れ中...";
    console.log(msg);
  }
}


/*********************
LINEにメッセージ送信する
*********************/
function sendLine(strMessage){ 
  //Lineに送信するためのトークン
  var strToken = "xxx";
  
  var options = {
     "method"  : "post",
     "payload" : "message=" + strMessage,
     "headers" : {"Authorization" : "Bearer "+ strToken}
   };
 
   UrlFetchApp.fetch("https://notify-api.line.me/api/notify",options);
}


/*********************
メイン
*********************/
function main() {  
  var sony = {
    name : "SONYストア",
    url : "https://pur.store.sony.jp/ps4/products/ps4_ss_original/CUHJ-10035_product/",
    word : "入荷待ち",
    charset : "",
    tag_start : '<a class="s5-shippingLabel s5-shippingLabel--2"',
    tag_end : "</a>"
  };
  
  var sevennet = {
    name : "7net",
    url : "https://7net.omni7.jp/detail/2110615455",
    word : "在庫切れ",
    charset : "",
    tag_start : '<input class="linkBtn js-pressTwice"',
    tag_end : "</p>"
  };
  
  var rakuten = {
    name : "楽天ブックス",
    url : "https://books.rakuten.co.jp/rb/16256849/",
    word : "ご注文できない商品",
    charset : "euc-jp",
    tag_start : '<span class="status">',
    tag_end : "</span>"
  };
  
  var shop_list = [];
  shop_list.push(sony);
  shop_list.push(sevennet);
  shop_list.push(rakuten);
  
  shop_list.forEach(check_zaiko);
}
```

もし入荷されると、こんな感じでURL付きでLINE通知がきます。

![スクリーンショット 2020-04-11 23.36.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206972/378adbc4-c015-2363-1f40-c71b89e2cf2d.png)

昨日から定期実行させてますが、GASの管理画面からは状況が見れます。
デバッグ用に出力されたログ確認も出来ますよ。
![スクリーンショット 2020-04-11 23.39.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206972/333d2df3-24ea-806d-0371-0cd20ce6d9a3.png)


#さいごに
しばらくプログラム回しながら入荷を待ちたいと思います。
というかそもそも入荷されるのか疑問ですが・・・。
もし無事に購入できた時はこの記事を更新しようかな。


#参考
スクレイピングはParserライブラリを使っています。使い方などは以下のページなどを参考にしてみてください。

- Google Apps ScriptでスクレイピングしてSlackに定期ポストするbotを瞬殺で作った（Qiita）
    - https://qiita.com/fireowl11/items/e703e35073b600528e7c