9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

IFTTT+pythonのslackbotライブラリで、出社したらほめてくれるマーリンbotを作るまで

9
Last updated at Posted at 2019-01-23

導入

会社の同僚が出社したら元気が出る画像を投稿するslackbotを作っていたので、自分もやってみたくなりました。
毎日出社したらほめてくれるマーリン1のslackbotを作ります。
細かいトラップを回避しながらがんばって作ります。

システム構成

slackbotライブラリ → https://github.com/lins05/slackbot/
なおこのツールは、RTM APIを利用する方式のようです。
参考:https://qiita.com/namutaka/items/233a83100c94af033575

システム構成は以下のようになります。

こうせいず.png

  1. 出社すると、スマホのIFTTTアプリが特定の範囲に入ったことを検知し、IFTTTのトリガーが起動
  2. トリガーを受けてIFTTTがでslackに「しゅっしゃ」と送る
  3. slackがslackbotに投稿したことを送る
  4. slackbotは「しゅっしゃ」という文字列が入っていたら回答「おはよう!」を生成
  5. slackbotがslackに「おはよう!」を投稿する
    ※slackbotは最終的にheroku上にデプロイしますが、ローカルでも動作します

開発環境

Mac OS X 10.12.6
iOS 12.1.2

おおまかな手順

0. 事前準備
1. slackbotを動かしてみる
2. IFTTTのAppletを作ってslackに投稿する
3. slackbotをIFTTTに対応させる
4. いろんなパターンでほめてもらう処理を作る
5. herokuにデプロイ

0. 事前準備

PCでやっておくこと

  • IFTTTのアカウント作成
  • python3.6系インストール(今回は3.6.6)
  • heroku cliインストール 参考
  • gitインストール
  • (slackアプリのインストール)
  • slackにbot用のワークスペースとチャンネルを用意しておく

スマホでやっておくこと(今回はiOS)

  • iPhoneにIFTTTアプリをインストール

1. slackbotを動かしてみる

まずは、slackで何か発言したら反応を返すslackbotを作ります。
構成図③〜⑤の部分です。
slack側でBotを登録し、そのBotとWebSocket通信するpythonツールを作ります。

1-1. Bot登録

slack側のBot登録は以下のページを開いて、「設定を追加」ボタンから。
https://slack.com/apps/A0F7YS25R-bots
するとBot登録画面になるので、適当にBotの名前を入力しましょう。
ここでは「merlin_bot」としています。

「ボットインテグレーションを追加する」を押すと、botが作成され、インテグレーション設定画面に遷移します。
APIトークンが表示されますので、どこかにメモしておきましょう。

このbotはslackからメンバとして見ることができます。
この時点で、bot用のチャンネル(今回はchaldeaにしました)に、このbotを招待しておきます。

1-2. slackbotの動作確認

次にslackbotを動かします。
(参考:https://qiita.com/sukesuke/items/1ac92251def87357fdf6)

まずは適当な場所にgit cloneでslackbotリポジトリをクローンします。
※ pip installでも入りますが、そのままだとIFTTTに対応してないので、あとで書き換え作業をするためにクローンします

git clone https://github.com/lins05/slackbot.git

そして、cloneしてきたリポジトリはいったんそのままにしておき、
別の場所に作業用のディレクトリを作ります。

mkdir merlin_bot
cd merlin_bot

さきほどクローンしたslackbotリポジトリから必要なファイルをコピーしてきます。
(ついでに今回は使わないファイルは消しておきます)
また、ボット起動用のファイルやpluginディレクトリ(あとで利用)もつくります。

# slackbotリポジトリのslackbotディレクトリをまるっとコピー
cp -r ~/git/slackbot/slackbot . 
# 使わないファイルを削除
rm slackbot/VERSION
rm -r slackbot/plugins/
# requirementsもコピー
cp ~/git/slackbot/requirements.txt .
# bot起動用ファイル作成
touch run.py
touch slackbot_settings.py
# plugin
mkdir plugins
touch plugins/__init__.py

ディレクトリ構成はこんな感じ。

merlin_bot/
├── plugins
│   └── __init__.py
├── requirements.txt
├── run.py
├── slackbot
│   ├── __init__.py
│   ├── bot.py
│   ├── dispatcher.py
│   ├── manager.py
│   ├── settings.py
│   ├── slackclient.py
│   └── utils.py
└── slackbot_settings.py

requirementsをインストールします。

pip install -r requirements.txt 

run.pyを以下のように編集します。

run.py
# -*- encoding: utf-8 -*-
from slackbot.bot import Bot

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

if __name__ == '__main__':
    main()

slackbot_settings.pyを以下のように編集します。

slackbot_settings.py
# -*- encoding: utf-8 -*-

# botアカウントのトークンを指定
API_TOKEN = "(さきほどメモっておいたAPIトークン)"

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

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

# 投稿するslack上のチャンネル
ERRORS_TO = 'chaldea'

ここまでできたら、botを起動して動作確認します。

python run.py

chaldeaチャンネルで、merlin_bot宛にメッセージを送ると、デフォルトの発言が返ってきます。
moshimoshi.png

1-3. 特定の文字列に反応させる

listen_toデコレータを使うと簡単にできます。
run.pyで、listen_toのインポートを追加し、listen_func関数を追加。

run.py
# -*- encoding: utf-8 -*-
from slackbot.bot import Bot
from slackbot.bot import listen_to

@listen_to('しゅっしゃ')
def listen_func(message):
    message.send('おはよう!')

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

if __name__ == '__main__':
    main()

runしてslackに「しゅっしゃ」と投げると...

python run.py

しゅっしゃ.png

出社に反応してくれるようになりました!

2. IFTTTのAppletを作ってslackに投稿する

構成図①〜②の部分です。
※今回はiOSの解説になります

IFTTTのNew Appletから登録します。
今回は、位置情報トリガの本番用と、ボタンをポチッと押すデバッグ用の2つのAppletをつくります。

2-1. 位置情報トリガのIFTTT

「this」をタップすると、「Location」というメニューが出てくるのでタップ。
ifttt.png
今回は出社なので、「You enter an area」を選択。
IMG_3084.PNG
次のページの位置情報選択で、自分の会社の位置を選択します。
(なお私はしがないエンジニアなので皇居勤務ではありません...)
IMG_3087.PNG
create an triggerでトリガーが作れます。

次は「that」を選択。
search servicesからslackと入れるとslackがでてきます。
スクリーンショット 2019-01-20 14.42.36.png
Post to channelと選択し、ワークスペースやチャンネルの情報を入れます。
「Message」には「しゅっしゃ」を入れます。
IMG_3091.PNG
「Create action」を押すと新しいAppletができます。

2-2. ボタントリガのIFTTT

位置情報トリガだと、動作確認のために毎回スマホを持って行ったり来たりする必要があります。
なので、ボタンを押すとslackに投稿するデバッグ用IFTTTを作っておきます。

「this」の部分で、buttonと入力すると「Button widget」が出てきます。
次の画面で「Button press」をタップすると「this」のところがボタンになります。
ボタン.png
thatの部分は2-1と同じ、slackへの投稿を設定します。

ボタンは、MyAppletsから登録したAppletを選択し、「Widget settings」を選択、次の画面でボタンアイコンをタップするとボタンを押す画面に遷移します
ぼたん.png
ボタンを押すと、slackのチャンネルにIFTTTから投稿が確認できます。
スクリーンショット 2019-01-20 15.01.02.png

ただし、このままではslackbotが反応しません。

3. slackbotをIFTTTに対応させる

こちらの記事に書いたんですが、IFTTTの投稿フォーマットが通常のそれと異なるため、このままではIFTTTの発言にbotが反応してくれません。
なので、slackbot/dispacher.pyというファイルを修正します。

(編集前)dispacher.py
    def _dispatch_msg_handler(self, category, msg):
        responded = False
        for func, args in self._plugins.get_plugins(category, msg.get('text', None)):
            if func:
                responded = True
                try:
(編集後)dispacher.py
    def _dispatch_msg_handler(self, category, msg):
        responded = False
        text = None
        if 'text' in msg:
            text = msg.get('text', None)
        elif 'attachments' in msg and len(msg.get('attachments')) > 0:
            text = msg['attachments'][0].get('pretext', None)

        for func, args in self._plugins.get_plugins(category, text):
            if func:
                responded = True
                try:

修正後、slackbotを起動してからIFTTT経由で投稿すると、ちゃんと反応が返ってきます。
スクリーンショット 2019-01-20 15.27.16.png

4. いろんなパターンでほめてもらう処理を作る

「おはよう!」だけだと味気ないので、毎日いろんなパターンで出社をほめてもらいます。

4-1. pluginsを作成

さきほどのlisten_toの処理をplugins以下に新しくファイルを作って移動します。

touch plugins/good_morning.py
run.py
# -*- encoding: utf-8 -*-
from slackbot.bot import Bot

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

if __name__ == '__main__':
    main()
plugins/good_morning.py
# -*- encoding: utf-8 -*-
from slackbot.bot import listen_to

@listen_to('しゅっしゃ')
def listen_func(message):
    message.send('おはよう!')

4-2. ほめセリフを収集

出社したらほめてくれるといえばコウペンちゃんです。
今回はコウペンちゃんbotから出社したり起きたりしたらほめてくれるセリフを収集し、マーリン風に加筆修正したものを使います。
一行一セリフの以下のようなテキストファイルを作りpluginsの下に置きます。

plugins/serif_merlin.txt
今日も出勤するなんて、君はえらいね。
今日もえらいね。
今日も1日頑張ってね。
ちゃんと起きられたなんて、えらいじゃないか!
電車に乗れたのかい?えらいね!

これを読み込んでランダムに出すようにgood_morning.pyを修正します。

plugins/good_morning.py
from slackbot.bot import listen_to
import random

serif = []
serif_file = "plugins/serif_merlin.txt"
with open(serif_file, 'r') as f:
    serif = [l.strip() for l in f.readlines()]

prefix = ['おはよう!', 'おはようマスター。']

@listen_to('しゅっしゃ')
def listen_func(message):
    message.send(random.choice(prefix) + random.choice(serif))

python run.pyして動作確認します。
スクリーンショット 2019-01-20 15.42.07.png
だいぶマーリンに近づいてきました。

4-3. アイコンや名前を整える

slackのアイコンや名前がデフォルトのままだったので、slackのBot管理画面から編集します。
APIトークンが表示されてた画面を下にスクロールすると画像や名前を設定できます。
スクリーンショット 2019-01-20 15.48.04.png
インテグレーションを保存して、slack画面に戻ると名前やアイコンが反映されてます。
スクリーンショット 2019-01-20 15.49.12.png
おお!!マーリンがほめてくれた!!

5. herokuにデプロイ

実際に運用する際、ローカルでpythonを実行しつづけるのは辛いので、herokuにデプロイします。

5-1. デプロイ用のファイルを準備

merlin_botディレクトリ直下にファイルを作ります。

cat <<EOF > Procfile
worker: python run.py
EOF
cat <<EOF > runtime.txt
python-3.6.7
EOF

また、このへんを参考に.gitignoreを作ります。

現在のディレクトリ構成はこんな感じ。

merlin_bot
├── .gitignore
├── Procfile
├── plugins
│   ├── __init__.py
│   ├── good_morning.py
│   └── serif_merlin.txt
├── requirements.txt
├── run.py
├── runtime.txt
├── slackbot
│   ├── __init__.py
│   ├── bot.py
│   ├── dispatcher.py
│   ├── manager.py
│   ├── settings.py
│   ├── slackclient.py
│   └── utils.py
└── slackbot_settings.py

5-2. herokuにデプロイ

gitのfirst commitを作っておく。

git init
git add .
git commit -m "first commit"

herokuにログインして、新しくアプリを作る。

heroku login
heroku create

herokuにデプロイ

git push heroku master

しばらく待つとデプロイが完了します。

Herokuのプロセスをworkerにすると、デプロイしただけではプロセスが立ち上がりません。
なので、Herokuの管理画面の「Resources」から、workerをオンにします。
スクリーンショット 2019-01-21 21.55.22.png

heroku ps
Free dyno hours quota remaining this month: 998h 20m (99%)
Free dyno usage for this app: 0h 0m (0%)
For more information on dyno sleeping and how to upgrade, see:
https://devcenter.heroku.com/articles/dyno-sleeping

=== release (Free): /bin/sh -c 'if curl $HEROKU_RELEASE_LOG_STREAM --silent --connect-timeout 10 --retry 3 --retry-delay 1 >/tmp/log-stream; then
  chmod u+x /tmp/log-stream
  /tmp/log-stream /bin/sh -c '"'"'python run.py'"'"'
else
  python run.py
fi' (1)
release.2746: up 2019/01/20 16:24:03 +0900 (~ 21s ago)  ### あがってます

ちゃんと動いています。
スクリーンショット 2019-01-20 16.26.05.png
できあがりです!

いかがでしたか?

マーリンのセリフはちょっとバリエーションが少ないので、同じ仕組みでキュケオーン(@QK_otabe)とトリスタン(@wtsknsi)も追加してみました2
弊カルデアは今日も平和です。
スクリーンショット 2019-01-20 16.56.23.png

ソースコード

大いなる参考記事

  1. マーリンといえばアーサー王伝説に登場する魔術師のおじいさんですが、ここではFate/Grand Orderに出てくる白髪の美青年(しかも櫻井孝宏の声で喋る)を指します

  2. なお、弊カルデア(iPhone)にキュケオーンとトリスタンはいません

9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?