GoとさくらのVPSでSlackのコマンドを自作する
TL;dr
Slackのスラッシュコマンドを作る
Slackのbotを作る記事は多いですがSlackのスラッシュコマンドを作る記事はなかなかないので。
といっても,参考にさせていただいた以下の記事がとても詳しくてわかりやすいのでそちらを参照してもらったほうがいいかも。
Slackのスラッシュコマンドは以下のような仕組みで動いています。
ユーザーがコマンドを入力する ↓ トークンを付けてサーバーにPOST ↓ サーバーはリクエストのトークンを認証 ↓ リクエストの中身によって処理 ↓ レスポンスを返す ↓ Slackのbotとしてレスポンスを表示
よって,「POSTリクエスト中のトークンを確かめて必要な処理をした結果をレスポンスする」webサーバーを用意すればスラッシュコマンドを自作することができます。
このときのトークンというのはSlackAPIのbot管理画面,App Credentialsタブ内のVerification Token
です。
一般的なwebフレームワークで簡単に作ることができますが,今回はGoとnet/http
ライブラリを用います。
GoでSlackのコマンドを実装する
以前ブログに書いた「部活のための備品管理アプリ」を改良してSlack上で使えるスラッシュコマンドにします。
今回の使用言語はGo。最近のお気に入りです。
GoにはSlackのライブラリがあり,幸運にもスラッシュコマンドを受け付けるための関数群も用意されています。
とりあえず手始めにサンプルプログラムを動かしてみます。
使ったソースはこれ。
https://github.com/hsm-hx/equipper/blob/07b6ee1ed8a94f20fc7290a28f184b3153910d41/src/server.go
ほとんどライブラリのサンプルコードをそのまま使っています。
最初の数行(flag周り)については前回の記事に解説を載せています。
さて,これをgo run
なりgo build
して実行するなりすればサーバーは動くのですが,実際にSlackからのコマンド入力を受け付けるには外部から接続できる場所にサーバープログラムを置かなければいけません。
ここで,さくらのVPSにこのプログラムをデプロイしていきます。
さくらのVPSにデプロイする
幸運にもプロコンのときにいただいたクーポンで借りていたVPSがあったので,動かしていきます。
VPSにはUbuntu16.04をインストールしておきます。また,パッケージとしてgitやgoなど必要なものを適宜インストールして使います。
GitHubからソースをcloneし,go build
します。slackライブラリはgo get
しておかないとエラーが出ます(それはそう)。
実行ファイルは適当なところに置いておいて,端末を閉じても良いようにサーバープログラムをサービス化します。
サービス化の手順については以下リンクを参照。このUnit定義ファイルのExecStart
に実行コマンドを絶対パスで表記します。
場所は/home/ubuntu
とか適当なところで大丈夫です。また,パスの後ろに--token=XXXXX
とトークンを指定しておきましょう。
作ったサービスを実行したら,Slackのbotのコマンド管理画面の設定のRequest URLにhttp://[VPSのアドレス]:3000/hello
と入力して保存します。これで,指定したコマンドをSlackから入力したときに指定したURLにリクエストが飛ぶようになります。
また,さくらのVPSのUbuntuでは標準で/etc/iptables/iptables.rules
の設定が有効になっています。
これを無効化しなければSlackからのリクエストを受け付けることができないみたいです。
詳細は以下のリンクの通り。
ハマったところ
上のiptablesの設定の他に,実行コマンドにトークンを付け忘れるとかをしました(アホ?)。
上の2つやRequest URLが間違っている,のような不具合があると,Slack上でコマンドを実行したときに「何らかのエラーが発生しました。もう一度お試しください!」という曖昧なエラー文を投げつけられます。
まとめ
GoでWebサーバーを立ててVPS上にデプロイしSlack上で動作するSlashコマンドをとりあえず作ることができました。
トークンが一致しているかどうかでちゃんと認証できるので攻撃を防げるのが良いなと思います(小学生か?)。
今後は備品データベースと連携し貸し借りの処理ができる機能を追加したり,延滞の場合に返却を催促する機能を追加していきます。
また,せっかくWebサーバとして動いているので外部から備品の貸借状況を確認できるページも作ります。
ということで,ginを使っていい感じに書き直しつつ機能を追加していきます。
おわり〜