概要
ErrbotはPython製のchatbotです。
このページにはErrbotのプラグイン(自作bot)の作り方で学んだことをまとめます。
内容は公式ドキュメントのPlugin Developmentに概ね沿っていて
Pythonの基礎的な知識があれば容易に理解できるはずです。
環境構築については以前の記事をご参照ください。
作成前の基礎知識
ローカルディレクトリの読み込み
基本的にErrbotにおけるpluginは
組み込みの!repos
コマンドによりgitを経由して管理されます。
ただし、開発中はいちいちgitリポジトリにソースをあげるのも手間ですので
ローカルディレクトリからpluginを読み込みます。
errbot --init
によって生成されたconfig.py
の中に
BOT_EXTRA_PLUGIN_DIR
という設定項目があります。
ここにローカルディレクトリとしたいディレクトリのパスを記載します。
とはいえ、デフォルトでplugins
ディレクトリが指定されているはずですので
そのまま使って問題ないはずです。
テストモードでの実行
他のサーバとの接続なしでbotのデバッグをするため
起動時に--text
か-T
を指定することで、テストモードでの実行が行えます。
test
ではなくtext
です。
$ errbot --text
pluginの構成ファイル
-
.plug
ファイル: pluginのメタデータをINIファイル形式で記載 -
.py
ファイル: pluginで実際に処理されるPythonコードを記載
詳細は後述します。
Hello, World!
ファイルの作成
BOT_EXTRA_PLUGIN_DIR
で指定されているディレクトリ内に
HelloWorld
ディレクトリとその構成ファイルを作成します。
plugins/
|~err-example/
| |-example.plug
| `-example.py
`~HelloWorld/
|-helloworld.plug
`-helloworld.py
helloworld.pyには、例に従って以下のように記載します。
from errbot import BotPlugin, botcmd
class HelloWorld(BotPlugin):
"""Example 'Hello, world!' plugin for Errbot"""
@botcmd
def hello(self, msg, args):
"""Say hello to the world"""
return "Hello, world!"
コードの解説
まず、pluginの継承元になるクラスと
コマンドに対応する関数を作成するためのデコレータをimportします。
from errbot import BotPlugin, botcmd
BotPluginクラスを継承し、plugin用のクラスを生成します。
docstringの部分は!help
コマンドを使った際に表示されます。
class HelloWorld(BotPlugin):
"""Example 'Hello, world!' plugin for Errbot"""
次に関数を記載し、@botcmd
でデコレートします。
関数名がコマンド名になり、botは!hello
コマンドを受け付けるようになります。
関数内のdocstringも、!help
コマンドを使った際に表示されます。
@botcmd
def hello(self, msg, args):
"""Say hello to the world"""
return "Hello, world!"
hello
関数はmsg
とargs
という複数の引数を受け取ります。
-
msg
: ユーザが入力した文章全体 -
args
: ユーザが入力した文章からコマンド部分を除いたもの
例えば、!hello hoge moge
と入力した際は以下の値を格納しています。
-
msg
:'!hello hoge moge'
-
args
:'hoge moge'
両方ただの文字列っぽく書いてますが、msg
は
errbot.backends.base.Message
クラスのインスタンスのようです。
pluginのメタデータ
helloworld.plugには、例に従って以下のように記載します。
[Core]
Name = HelloWorld
Module = helloworld
[Python]
Version = 2+
[Documentation]
Description = Example "Hello, world!" plugin
-
Name
: 実行ファイルの名前から.py
を除いたもの -
Module
: botクラスとなるモジュール(Name
で指定したファイル内) -
Version
: 対応するPythonのバージョン(詳細不明) -
Description
: プラグインの詳細(詳細不明)
作成したbotの実行
ここまで記載すれば、botの実行が可能になります。
>>> !hello
Hello, World!
コマンド作成における応用
引数の自動分割
botcmd
デコレータには引数が指定可能です。
キーワード引数としてsplit_args_with
を指定することで
前述のargs
変数をリストとして受け取ることができます。
@botcmd(split_args_with=None)
def action(self, mess, args):
# !action one two three と入力したときに
# argsは ['one', 'two', 'three']を受け取る
split_args_with
の指定はstr.split()
のように振る舞い
None
はホワイトスペースを示しています。
サブコマンド
関数名の中で_
を使用している場合、_
以降はサブコマンドとして扱われます。
これはコマンドのグルーピングに役立ちます。
@botcmd
def basket_add(self, mess, args):
# !basket add という入力に対応
pass
@botcmd
def basket_remove(self, mess, args):
# !basket remove という入力に対応
pass
このとき、add
とremove
はあくまでもコマンドの一部ですので
args
の中に引数として格納されることはないようです。
argparseによる引数の分割
botcmd
の代わりにarg_botcmd
デコレータを使用することで
argparseのフォーマットで引数を定義することができます。
デコレータは重ねて記載することで複数の指定が可能です。
@arg_botcmd('first_name', type=str)
@arg_botcmd('--last-name', dest='last_name', type=str)
@arg_botcmd('--favorite', dest='favorite_number', type=int, default=42)
def hello(self, mess, first_name=None, last_name=None, favorite_number=None):
# !hello Err --last-name Bot と入力したとき
# first_name は 'Err'
# last_name は 'Bot'
# favorite_number は 42(デフォルト値)
まとめ
pluginの作成の基本的な部分について書きました。
引数はある程度自由に受け取れるようになったため
あとはPythonで実行させたい処理を好き勝手に処理を書くだけです。
他にも正規表現を用いたコマンドの使用やテンプレートの活用など
シンプルながら多くの機能があるようです。
興味を持たれたら、ドキュメントをご一読ください。