目次
Slack に 毎日自動で天気予報を投稿するスクリプトを書きました。 Google Apps Script を使いました。 Google Apps Script なので、 祝日または休日だったら投稿しないという分岐もできます。 (参考: 営業日だけ処理を実行したい場合)
方針
- 天気予報の取得は Open Weather Map を使用する。
- Script は CoffeeScript を使用して記述する。
- Slack へは、 Incoming WebHooks を利用して投稿する。
- Google Apps Script を使って自動で定期的に実行します。
準備
Slack で Incoming Webhooks の URL を取得しておきます。
コード
Open Weather Map へのリクエストで APIキーが必要になりました。 下のコードは古いので適宜変更してください。
まず 次の CoffeeScript を用意します。 昔作った別のコードを改変したものです。
コピーして使う場合は、 Slack の URL を変更してください。
CoffeeScript なので、 だいたい JavaScript として動きますが、 UrlFetchApp
, Utilities
は Google Apps で用意されたものを使っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
Temparature = AbsoluteZeroDegree: -273.15 City = Tokyo: Id: 1850147 TimeZone: '+09:00' SlackUrl = incoming: bot: 'https://hooks.slack.com/services/THIS/IS/EXAMPLE' class WeatherAPIGateway instance = null class _WeatherAPIGatewayCore url_base = 'http://api.openweathermap.org/data/2.5/weather' tmp_json = null getWeatherByCityId: (id) -> url = url_base + '?id=' + id return @.getWeatherJSONByUrl(url) getWeatherJSONByUrl: (url) -> webGateway = WebGateway.getInstance() jsonString = webGateway.getBody(url) return new Weather(Utilities.jsonParse(jsonString)) getDetailUrlByCityId: (id) -> return 'http://openweathermap.org/city/id?=' + id @getInstance: () -> instance ?= new _WeatherAPIGatewayCore() class Weather _json = null constructor: (json) -> _json = json getImageUrl: () -> return 'http://openweathermap.org/img/w/' + _json.weather[0].icon + '.png' getTempertureInCelcius: () -> return _json.main.temp + Temparature.AbsoluteZeroDegree getMinimumTemparetureInCelcius: () -> minimumTemparature = _json.main.temp_min + Temparature.AbsoluteZeroDegree minimumTemparature = Math.round(minimumTemparature * 100) / 100 return minimumTemparature getMaximumTemparatureInCelcius: () -> maximumTemparature = _json.main.temp_max + Temparature.AbsoluteZeroDegree maximumTemparature = Math.round(maximumTemparature * 100) / 100 return maximumTemparature getCityName: -> return _json.name getTitle: -> return _json.weather[0].main getDescription: -> return _json.weather[0].description getWindSpeed: -> return _json.wind.speed getUnixTime: -> return _json.dt class SlackPushMessage _message = {} setText: (text) -> _message['text'] = text return @ getText: -> return _message['text'] setUserName: (user_name) -> _message['username'] = user_name return @ getUserName: -> return _message['user_name'] setIconUrl: (icon_url) -> _message['icon_url'] = icon_url return @ getIconUrl: -> return _message['icon_url'] setMarkDown: (trueOrFalse) -> _message['mrkdwn'] = trueOrFalse return @ getMarkDown: -> return _message['mrkdwn'] toJson: -> return JSON.stringify(_message) class SlackGateway instance = null class _SlackGateway push: (url, payload) -> webGateway = WebGateway.getInstance() webGateway.post(url, payload) @getInstance: -> return instance ?= new _SlackGateway() class WebGateway instance = null class _WebGateway getBody: (url) -> UrlFetchApp.fetch(url).getContentText() post: (url, payload) -> options = method: 'post' payload: payload UrlFetchApp.fetch(url, options) @getInstance: -> return instance ?= new _WebGateway() class PushWeatherToSlackService instance = null class _PushWeatherToSlackService pushToSlack: (city) -> # generate weather object weatherAPIGateway = WeatherAPIGateway.getInstance() weather = weatherAPIGateway.getWeatherByCityId(city.Id) # create slack push message message = new SlackPushMessage() message.setUserName( 'Tokyo Weather Forecast at ' + Utilities.formatDate( new Date(weather.getUnixTime() * 1000), 'GMT' + city.TimeZone, 'yyyy-MM-dd HH:mm')) message.setIconUrl(weather.getImageUrl()) message.setText( '*' + weather.getTitle() + '* (' + weather.getDescription() + ')n' + 'Temp Range: ' + weather.getMinimumTemparetureInCelcius() + '-' + weather.getMaximumTemparatureInCelcius() + ' °;Cn' + 'Wind: ' + weather.getWindSpeed() + ' m/sn' + '<' + weatherAPIGateway.getDetailUrlByCityId(city.Id) + '|More Detail>' ) # push to slack slackGateway = SlackGateway.getInstance() slackGateway.push( SlackUrl.incoming.bot, message.toJson()) @getInstance: -> return instance ?= new _PushWeatherToSlackService() ### execute ### pushWeatherToSlackService = PushWeatherToSlackService.getInstance() pushWeatherToSlackService.pushToSlack(City.Tokyo) |
いちいちオブジェクトを作らずに 直接 JSON を処理するようにしていれば、もっと短いコードになると思います。
CoffeScript ができたら、 コンパイルして JavaScript に変換します。 続いて、出力された JavaScript を Google Apps Script に次のようにコピーします。
1 2 3 |
function execute() { // paste JavaScript here } |
生成された JavaScript を execute
関数 の中に入れます。 このようにしてコードを作った後で、最初に実行する関数を execute
に設定します。 定期的に実行するには メニューのリソースからトリガ作成へと進みます。 そこで、いつ送るかを設定します。
今回は Slack への投稿 でしたが、 メール通知もできます。 メール通知の例は 定期的にメールを自動で送る方法 に記載しています。 営業日のみ処理を実行したい場合は 営業日だけ処理を実行したい場合 にサンプルを記載しておりますのでそちらもご参考ください。