住所と緯度経度を教えてくれるChatbot作った

G suiteアカウント向けにリリースされたHangouts Chatでは、誰でも簡単にbotが作れちゃうとか。

せっかくなんで何か社内業務に課題でもないかガサ入れしていたら、
「ある施設の緯度と経度をググってコピペする…」という単純作業を泥臭く繰り返していたので、
コイツを効率化すべく、投げかけた施設の住所・緯度経度とついでに検索時のGoogle MapのURLを返してくれるbotを
Google Apps Scriptで実装しました。

# いいからコード見せろ
はい。


```javascript
function onAddToSpace(event) {
  if (event.space.type == "DM") {
    var name = event.user.displayName;
    return {
      text: "@" + name +
      " さん、追加ありがとうございます。場所の名前を入力してみてください。"
    };
  } else {
    return {
      text: event.space.displayName + "への追加ありがとうございます。場所の名前を入力してみてください。"
    }
  }
}

function onMessage(event) {
  // Creates a new Geocoder object.
  var geocoder = Maps.newGeocoder();
  // Creates a Geocoder with the language set to Japanese.
  geocoder = geocoder.setLanguage('ja');

  var msg = event.message.argumentText;
  // Delete Space
  msg = msg.replace(/ /g, '');

  var response = geocoder.geocode(msg);

  for (var i = 0; i < response.results.length; i++) {
    var result = response.results[i];
  }

  if (result){
    return {
      text: "住所： " + result.formatted_address
      + "\n" + "緯度： " + result.geometry.location.lat
      + "\n" + "経度： " + result.geometry.location.lng
      + "\n" + "URL： https://www.google.co.jp/maps/search/" + msg + "/"
           };
  } else {
    return {
      text: "結果が出力できませんでした。 \n 入力内容をお確かめの上、再度入力してください。"
    };
  }
}

function onRemoveFromSpace(event) {
  return {
    text: "退出します。"
  };
}
```

# コード解説

簡単に言うと、Hangouts Chat APIのなかでGeocoding APIを呼んでいます。

## Hangouts Chatの部分
[Hangouts Chat APIの公式ドキュメント](https://developers.google.com/hangouts/chat/how-tos/bots-apps-script)に「メッセージをそのままオウム返しするbot」のスクリプトが載っているので、
まずはそのコードをGASで実装します。
受け取ったメッセージ `event.message.argumentText` を、そのあとの処理でゴチャゴチャいじくり回していく感じ。
ちなみにメッセージのバラし方も[公式リファレンス](https://developers.google.com/hangouts/chat/reference/message-formats/events)にて解説してくれてます、親切ぅ！

## Geocode部分
[Class Geocoderの公式リファレンス](https://developers.google.com/apps-script/reference/maps/geocoder)を参考に、
`formatted_address`(住所)、`geometry.location.lat`(緯度)、`geometry.location.lat`(経度)と、
ついでにGoogle Mapでの検索URLを返してくれます。

`newGeocoder()`オブジェクトに日本語を設定（`.setLanguage('ja')`）しておくと、`formatted_address`で出力される住所が日本語になります。
設定しないと英語で帰ってくる。読みづらッ！
![address_eng.png](https://qiita-image-store.s3.amazonaws.com/0/143784/4441a393-7a94-ac9f-1faf-ccc572f40104.png)

そしてDMでなくグループで遣われた場合、送られるメッセージは「@botname 施設名」になりますが、
この時の`event.message.argumentText`の値が` 施設名`。チクショウ。
なので余計な半角スペースを`.replace`で消しちゃいます。
この辺の処理の手軽さはjsの便利なところですね。

そしてそしてちゃんと`result`の値が`true`かの判定を入れておかないと、
Geocodeに失敗したら「応答がない」と応答が帰ってくるので注意。
![latlng_err.png](https://qiita-image-store.s3.amazonaws.com/0/143784/0a7152a9-1860-2022-6766-6e724b8cf7da.png)


## いざ、デプロイ。
[【GAS】Hangouts Chat botsをGoogle Apps Scriptで試してみた](https://webird-programming.tech/archives/624)に詳細な手順を書いてくれていたので、この記事に従いデプロイ。
ぶっちゃけ本botの作成自体がこの記事のおかげです、ありがとうございます！

なお、自分（GASの所有者）以外の同ドメインのG Suiteアカウントでもこのbotを使えるようにするには、
1. 作成したGASの実行権限の付与![iam_mng2.png](https://qiita-image-store.s3.amazonaws.com/0/143784/adf0c0e9-f951-35e5-a75e-60129984e440.png)
2. bot自体のインストール権限の付与![gcp.png](https://qiita-image-store.s3.amazonaws.com/0/143784/81419098-be52-3189-6234-4c995ad3f09a.png)
が必要です。


# 挙動したらこーんな感じ。

![latlng01.png](https://qiita-image-store.s3.amazonaws.com/0/143784/01fd3e07-8ed3-dbc9-71a5-d03cf14e315b.png)
住所でもイケます。
![latlng02.png](https://qiita-image-store.s3.amazonaws.com/0/143784/b99e8605-4ff6-655e-1167-bdd5638a8ac7.png)


[gist](https://gist.github.com/Kento-E/bef453d12162fae44af4e023622e324a) にて、割愛した部分を含むソースを公開しています。

[Class Geocoderの公式リファレンス](https://developers.google.com/apps-script/reference/maps/geocoder)には`reverseGeocode`(緯度・経度から住所を出す、いわゆる"逆"Geocode)もあるみたい。
そっちの需要も（たま～に）あるので、メッセージが数値かどうかで`geocode(msg)`するか`reverseGeocode(msg)`するかの判定を追加したら、同じbot上で両方のGeocode処理ができそう。