Raspberry PiでSlackbotを飼う

このエントリは「[Raspberry Piでスマートロックつくった](https://qiita.com/undo0530/items/669b6ee6b2277ea64b33)」の解説6つめになります。
前回まででスマートロック開閉の記録をとるところまでつくることができました。
今回は遠隔での鍵開閉を実現するため、Slack経由で開閉命令を出せるようにしてみます。Raspberry Piの中にSlackbotを住まわせて、「カギ開けて」「施錠して」等のキーワードに反応させてみます。

# Slackbotをインストール
こちらのライブラリを使わせてもらいます。
[GitHub - lins05/slackbot: A chat bot for Slack (https://slack.com).](https://github.com/lins05/slackbot)
pipでインストールできます。

```bash
$ sudo pip install slackbot
```
# SlackでBotアカウントを作成する
まずはSlackアカウントを取得し、チームを作成しておきます。
チャットルームが用意できたら、次は[https://my.slack.com/services/new/bot](https://my.slack.com/services/new/bot)にアクセスしてBotアカウントを作成します。適当なBotのアカウントID（raspibotなど）を入力して「ボットインテグレーションを追加する」をクリックします。すると次の画面でAPIトークンが表示されるので、メモっておきます。
# Botアカウントをチャットに招待する
Bot作成が成功したら、一旦チームのチャットルームに戻ります。左カラムの「App」欄に作成したBotアカウントが表示されていれば成功です。（こんにちは、Slackbotです！って言ってるヤツは別物ですので注意）
![9164df6fe3686fd1ac97a577aa9d4103.png](https://qiita-image-store.s3.amazonaws.com/0/222969/3d673f29-6f1a-3688-bedf-d61c52af72bb.png)
Botアカウントを任意のチャットルームに招待します。①チャットルームを選択し、②メンバーを表示をクリック、③「メンバーをもっと追加する」をクリックし、Botアカウントを選択して招待します。
![1a2c2a5b2cdd91b6a1837f0d76e59894.png](https://qiita-image-store.s3.amazonaws.com/0/222969/c51ede47-dc03-0b5f-6604-a34b43148390.png)
↓こんな感じになればOKです。
![8436cfde415151148bd0cd4d3e9cc6e9.png](https://qiita-image-store.s3.amazonaws.com/0/222969/63924ffb-9b7d-9172-6c49-7d9ba9fc7e00.png)
# Raspberry Piの中にSlackbotを実装する
次はRaspberry Piで動かすプログラムの方をやっていきます。
## 設定ファイルを作成
slackbot_settings.pyという名前のファイルを作成します。これはSlackbotを動かすための基本設定の記述になります。

```python:slackbot_settings.py
# -*- coding: utf-8 -*-
API_TOKEN = '<作成したBotのAPIトークン>'

# デフォルトの返答
default_reply = 'すみません、よくわかりません。'

# プラグインを記述するパッケージ名のリスト
PLUGINS = [
    'SlackBotPlugin',
]
```
## プラグインファイルを作成
Slackbotがどういうワードに反応してどういう返事を返すのか、というのを記述するのがプラグインの役割になります。
上記のPLUGINS = [ ]の中に記述した名前でプラグインファイルを作ります。

```python:SlackBotPlugin.py
# -*- coding: utf-8 -*-
from slackbot.bot import respond_to, listen_to
import re

# 「カギ開けて」「解錠して」等に反応するようにします
@listen_to(u'(鍵|カギ)+.*(開|あけ|空け)+')
@listen_to(u'(解錠)+')
@listen_to('(open)+.*(door)+', re.IGNORECASE)
@respond_to(u'(鍵|カギ)+.*(開|あけ|空け)+')
@respond_to(u'(解錠)+')
@respond_to('(open)+.*(door)+', re.IGNORECASE)
def openKeyOrder(message, *something):
    # if カギが閉まっていたら :
    message.reply(u'わかりました。解錠します。')
    # 命令を出したユーザ名を取得することもできます。
    userID = message.channel._client.users[message.body['user']][u'name']
    print userID + 'さんの命令でカギを開けます'
        
# 「鍵閉めて」「施錠」等の場合はこちら
@listen_to(u'(鍵|カギ)+.*(閉|しめ|締め)+')
@listen_to(u'(施錠)+')
@listen_to('(lock)+.*(door)+', re.IGNORECASE)
@respond_to(u'(鍵|カギ)+.*(閉|しめ|締め)+')
@respond_to(u'(施錠)+')
@respond_to('(lock)+.*(door)+', re.IGNORECASE)
def closeKeyOrder(message, *something):
    # 以下openと同じなので省略

# 未許可なFeLiCaを許可ユーザとして追加する命令
@listen_to(u'(許可|追加)+')
@respond_to(u'(許可|追加)+')
def addUserOrder(message, *something):
    # 「」で囲まれている場合はユーザ名付きで許可する。
    m = re.search(u'「.*」', message.body['text'])
    if m:
        hit = m.group(0)
        userName = hit[1:][:-1]
        message.reply(u'わかりました。直近のインスタントユーザを「' + userName + u'」として追加します。有効期限は10分間です。')
    else:
        userName = 'John Doe'
        message.reply(u'わかりました。直近のインスタントユーザを追加します。有効期限は10分間です。')
    
    # 該当のFeLiCaを許可ユーザに追加する処理… userAddHandler(userName, userID)
```
プラグインの書き方はこんな感じで、@listen_toと@respond_toで反応するワードを設定しておき、その直後に処理内容を書いていく形になります。message.reply()を実行すれば反応したワードの発言者に対してリプライを返します。

```python
@listen_to(u'正規表現で記述できます')
@respond_to(u'respond_toの場合は@raspibot宛のメッセージにだけ反応します')
def openKeyOrder(message, *something):
    message.reply(u'こんにちは。')
```
なお、Stringの頭にuって付けてるのは、nfcpyを利用する関係上スマートロックのプログラムをpython2.7で組んでいたためです。python3であればUnicodeの面倒なヤツとかやらなくていいってどこかで見ました。
## Slackbotを起動する
設定ファイルとプラグインファイルが用意できたら、いよいよSlackbot本体を動かします。Botの起動は簡単です。

```python:bot.py
from slackbot.bot import Bot

# SlackBot起動
paspi_doorlock_bot = Bot()
paspi_doorlock_bot.run()
```
# 動作の様子
試しにチャットで命令してみます。目の前のPCで操作してはいますが、一応ちゃんとインターネットを経由してRaspberry Piに命令が届いてサーボを回しています。タイムラグもなく、いい感じです。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">やったー！Slackチャットから鍵の開け閉めをオーダーできるようになったよー＼(^o^)／<br>これでカレンちゃんが急にウチに来ても遠隔で解錠して夕飯作って待っててもらえるね！<a href="https://twitter.com/hashtag/RaspberryPi?src=hash&amp;ref_src=twsrc%5Etfw">#RaspberryPi</a> <a href="https://t.co/ufK3NQZEss">pic.twitter.com/ufK3NQZEss</a></p>&mdash; undo (@undo) <a href="https://twitter.com/undo/status/938803767973003264?ref_src=twsrc%5Etfw">2017年12月7日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Botのアイコンや名前などはslackの設定ページで自由に変更できますので、Raspberryのアイコンとか好きなロボキャラとかを設定すると幸せになれるかと思います。
Next：[Raspberry Piで開発したプロトタイプを実装する](https://qiita.com/undo0530/items/a444fa9e10bc060334ad)

[![Image-1.png](https://qiita-image-store.s3.amazonaws.com/0/222969/4723d8e2-a771-39b1-5e1d-284da24e2786.png)
翠星のガルガンティア | Netflix
https://www.netflix.com/title/80039789?s=i&trkid=14170032](https://www.netflix.com/title/80039789?s=i&trkid=14170032)