Help us understand the problem. What is going on with this article?

GASを使ってGoogleカレンダーの予定をLineに送る.

初めに

自分がこれを実装したのは一年ほど前なのですが,せっかくなので投稿しておきます.
一応全コードはここ

やりたいこと

予定をGoogleカレンダーに書いても結局見ずにすっぽかしてしまうので,明日の予定を自動的にLineに送りつけてほしい.

手順

Line Tokenの入手

ここは散々先人の知恵があるので割愛
Line Notify 公式
[超簡単]LINE notify を使ってみる

GAS記述

Line Notifyに通知を送る方法はたくさんあるが,Python+cronとかだとちょっと面倒くさいのでトリガー設定しとけば勝手に定期実行してくれるGASを利用する.
また,Googleカレンダーにアクセスする観点からしてもGASが優秀.
というわけで自分のGoogle DriveにアクセスしてGASのスクリプトをコーディングしていく.

Lineに送る関数

まずはLineに送る関数を記述する.

function sendToLine(text){
  var token = lineToken;
  var options ={
     "method"  : "post",
     "payload" : "message=" + text,
     "headers" : {"Authorization" : "Bearer "+ token}
   };
   UrlFetchApp.fetch("https://notify-api.line.me/api/notify", options);
}

lineTokenにはLine NotifyのTockenを入れる.
引数に送りたいメッセージを添えて実行すると,Lineにメッセージが送られる.

続いて,送るメッセージを構築していく.

明日の予定入手

自分のGoogleカレンダーにアクセスして明日の予定を取ってくる処理を記述する.

function main() {
  var calendars = CalendarApp.getAllCalendars();
  var calendar = calendars[1]; //自分のカレンダー取得
  var text = ""; //送信メッセージ初期化

  var now = new Date();
  var date = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1); //明日の日付
  var events = calendar.getEventsForDay(date);  //明日の予定取得

  for(j in events) { //予定を1個ずつ見ていく
    var event = events[j]; //j番目の予定を取得

    var title = event.getTitle(); //予定のタイトル
    var start = toTime(event.getStartTime()); //開始時刻取得
    var end = toTime(event.getEndTime()); //終了時刻取得
    var at = event.getLocation() //開催場所

    //メッセージに追加
    text +=  "\n" + (Number(j) + 1) +". " +title+"\n" +start + ' - ' + end  ;
    if (at !=""){
      text += " @" + at;     //場所があれば追加
    }
  }

  if(text ==""){//予定がなかったとき
   text += "\n明日の予定はありません"; 
  }
}

//時刻のフォーマット変換
function toTime(str){   
  return Utilities.formatDate(str, 'JST', 'HH:mm');
}

流れとしては,
1. 自分のGoogleカレンダーにアクセス
2. カレンダー選択
3. 全予定リスト取得
4. それぞれの予定に対してメッセージを追加していく.
というような流れになっている.

Googleカレンダーに複数個のカレンダーを登録している人は,

var calendar = calendars[1]; //自分のカレンダー取得

この部分を変更すれば任意のカレンダーが取得できる.

あとは上記のメイン関数の最後に

 sendToLine(text);

としてLineに送る関数を実行すればOK.

あとはトリガーを任意の時間に設定してあげれば自動的にその時間帯になったらLineに通知してくれる.
予想以上にシンプルになってしまったので以下おまけ

おまけ【天気予報】

これだけじゃ面白くないので天気予報でも追加してみる.
方針としてはどこかから天気予報の情報を入手して先程のtextに追加していく.
お手軽な天気予報APIを探してみると,Dark Skyという良さげなものを見つけた.
Dark Skyの使い方に関しては,ちょうど良い記事を見つけたのでこちらを参考にしてほしい(他力本願甚だしい)
以下のページの,
[ 4,登録したのち、最初の画面からLogInすると、早速自分のAPIキーが用意されています。]のところまで進める.
【初心者用】API利用法 DarkSkyで天気を自動取得、WEBページに組み込む方法

自身のAPIキーを入手したら,先程のmain関数に処理を追加していく.

 //続いては天気予報です.
  text += "\n\n[天気予報]"
  //DarkSkyにアクセス. "https://api.darksky.net/forecast/<自分のキー>/<緯度,経度>?units=si&lang=ja&exclude=alerts,flags"
  var response = UrlFetchApp.fetch("https://api.darksky.net/forecast/<Your Key>/<Location>?units=si&lang=ja&exclude=alerts,flags"); 
  var retjson = JSON.parse(response.getContentText()); //JSON形式データを配列に格納
  date_data = retjson["daily"]["data"][1] //日報データ
  var date_data_date =Moment.moment.unix(date_data["time"]).format("DD") //日付
  text += "\n" + date_data_date + "" +date_data["summary"] +" \n最高気温 " + date_data["temperatureHigh"] + "\n最低気温 " + date_data["temperatureLow"] + "\n降水確率 " +  Math.round(date_data["precipProbability"]*100) + escape("%");

  text += "\n\n[3時間毎の予報]"
  for(item_num in retjson["hourly"]["data"]){
    var item = retjson["hourly"]["data"][item_num];
    var time_a = item["time"]
    var hour =Moment.moment.unix(time_a).format("HH")
    if(hour % 3 == 0){
      text += "\n" + Moment.moment.unix(time_a).format("DD日HH時") + " " + item["summary"] + " " + Math.round(item["temperature"]) + "度 降水確率" + Math.round(item["precipProbability"]*100) + escape("%");
    }
    if(hour == 21){
      break;
    }
  }

(変数名とか気持ち悪いけど自分用に適当に書いたコードだから許してほしい...)
実際には,

//DarkSkyにアクセス. "https://api.darksky.net/forecast/<自分のキー>/<緯度,経度>?units=si&lang=ja&exclude=alerts,flags"
  var response = UrlFetchApp.fetch("https://api.darksky.net/forecast/<Your Key>/<Location>?units=si&lang=ja&exclude=alerts,flags"); 

この部分は自身のキーと天気予報の欲しい場所の軽度,緯度を入力する.
APIのレスポンスはjsonで得られるのでパースしている.
あとは,実際のAPIレスポンス見ながらほしいデータをポチポチ探索しながら記述していった.
結構詳細な情報が得られるが長くても鬱陶しいので自分は3時間毎の天気のみ通知するようにしている.
実際の通知は以下のようになる.
Screenshot_2019-10-07-23-40-50-158_jp.naver.line.android.png

若干3時間毎じゃなくて6時間毎で良かった気がする.

おまけ【Qiitaの人気記事取得】

正直ここからが一番やりたかったことだったりする.
天気予報とかは正直別にどうでもよくて,Qiitaの人気記事が自動で配信されたら嬉しいなと思っていたのでついでに実装する.
ここでも既存のAPIがないかと思い探したら良さげなのがあったので,以下を利用させていただく.

Qiitaいいね数ランキングAPIの作成

元記事によると,

https://us-central1-qiita-trend-web-scraping.cloudfunctions.net/qiitaScraiping/{type}/{YYYY-MM-DD}

の形式で叩けばランキングの情報がもらえるよう.
今回は,{type}には日別を表す{daily}を,
日付には昨日の日付を入れる.
したがってコードは以下のようになる.

text += "\n\n[昨日のQiitaベスト5]"

  var yesterday =Moment.moment(date).subtract(2,'days').format("YYYY-MM-DD") 
  var response = UrlFetchApp.fetch("https://us-central1-qiita-trend-web-scraping.cloudfunctions.net/qiitaScraiping/daily/"+yesterday); 
  var qiita_ranking = JSON.parse(response.getContentText())["data"]; //JSON形式データを配列に格納

  for(var i = 0; i < 5 ; i ++){
    text += "\n" + qiita_ranking[i]["title"] + "\n" + qiita_ranking[i]["url"];
  }

これを実行すると以下のようなメッセージが送られてくる.
Screenshot_2019-10-07-23-58-24-597_jp.naver.line.android.png

最後に

やっぱりいちばん使うLineにQiitaの情報を流し込むことによって以前より効率的に情報収集ができている(気がする.)

余談だが,最近はアナログに切り替え手帳ユーザーになりつつあるので毎日毎日
明日の予定はありません
とLineに煽られて寂しいです.
ホントは予定あるよ

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away