Pythonを使ったSlackBotの作成方法


## 前書き（飛ばしていいです）
### slackbotといえばhubot！
そんなふうに考えていた時期が俺にもありました

[このへん](https://hubot.github.com)とか[このへん](http://gihyo.jp/dev/serial/01/hubot/0001)とか読んでみるといいよ！
いいよ！

Hubotは ~~髪！~~ 神！

### とはいえ、今から CoffeeScript を学ぶのは難しい。
なにせ、プロトタイプ作成納期が21日（作ることになったのが18日の日が落ちたあと）。
やってやれないこともないだろうけど、実装する機能の勉強時間を考えるとかなり厳しい。
アドベントカレンダーも書かなきゃいけないし。

いずれHubotに載せ替えるとしても、今はPythonでやりたい。

### あります。あるんです。Pythonで使えるSlackbotライブラリが！
[PythonのslackbotライブラリでSlackボットを作る](https://qiita.com/sukesuke/items/1ac92251def87357fdf6)

このページを参考に、Pythonを使ってSlackbotを作ってみました。

## Slackで利用するBotアカウントを作成
まずは、Botとして受け答えしてくれるインターフェースを作らなければ何もできません。
[ここ](https://my.slack.com/services/new/bot)からBotアカウントを作成します。

##### ワークスペースにサインインしていない場合、先ずサインインします。
![スクリーンショット 2017-12-20 11.55.08.png](https://qiita-image-store.s3.amazonaws.com/0/177247/e41dce51-61cf-2d40-3494-051760d61b6e.png "スクリーンショット 2017-12-20 11.55.08.png")

##### Botアカウントの名前を入れて、ボットインテグレーションを追加します。
![スクリーンショット 2017-12-20 11.57.22.png](https://qiita-image-store.s3.amazonaws.com/0/177247/9c0f10f5-5121-3b4d-c899-bb88118675aa.png "スクリーンショット 2017-12-20 11.57.22.png")

##### APIトークンが発行されるので、それをメモしておきます。
![IMG_5001.PNG](https://qiita-image-store.s3.amazonaws.com/0/177247/824fa365-2066-1df3-0f58-4da7a80558a4.png "IMG_5001.PNG")

このBotアカウントのトークンを使うことが、1つめのコツになります。
考えてみたら当たり前なのですが、古い情報ですとレガシートークンを利用したりしていますので、注意が必要です。

## slackbotのインストール
おなじみ、pipを利用してインストールします。
`# pip3 install slackbot`

これだけ。

### ディレクトリ構造の作成
以下の形で作成します。

```
slackbot
    ├ run.py
    ├ slackbot_settings.py
    ├ plugins
    │   ├ __init__.py
    │   └ my_mention.py
    └ libs
        ├ __init__.py
        └ my_functions.py
```

slackbot: トップレベルディレクトリ。名前は何でも良いです。
run.py: slackbotを起動するためのファイル。
slackbot_settings.py: slackbotの設定用ファイル。
plugins: botの機能を追加するためのディレクトリ。
my_mention.py: slackbotの機能ファイル。名前は何でも良いです。
libs: my_mentions.pyから呼び出すモジュールの配置ディレクトリ。適当に作りました。
my_functions.py: 裏で動くためのモジュールファイル。適当に作りました。

### 初期設定
~~~run.py
# -*- coding: utf-8 -*-
from slackbot.bot import Bot

def main():
    bot = Bot()
    bot.run()

if __name__ == "__main__":
    print('start slackbot')
    main()
~~~

~~~slackbot_settings.py
# -*- coding: utf-8 -*-

# botアカウントのトークンを指定
API_TOKEN = "xxxx-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx"

# このbot宛のメッセージで、どの応答にも当てはまらない場合の応答文字列
DEFAULT_REPLY = "何言ってんだこいつ"

# プラグインスクリプトを置いてあるサブディレクトリ名のリスト
PLUGINS = ['plugins']
~~~

### 起動確認
`$ python3 run.py`

エラーなく、`start slackbot`と表示されれば問題ありません。
`Ctrl+C`で終了します。

### メンションの作成
~~~my_mention.py
# -*- coding: utf-8 -*-
from slackbot.bot import respond_to     # @botname: で反応するデコーダ
from slackbot.bot import listen_to      # チャネル内発言で反応するデコーダ
from slackbot.bot import default_reply  # 該当する応答がない場合に反応するデコーダ

from libs import my_functions           # 外部関数の読み込み

# @respond_to('string')     bot宛のメッセージ
#                           stringは正規表現が可能 「r'string'」
# @listen_to('string')      チャンネル内のbot宛以外の投稿
#                           @botname: では反応しないことに注意
#                           他の人へのメンションでは反応する
#                           正規表現可能
# @default_reply()          DEFAULT_REPLY と同じ働き
#                           正規表現を指定すると、他のデコーダにヒットせず、
#                           正規表現にマッチするときに反応
#                           ・・・なのだが、正規表現を指定するとエラーになる？

# message.reply('string')      @発言者名: string でメッセージを送信
# message.send('string')       string を送信
# message.react('icon_emoji')  発言者のメッセージにリアクション(スタンプ)する
#                              文字列中に':'はいらない
@respond_to('メンション')
def mention_func(message):
    message.reply('私にメンションと言ってどうするのだ') # メンション

@listen_to('リッスン')
def listen_func(message):
    message.send('誰かがリッスンと投稿したようだ')      # ただの投稿
    message.reply('君だね？')                       # メンション
~~~

ここのポイントは、外部モジュールを読み込む際に`from libs import <モジュール名>`にする事です。
run.pyから起動しているため、run.pyから見た相対パスで読み込む必要があります。

![スクリーンショット 2017-12-20 14.33.59.png](https://qiita-image-store.s3.amazonaws.com/0/177247/c12e6047-27be-7666-f7eb-f677914a0ef8.png "スクリーンショット 2017-12-20 14.33.59.png")

run.pyを起動して、このように反応したら成功です。
あとは、アイデア次第です。

Enjoy your bot!