Go
docker
さくらのクラウド
Slack
docker-machine

さくらのクラウド + Go言語 + Dockerでお手軽Slack Bot

私が普段使っている、さくらのクラウド上にGo言語で書かれたBOTを起動し、Let's encryptを利用してHTTPS化したエンドポイントを手軽に建てるBOT開発環境についてご紹介します。Goのソースコードやスクリプトなど一式は以下で公開しています。

sacloud/slack-bot-template

どんな環境?

  • BOTはGo言語で開発、Dockerコンテナとして起動
  • SlackのInteractive messageのためにエンドポイントをHTTPS化
  • Let's encryptからの証明書取得/更新を自動化するコンテナ

eye_catch.png

この構成は、実際にさくらのクラウド CLI「Usacloud」のリリース用に使っているものを公開できるように切り出したものです。

Usacloudでは以下のようにリリース用にGitHubの操作をするために使っています。
(このテンプレートを元にGitHub操作用の実装を追加してます)

UsacloudでのSlack-BOT利用例

slack_release.png

動機

DevOpsしているとSlack-Botを作りたくなりますよね。Botを作るのであればボタンやリストを使ったインタラクティブなやりとりしたいですよね。

そのためにSlackではInteractive messageという仕組みが用意されています。

これはSlack上にデプロイしたApp(Bot)やスラッシュコマンドから特定のレスポンスを返すことでボタンやリストを使えるようになる仕組みで、やりとりにはWebHookが利用されます。

ただし、このWebHookを受信するためにはパブリックにアクセスできる、有効な証明書を持つHTTPSエンドポイントが必要となります。

参考:Slack: Interactive messageドキュメント

slack_https.png

つまり開発時の動作確認では、手元のマシンで開発 -> 自前のサーバやHerokuなどにアップロードという手順を踏む必要があるということです。さらに自前でマシンを用意するのであればSSL用の証明書の取得/設定が必要となります。

テストであれば手元のマシンをngrokのようなリレー/トンネルしてくれるようなツールを使ってもよいですが、この場合本番移行時にはSlack側のWebHook送信先URLの設定を変える必要があります。ちょっとしたBOTのためにこの辺の作業するのは面倒ですよね。

このあたりをdocker-machine + Let's encryptでの証明書周りの処理をよろしくやってくれるコンテナ(steveltn/https-portal)を使うことで解決しています。

Goで実装するBOTについては、Dockerでビルドすることでソースのサーバへのアップロードをdockerがやってくれます。手元でソース修正 -> docker-compose up -d --buildとするだけですぐに本番環境に反映できちゃいます。

ということで早速使い方を見ていきましょう。

準備/必要なもの

以下はあらかじめ準備しておく必要があります。

使い方

1) docker-machineでサーバ作成

まずはBotを動かす + WebHookを受信するためのサーバをdocker-machineコマンドで作成します。

# docker-machineでサーバ作成(1Core-1GBメモリ、Ubuntu)
docker-machine create -d sakuracloud \
  --sakuracloud-access-token <さくらのクラウド APIアクセストークン> \
  --sakuracloud-access-token-secret <さくらのクラウド APIシークレット> \
  --sakuracloud-os-type ubuntu \
  slack-bot

# DOCKER_HOST環境変数などを作成したサーバに向ける
eval $(docker-machine env slack-bot) 

2) 割り当てられたグローバルIP確認とDNSレコード登録

サーバ作成時にさくらのクラウドにて割り当てられたグローバルIPを確認し、DNSレコードの登録を行っておきます。

# グローバルIPの確認
docker-machine ip slack-bot

確認したグローバルIPをDNSレコード登録しておきましょう。

3) Slack Appの作成

続いてSlack Appの作成を行います。

App作成

以下のURLからSlack Appを作成してください。

https://api.slack.com/apps

op01.png

App Nameは任意のものを入力してください。

op02.png

Botユーザー作成

続いて作成したSlack App用のBotユーザーを作成します。このBotに対してSlack上でメンションすることで動くアプリとするためです。

op03.png

op04.png

ボットの名前や表示名、Online表示などの設定項目がありますが後からでも変更可能ですので適当に設定してください。

op05.png

Interactive messageの有効化

続いてこのAppでInteractive messageを有効化します。

op06.png

op07.png

Request URLには https://<用意しておいたドメイン>/interactionと入力してください。

op08.png

パーミッションの設定 & ワークスペースにアプリをインストール

続いてBotの権限設定とワークスペースへのアプリインストールを行います。

op09.png

今回は必要ないですが、Botに実装する機能によっては追加の権限が必要になることがあります。
画面下の方にScopesという項目がありますので、必要に応じてここでBotに許可する権限を追加してください。
op11.png

その後、画面上の方の「Install App to Workspace」ボタンをクリックします。

op10.png

クリックすると認証画面に遷移しますので確認後「Authorize」ボタンをクリックします。

op12.png

Bot用トークンを控えておく

認証後の画面にOAuthアクセストークンが表示されます。下側のBot用トークンを控えておきましょう。

op13.png

Interactive message用のverification tokenを控えておく

続いて左メニューから「Basic Information」を選ぶとverification tokenが表示されているはずです。こちらも控えておきましょう。

op14.png

チャンネルIDとBotユーザーのIDを調べる

Botが特定のチャンネルで呼びかけられた時のみに応答するために、対象のチャンネルIDとユーザーIDを調べておきます。(この辺りの限定をしない場合は不要ですが)

調べるにはAPIを使うのが楽でしょう。以下のリンクからAPIを叩き確認してください。

チャンネル: API channels.list
ユーザー: API users.list

以上でSlack側の設定は完了です。

4) テンプレートのソースコード一式をダウンロード(クローン)

まずはソースコード類一式をGitHubからクローンします。

git clone https://github.com/sacloud/slack-bot-template.git
cd slack-bot-template

5) トークンなどの環境変数の設定/対象ドメインの設定

トークンなどを環境変数に設定します。
.envというファイルを作成し、そこに環境変数を記入してください。
(雛形としてenv-exampleというファイルをリポジトリ内に用意しています)

mv env-example .env
vi .env
.envの内容
# 以下の環境変数に控えておいたトークンやIDを記入
# Bot用 OAuthトークン(xoxb-で始まるもの)
BOT_TOKEN=<bot-tokenを入力>

# Verificationトークン
VERIFICATION_TOKEN=<verificationトークンを入力>

# BotのユーザーID(Uで始まる文字列)
BOT_ID=<BotIDを入力>

# Botが応答するチャンネルのID(GまたはCで始まる)
CHANNEL_ID=<チャンネルIDを入力>

続いてdocker-compose.ymlを編集し、対象のドメインを記述しておきます。
example.comとなっている部分を自身のドメインに書き換えておきます。

vi docker-compose.yml

###################################
# example.comとなっている部分を任意のドメインに書き換え
###################################

6) 起動!!!

いよいよ起動してみます!

# 起動
docker-compose up -d

このコマンドで、

  • カレントディレクトリの内容をVMに転送(docker build用)
  • Docker上でGoのビルドが行われる
  • コンテナ起動

が行われます。コンテナが起動するとLet's encryptを利用して証明書の取得が行われます。
証明書の更新も自動的に行われるようになっています。

実行

あとは試すだけです。
環境変数に指定したチャンネルでBotに呼びかけてみてください。

# <botの名前が "test-bot"の場合の例>

# メッセージへの応答例
@test-bot message

# Interactive message(ボタン)
@test-bot button

# Interactive message(リスト)
@test-bot list

examples.png

うまくいきましたね?あとはお好みでソースコードの修正などを行ってみてください。

ソースコードの修正を行った場合

ソースの修正を行った場合、以下のコマンドで反映されます。

docker-compose up -d --build

コンテナイメージを再ビルドして実行するだけですね。

終わりに

いかがでしたでしょうか?
Bot作成は日々の運用に合わせて非常に短い時間で頻繁に行うことも多いかと思います。
適当に書捨てる実装で構わないことも多いと思いますのでこういったテンプレートを活用してチャレンジしてみてはいかがでしょうか?

なお、12日目にはこのBotを含むUsacloudなどでのリリースの仕組みの全体像について紹介予定です。お楽しみに!

以上です。

参考情報

GoのBot実装は以下を参考にしました(Thank you!!)。

Mercari Engineering Blog: GolangでSlack Interactive Messageを使ったBotを書く