Go で slack bot

Kohei Yoshida
4 min readDec 29, 2019

--

slack bot 作成にあたり、いい感じの記事がなかったので自分で書くことにした。
やりたいこと、API の話、簡単な導入をまとめる。

やりたいこと

slack チャンネルに bot を入れておき、特定の文字列を検知したら反応する、という bot を作りたかった。
このとき、bot をメンションしたり、スラッシュでコマンドを認識することなく、正規表現かなんかでマッチしたものを勝手に拾って処理したいという目的があった。
そもそもできるのか?という部分もあったが、結論から述べると実現可能な話だった。

API について

一番単純な Incoming Webhook では、Webhook URL というエンドポイントに json 形式のデータを投げれば bot から何かを投稿することができる。
ただ、今回はチャンネル内の発言を何らかの「イベント」として検知し、その内容を正規表現にかけたいというもの。

Event について

slack では Events APIReal Time Messaging API (以下 RTM) という 2 種類の形で Event を扱うことができる。
簡単には以下のような違いがある。

  • Events API は、イベントが発生するたびに HTTP ベースのイベントを push するもの
  • RTM API は、websocket のコネクションを持っておき、その上で各イベントを publish するもの

どちらもリアルタイムで処理は可能だが、イベントの取り扱いやすさやコネクションの管理などでどちらを利用するかが変わってくる。
また、イベントによってはどちらか片方のみの対応だったりするので、実際に自分が利用したいイベントに応じてここは要検討の必要がある。
具体的な対応表については、以下を参考にして欲しい。

API Event Types
https://api.slack.com/events

とりあえず今回は message event だけあればよかったので、どちらを利用しても問題なかった。
長時間保持されるコネクションを管理するのが面倒だったので、今回は Events API を利用することにした。

実装

タイトルにある通り Go で書く。
素晴らしいライブラリがあったのでそのまま利用させていただいた。

nlopes/slack
https://github.com/nlopes/slack

最小限とも呼べるコードは以下のような形になる。

環境変数

var token = getenv("SLACKTOKEN")
var vtoken = getenv("VTOKEN")
var botname = getenv("BOTUNAME")
  • SLACKTOKEN
    Bot User OAuth Access Token が入っている。
    Features > OAuth & Permissions から確認可能。
  • VTOKEN
    Verification Token が入っている。
    Basic Information > App Credentials から確認可能。
  • BOTUNAME
    App のユーザーネームが入っている。
    認証に必要なわけではなく、bot 自身の投稿に反応しないように用意したもの。
    PostMessage で適当なメッセージを投稿してデータを確認したが、もっと簡単に見る方法があるかも。
    1/4 追記: 以下の API で見れる。ブラウザからテストの実施も可能。
    https://api.slack.com/methods/users.list

その他

http.HandleFunc("/events-endpoint", func(…と記載のある通り、/events-endpoint の path で受け付ける。
また、ポートは 3000 番で受け付けている点に注意。

if eventsAPIEvent.Type == slackevents.URLVerification の部分で、認証を行う。 このまま利用可能。

slack 側設定

イベントを発行するには slack 側で Event Subscription を有効にしないといけない。
設定画面の Features > Event Subscriptions から有効にできる。

ご覧の通り、エンドポイントを用意する必要があるので、そこは各自でよしなに。
エンドポイントを設定し、認証後、有効にしたいイベントを選択する。
(下の Subscribe to bot events > Add Bot User Event から)

今回は message.channels だけ有効にすれば問題ない。

動作

$ go build bot.go
$ ./bot

これだけでよし!
デーモン化するなりコンテナ上で動かすなり、あとはお好きに。

--

--