Mattermostの「褒めbot」をLambdaとPythonで作ってみた

Mattermostの「褒めbot」をLambdaとPythonで作ってみた:


「褒めbot」を作ってみた経緯


  • Mattermost(マッターモスト)は、Slack互換を謳ったオープンソースのチャット型コミュニケーションツールです。「Slackだと、チャットの内容が社外サーバへ飛んでしまうため、セキュリティ的にNG。チャットは導入したいけど、自分で管理できるプライベートな環境で構築したい。」などの理由からMattermostを使い始めている人も多いのではないでしょうか。まさに私もそうでした。
  • 私はMattermostをEC2で立てたので、「せっかくAWSだしLambdaでも使ってサクッとbotでも作るか!作るなら褒めbotでコミュニケーションしやすい環境にしておきたいなぁ。心理的安全性、大切。まずはチームにポジティブな雰囲気を!」と思い、作ってみることにしました。
  • 実際、作ってみると、少ない手順でサクッと作ることができるし、ほどよくいろんな要素を使って作るので、「これはQiitaにちょうどいいかも?」ってことで、作り方を共有します!


「褒めbot」の概要

  • 「褒チャンネル」に投稿があったら、褒め言葉を返すbotを作ります。完成形はこんなイメージです。


    image.png
  • AWSの構成は以下の通りです。


    image.png

  • 動作検証バージョンは以下の通りです。



    • Mattermost 5.3.1
    • Python 3.7 (Lambda)


「褒めbot」を作る4つの手順

作る手順は以下の4STEPです。

  1. Mattermostで、内向きのウェブフック(Incoming Webhook)を作成する
  2. Lambda関数を作成する
  3. API Gatewayを設定する
  4. Mattermostで、外向きのウェブフック(Outgoing Webhook)を作成する
Mattermostのインストールやセットアップについては、この記事では取り扱いません。以下の@terukizmさんの記事が参考になるので、参照してください。

それでは、ひとつずつ説明していきます!


1. Mattermostで、内向きのウェブフック(Incoming Webhook)を作成する

  • まずは、botが投稿に使うURLを払い出します。Mattermostの統合機能の画面を開き、内向きのウェブフックを作成します。(投稿先の「褒チャンネル」は先に作成しておきます。)内向きのウェブフックを作成するとURLが払い出されるので、次の手順でLambda関数に組み込みます。
    image.png


2. Lambda関数を作成する

  • 次に「褒めbot」の本体となるLambda関数を作成します。


    image.png
  • コードは以下の通りです。WEBHOOK_URLに前の手順で払い出したURLを指定します。(オレオレ証明書を使っている場合は、最後のコメントアウトしてある方のコードを使います。)
lambda_function.py
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です!
    image.png


3. API Gatewayを設定する

  • 今度は、「褒チャンネル」に投稿があったときに呼び出す先のAPIを作成します。API Gatewayの設定は、「API→リソース→メソッド」の順に設定し、最後に作成したAPIをデプロイするという流れです。まず、APIを作成します。


    image.png
  • 次にリソースを作成します。ここのリソース名がAPIのURLに含まれます。


    image.png
  • 作成したリソースの中に、メソッド(POST)を作成して、前の手順のLambda関数が呼び出されるように設定します。


    image.png
  • 作成したAPIをデプロイします。ここのステージ名がAPIのURLに含まれます。


    image.png
  • ステージのURLと、リソース名をつなげたものが、Mattermostから呼び出すAPIとなるので、次の手順でMattermostに設定します。


    image.png


4. Mattermostで、外向きのウェブフック(Outgoing Webhook)を作成する

  • 最後の手順として、「褒チャンネル」に投稿があったときにbotのAPIを呼び出す設定をします。Mattermostの統合機能の画面を開き、外向きのウェブフックを作成します。コールバックURLに、前の手順の[ステージのURL]/[リソース名]を指定します。また、トリガーワードは指定せず、すべての投稿でbotが呼び出されるようにします。


    image.png
  • これで手順は完了です。「褒チャンネル」に投稿してみて、以下のようにbotから褒め言葉が返ってくればOKです!


    image.png


「褒めbot」をもう少しブラッシュアップ

これだけだとちょっと味気ないので、もう少しブラッシュアップして、以下の機能を作ります。

  1. アイコンを設定する
  2. いろんな褒め言葉をランダムに投稿する


1. アイコンを設定する

  • アイコンは、内向きのウェブフックのプロフィール画像で指定します。


    image.png
  • 私は「褒めbot」の作成にあわせて「褒めスタンプ」のカスタム絵文字も作ったので、カスタム絵文字が保存されているURLをブラウザのデベロッパーツールで調べて指定しました。


    image.png


2. いろんな褒め言葉をランダムに投稿する

  • 今のままだと「いいね!」しか褒め言葉がないので、いろんな褒め言葉をランダムに投稿するように修正します。Lambda関数を修正しますが、直接修正すると「褒チャンネル」に即反映されてしまい、おかしな動作になる可能性があります。そこで、Lambda関数を修正する前にエイリアスを使って、「褒チャンネル」からのリクエストを受け付けるバージョンを切り離します。Lambda関数の新しいバージョンを発行した上で、以下のようにエイリアスを作成します。


    image.png
  • API Gateway側の設定もprodを呼び出すように修正します。修正した後、APIをデプロイすると「褒チャンネル」の投稿に対して、Lambda関数の最新バージョンではなく、prodのバージョンでbotが動くようになります。


    image.png
  • 次に、Lambda関数を修正します。修正後のコードは以下の通りです。
lambda_function.py
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) 
 
  • Lambda関数の修正が完了したら、エイリアスprodが指すバージョンを最新版である$LATESTに切り替えます。


    image.png
  • 「褒チャンネル」に投稿してみて、以下のように新しく増やした褒め言葉がランダムに返ってくればOKです!


    image.png
  • この記事では、シンプルなbot作成までを書きました。ブラッシュアップはしたものの、まだまだ他にも機能を追加できます(公式ドキュメント Outgoing Webhooks — Mattermost documentation # Create an Outgoing Webhook)。例えば、投稿された内容からuser_nametextを拾って、発言したユーザや発言内容で処理を振り分けてみたり…など、色々と考えられるので、また試してみたいと思います!


「褒めbot」を作ってみた結果

  • 「褒めbot」を実際に、1ヶ月くらい運用しているのですが、どんな雰囲気かというと…
    image.png

① 最初は面白がって使ってくれた!

 ② 機能が物足りなくて、すぐ飽きたので改善(記事のブラッシュアップ)。チームの雰囲気もイイ感じ!

 ③ でも盛り上がりは一時的で、すぐ特定の人しか使わなくなる…。それでもこの段階では、個々の進捗や学びが共有できていた。

 ④ がスケジュールに切羽詰まり始め、投稿ゼロの日が発生…過疎化してしまう。チームの雰囲気もちょっと微妙に…。

 ⑤ いま、また盛り上がるように自作自演から再開中!

  • …と、思いっきり作り方の記事を書いておいてー、って感じですが、あくまでツールはツールでしかないです。「褒めbot」は、チームの雰囲気作りや情報共有を助けてはくれますが、人間系での布教活動は忘れてはいけません。④のような時期にこそ、自分から「褒チャンネル」を盛り上げることが大切なのだと思いました。私も引き続きがんばります!

コメント

このブログの人気の投稿

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2024-02-12 22:08:06 RSSフィード2024-02-12 22:00分まとめ(7件)