2&>1

AWSとかGCPとかGolangとかとか

Massage API + GAS で電車遅延情報をpush通知する

はじめに

LINE Botから通勤電車の遅延情報を勝手に通知してくれてると楽だなーと思って作りました。 post通知(自分から聞くと答えてくれる)のなら公式のでもあるけど、JRとメトロとかだと同じアプリではできないのが勝手が悪いなー(´・ω・`)と思ってました。

ざっくり仕様

・遅延情報を勝手に送ってくる(遅延なければ通知なし) ・使用する路線を指定できる ・送る時間を指定できる

流れ

1.LINE developer登録する 2.googleアカウントを作成しgoogle APPS scriptを使う 3.スクリプト書いて実行時間指定 4.終わり

詳細

LINE developer登録する

割愛します。 ググレはいくらでも出てくるので。。 PUSH通知をするにはトライアルかプロアカウントである必要があるのでご注意。 (人数制限ありを我慢するか、諭吉を使うか。。私はトライアルでやってます)

googleアカウントを作成しgoogle APPS scriptを使う

割愛します。 Googleアカウントはすでに持ってるでしょうしGASもググレすぐ開けるので。。

スクリプト書いて実行時間指定

コードは以下

[code lang=js] // line developersに書いてあるChannel Access Token var access_token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" // pushしたいときに送る先のuser_idを指定する var to1 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" var to2 = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" // 路線リストのスプレッドシートid var spreadsheet_id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

//電車遅延情報をJSON形式で取得 var json = JSON.parse(UrlFetchApp.fetch("https://rti-giken.jp/fhc/api/train_tetsudo/delay.json").getContentText()); //シートとその最終行数、シートのデータを取得 var SheetID = SpreadsheetApp.openById(spreadsheet_id); var mySheet = SheetID.getSheetByName("list"); var maxRow = mySheet.getDataRange().getLastRow(); var myVars = mySheet.getDataRange().getValues();

//pushするときの設定

function push(text) { //var url = "https://api.line.me/v2/bot/message/push"; //1userへ送る場合はpushでOK var url = "https://api.line.me/v2/bot/message/multicast"; var headers = { "Content-Type" : "application/json; charset=UTF-8", 'Authorization': 'Bearer ' + access_token, };

var postData = { "to" : [to1,to2], "messages" : [ { 'type':'text', 'text':text, }, { 'type':'text', 'text':text, } ] };

var options = { "method" : "post", "headers" : headers, "payload" : JSON.stringify(postData) };

return UrlFetchApp.fetch(url, options); }

//reply_tokenを使ってreplyする

function reply(data) { var url = "https://api.line.me/v2/bot/message/reply"; var headers = { "Content-Type" : "application/json; charset=UTF-8", 'Authorization': 'Bearer ' + access_token, };

var postData = { "replyToken" : data.events[0].replyToken, "messages" : [ { 'type':'text', 'text':data.events[0].message.text, } ] };

var options = { "method" : "post", "headers" : headers, "payload" : JSON.stringify(postData) };

return UrlFetchApp.fetch(url, options); }

//postされたときの処理

function doPost(e) { var post = JSON.parse(e.postData.contents); var data = SpreadsheetApp.openById(spreadsheet_id).getSheetByName('log').getRange(1, 1).setValue(json.events);

reply(post); }

//pushするときの処理 function trainDelayInfo() {

var body = "電車の遅延";

for(var i=2;i<=maxRow;i++){

var name = myVars[i-1][1-1];
var company = myVars[i-1][2-1];

for each(var obj in json){
  if(obj.name === name &amp;&amp; obj.company === company){
    body = company + name + &quot;が遅延しています&quot;;
      push(body);
  }
}

}

if(body === "電車の遅延"){ //body = company + name + "が遅延してない"; push("遅延なし"); }

} [/code]

ちょっと説明

遅延情報を取得する一覧はスプレッドシートに記載する 下のように記載。 キャプチャ.PNG

鉄道一覧は以下から拝借しており、同じ名前で記載する必要がある。 https://rti-giken.jp/fhc/api/train_tetsudo/ 

**スプレッドシートを参照させるために以下が必要

[code lang=js] // 路線リストのスプレッドシートid var spreadsheet_id = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"  →「https://docs.google.com/spreadsheets/d/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/editスプレッドシート開いたURLのxxxをコピペ

//シートとその最終行数、シートのデータを取得 var mySheet = SheetID.getSheetByName("list");  →スプレッドシートのシート名を書く(ここでは「list」という名前)  →シート名「log」を作成しておけばpostした時のログがでる [/code]

Line developerの管理画面から以下項目も確認

[code lang=js] // line developersに書いてあるChannel Access Token var access_token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" // pushしたいときに送る先のuser_idを指定する var to = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" [/code]

これで「trainDelayInfo」を実行すると対象user_idへ通知がくるはず。。 問題なければトリガーセットして完了!!

ハマったところ

スプレッドシートを参照エラーになる  →spreadsheet_idを指定しないと参照できない。他サイトでは省略してるのか明示的に書いていないとこがあるがそのまま真似するとハマる。

参考

https://blog.pnkts.net/2018/06/03/line-messaging-api/ https://tonari-it.com/gas-chatwork-train-delay-spreadsheet/

これから改修したいところ

・postしたときに電車遅延情報を返す(今はオウム返し) ・user_idを自動追加する ・ホントはlambda + APIGWを使いたい。。

まとめ

意外と時間がかかりました(コナミカン