NISHIO Hirokazu[Translate]
Mattermostでチャットボット
tokorotenVeinを接続したいと言い出して、どうせならみんなHackableな方がいいよねとなった
というわけでみんな色々繋げれるようになったから僕もチャットボットを作ってみた

Incoming Webhookを設定する
設定したらcurlでリクエストを投げてみる
$ curl -i -X POST -d 'payload={"text": "日本語!"}' https://mattermost....
正しく設定できていればこんな感じになる
プロフィール画像の設定がファイルアップロードではなく画像URLの指定だった

Slash Commandを設定する
チャットボット自体には使わないかもだけど一歩一歩進むためにこれをやる
何がおきているかわかりやすくするために手元のサーバでやる
$ python3 -m http.server
ローカルの8000番ポートでHTTPサーバを立てた
ディレクトリ内のファイルが晒されるので見られて困るもののないところでやること
$ ngrok http 8000
ローカルの8000番ポートへngrokでトンネリング
ブラウザで http://***.ngrok.io/ にアクセスしてディレクトリ内が見えることを確認
スラッシュコマンドの設定
リクエストURL: http://***.ngrok.io/
リクエストメソッド: GET
これでスラッシュコマンドを実行するとサーバにこんなリクエストが届くのが見える
GET /?channel_id=***&channel_name=z-botplayground&command=%2Fnisbot&response_url=***&team_domain=***&team_id=***&text=&token=***&user_id=***&user_name=nishio
http.server はこのリクエストに対して、パラメータを無視してディレクトリ内のファイルの一覧表示のHTMLを返す
そのHTMLがMattermost上に表示される
これで手元のサーバとMattermostが相互にやり取りできることが確認された
なおリクエストメソッドをPOSTにするとMattermost上に
トリガー'nisbot'によるコマンドは501 Unsupported method ('POST')状態を返しました
とエラーメッセージが表示される。 http.server がPOSTに対して501を返すという理由

Outgoing Webhookを設定する
微妙な落とし穴にはまった:
/nisbot nisbot foo の両方を同時に使うことはできない
スラッシュコマンドの側を適当に変更しておく
POSTメソッドのリクエストを扱うことのできるサーバを用意する
たとえばFlaskを使う
POSTの受け取り方はここに書いてある
「GETではなく、POSTを受け取る」と記述する
これを間違えるとngrokが"405 METHOD NOT ALLOWED"と表示する
Mattermostに返事をどう返せば良いかはこれの10に書いてある
まとめると以下のようなコードになる
python
from flask import Flask import json app = Flask(__name__) @app.route("/", methods=["POST"]) def hello(): return json.dumps(dict(text="hello"))
$ FLASK_APP=server.py flask run --port 8000
サーバを起動した
ポート8000を指定しているのはhttp.serverに揃えることでngrokを起動し直すのを避けただけ
これで話しかけるとhelloと返事してくるようになった

毎回固定文字列の返事では面白くないのでとりあえずパラメータを扱いたい
パラメータがどういう名前で渡されるかはこれの8に書いてある
python
from flask import Flask, request import json app = Flask(__name__) @app.route("/", methods=["POST"]) def hello(): username = request.form["user_name"] text = request.form["text"] reply = f"{username}が「{text}」と入力した" return json.dumps(dict(text=reply))
作成過程の失敗メモ
from flask import Flask, request のrequestを忘れて500 Internal Server Errorになった
user_nameとすべきところをusernameにすると400 Bad Requestになる
コンテントタイプをデフォルトのurlencodedからjsonに変更してても400になる

今回は手元のサーバでbotをつくるところまでをやった
個人的には次はAWS Lambdaを試したいと思っている
あと、トリガーワードなしで起動するためには
とかかなぁ?(まだしっかり読んでない)
Slackで全メッセージ受信するBOTを作ってる人はいる

PythonからIncoming WebHookを叩いてチャットボットに喋らせる
requests.post(url, json=dict(text="rebooting server..."))
調子に乗ってFORTHを雑に実装して接続した


"Engineer's way of creating knowledge" the English version of my book is now available on [Engineer's way of creating knowledge]

(C)NISHIO Hirokazu / Converted from [Scrapbox] at [Edit]