Slackに天気や予定を毎朝通知する Google Apps Script

最近Google Apps Scriptにハマり始めたので記録。

#概要

- **夜になると翌日のGoogleカレンダーの予定をSlackに送る**
- **朝になるとその日のお天気をSlackで通知**

という機能をGoogle Apps Scriptを用いて実装しました。

基本的には

    外部API → Google Apps Script → Slack Incoming Webhook

といった構成でやってます。
ここのGoogle Apps Scriptを書いて実行することで、天気やカレンダーなどの情報をSlackに流すことができます。


#Google Apps Scriptって？

Google Apps ScriptはGoogle社が提供しているサーバーサイドスクリプト環境です。
基本的にはChrome上でスクリプトを書くだけで実行できます。


すでに良いqiitaがいっぱい上がっていますが、導入には以下の記事を参考にしました。
[Google Apps Script 入門](https://qiita.com/t_imagawa/items/47fc130a419b9be0b447)


#スニペット
##お天気をSlackに通知
```javascript:コード.gs
function getWeatherPostSlack() {

    var response = UrlFetchApp.fetch("http://weather.livedoor.com/forecast/webservice/json/v1?city=130010");

    var json=JSON.parse(response.getContentText());

    Logger.log(json["title"]);
    Logger.log(json["description"]);
    Logger.log(json["forecasts"]);  

    var data={
        "text":json["description"]["publicTime"]+json["description"]["text"],
        "username": json["title"],
        "icon_emoji" : ":sunny:"
    }
    
    var options =
    {
        "method" : "POST",
        'contentType': 'application/json',
        'payload' : JSON.stringify(data)
    };
    // SlackのIncoming WebhookのURLを取得して入力
    UrlFetchApp.fetch("https://hooks.slack.com/services/***/***/***", options);
}
```
↓Slackにこんな感じできます。
<img width="666" alt="スクリーンショット 2018-04-20 15.02.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/242744/b15ed89f-2303-7d7d-c480-7d95bab88aa9.png">


##Googleカレンダーの明日の予定をSlackに通知
```javascript:コード.gs
function getCalendarPostSlack() {

    var dt = new Date();
    dt.setDate(dt.getDate() + 1);//明日にset

    //カレンダーURL、もしくはメールアドレスを取得して入力。
    var myCal=CalendarApp.getCalendarById('*****@group.calendar.google.com');
    var events=myCal.getEventsForDay(dt);

    var strBody = "";

    // イベントごとにループ
    for(var i_e=0;i_e<events.length;i_e++){
        var strTitle=events[i_e].getTitle();
        var strStart=_HHmm(events[i_e].getStartTime());
        var strEnd=_HHmm(events[i_e].getEndTime());
        strBody=strBody + "`"+strStart + ' - ' + strEnd +"`"+" "+strTitle+ '\n'; //ここはSlackで送りたい文章に合わせて調整
    }

    var data={
        "text":strBody,
        "username": "明日の予定",
        "icon_emoji" : ":tokyo_tower:"
    }
  
    var options =
    {
        "method" : "POST",
        'contentType': 'application/json',
        'payload' : JSON.stringify(data)
    };

    // SlackのIncoming WebhookのURLを取得して入力
    UrlFetchApp.fetch("https://hooks.slack.com/services/***/***/***", options);
}

function _HHmm(str){
    return Utilities.formatDate(str, 'JST', 'HH:mm');
}
```

↓Slackにこんな感じできます。

<img width="481" alt="スクリーンショット 2018-04-20 15.05.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/242744/47e11318-0416-5e81-80fc-c7aff52f6a9d.png">

(追記)
**2018年4月現在、Slackのデフォルトの機能でGoogle Calendarから予定をアナウンスする機能があります。
ただ、「明日の予定をまとめて前日に通知する」機能が存在しないので、今回作成しました。**

#お天気のAPIについて
いろいろありますが、livedoorのAPIを利用。

以下のようなURLから東京都の天気情報をJson形式で取得します。

http://weather.livedoor.com/forecast/webservice/json/v1?city=130010

APIについての参考。
http://hello-apis.blogspot.jp/2013/03/webapi.html
https://tonari-it.com/gas-api-weather/

# Google CalendarのAPIについて
カレンダー固有のURLから情報をとることができます。

自分のカレンダーのURL取得等、以下を参考にしました。感謝。
https://tonari-it.com/gas-calendar-getevents/
http://www.googleappsscript.info/2017-12-31/calendar_get_and_register.html

# SlackのIncoming WebhookのURL取得方法
[SlackのWebhook URL取得手順](https://qiita.com/vmmhypervisor/items/18c99624a84df8b31008)
にわかりやすくまとまってます。

僕の場合は[Curlで送るテスト](https://qiita.com/maatumoDev/items/9e97785f11df30a4c119#slack%E3%81%AB%E9%80%81%E4%BF%A1%E3%81%97%E3%81%A6%E8%A9%A6%E3%81%99
)をして使い始めました。

#実行時刻の設定のやりかた
**Google Apps Scriptはスクリプトの実行時刻が簡単に指定できます。**
夜中に上司へSlackを投げるボットが一瞬で作れますね。

左上の時計マークを押します。

<img width="603" alt="スクリーンショット 2018-04-20 15.16.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/242744/612e72ad-69f3-fe38-aebd-70b099c0f635.png">

時刻設定用のウィンドウが出るので、所望の時刻に設定します。
<img width="839" alt="スクリーンショット 2018-04-20 15.15.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/242744/ef3df344-637a-d3f0-383c-98d19bef15d2.png">



#そもそもwebhookって？

<img width="244" alt="スクリーンショット 2018-04-20 12.28.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/242744/aee15fe3-7c27-ee54-6acd-e8e6878cc2d9.png">

Webhookは、APIのコンセプトの一つみたい。要はAPIです。
一般的なAPIはこちらからAPIを呼んで情報をもらうのに対し、Webhookはサーバー側から所望のURLを呼んでもらう仕組みです。


ググってたら野球監督とウォームアップ中のピッチャーの例がでてきました

- ピッチャーのウォームアップが終わったかを監督が電話で聞く(ふつうのAPI)
- ピッチャーのウォームアップが終わったら監督に電話がいく(Webhook)

といった感じのようですね。


> Baseball managers could really use webhooks. As the game progresses, they often want to change pitchers. To do this requires the new pitcher to first warm up in the bullpen, which is usually over 300 feet from the team’s dugout. If you watch baseball on television, you’ll often see the manager pick up a phone in the dugout. He’s making a call to the bullpen to check on the new pitcher.

>“Is he warmed up yet?”
“Not yet”
Then he hangs up the phone. In a few minutes he’ll have to call again. Programmers would call this polling and it’s process-intensive for both sides. A webhook lets you say, “call me when he’s warmed up.”

https://sendgrid.com/blog/webhook-vs-api-whats-difference/ 



#最後に
間違っているところ等がありましたらご指摘ください。