Swift がオープンソース化して、Linux、OSX両方で動くコードを書けるようになったので、Slackのボットに挑戦してみました。
tomohisa/SwiftSlackBotter: Bot Framework for Swift Linux Command Line
以下はReadmeの意訳です。
SwiftSlackBotter
SwiftSlackBotter はLinux、OSXで動くSlackボットのためのフレームワークです。 J-Tech Creations, Inc. により作成されました。
SwiftSlackBotter はSwiftのための Slack Bot フレームワークです。オープンソース版の DEVELOPMENT-SNAPSHOT-2016-02-08-a Swift を使用する必要があります。Zewo フレームワークのバージョン 0.3、Environment フレームワークのバージョン 0.1 を使用しています。
Zewo/Zewo: Open source libraries for modern server software.
czechboy0/Environment: Easy access to environment variables from Swift. Linux & OS X ready.
環境設定方法
ここでは、OSX環境の設定方法を書いています。Linuxでのビルド方法は、各ツールのページから見つかります。
(Linuxのビルドはまだ試していません)
Homebrew のインストール(まだの場合)
Homebrew — The missing package manager for OS X はOS Xのパッケージマネージャーです。
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
Swift Env のインストール
kylef/swiftenv: Swift Version Manager はSwiftのコマンドライン環境の選択ツールです。今のバージョンのSwiftSlackBotterは古いバージョンの開発ツールを使う必要があるので、SwiftEnvで切り替えられるようにすることをお勧めします。
Home-brewを使ってインストールできます。
$ brew install kylef/formulae/swiftenv
環境変数に必要な情報を追加します。
$ echo 'if which swiftenv > /dev/null; then eval "$(swiftenv init -)"; fi' >> ~/.bash_profile
ZSHなどの場合は違うのでご注意ください。
Swiftのオープンソースパッケージのインストール
SwiftEnvで2016/2/8版のパッケージを以下のようにインストールできます。
$ swiftenv install 2.2-SNAPSHOT-2016-02-08-a
Zewoのランタイムのインストール
Zero はLinux、OS X環境で動くたくさんのパッケージをリリースしています。Apple製のフレームワークが、Linux版がリリースしていないため、Linuxでも動くバイナリを作るために、OSXとLinuxで共通で存在するライブラリに対するC言語のリンクを作成しています。そのため、関連するフレームワークを一括してHomebrewでインストールするための機能が準備されています。現在、SwiftSlackBotterではZewoの0.3でタグ付けされた機能を使用しています。詳しくはZewoのどきゅめんとをご覧下さい。Zewo/Zewo: Open source libraries for modern server software.
brew install zewo/tap/zewo
これでボットを作るための準備ができました。
最初のボットを作る
まず、新しいフォルダを作ります。
mkdir SwiftBotSample && cd SwiftBotSample
そして、2016-2-8版のSwiftコマンドラインスナップショットを取得します。
swiftenv install DEVELOPMENT-SNAPSHOT-2016-02-08-a
swiftenv local DEVELOPMENT-SNAPSHOT-2016-02-08-a
SPM – Swift Package Manager を使用してプロジェクトのテンプレートを作ります。
$ swift build --init
Creating Package.swift
Creating .gitignore
Creating Sources/
Creating Sources/main.swift
Creating Tests/
以下の構成で、swiftのコマンド実行環境のテンプレートを作られます。
.
├── Package.swift
├── Sources
│ └── main.swift
└── Tests
Package.swift を開いて、SwiftSlackBotterのgitアドレスを依存関係に設定します。
import PackageDescription
let package = Package(
name: "SwiftBotSample",
dependencies: [
.Package(url: "https://github.com/tomohisa/SwiftSlackBotter.git", majorVersion: 0, minor: 1),
]
)
これでボットのコードを書き始められます。[Sources/main.swift]を開いて、以下のシンプルなボットを書いてみます。
import SwiftSlackBotter
do {
let bot : Bot = try Bot()
bot.addObserver(DefaultEventObserver(onMessage:{
(message:MessageEvent,bot:Bot) in
try bot.reply("hello - " + bot.botInfo.userRealNameFor(message.user),event:message)
}))
try bot.start()
} catch let error {
print("Error Occured \(error)")
}
このコードは、以下のことを行います。
- rtm.start method | Slack に接続して、WebSocketのURLを取得
- BotとしてWebSocketでSlackに接続
- Botに送られたメッセージを取得
- Botがメッセージを受け取ったら、[Hello – {コメントしたユーザーの名前}]と返信
シンプルなボットですね。
Slack側の設定
Slackで以下の準備が必要です。
- Bot Users | Slack を参考にしてBoユーザーを作成して、Tokenを取得
- Tokenを環境変数に保存
以下の一文を~/.bash_profileに加えて、terminalを再起動します。
export SLACK_BOT_TOKEN=xoxb-YOUR_SLACK_TOKEN
ビルドと実行
ビルドは以下のコードで行います。
swift build -Xcc -I/usr/local/include -Xlinker -L/usr/local/lib
2016/4/14 時点では、ビルド時の出力は以下のとおりです。
Cloning https://github.com/tomohisa/SwiftSlackBotter.git
Using version 0.1.8 of package SwiftSlackBotter
Cloning https://github.com/Zewo/WebSocket.git
Using version 0.3.1 of package WebSocket
Cloning https://github.com/Zewo/HTTP.git
Using version 0.3.0 of package HTTP
Cloning https://github.com/Zewo/Stream.git
Using version 0.2.0 of package Stream
Cloning https://github.com/Zewo/Data.git
Using version 0.2.2 of package Data
Cloning https://github.com/Zewo/System.git
Using version 0.2.0 of package System
Cloning https://github.com/Zewo/MediaType.git
Using version 0.3.1 of package MediaType
Cloning https://github.com/Zewo/InterchangeData.git
Using version 0.3.0 of package InterchangeData
Cloning https://github.com/Zewo/URI.git
Using version 0.2.0 of package URI
Cloning https://github.com/Zewo/CURIParser.git
Using version 0.2.0 of package CURIParser
Cloning https://github.com/Zewo/String.git
Using version 0.2.6 of package String
Cloning https://github.com/Zewo/CHTTPParser.git
Using version 0.2.0 of package CHTTPParser
Cloning https://github.com/Zewo/HTTPClient.git
Using version 0.3.0 of package HTTPClient
Cloning https://github.com/Zewo/TCP.git
Using version 0.2.2 of package TCP
Cloning https://github.com/Zewo/IP.git
Using version 0.2.1 of package IP
Cloning https://github.com/Zewo/Venice.git
Using version 0.2.2 of package Venice
Cloning https://github.com/Zewo/CLibvenice.git
Using version 0.2.0 of package CLibvenice
Cloning https://github.com/Zewo/HTTPSClient.git
Using version 0.3.0 of package HTTPSClient
Cloning https://github.com/Zewo/TCPSSL.git
Using version 0.2.0 of package TCPSSL
Cloning https://github.com/Zewo/OpenSSL.git
Using version 0.2.4 of package OpenSSL
Cloning https://github.com/Zewo/COpenSSL-OSX.git
Using version 0.2.0 of package COpenSSL-OSX
Cloning https://github.com/Zewo/File.git
Using version 0.2.5 of package File
Cloning https://github.com/Zewo/Event.git
Using version 0.2.0 of package Event
Cloning https://github.com/Zewo/Base64.git
Using version 0.2.1 of package Base64
Cloning https://github.com/Zewo/JSON.git
Using version 0.3.1 of package JSON
Cloning https://github.com/czechboy0/Environment.git
Using version 0.1.0 of package Environment
Cloning https://github.com/Zewo/Log.git
Using version 0.3.0 of package Log
Compiling Swift Module 'System' (1 sources)
Linking Library: .build/debug/System.a
Compiling Swift Module 'Data' (1 sources)
Linking Library: .build/debug/Data.a
Compiling Swift Module 'Stream' (1 sources)
Linking Library: .build/debug/Stream.a
Compiling Swift Module 'InterchangeData' (1 sources)
Linking Library: .build/debug/InterchangeData.a
Compiling Swift Module 'MediaType' (1 sources)
Linking Library: .build/debug/MediaType.a
Compiling Swift Module 'String' (1 sources)
Linking Library: .build/debug/String.a
Compiling Swift Module 'URI' (1 sources)
Linking Library: .build/debug/URI.a
Compiling Swift Module 'HTTP' (23 sources)
Linking Library: .build/debug/HTTP.a
Compiling Swift Module 'Venice' (16 sources)
Linking Library: .build/debug/Venice.a
Compiling Swift Module 'IP' (2 sources)
Linking Library: .build/debug/IP.a
Compiling Swift Module 'TCP' (7 sources)
Linking Library: .build/debug/TCP.a
Compiling Swift Module 'HTTPClient' (1 sources)
Linking Library: .build/debug/HTTPClient.a
Compiling Swift Module 'File' (3 sources)
Linking Library: .build/debug/File.a
Compiling Swift Module 'OpenSSL' (15 sources)
Linking Library: .build/debug/OpenSSL.a
Compiling Swift Module 'TCPSSL' (2 sources)
Linking Library: .build/debug/TCPSSL.a
Compiling Swift Module 'HTTPSClient' (1 sources)
Linking Library: .build/debug/HTTPSClient.a
Compiling Swift Module 'Event' (2 sources)
Linking Library: .build/debug/Event.a
Compiling Swift Module 'Base64' (1 sources)
Linking Library: .build/debug/Base64.a
Compiling Swift Module 'WebSocket' (5 sources)
Linking Library: .build/debug/WebSocket.a
Compiling Swift Module 'JSON' (5 sources)
Linking Library: .build/debug/JSON.a
Compiling Swift Module 'Environment' (1 sources)
Linking Library: .build/debug/Environment.a
Compiling Swift Module 'EnvironmentTests' (1 sources)
/Users/tomohisa/Desktop/SwiftBotSample/Packages/Environment-0.1.0/Sources/EnvironmentTests/main.swift:9:63: warning: __FUNCTION__ is deprecated and will be removed in Swift 3, please use #function
guard let path = Environment().getVar("PATH") else { return (__FUNCTION__, false) }
^~~~~~~~~~~~
#function
/Users/tomohisa/Desktop/SwiftBotSample/Packages/Environment-0.1.0/Sources/EnvironmentTests/main.swift:10:10: warning: __FUNCTION__ is deprecated and will be removed in Swift 3, please use #function
return (__FUNCTION__, !path.isEmpty)
^~~~~~~~~~~~
#function
/Users/tomohisa/Desktop/SwiftBotSample/Packages/Environment-0.1.0/Sources/EnvironmentTests/main.swift:16:10: warning: __FUNCTION__ is deprecated and will be removed in Swift 3, please use #function
return (__FUNCTION__, val == "FUZZY")
^~~~~~~~~~~~
#function
/Users/tomohisa/Desktop/SwiftBotSample/Packages/Environment-0.1.0/Sources/EnvironmentTests/main.swift:22:40: warning: __FUNCTION__ is deprecated and will be removed in Swift 3, please use #function
guard val == "FUZZIER" else { return (__FUNCTION__, false) }
^~~~~~~~~~~~
#function
/Users/tomohisa/Desktop/SwiftBotSample/Packages/Environment-0.1.0/Sources/EnvironmentTests/main.swift:25:10: warning: __FUNCTION__ is deprecated and will be removed in Swift 3, please use #function
return (__FUNCTION__, valFinal == nil)
^~~~~~~~~~~~
#function
Linking Executable: .build/debug/EnvironmentTests
Compiling Swift Module 'Log' (1 sources)
Linking Library: .build/debug/Log.a
Compiling Swift Module 'SwiftSlackBotter' (12 sources)
Linking Library: .build/debug/SwiftSlackBotter.a
Compiling Swift Module 'SwiftBotSample' (1 sources)
Linking Executable: .build/debug/SwiftBotSample
以下のコマンドで実行します。
.build/debug/SwiftBotSample
Botが実行され、起動すると、SlackのDirect MessagesのBotユーザーの印が緑色になります。ボットに話しかけるには2つの方法があります。
- Direct MessagesでBotに話しかける
- BotをPublicチャンネルか、Privateチャンネルに招待します。Botは招待されたチャンネルのメッセージだけが配信されます。
今のコードだと、誰かが会話するとBotは(Hello - (話したユーザーの名前))と話しかけます。
これから
今のフレームワークは現在の特定のプロジェクトの必要に合わせて作成されています。現在も拡張性を考えて作成されていますが、さらに機能を追加して色々な状況で使えるようにしていきたいと思います。
- 会話の定義
- タイマー機能
- Slackアプリへの対応
Apple Swift チームと Zewo / OpenSwift チームには良いフレームワークと環境を作ってくださり感謝しています。
「Swiftでボットを作るためのフレームワークをオープンソース化しました」への2件のフィードバック