あるシステムでユーザーが作成したTodoを、その期限の前日の21時にLINE通知させる

#概要
すでにあるシステムやプログラム内で、ユーザーが作ったタスクを、その期限の前日の特定の時間にまとめてLINEに通知する方法です。

- Googleスプレッドシート・・・Googleが作った無料で使えるエクセルみたいなやつ
- Google Script・・・上のスプレッドシートの操作をプログラミングでできるやつ。定期実行(毎日○時に実行とか)できる。無料！
- LINE notify API・・・簡単にLINEに通知を飛ばせるやつ

を使います。


#大まかな方法
0. あるシステムでユーザによってタスクが生成される
1. それを、URLの一部分に"タスク期限"と"タスク内容"に分けて組み込んで、Google Scriptに送信
2. 送られてきたURLから"タスク期限"と"タスク内容"を取得し、Googleスプレッドシートにメモする
3. 毎日21時にGoogle Scriptが自動実行され、Googleスプレッドシートにメモされているタスクを確認
4. もし、明日期限を迎えるタスクがあったら、LINEに送信

これでタイトルのような動作ができます。
#詳しい方法
###LINE notify APIを使う準備
[こちら](https://qiita.com/iitenkida7/items/576a8226ba6584864d95)のかたの
*[スマフォで作業] 設定したルームに「LINE notify」 を招待する*
までを行って、APIのアクセストークンを入手する。
###Googleスプレッドシートを作成する
自分のアカウントでGoogleドライブを開き、赤丸のところから、スプレッドシートをクリック。
<img width="1440" alt="スクリーンショット 2020-01-15 23.52.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214547/c7861744-e57a-a2fe-d3cf-568943b7b951.png">
スプレッドシートの名前は好きなようにつけてOK。
###Google Scriptを作成する
上のツール->スクリプトエディタをクリック。
<img width="1440" alt="スクリーンショット 2020-01-15 23.53.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214547/c2f4cf56-c5ed-e954-a01a-768f4c658bf9.png">
これも名前は好きなようにつけてOK。
<img width="1440" alt="スクリーンショット 2020-01-16 2.09.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214547/ee16b92c-aa4f-bdf2-9e85-f59b6b2cca95.png">
###プログラムを書く
URL経由で飛ばされてきたタスクをスプレッドシートにメモするプログラム
と
全てのタスクを調べ、明日期限のものを発見し、LINEに飛ばすプログラム
を書きます。
function myFunction() {
}
を消して、下のやつをまるっとコピペすればいいはずです。
できるかぎり、説明をつけたつもりです...動くと思います...


```Javascript:コード.gs
//【やること】設定しなきゃいけない変数
var line_api_token = "?????????????????";//LINEのAPI使うときに発行したトークン



//★飛ばされてきたタスクをスプレッドシートにメモするプログラム
//function doGet(e)はURL(タスク情報を含んだ)からアクセスが来た時、自動的に実行されます。
function doGet(e) {
  //URLに書かれた期限と内容の情報をGET
  var deadline = e.parameter.deadline;
  var contents = e.parameter.contents;
  
  //スプレッドシートへのメモ
  var sheet = SpreadsheetApp.getActiveSheet();//スプレッドシートを操作できるようにする
  sheet.insertRowBefore(1);//一番上に行を新規に挿入
  sheet.getRange('A1').setValue(deadline);//1行目A列に期限を設定
  sheet.getRange('B1').setValue(contents);//1行目B列にタスク内容を設定
}





//★全てのタスクを調べ、明日期限のものを発見し、LINEに飛ばすプログラム
//function myFunction()は、設定後、特定の日時に自動的に実行されます。
function myFunction() {
  var sheet = SpreadsheetApp.getActiveSheet();//スプレッドシートを操作できるようにする
  var last_row = sheet.getLastRow();//スプレッドシートに書き込みがある最終行を調べる
  //上から最後に書き込みがある行まで1行ずつ調べるためのforループ
  for(var i = 1; i <= last_row; i++) {
    var target_deadline = new Date(sheet.getRange('A' + i).getValue());//i行目のタスクの日付をGET
    var tommorow = new Date();tommorow.setDate(tommorow.getDate() + 1);//明日の日付を生成
    
    //もし、タスクの日付が、明日の日付と、年も月も日にちも同じだったら、明日のタスクだ！と判定
    if(tommorow.getYear() == target_deadline.getYear() && tommorow.getMonth() == target_deadline.getMonth() && tommorow.getDate() == target_deadline.getDate()) {
      //まず、タスクの内容をGET
      var target_contens = sheet.getRange('B' + i).getValue();
      
      
      //次に、LINEに送りつけるために、データの塊を作る
      var options = 
          {
            "method" : "post",
            "headers" : {'Authorization': "Bearer " + line_api_token},
            "payload" : {"message" : target_contens}
          };
      UrlFetchApp.fetch("https://notify-api.line.me/api/notify", options);//LINEに送信
      
      
      //最後に送信したタスクを行ごと全て削除する
      sheet.deleteRow(i);
      i--;//行を削除すると今見てる行が次の行になるからiを1減らす
      last_row--;//行を削除すると最終行も最初と比べて1行減るから、減らす
    }
    //もし、明日のタスクじゃなかったら、次の行を調べにいく
  }
  //最終行まで確認し終わったら、その日の動作は終わり！
}
```
###プログラムを自分用に改変する
上のプログラムの1行目、
【やること】設定しなきゃいけない変数
の???????の部分を最初に取得したLINEアクセストークンに置き換えることで、自分のLINEアカウントにタスクが飛んできます。
例) "????????" -> "ELSUEGXSUEYW"
###Google Scriptを定期実行させる設定にする
上のプログラムのmyFunction()を好きな時間に定期実行させます。
上の編集->現在のプロジェクトのトリガーをクリック。
<img width="1436" alt="スクリーンショット 2020-01-16 0.17.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214547/1bbdb906-7079-b896-f134-6b61cb38be5d.png">
右下のトリガーを追加をクリック後、以下のように設定。※21時通知希望の場合
<img width="1440" alt="スクリーンショット 2020-01-16 0.20.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214547/43d06fcb-660e-5f07-4d5b-a4ea6f1a27f3.png">
###外のシステムからタスクを受ける窓口を作る
上の公開->ウェブアプリケーションとして導入
<img width="1440" alt="スクリーンショット 2020-01-16 0.36.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214547/f113a887-20ff-8e72-3ee1-c49ef2c83e3b.png">
以下のように設定後、表示されてるURLをメモっておく。
<img width="409" alt="スクリーンショット 2020-01-16 1.53.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214547/eba138e8-e303-efa5-5387-6cdc09d40ac0.png">



以上でGoogle Scriptの設定は終了です！



###スプレッドシートの行を1行残して削除する
上のプログラムでは、新規タスクに対して1行増やし、LINEに送信したら1行消すので、他の行は必要ありません。
<img width="1436" alt="スクリーンショット 2020-01-16 0.10.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214547/d296d0c4-8fbf-1c74-2718-6a664625ba24.png">


###動作確認をする
**1動作許可をする**
赤丸のところが"myFunction"になっていることを確認して、青丸を押してください。
<img width="1440" alt="スクリーンショット 2020-01-16 1.04.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214547/12902c27-d104-55c4-8979-eba3e44b937b.png">
初めて動かすときだけ、なんか、許可を求められます。赤丸を押し、自分のアカウントを選択するなどして、全部許可にします。
<img width="485" alt="スクリーンショット 2020-01-16 1.08.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214547/a10af65b-389f-0abf-0bf6-1a2ad5160b94.png">
<img width="581" alt="スクリーンショット 2020-01-16 1.08.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214547/2ca4f36e-4836-a7ca-9fae-ea9ac039a67b.png">


**2次に、タスクをこのシステムに送信してみます。**
先ほどメモしたURLの後ろに
"?deadline=YYYY/MM/DD HH:MM:SS&contents=見本ブロックを作る"
を追加します。
deadline=YYYY/MM/DD HH:MM:SS
でタスクの期限を表現していて、
contents=見本ブロックを作る
でタスクの内容を表現しています。
★YYYY...には明日の日付と適当な時間を入れてください。★
URLの完全な例)

- https\://script.google.com/macros/s/AFEDA・・・・人それぞれ違う・・・Hc0/exec?deadline=2020/01/16 16:20:00&contents=見本ブロックを作る

★"作る"までがURLです。日付と時間の間の半角スペースを忘れずに。


**3作成したURLにブラウザでアクセスしてみる**
この操作が、システムへのタスク送信作業になります。
<img width="1418" alt="スクリーンショット 2020-01-16 1.01.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214547/190fe01d-ed98-e10d-6562-dd304a8bc53c.png">
が正しい状態です。


**4スプレッドシートを開いて、タスクがメモされているか確認する。**
<img width="1440" alt="スクリーンショット 2020-01-16 1.02.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214547/11e22784-ab49-bf63-d3f4-af00d0f80d16.png">
が正しい状態です。※日付はそれぞれ。


**5手動でLINEに送ってみる**
本来は、21時に自動実行されて、自動的にLINEに送られるはずですが、今回は動作確認のため、手動でプログラムを実行し、LINEに送ってみます。
赤丸のところが"myFunction"になっていることを確認して、青丸を押してください。
<img width="1440" alt="スクリーンショット 2020-01-16 1.04.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214547/12902c27-d104-55c4-8979-eba3e44b937b.png">



**6LINEにとどく**
プログラムが動き出し、明日期限のタスクがスプレッドシートにあったら、LINEに通知してくれるはずです。


###自分の環境に合うようにする
以上の流れを行えば、希望の時間に翌日のタスクを全部LINEに通知できるはずです。
あとは、自分が制作しているプログラムで、ユーザーがタスクを作った時にURLに情報を含ませて読み込めばOKです。

以下はPython3のプログラムから、タスクを追加する例です。
requestsモジュールのインストールが必要かもしれません。

```Python3:test.py
# Python3のコード
import requests
url = 'https://script.google.com/macros/s/AKfycbzmK・・・それぞれ違う・・・1yHc0/exec?deadline=2020/01/17%2016:20:00&contents=見本のブロックを作る'
requests.get(url)
```