はじめに
Server Side SwiftのwebフレームワークであるVaporのサンプルアプリケーションとして、Slack botの例があります。
そのリポジトリに倣うと、Swiftでとても簡単に Slack bot が作れたので、その方法を紹介します。
事前注意
かなり簡単に作成できた印象で、個人的にはとても面白いのですが、
Vapor自体が日々アップデートをしていっているようなフェーズなため、今回の手順でうまくいかなくなる可能性は大いにあります。
あくまで遊び程度で触るのがいいかなと思います。
サンプルコード
今回作ったサンプルコードはGithub上に上げています。
https://github.com/taji-taji/VaporSampleBot
ゴール
- Slackに投稿したメッセージの任意のテキストに反応して発言するSlack botを
Vapor
を使って作成する。 - 上記をHerokuにデプロイして動かす。
筆者実行環境
- OSX: 10.11.6(15G31)
- Swift: DEVELOPMENT-SNAPSHOT-2016-07-25-a
- Vapor Toolbox v0.8.0
- heroku-toolbelt/3.43.9
前提
-
vapor
コマンドが使用できること-
こちらのドキュメントを参考に、
vapor
コマンドが使える環境を整えてください。
-
こちらのドキュメントを参考に、
- Slackアカウントを持っていること
- Herokuのアカウント・Toolbeltを持っていること
- ローカルmac上で動かすだけなら不要です。
1. 準備
SlackでBot Userを作る
- 以下のURLからBotのアカウントを作成します。
- 作成が完了すると、Botアカウントの
API Token
が取得できます。あとで使用するので、これをメモっておきます。(メモらなくても後からでも確認できます。)
2. プロジェクトの作成
作業ディレクトリ直下でVaporのアプリケーションのプロジェクトを作成します。
$ vapor new {プロジェクト名}
作成したら、プロジェクトの直下に移動します。
$ cd {プロジェクト名}
例)筆者の場合
$ vapor new VaporSampleBot
$ cd VaporSampleBot
3. サンプルアプリのコードをダウンロード
Vaporのサンプルアプリのコードを雛形として使用するため、以下のリポジトリからサンプルアプリのコードをダウンロードし、先ほど作ったプロジェクトにコードを置き換えていきます。
Sourceコードの置き換え
2で作成したプロジェクト直下のApp
フォルダ内のファイル・フォルダを全て、ダウンロードしたサンプリアプリのSourceフォルダ内のファイルに置き換えます。
Packageファイルの変更
次に、2で作成したプロジェクトのPackage.swift
を次のように変更します。
import PackageDescription
let package = Package(
name: "VaporSampleBot",
dependencies: [
.Package(url: "https://github.com/vapor/tls-provider", majorVersion: 0, minor: 4)
],
exclude: [
"Config",
"Database",
"Localization",
"Public",
"Resources",
"Tests",
]
)
4. 設定ファイルの作成
プロジェクト直下のConfigフォルダの下にbot-config.json
を作成し、準備の項で取得したSlack botのAPI Tokenを以下のように記述します。
{
"token": "xcxb-your-api-key-here",
}
ローカルmac上で動かす際には上のように直接文字列としてAPI Tokenを指定すればいいですが、
実際にherokuにデプロイする際には、環境変数として設定するため、次のような記述になります。
{
"token": "$BOT_TOKEN",
}
注意点
mac上で動かす際に、tokenの値を$BOT_TOKEN
とすると、以下のような設定値が取得できないエラーが出てしまいます。
fatal error: Error raised at top level: App.BotError.missingConfig
5. ローカルで動かしてみる
まず、ビルドしてみましょう。
$ vapor build
Fetching Dependencies [Done]
Building Project [Done]
うまくビルドできれば上のようになります。
それでは動かしてみましょう。
$ vapor run
うまくつながれば、次のような感じでwssで繋がった様子が表示されるかと思います。
Running VaporSampleBot...
Connected to wss://mpmulti-5..[略]
さあ、それではSlackのbotがいるチャンネルかbotユーザーへのダイレクトメッセージで「hello bot!」と発言してみましょう!
6. Herokuへのデプロイ
Procfileの変更
プロジェクト直下のProcfileを変更します。
「web」から「worker」にすればOKです。
worker: App --env=production --workdir="./"
Herokuでアプリケーション作成
Heroku Git の設定
アプリケーション作成後の画面に従ってこの設定ができるかと思うので、設定を進めてください。
Herokuの各種設定
Slack bot の API Token
$ heroku config:set BOT_TOKEN=xoxb-00000000000-XXXXXXXXXXXXXXXXXXXXXXXXX
buildpackの設定
$ heroku buildpacks:set https://github.com/kylef/heroku-buildpack-swift
herokuへpushしてデプロイ
$ git push heroku master
デプロイには数分かかります。しばらく待ちましょう。
dynoをscale
次のコマンドでdynoを起動します。
$ heroku ps:scale worker=1
Herokuの管理画面で下のようになっていればOKです。
(画面上に反映されるまで若干のタイムラグがあるかもしれないです。)
7. 動作確認
5でローカルで動作させた時と同様に、Slackのbotがいるチャンネルかbotユーザーへのダイレクトメッセージで「hello bot!」と発言してみましょう!
うまく返事が返って来ればOKです!
お疲れ様でした
Advanced
反応する言葉や返信内容を変えたい時
おそらくコード見れば分かるので書くまでもないかと思うのですが、、
App/main.swift
の次の箇所を自分好みに変えていけばいいですね。
// ~略~
ws.onText = { ws, text in
print("[event] - \(text)")
let event = try JSON(bytes: text.utf8.array)
guard
let channel = event["channel"]?.string,
let text = event["text"]?.string
else { return }
if text.hasPrefix("hello") {
let response = SlackMessage(to: channel, text: "Hi there 👋")
try ws.send(response)
} else if text.hasPrefix("version") {
let response = SlackMessage(to: channel, text: "Current Version: \(VERSION)")
try ws.send(response)
}
}
// ~略~
例えば、次のように変更をすると、
// ~略~
ws.onText = { ws, text in
let event = try JSON(bytes: text.utf8.array)
guard
let channel = event["channel"]?.string,
let text = event["text"]?.string
else { return }
if text.contains("すし") {
let response = SlackMessage(to: channel, text: "🍣")
try ws.send(response)
}
}
// ~略~
このような感じになります。
その他
bot-config.json
について
4で作成したbot-config.json
のtoken
の値ですが、前述の説明では、
「ローカルで動かす時は値を直接書いて、Herokuにあげる時は $BOT_TOKEN
と書く」
という説明になっていますが、ローカルのmacでも、環境変数としてBOT_TOKEN
を設定すればコードの書き換えを行うことなくできます。
$ export BOT_TOKEN=xoxb-00000000000-XXXXXXXXXXXXXXXXXXXXXXXXX
また、当然ただの環境変数なのでBOT_TOKEN
という名前でなくでも大丈夫です。
ただし、変更する場合はコード上の環境変数を表す文字列とローカル環境・リモート環境(Heroku)の環境変数も変更することを忘れないようにしないといけません。
Reference
- Vapor の Docs
- Vapor の Slack bot リポジトリ
- Vapor製の Slack bot 「penny」のリポジトリ