2017年6月8日木曜日

PythonでSlackのボットを作成する

このブログ記事をはてなブックマークに追加

職場でSlackを利用している。なかなか使いやすいし便利だ。しかし、技術者としては与えられた機能を利用するだけではやはり満足できない。自分好みの道具を作りたい。

というわけで、単なるチャットツールとして使うSlackでは物足りなくなったので、Slackのボット(bot)をPythonで作ってみることにした。Hubotのようなボット用フレームワークも利用可能だが、SlackのAPIをガシガシ制御する感じにしたかったので、Slack Real Time Messaging APIをPythonから制御してSlackと連携した。今回は、書き込んだ数字を素因数分解するボットを作ってみた。


まずは、Slack用のボットを利用する準備をする。Slack APIにアクセスして、Bot usersをクリックし、Custom bot usersにあるcreating a new bot userのリンクからBotsのページを開く。 名前(ここでは @prime_decomposition)を入力したらAdd bot integrationボタンをクリックする。







Integration Settingsの画面ではAPI Tokenが表示されており、ボットのスクリプトでこれを利用する。あとは好みに応じてアイコンの変更やボットの説明を記述しておく。今回のボットでは、デフォルトのフェイスマークに用意してあるロボットのアイコンを使い、説明文は「素因数分解をするよ!」とした。あとは、Save Integrationのボタンをクリックして設定を保存する。



ボットの準備ができたら、それをSlackへメンバーとして加える。ボットを参加させたいチャンネル(ここの画像では #general だが #random に参加させたい場合は #random を選択すること)のChannel Settings(歯車のアイコン)から、Invite team members to join...を選択する。先ほど設定したボットがメンバーとして表示されているのでそれを選ぶ。これで下準備は完了だ。



次にPythonを使ってボット用スクリプトを作成する。目的は、Slack上で誰かが数字を書き込んだ際に、それを取得して素因数分解をすること。そのためには、Slackに書き込まれた内容を取得しなければならないが、そのためにslackclientというPythonのモジュールを利用する。

# pip install slackclient

pipであれば上記のコマンドでインストールが終わる。手動で導入する場合は、python-slackclientから入れる。

また、素因数分解プログラムをスクラッチから作るのも面倒なので、数論用ライブラリNZMATH(ニジマス)を利用する。これもpipでインストールできる。

# pip install nzmath

さて、ここまでできたらあとはコードを書くだけだ。Slackからデータを取得する場合は SlackClient.rtm_read() を、書き込みには SlackClient.rtm_send_message([channel, message]) を使う。これらを使うためには SlackClient.rtm_connect() で通信を確立するだけで良い。

以下に簡単な例を書いておく。

sc = SlackClient(TOKEN) if sc.rtm_connect(): r = sc.rtm_read() print r sc.rtm_send_message(u"random", u"こんにちは")

こんな感じ。簡単。

今回のボットの場合、数字を取得してそれを素因数分解する。数字を取得すること自体は上に書いたとおり簡単なのだが、連続して数字が書かれた場合はそれを漏らさないためにキューに保存しておく必要がある。また、一定時間で解けない分解が難しい合成数などを取得した場合、タイムアウトを設定しなければならない。これらを実現するためにはスレッドを使って並列処理をする必要がある。

数字を取得したらキューに入れ、そのキューから別スレッドのworkerスレッドが処理を行う。workerスレッドはキューから数字を一つ取り出し、それの素因数分解を試みる。この時にタイムアウトを考慮するので、この素因数分解を行う関数についてもスレッドを利用する。そのスレッド内で時間を測り、計算が終了しないまま一定時間が過ぎたら処理を強制終了する。

実行方法はネットにつながっているPCから以下のコマンドを実行するだけ。

$ ./prime_decomposition_bot.py

そして、実際のSlack上の画面は以下のようになる。



今回書いたコードは以下の通り。今回は素因数分解をするボットだったが、これをベースに作り変えれば大抵のことはできると思う。


2 コメント:

console commands xcom 2 さんのコメント...

Hey WhiteboardCoder, i've been watching your tutorial and i'm completely new with cURL (I'm a student at the moment, doing HTML/SCSS and entry level PHP) but very interested in just making a small webhook like you're doing in your video. One thing that is still unclear to me, as to how do you save the cURL command? i've been doing some reading and can't seem to figure out how cURL works at all. any help would be greatly appreciated.

alternative to ziploc bags さんのコメント...

Good tips, but I would add 2 more tips...

the single > that makes a quote line, and the >>> that makes all lines as single quote :)