はじめに
深夜テンションで一気に書ききったのでたくさん修正するかもしれません。
この記事ではslackbotを起動に漕ぎ着けるまでの解説を行います。デプロイして運用!とかは他の記事を見ながら頑張っていただけたら...
この記事で使用してるコードはこちらに上げてます。
なお、この記事は様々な説明を省略してたりするのでご了承ください。
本文
環境など(筆者の環境なのであくまでも目安に)
- macOS Catalina 10.15.4
- Slack
- processing-java
- Python 3.7.4(Python3系なら多分大丈夫だと思います)
pipでslackbot、Pillowライブラリをインストールしておきましょう。(場合によってはpip3
)
$ pip install slackbot
$ pip install Pillow
$ pip list # インストール済みのライブラリの確認
また、processing-javaのインストールもしてください。processingの導入はこの記事がおすすめです。
processingのダウンロードし、起動、ツールバーから「ツール」>「processing-javaをインストール」を選択でインストールできるはずです。
botの作成
以下のサイトからbotを作成してください。なお作成するワークスペースを間違えないよう注意しましょう。
https://my.slack.com/services/new/bot
(本来こちらは推奨されておらず、scopeの設定などめんどくさいものをやらなくてはいけませんが今回はこれで行きます。)
こちらのユーザー名にbotの名前を入れて「ボットインテグレーションを追加する」を押してください。
表示された「APIトークン」はコピペなりなんなりでメモしておきましょう。名前、アイコンなどは好きにカスタマイズしましょう。
完了したらページ一番下のボタンを押して設定の保存をしてください。
以降はhttps://<ワークスペースのURL>/apps
のページで「bots」と調べて出てくるページで編集及びトークンの確認ができます。
botを動かす準備
下記のようなディレクトリを用意しましょう。こちらをcloneしてくると大体の作業を飛ばせます。(その場合(※)のフォルダ、ファイルを用意してください!)
slackbot # プログラムをまとめるディレクトリ。任意の文字列
├─ run.py # bot起動のためのメインファイル
├─ slackbot_settings.py # botに関する設定を書くファイル(※)
├─ plugins # botの機能はこのディレクトリに追加する
├─ __init__.py # モジュールを示すためのファイル。空でOK
└─ func.py # 機能を書くファイル。任意の文字列
└─ sketch (※)
└─ sketch.pde # 一旦書き込むスケッチファイル。空でOK(※)
以下のコードを書いてください。
```run.py```のコード
from slackbot.bot import Bot
def main():
bot = Bot()
bot.run()
if __name__ == "__main__":
print('start slackbot')
main()
```slackbot_settings.py```のコード
API_TOKEN = "<メモしたAPIトークン>"
DEFAULT_REPLY = "<デフォルトで返したい任意の文字列>"
PLUGINS = ['plugins'] # botの機能を書いてるコードがあるディレクトリのお名前
```func.py```のコード
import glob
import os
import os.path
import subprocess
import sys
import time
from PIL import Image
from slackbot.bot import default_reply # 該当する応答がない場合に反応するデコーダ
from slackbot.bot import listen_to # チャネル内発言で反応するデコーダ
from slackbot.bot import respond_to # @botname: で反応するデコーダ
@listen_to('!exit') # exitコマンド:プロセスを終了する
def kill_process(message):
message.send('See you!')
print('process finished')
os._exit(10) # プロセスの強制終了
@listen_to('!output (.*)')
def output(message, arg): # argはオプション
# 送信されたテキストを整形
tmp = message.body['text']
tmp = tmp.replace("<", "<")
tmp = tmp.replace(">", ">")
# pde上書き用の文字列に整形
pdeCode = shaping_code(tmp.strip("!output " + arg + "\n"), arg)
message.send('wait...')
# pdeに上書き
print(pdeCode)
with open('sketch/sketch.pde', 'w') as f:
f.write(pdeCode)
# processingの実行
sketch_path = '--sketch=' + os.path.abspath('./sketch')
cp = subprocess.run(
['processing-java', sketch_path, '--run'])
if cp.returncode != 0: # processingの実行失敗時の処理
message.send('Run is failed. Please send your sketch again.')
return
upload_sequence(message, arg) # upload処理
def shaping_code(code, option):
if option == '--png': # pngオプション
pictFunc = " if((frameCount <= 15) && (frameCount % 15 == 0)) saveFrame(\"####.png\");\n else if(frameCount > 15) exit();"
elif option == '--gif': # gifオプション
pictFunc = " if((frameCount <= 300) && (frameCount % 15 == 0)) saveFrame(\"####.png\");\n else if(frameCount > 300) exit();"
else: # デフォルトではpngで返す
pictFunc = " if((frameCount <= 15) && (frameCount % 15 == 0)) saveFrame(\"####.png\");\n else if(frameCount > 15) exit();"
return code.replace("void draw(){", "void draw(){\n" + pictFunc)
def upload_sequence(message, option):
if option == '--png': # pngオプション
message.channel.upload_file(
fname="sketch/0015.png", fpath="sketch/0015.png")
for p in glob.glob('sketch/*.png'):
if os.path.isfile(p):
os.remove(p)
elif option == '--gif': # gifオプション
time.sleep(6)
file_list = sorted(glob.glob('sketch/*.png'))
images = list(map(lambda file: Image.open(file), file_list))
images[0].save('sketch/output.gif', save_all=True,
append_images=images[1:], duration=400, loop=0)
if os.path.exists('sketch/output.gif'):
message.channel.upload_file(
fname="sketch/output.gif", fpath="sketch/output.gif")
for p in glob.glob('sketch/*.png'):
if os.path.isfile(p):
os.remove(p)
os.remove('sketch/output.gif')
else: # デフォルトではpngでupload
message.channel.upload_file(
fname="sketch/0015.png", fpath="sketch/0015.png")
for p in glob.glob('sketch/*.png'):
if os.path.isfile(p):
os.remove(p)
bot起動
準備が完了したら実際にbotを起動してみましょう。
slackbotディレクトリに移動して、
$ python3 run.py
を叩いてプログラムを実行しましょう。
- pngの場合
- gifの場合
このように!output --gif
とつけてコードを送信し、gifで返してくれれば勝ちです。
こちらも同じようにgif、png共に消去されます。
終わりに
拙い説明ですが以上で起動までの説明を終わらせていただきます。
subprocessでコマンドを叩いたり、正規表現使って色々なコマンドを作成できそうで面白かったです。
やる気が出れば使用したメソッドの解説記事やbot運用記事など書いてみようかと思います。
デプロイをまだやってないので未知数ですが...(インフラって何)
参考記事
- Herokuでslackbot(python)を動かしてみた【おみくじBOT】
- PythonのslackbotライブラリでSlackボットを作る
- 時差出勤始まったので退勤時刻を教えてくれるBotを作った
追記
- 2020-06-16 cfg.pyの廃止に成功したので関連するものを消去しました。