【GAS × LINE WORKS】天気のお知らせ Bot を作った話

ゆるっと Advent Calendar 2020 16日目
どうぞよろしくお願いいたします～。

# はじめに

今日の Advent Calendar を見ていたら、@_nsk_ さんがこんな記事を書いていたので私も作ってみよーと思い LINE WORKS Bot でゆるゆるっと作ってみました～(*´Д｀)
参考元：[GASで天気のおしらせボットを作った話](https://qiita.com/_nsk_/items/b8b2f71cfbecb6e2ec59)

# 作成した Bot

雨が降ってきたら教えてくれて、雨が止んでも教えてくれます。

![1608100682.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363367/f86337a9-0b5f-2efe-2f73-87597b7fa0aa.png)

優しさ(*‘∀‘)

# 作るに当たって必要なもの

- Google アカウント
- Yahoo アカウント
- LINE WORKS アカウント
- 好奇心

# 使用するサービス

- Google Apps Script（略称 GAS）

Google が提供しているスクリプト言語。
開発環境不要で無料で Gooogle のアプリの連携サービスなどが使用できる。

- Yahoo! Open Local Platform（略称YOLP）

Yahoo! JAPAN が提供している地図・地域情報の API。基本無料。
今回は[気象情報 API](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/weather.html) を利用します。

- LINE WORKS トーク Bot API

WORKS MOBILE Japan が提供している[トーク Bot API](https://developers.worksmobile.com/jp/document/3005001?lang=ja)。
無料プランの範囲でトーク Bot が 10個まで登録でき、API も無料で使える。

# 開発手順

1. [Yahoo! Open Local Platform 認証情報の取得](https://developer.yahoo.co.jp/start/)
2. [LINE WORKS 認証情報の取得](https://qiita.com/kunihiros/items/54853e910ed1dff9ebdc)
3. [LINE WORKS Bot の登録](https://qiita.com/kunihiros/items/465e99e491b8be4cabdb)
4. Google Apps Script でコードを書く
5. Google Apps Script Home でトリガーを設定

1 ～ 3 は登録・取得手順のリンクを貼っておきましたのでそちらをご参考くださいませ。

### 1. Yahoo! Open Local Platform 認証情報の取得

[Yahoo! Open Local Platform 認証情報の取得](https://developer.yahoo.co.jp/start/)
必要な認証情報は `Client ID` と `シークレット` です。

![1608087424.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363367/043e68e2-e9e0-67ff-5a18-f2ea63d60d91.png)

### 2. LINE WORKS 認証情報の取得

[LINE WORKS 認証情報の取得](https://qiita.com/kunihiros/items/54853e910ed1dff9ebdc)
必要な情報は `API ID`、`Server API Consumer Key`、`Server List ID`、`認証キー` の４つです。

![1608088823.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363367/27d912d2-bc7e-95dd-4c1f-6a438518a2f8.png)

### 3. LINE WORKS Bot の登録

[LINE WORKS Bot の登録](https://qiita.com/kunihiros/items/465e99e491b8be4cabdb)
登録が完了すると `BotNo` が取得できます。

![1608089119.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363367/ae09dc51-49bd-af01-345e-3f3336e75fbd.png)

### 4. Google Apps Script でコードを書く

[Google Apps Script Home](https://script.google.com/home) にアクセスして「新しいプロジェクト」を作成します。
プロジェクト名は何でも良いのですが、私は `お天気 Bot on Qiita` としました。

![1608089554.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363367/e53707e2-a1d6-efdb-b5d4-92aae6a7e777.png)

#### ライブラリの登録

Google Apps Script には javascript のモジュールみたいに `ライブラリ` という機能があります。これがとても便利。

LINE WORKS の API を使用するにあたり JWT の認証が必要になるのですが、ライブラリを登録しておけば勝手にやってくれます！ヾ(*´∀｀*)ﾉ

1. 「リソース」-「ライブラリ」をクリック
2. 「ライブラリを追加」の欄に `1aLcCr3CWqfenPMyM0_FWIDUgRcTxsit9bO6BTx61NCXrCtkY2zbHBlod` を入力して追加ボタンをクリック
3. 「LINEWORKS」ライブラリが追加されるので、一番新しいバージョンを選んで保存ボタンをクリック

登録したら、取得した認証情報を使ってコードを書いていきます。

```js:コード.gs
// Yahoo! Open Local Platform 認証情報
// LINE WORKS API 認証情報
const CONSTS = {
  'clientId': 'Yahoo! Open Local Platform の clientId',
  'apiId': 'LINE WORKS の API ID',
  'consumerKey': 'LINE WORKS の Server API Consumer Key',
  'serverId': 'LINE WORKS の Server ID',
  'privateKey': 'LINE WORKS 認証キー',
  'botNo': 'LINE WORKS Bot の botNo',
  'accountId': 'Bot を使用する LINE WORKS アカウント'
}
// 東京タワーの緯度、経度
const latitude = '35.658584' // 緯度
const longitude = '139.7454316' // 経度
const coordinates = `${longitude},${latitude}` // 経度・緯度の順番で、コンマ区切りで指定

function weatherFunction() {
  // 日時を取得して成形
  const date = new Date()
  const formatDate = Utilities.formatDate(date,'JST','yyyyMMddHHmm')

  // 気象情報 API の呼び出し
  const defaultUri = 'https://map.yahooapis.jp/weather/V1/place'
  const uri = `${defaultUri}?coordinates=${coordinates}&past=1&output=json&appid=${CONSTS.clientId}&date=${formatDate}`
  const response = UrlFetchApp.fetch(uri)
  const resJson = JSON.parse(response.getContentText())

  // 気象情報 API の結果から10分前の降水量と現在の降水量を取得
  const pastRain = resJson.Feature[0].Property.WeatherList.Weather[5].Rainfall
  const nowRain = resJson.Feature[0].Property.WeatherList.Weather[6].Rainfall
  
  // 現在の降水量と10分前の降水量を比較してメッセージをセット
  let message = ''
  if(pastRain === 0 && nowRain > 0){ message = '☂☂☂雨が降ってきました☂☂☂' }
  else if(pastRain > 0 && nowRain === 0){  message = '☀☀☀雨が止みました☀☀☀' }

  // 天候に変化があればメッセージを送信
  if(message.length) LINEWORKS.sendMsg(CONSTS, CONSTS.accountId, message)
}
```

「自分でもやってみたい！」という方は、認証情報のところを書き換えていただければ使用できると思います(*'▽')

### 5. Google Apps Script Home でトリガーを設定

https://script.google.com/home にアクセスして、お天気 Bot のスクリプトのメニューから [トリガー] をクリックします。

![1608102233.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363367/3911b9ae-fc32-f739-f51d-e3a1017ae70a.png)

[トリガーを追加] を選んで 10分おきにプログラムを実行するようにします。

![1608102382.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363367/b6094b90-80f4-ae25-2ab8-ad45a1ee093d.png)

すると、雨が降ると自動でメッセージが届くようになります。

![1608102912.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363367/95ff834b-6710-a5b7-8603-36f676a15725.png)

これで完成です！やったね♪(*‘∀‘)

# コーディングで苦戦したところ

- テンプレートリテラルが機能しない？？

`uri` のところでテンプレートリテラルを用いて記述しているのですが、文字列に `//` が入っているとうまく読み込みませんでした。

```js
// これだと NG
const uri = `https://map.yahooapis.jp/weather/V1/place?coordinates=${coordinates}&past=1&output=json&appid=${CONSTS.clientId}&date=${formatDate}`
```

仕方ないから `defaultUri` 部分と分けたのですが、悔しいので時間あるときに理由を調べてみたいと思います。

- 現在時刻のデータを間違えて取得してた

ドキュメントよく読みなさいって話なんですが、YOLP の気象情報 API  って指定した時刻から60分後までのデータを取得する API なのですよ。
なので、デフォルトだと `Feature[0].Property.WeatherList.Weather[0]` が現在時刻のデータになります。
なのですが、１時間前からのデータが欲しくて `past` パラメータを `1` にしているので `Feature[0].Property.WeatherList.Weather[0]` は１時間前のデータになるんですよ！( ﾟДﾟ)
なので、コードの通り `Feature[0].Property.WeatherList.Weather[6]` が現在時刻のデータになります。

# おわりに

ここまでお付き合いいただきありがとうございました。

Advent Calendar の時期は「あ、ちょっとやってみようかな」って思わせてくれる記事が多くて助かります。
勉強になりますし、アウトプットもできますし。

また何か良い記事があったら真似してみよーっと！
ではまた！(^^)/

# 参考にさせていただきましたm(_ _)m

[GASで天気のおしらせボットを作った話](https://qiita.com/_nsk_/items/b8b2f71cfbecb6e2ec59)
[Yahoo! Open Local Platform - 気象情報 API](https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/weather.html)
[LINEWORKS Developers](https://developers.worksmobile.com/jp/document?lang=ja)