みんなが自由に路線を追加できる電車遅延LineBOTを作ってみた話

# はじめに
<!-- 発端や概要を記載 -->
会社に行くときも、友人に会いに行くときも、電車の遅延は痛手となる時代。
Lineに自分の乗る路線が遅延している情報をいち早くキャッチしたいと思い、
このBOTの制作に至りました。
Qiitaを知って間もなく、
初めての投稿となります故、至らない所が多いと思いますがよろしくおねがいします！

※本記事はGASの初期設定や、GASやスプレッドシートをある程度扱えるよ！という方向けです！
　Line NotifyとGAS自体は非常に簡単に扱えるのであまり身構えず取り掛かってみて下さい。
　そっちの方の解説も欲しいよ！というコメントがあったら追記で書きます😶

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [欲しい路線を記載するスプレッドシートを作ろう！](#欲しい路線を記載するスプレッドシートを作ろう！)
1. [LINEに送信するコードを作成しよう！](#LINEに送信するコードを作成しよう！)
1. [遅延情報を取得するGASを作成しよう！](#遅延情報を取得するGASを作成しよう！)
1. [路線と会社名を記載しよう](#路線と会社名を記載しよう)
1. [最後にトリガーを設定してこの戦いを終わらせよう](#最後にトリガーを設定してこの戦いを終わらせよう)
1. [おわりに](#おわりに)
1. [参考文献](#参考文献)

<!-- 各チャプター -->
<a id="#欲しい路線を記載するスプレッドシートを作ろう！"></a>
# 欲しい路線を記載するスプレッドシートを作ろう！
やることはとてもシンプル！
①新規スプレッドシートを作成する
②A1セルに「name」と入力する
③B1セルに「company」と入力する
④「name」以降の行に路線名を入力する
⑤「company」以降の行に路線の運営会社名を入力する
おわり！

さて、この路線名と会社名ですが、
今回使用するのは [鉄道遅延情報のjson](https://rti-giken.jp/fhc/api/train_tetsudo/) さんのサイトを使用させて頂いてます。
こちらのサイトは現在遅延している様々な路線(どこまで網羅してるかは知らないけどたぶんほぼ全国)の情報を
10分毎にjson形式で表示してくれている非常にありがた～いサイトです。
ここ以外だとスクレイピングが必要だったり敷居がかなり高かったので、私のような初心者は
このサイトを利用させて頂くのが良いお勉強になると思います。

<a id="#LINEに送信するコードを作成しよう！"></a>
# LINEに送信するコードを作成しよう
はい！まず結論としてコードをﾊﾞﾊﾞﾝ😤
```Google Apps Script
  function LINESENDING(body){
  var url = "https://notify-api.line.me/api/notify";
  var token = ["LINEのトークンをこのダブルクォーテーションの間に貼り付けてください"];

  var data = {
    "message" : body,
    }
    var options = {
      "method":"post",
      "contentType":"application/x-www-form-urlencoded",
      "headers":{
        "Authorization":"Bearer " + token,
        },
        "payload":data,
        }
        UrlFetchApp.fetch(url,options);

}
```
こちらをまず一つ目のスクリプトに貼り付けて保存して下さい！
ﾊﾟｸ....参考にさせていただいたコードはこちらです。
[【Google Apps Script（GAS）】LINEにメッセージ送信しよう【業務効率化】](https://note.com/taraco123/n/n522774098e00)

LINEのトークンってどうやって発行するの？
という方はこちらを参考にどうぞ！
[LINE Notify アクセストークン](https://firestorage.jp/business/line-notify/)

<a id="#遅延情報を取得するGASを作成しよう！"></a>
# 遅延情報を取得するGASを作成しよう！
こちらもコードをﾊﾞﾊﾞﾝ😤
```Google Apps Script
function fetchDelayInfo() {

  //電車遅延情報をJSON形式で取得
  const json = JSON.parse(UrlFetchApp.fetch("https://tetsudo.rti-giken.jp/free/delay.json").getContentText());

  //シートとその最終行数、シートのデータを取得
  const mySheet = SpreadsheetApp.getActiveSheet();
  const maxRow = mySheet.getRange(2,1).getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow();
  const myVars = mySheet.getDataRange().getValues();
  body = "電車運行情報";
  
  for(let i=2; i<= maxRow; i++){
    let name = myVars[i-1][1-1];
    let company = myVars[i-1][2-1];
    json.forEach(function(obj) {
      if(obj.name === name && obj.company === company){
        body = body + "\n" + company + name + "が遅延しています";
      }
    });
  }

  if(body === "電車運行情報"){
    return;
  }
  LINESENDING(body);
}
```
コードの内容としては
Jsonを読み込んで、スプレッドシートの最終行等を取得して、
for構文でjsonの中身をくるくる見回して、スプレッドシートに記載された路線と会社名に一致する遅延情報があったら
LINEに送るよ～ といったところです。
従来であれば遅延情報がない場合は「遅延情報はありません」というメッセージを送るようにしてましたが、
短いスパンで定期実行させるのでそれは鬱陶しいということで、何も遅延がない時はメッセージを送らないようにしました。

さて、ここら辺で重要なお話をします。
上記のコード達は皆、IQ20000ぐらいの有志の方々が記事で上げてくれていたコードです。
レトルト🍛のようなものです。
[Google Apps Scriptで毎朝チャットワークに電車の遅延情報をプッシュ通知する](https://tonari-it.com/gas-chatwork-train-delay/)
当初はこれらのサイトのおかげで本記事は必要ねえｼﾞｬﾝ!と思っていたのですが、
コードをそのまま流用しつつコードの解析やデバッグを行っていた所.....
謎のエラーが発生する。
for each文が悪さをしてるらしきエラーが発生するが、何がどうダメなのかまったくわからない。
GASを旧エディタにしたら使えるけどこのままでは埒が明かない。
そこで1日が潰れた。他の方法を試行錯誤するもどれも初心者には難しい！
酷い二日酔いのテンションでGoogle先生ﾀｽｹﾃ.....としていたら、神が降臨した。
[【GAS】V8ランタイムを有効にした時のfor each文の修正方法](https://life89.jp/gas-v8-for-each-repair/)

ああそうか、旧エディタで使えるということはV8ランタイムが悪さをしていたのか。
しかしこちらの記事に書いてある事がサッパリわからないけど、頭をフル回転させて見よう...
参考文献のコードでは
```
for each(var obj in json){

    if(obj.name === name && obj.company === company){

    }
  }
```
となっている。
そして神のお告げでは

```
for each(var address in addresses){
   ...
}

をこれに変えろ↓
addresses.forEach(function(address) {
   ...
});
```
と仰られている。
ってなわけで度重なるエラーと戦いながら出来上がったコードがこれである。
```
json.forEach(function(obj) {
```
こんなシンプルなのにここに辿り着くまで血反吐を

まぁそんなことはいいんです。とりあえずこれでV8ランタイムに対応したコードとなり、解決しました。
ぶっちゃけこの記事で言いたかった事の大半はここに集約されてます。
あとは下り坂です。

長くなって申し訳ないのですが、あと1点。
元々このコードはChatWorkに送信するためのコードでした。
最初は社内用に作成するためそのままで良かったのですが、
LINEに送られた方が便利じゃね？無料のチャットワーク垢だとグループ窓に制限数あるし。
とのことなのでLineBotに改変しました。

<a id="#路線と会社名を記載しよう"></a>
# 路線と会社名を記載しよう
あとちょっとで完成です。耐えて下さい。
[欲しい路線を記載するスプレッドシートを作ろう！](#Chapter1)で作成したスプレッドシートに
遅延情報が欲しい路線名と会社名を入力します。
他の方の記事を見ると基本的に1路線に限った物が多いですが、
複数人で扱うとなると必然的に複数の路線情報が必要になってきますよね。
大丈夫です。対応してます。
※間違っても他の方の記事にケチを付けるつもりは一切ございません😯

スプレッドシートへの記入の仕方はこんな感じです。
あとは路線を追加しまくれば勝ちです。
![qiita.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2533975/41b748c7-b462-baf5-f190-9b3d5e0cf692.png)

で、正確な路線名はどこから引っ張るの？という話になるのですが、
 さんの画面下部にスクロールすると、
「対応してると思われる鉄道路線」という欄があると思います。(2022/3/28現在)
路線名を「name」に、運営会社を「company」に当てはめて自分の求めてる路線を探してコピペです。
Ctrl+Fで検索するのが早いでしょう。
「実績」の「!」というのはどうやら「既に遅延情報を通知したことがある」という意味らしいです。
つまり実績が無い路線は....元サイトの更に元サイト
[TETSUDO.com](https://www.tetsudo.com/traffic/) さんのサイトから
路線名と会社名を探す度にでかけましょう。田舎は辛い。

<a id="#最後にトリガーを設定してこの戦いを終わらせよう"></a>
# 最後にトリガーを設定してこの戦いを終わらせよう
最後にGASのトリガーを設定して終わりに向かいましょう。
通常であれば一日に数回、朝と昼と夕方などにトリガーをかけるかと思いますが。
考えても見てください。トリガーが発動して「遅延がないよ！」って言われた5分後に遅延が起きたら...
神速退勤ラッシュをキメたところで帰りの電車が無ければ
家で待ってる前日にインストールした最新のゲームもボロ泣きしてしまいます。
なので今回はトリガーを5分おきに設定してます。

Q.サーバーの負荷的に大丈夫なの？

A.Google先生が十字架を背負ってくれるので問題ないです。

ただ、鉄道遅延情報のjsonさんのサイトにも記載されている通り、
膨大なアクセスがあったため当初とは違うサーバーに切り替わったのがつい最近の話です。
今後もしかしたらこのやり方が利用できなくなる可能性もあるため、そこはご了承下さい。

ということで、トリガーはこんな感じで設定しましょう。
関数は「fetchDelayInfo」を選択してくださいね！
![２キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2533975/9ce6a887-0017-27dd-c84b-a582fab12908.png)

この時間設定は基本的に皆様の自由です🙂

以上で設定は完了です！お疲れ様でした！

<a id="#おわりに"></a>
# おわりに
本当なら自分でコードを1から構築できたら良かったのですが、
プログラミングはおろか関数すらわからない状態から初めたノンプロ勢にはコードの改変がギリ限界でした。
個人的に大事だと思うのはこれらのコードを解析し、どのような仕組みで動いてるのかお勉強することだと思います。
myVarsの[i-1]とか正直なにしてるのこれ状態なので...私自身もこのぐらいコードを書けるまで精進します！
それではみなさん、良いコードライフを。


<a id="#参考文献"></a>
# 参考文献
- [LINE Notify アクセストークン](https://firestorage.jp/business/line-notify/)
- [Google Apps Scriptで毎朝チャットワークに電車の遅延情報をプッシュ通知する](https://tonari-it.com/gas-chatwork-train-delay/)
- [【GAS】V8ランタイムを有効にした時のfor each文の修正方法](https://life89.jp/gas-v8-for-each-repair/)
- [TETSUDO.com](https://www.tetsudo.com/traffic/)
- [【Google Apps Script（GAS）】LINEにメッセージ送信しよう【業務効率化】](https://note.com/taraco123/n/n522774098e00)