Slackに勉強会情報を垂れ流している話

この記事は[Slack Advent Calendar 2014](http://qiita.com/advent-calendar/2014/slack)最後の記事です。
超ギリギリ(12/25の23時半すぎ)に飛び入りさせて貰いました。

# 概要

Slackに勉強会の情報を垂れ流すツールの紹介です。
(2015/05/18更新しました。主な変更点は対応APIの追加(Meetup, Eventbrite)とtaboo(NGワード)の設定です。)
https://github.com/daikikohara/enotify-slack

![capture01.png](https://qiita-image-store.s3.amazonaws.com/0/36003/09f5b6d0-fec4-afb9-1628-621f879a8ebc.png)


以下のいずれかの場合にイベントの情報をSlackの指定のチャネルに通知します。

* キーワードに一致する単語がイベントタイトルまたは説明に含まれる場合
* ニックネームに一致するユーザがイベントの開催者または参加者に含まれる場合

キーワード/ニックネームの指定は設定ファイルで行います。

なお、上記のキャプチャはSlack社に許可を取って載せています。
また、[こちらのページ](https://api.slack.com/community)に掲載して頂いております。
(2015/05追記)Connpassさんにも[載せてもらいました](http://connpass.com/about/api/)。

# 動機

ATND等の各イベント支援サイトでもフォローしているユーザが参加したイベントや過去に参加したイベントのシリーズだと通知されますが、これだと初回のイベントには気づけないのでキーワードベースで通知したいなぁと思ってました。

また、類似のサービスが色々あることはもちろん存じてますが、仕事中はSlackを見ていることが多く、メールやTwitter等の通知だと気づいたときには埋まってたりするため、Slackに通知するようにしました。

そして何よりGoを勉強中でちょうど良いテーマだと思ったため自作しました。

# 作りの話

ATNDやConnpass等のAPIを定期的に叩いて取得した情報を、Slackの[incoming-webhook](https://my.slack.com/services/new/incoming-webhook)で通知しているだけです。
簡単に使ったツールとAPIを紹介しておきます。

## 使ったツール/ライブラリ

以下を使わせて頂きました。
ありがとうございました。

* [mapstructure](https://github.com/mitchellh/mapstructure)<br>
[HashiCorp](https://hashicorp.com/)のMitchell Hashimoto氏製のライブラリです。
イベントAPIで取得したjsonをstructに変換するときに使ってます。
標準ライブラリと比べてstructへの変換がゆるくできます。
たとえばjson形式で`"id":"123"`とあった場合と`"id":123`とあった場合、標準ライブラリでは前者はstring、後者はintかfloatで扱わないとエラーになりますが、mapstructureでは透過的に扱えます。
最初、connpassとzusaarが殆ど同じjsonフォーマットだけどイベントIDがfloatで返されるのとstringで返されるという違いがあって一つのロジックにまとめたくて使いました。
結局可読性等を考えて全部のAPIごとにstructを分けましたが、上記のような場合でなくとも標準ライブラリと比べて短く書けるのでそのまま使ってます。
* [boltdb](https://github.com/boltdb/bolt)<br>
[LMDB](http://symas.com/mdb/)にインスパイアされたGo製のKVSです。別プロセスを立てず、importするだけで使えます。
一度通知したイベントを再通知しないように管理するために使ってます。
キーをAPI提供者(atndとか)+イベントID、valueは取ってきたjsonのイベント情報をそのまま入れてます。
最初はredisを使ってましたが、一意性の管理だけで別プロセスを立てたくなかったので変更しました。
データ特性的にboltdbが良かったとかはありません。
* [goyml](https://github.com/go-yaml/yaml)<br>
Golangでyamlを使うためのライブラリです。設定ファイルをyml形式にしているため読み込みで使ってます。
* [testify](https://github.com/stretchr/testify)<br>
テストのアサーションがしたくて使いました。有名なので説明は不要かと思います。
テストは標準ライブラリだけで十分って話をよく聞きますが、やっぱりアサーションは簡単にやりたいので使っちゃってます。
* [godep](https://github.com/tools/godep)<br>
依存性の解決に使ってます。これも有名なので説明は不要かと思います。
* [htmlパッケージ](https://godoc.org/golang.org/x/net/html)<br>
一部のAPIのイベント説明文がHTMLタグ付きで返されてしまうので、それを除去するために使いました。 

## 使ったAPI

Slack通知は上記の通り、Hubot等ではなくincoming-webhookを使ってます。

イベント情報の収集には以下を使わせて頂きました。
ありがとうございました。

* ATND
 * [トップページ](https://atnd.org/)
 * [API](http://api.atnd.org/)
* Connpass
 * [トップページ](http://connpass.com/)
 * [API/ロゴ](http://connpass.com/about/api/)
* Doorkeeper
 * [トップページ](http://www.doorkeeper.jp/)
 * [API](http://www.doorkeeperhq.com/developer/api)
* Eventbrite
 * [トップページ](https://www.eventbrite.com/)
 * [API](http://developer.eventbrite.com/)
* Meetup
 * [トップページ](http://www.meetup.com/)
 * [API](http://www.meetup.com/meetup_api/)
* Street Academy
 * [トップページ](http://www.street-academy.com/)
 * [API](http://www.street-academy.com/api)
* Zusaar
 * [トップページ](http://www.zusaar.com/)
 * [API](http://www.zusaar.com/doc/api.html)

### 残念ながらサービス終了になってしまったサイト

* ~~Partake~~
  * ~~[トップページ](http://partake.in/)~~
  * ~~[API](https://github.com/partakein/partake/wiki/PARTAKE-Web-API)~~


# 使い方

[githubのREADME](https://github.com/daikikohara/enotify-slack)を見て頂ければと思います。

# 改善したいところ

* 出力をメールにもできるとかもう少しプラガブルにしたいなと思いました。
勉強も兼ねて自作することにしましたが、もう少し他のツールと組み合わせようかなとかも考えてます。といっても既にメール通知できるサイトは多数あるので、やるとしたらHipChatとかですかね。
<br><br>
* イベント提供サイトへの負荷の軽減<br>
定期的なポーリングは帯域的にもデータ量的にも負荷的にも無駄が多いと思います。
できればイベント提供サイト側で指定キーワード等でpush通知してほしいと思います。
といっても全サイトで対応してくれるとは思えないので、沢山使ってくれる人がいるならツールじゃなくてサービス化した方が良いんだろうな、とかは思います。多分あんまりいないからしないと思いますがｗ

# 最後に

作りました系のエントリーを初めて書きましたが、割と書くことないっすねｗ
github見てね、で終わる気がしましたｗ
でもSlackのAdvent Calendarが埋まって良かったです。

とりあえず、golangもgithubもSlackもQiitaもAdvent Calendarもエンジニアとしても男としても人としても初心者なので、おかしな点があればぜひツッコミ入れて頂ければと思います。