勉強会情報をpush通知するslackアプリを作った

# はじめに
勉強会の情報を定期的にpush通知してくれるslackアプリを作った。

こんな感じでpush通知したい勉強会の条件を設定すると、

![study.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/a292bae9-c3dc-6519-f411-f9489bd40b36.gif)


条件に合致した勉強会が、設定した時刻に定期的に通知される。

<img width="683" alt="スクリーンショット 2020-03-22 21.39.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/f1b9e7db-7fc6-fd8e-6e22-183868f76be6.png">
# モチベーション
大きめの勉強会や人気の勉強会の開催を、qiitaのトレンド記事やはてブの記事に挙げられてるのを見て、後から知ることが結構ある。そういう人気の勉強会をpush通知してくれるような仕組みがあれば「やってたの知らなかった」ってことを減らせそうだと思ったので作ってみた。

アーキテクチャは以下の理由からherokuを使うことにした。
- サーバー代が無料
- dockerでのデプロイに対応してる
- スケジューラの仕組みもある

需要があるかわからないが、他の人もこの仕組みを使えるように環境構築の手順を書いていく。

# 構築手順

## ０） 事前にやっておくこと
- herokuのアカウントの用意
- herokuのcliをインストールしておく

```terminal
$ brew tap heroku/brew && brew install heroku
```

- [コード](https://github.com/pokotyan/study-slack)をローカルへクローンしておく。
- slackアプリを作成し、ワークスペースへ追加しておく。
[やり方はこの記事とかが参考になる](https://qiita.com/ykhirao/items/3b19ee6a1458cfb4ba21#1-%E3%82%A2%E3%83%97%E3%83%AA%E4%BD%9C%E6%88%90)

## 1） herokuへのリリース
事前にherokuのアカウントがない人は作っておく。

```bash

# 事前にアプリケーションのルートディレクトリに移動しておく
$ heroku container:login                                 # ログイン
$ heroku create -a app_name                              # herokuアプリの作成。アプリ名は適当に決める。(heroku内で一意なアプリ名である必要あり)
$ heroku git:remote -a app_name                          # herokuリポジトリをgit登録。
$ heroku addons:create scheduler:standard                # スケジューラのアドオンを追加（事前にherokuアカウントにクレジットカード登録が必要）
$ heroku addons:add cleardb:ignite                       # mysqlのアドオンを追加
$ heroku config                                          # CLEARDB_DATABASE_URLが登録されていることを確認
$ heroku config:set DATABASE_URL="<ユーザー名>:<password>@tcp(<ホスト名>:3306)/<DB名>?parseTime=true" # CLEARDB_DATABASE_URLの値を元にgolangのsql.Open()に渡す用の文字列に整形
$ heroku config:set SLACK_TOKEN="<slackのトークン>"        # slackアプリのトークンを環境変数に設定
$ heroku config:set WEB_HOOK_URL="<slackのwebHookURL>"   # slackのwebHookURLを環境変数に設定
$ heroku stack:set container                             # heroku.ymlを使う時はこれがいるぽい
$ git push heroku master                                 # リリース
```

## 2） slackの設定
作成しておいたslackアプリの設定画面に移動しておく。

### 2-1) slashコマンドの設定
通知する勉強会の条件設定は、slashコマンド経由で開くダイアログから行うようにしている。
そのslashコマンドの設定をしていく。

- コマンドを新規作成
<img width="977" alt="スクリーンショット_2020-03-22_18_42_14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/9af73710-4167-3597-295e-ee96d10c9e71.png">

- コマンド実行時のAPI先を設定
<img width="681" alt="スクリーンショット_2020-03-22_18_42_29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/f81bb764-a0ea-c9d9-71a0-04a181291a32.png">

### 2-2) Interactive Componentsの設定
勉強会の条件設定をするダイアログをsubmitした際に叩くAPI先の設定。

<img width="954" alt="スクリーンショット_2020-03-22_18_53_12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/26c26d10-9b99-150c-4202-4aee484ebe78.png">

## 3） スケジューリングの設定
herokuの画面に行って、スケジューラーのアドオンをクリック

<img width="635" alt="スクリーンショット_2020-03-22_19_04_21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/089492ad-0ac4-89b4-cbf5-aab47e23009a.png">

`/main connpass slack` を実行するジョブを作成する。実行間隔はお好みで。
<img width="414" alt="スクリーンショット 2020-03-22 19.06.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/6dbf4bf6-0872-c925-e015-886e13ffb6cf.png">


## 4） 勉強会通知の設定をする
作成したslashコマンドを実行し、開いた設定ダイアログ上で通知条件の設定をする。

<img width="532" alt="スクリーンショット 2020-03-22 19.10.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131625/2ffe36e9-2aaa-20a9-db8d-00b29b732b08.png">
※注意
herokuの無料プランだと、30分たつと自動でプロセスが落とされる。
なので初回のslashコマンドはサーバー起動の時間が掛かるのでタイムアウトで失敗する。その後あまり間を空けずに再度slashコマンドを実行すればダイアログが開く。


## 5） 設定完了
ここまでやれば、herokuの環境変数で設定したwebHookURL宛てに、勉強会情報が定期的にポストされるようになる。

# アーキテクチャ
golang、gin、docker、mysql、slack api、connpass api、herokuな感じで作っている。

一つのイメージでapiサーバーとしてもコマンド実行サーバーとしても起動させたかったため、起動時にフラグを渡すことでapiサーバー、コマンド実行サーバーが切り替わるようにしている。

また、ホットリロードのツールに [air](https://github.com/cosmtrek/air) を使っている。
goでホットリロードといえば [realize](https://github.com/oxequa/realize) が使われているのをよく見かけるが、realizeはmodulesに対応していなかったり、最近メンテもされなくなったりと微妙な感じ。いいのが他にないのかなと思っていたが、最近はairが流行ってきてる？ぽい。