「褒めbot」を作ってみた経緯
- Mattermost(マッターモスト)は、Slack互換を謳ったオープンソースのチャット型コミュニケーションツールです。「Slackだと、チャットの内容が社外サーバへ飛んでしまうため、セキュリティ的にNG。チャットは導入したいけど、自分で管理できるプライベートな環境で構築したい。」などの理由からMattermostを使い始めている人も多いのではないでしょうか。まさに私もそうでした。
- 私はMattermostをEC2で立てたので、「せっかくAWSだしLambdaでも使ってサクッとbotでも作るか!作るなら褒めbotでコミュニケーションしやすい環境にしておきたいなぁ。心理的安全性、大切。まずはチームにポジティブな雰囲気を!」と思い、作ってみることにしました。
- 実際、作ってみると、少ない手順でサクッと作ることができるし、ほどよくいろんな要素を使って作るので、「これはQiitaにちょうどいいかも?」ってことで、作り方を共有します!
「褒めbot」の概要
-
動作検証バージョンは以下の通りです。
-
Mattermost 5.3.1
-
Python 3.7 (Lambda)
「褒めbot」を作る4つの手順
作る手順は以下の4STEPです。
- Mattermostで、内向きのウェブフック(Incoming Webhook)を作成する
- Lambda関数を作成する
- API Gatewayを設定する
- Mattermostで、外向きのウェブフック(Outgoing Webhook)を作成する
Mattermostのインストールやセットアップについては、この記事では取り扱いません。以下の@terukizmさんの記事が参考になるので、参照してください。
- SlackクローンのMattermostを使ってみる - 導入、初期設定編-
- SlackクローンのMattermostを使ってみる - 外部連携編 -(WebHooks、Hubot) # 0. 事前準備
それでは、ひとつずつ説明していきます!
1. Mattermostで、内向きのウェブフック(Incoming Webhook)を作成する
- まずは、botが投稿に使うURLを払い出します。Mattermostの統合機能の画面を開き、内向きのウェブフックを作成します。(投稿先の「褒チャンネル」は先に作成しておきます。)内向きのウェブフックを作成するとURLが払い出されるので、次の手順でLambda関数に組み込みます。
2. Lambda関数を作成する
-
コードは以下の通りです。
WEBHOOK_URL
に前の手順で払い出したURLを指定します。(オレオレ証明書を使っている場合は、最後のコメントアウトしてある方のコードを使います。)
import json
import urllib.request
import ssl
# 内向きのウェブフックのURL
WEBHOOK_URL = "https://example.com/hooks/abcdefghij" # ここに内向きのウェブフックで払い出したURLを指定する
def lambda_handler(event, context):
# リクエストヘッダをJSONにする。
req_headers = {
"Content-Type": "application/json",
}
# JSONにメッセージをつめる。
req_json = {
"text": "いいね! :+1:",
}
# リクエストを生成してMattermostへ投げる。
req = urllib.request.Request(WEBHOOK_URL, json.dumps(req_json).encode(), req_headers)
urllib.request.urlopen(req)
# オレオレ証明書を回避する必要がある場合は、こちらのコードを使う。
# (contextを設定した上で、リクエストを生成してMattermostへ投げる。)
# req = urllib.request.Request(WEBHOOK_URL, json.dumps(req_json).encode(), req_headers)
# context = ssl._create_unverified_context()
# urllib.request.urlopen(req, context=context)
- いったん作成したLambda関数をテストしてみます。(最初のテストの前にテストイベントを作成する必要がありますが、デフォルトで作成すれば大丈夫です。)以下のようにMattermostへの投稿ができればここまでの手順はOKです!
3. API Gatewayを設定する
-
今度は、「褒チャンネル」に投稿があったときに呼び出す先のAPIを作成します。API Gatewayの設定は、「API→リソース→メソッド」の順に設定し、最後に作成したAPIをデプロイするという流れです。まず、APIを作成します。
-
ステージのURLと、リソース名をつなげたものが、Mattermostから呼び出すAPIとなるので、次の手順でMattermostに設定します。
4. Mattermostで、外向きのウェブフック(Outgoing Webhook)を作成する
-
最後の手順として、「褒チャンネル」に投稿があったときにbotのAPIを呼び出す設定をします。Mattermostの統合機能の画面を開き、外向きのウェブフックを作成します。コールバックURLに、前の手順の
[ステージのURL]/[リソース名]
を指定します。また、トリガーワードは指定せず、すべての投稿でbotが呼び出されるようにします。
「褒めbot」をもう少しブラッシュアップ
これだけだとちょっと味気ないので、もう少しブラッシュアップして、以下の機能を作ります。
- アイコンを設定する
- いろんな褒め言葉をランダムに投稿する
1. アイコンを設定する
2. いろんな褒め言葉をランダムに投稿する
-
今のままだと「いいね!」しか褒め言葉がないので、いろんな褒め言葉をランダムに投稿するように修正します。Lambda関数を修正しますが、直接修正すると「褒チャンネル」に即反映されてしまい、おかしな動作になる可能性があります。そこで、Lambda関数を修正する前にエイリアスを使って、「褒チャンネル」からのリクエストを受け付けるバージョンを切り離します。Lambda関数の新しいバージョンを発行した上で、以下のようにエイリアスを作成します。
-
API Gateway側の設定も
prod
を呼び出すように修正します。修正した後、APIをデプロイすると「褒チャンネル」の投稿に対して、Lambda関数の最新バージョンではなく、prod
のバージョンでbotが動くようになります。
-
次に、Lambda関数を修正します。修正後のコードは以下の通りです。
import json
import urllib.request
import ssl
import random
# 内向きのウェブフックのURL
WEBHOOK_URL = "https://example.com/hooks/abcdefghij" # ここに内向きのウェブフックで払い出したURLを指定する
def lambda_handler(event, context):
# リクエストヘッダをJSONにする。
req_headers = {
"Content-Type": "application/json",
}
# メッセージの候補リストを作成する。
msg_list = [
"いいね! :+1:",
"# :homeru:",
"ありがとー! :thankyou:",
"えらい! :erai:",
"すごい! :sugoi:",
"# :kansha:",
"さすがです :tada:",
]
# JSONにランダムにメッセージをつめる。
req_json = {
"text": random.choice(msg_list),
# チャンネルを指定して投稿もできるので、
# 修正後にLambdaのテストをしておきたいときは
# 自分へのダイレクトメッセージとするとよい。
# "channel": "@hoge.hoge",
}
# リクエストを生成してMattermostへ投げる。
req = urllib.request.Request(WEBHOOK_URL, json.dumps(req_json).encode(), req_headers)
urllib.request.urlopen(req)
# オレオレ証明書を回避する必要がある場合は、こちらのコードを使う。
# (contextを設定した上で、リクエストを生成してMattermostへ投げる。)
# req = urllib.request.Request(WEBHOOK_URL, json.dumps(req_json).encode(), req_headers)
# context = ssl._create_unverified_context()
# urllib.request.urlopen(req, context=context)
-
この記事では、シンプルなbot作成までを書きました。ブラッシュアップはしたものの、まだまだ他にも機能を追加できます(公式ドキュメント Outgoing Webhooks — Mattermost documentation # Create an Outgoing Webhook)。例えば、投稿された内容から
user_name
やtext
を拾って、発言したユーザや発言内容で処理を振り分けてみたり…など、色々と考えられるので、また試してみたいと思います!
「褒めbot」を作ってみた結果
① 最初は面白がって使ってくれた!
② 機能が物足りなくて、すぐ飽きたので改善(記事のブラッシュアップ)。チームの雰囲気もイイ感じ!
③ でも盛り上がりは一時的で、すぐ特定の人しか使わなくなる…。それでもこの段階では、個々の進捗や学びが共有できていた。
④ がスケジュールに切羽詰まり始め、投稿ゼロの日が発生…過疎化してしまう。チームの雰囲気もちょっと微妙に…。
⑤ いま、また盛り上がるように自作自演から再開中!
- …と、思いっきり作り方の記事を書いておいてー、って感じですが、あくまでツールはツールでしかないです。「褒めbot」は、チームの雰囲気作りや情報共有を助けてはくれますが、人間系での布教活動は忘れてはいけません。④のような時期にこそ、自分から「褒チャンネル」を盛り上げることが大切なのだと思いました。私も引き続きがんばります!