Node-REDでMattermostのカスタムスラッシュコマンドを作成してみた

この記事は株式会社富士通システムズウェブテクノロジーが企画するいのべこ夏休みアドベントカレンダー 2020の8月31日目の記事です。本記事の掲載内容は私自身の見解であり、所属する組織を代表するものではありません。

# はじめに
本記事では、Node-REDを使って簡単なMattermostのスラッシュコマンドを作成する方法を紹介したいと思います。
スラッシュコマンドを作るのは初心者ですので、初歩的な部分のみですが、少しでも参考になればと思います。

# 何を作るか
今回は入力したコメントをアスキーアートにして応答するスラッシュコマンドを作成したいと思います。
アスキーアートはコマンドを入力する度にランダムで変わるようにします。
また、コメントが入力されなかった場合は、吹き出しのないアスキーアートを出力します。


- コマンド  
    ```/aa-comment [コメント]```
- 想定  
    me ：```/aa-comment お疲れ様でした！```  
    bot：  
　|￣￣￣￣￣￣￣￣￣￣  
　| 　お疲れ様でした！  
　|＿＿＿＿＿＿＿＿＿＿  
　　　  ∧ ∧   ||  
　　　 ( ﾟдﾟ)||  
　　　 /　づΦ  

# 事前準備
下記はすでに実施済みの前提で記載します。

- サーバーの構築
- Node-REDのインストール
- Mattermostのインストール

# 作成する前にNode-REDを知る
Node-REDは、ブラウザから作成することができ、カプセル化された様々な機能(ノード)を繋ぐことで、ウェブサイトやサーバーベースアプリ等を簡単に実現できるツール。

基本的な使い方は下記サイトにお世話になりました。

- [Node-RED入門](https://qiita.com/egplnt/items/222a3ae289472bb759b1)

# Node-RED側を作成
## 構成
![構成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700857/8ab4258b-e480-cdc8-fca1-ffc2c77f1908.png)

## 各ノードの説明

|No.|ノード名|使用ノード|設定値| 機能説明|
|---|---|---|---|---|
|①|Mattermostからの入力を受け取る|http in|<ul><li>メソッド：POST</li><li>URL：/api/v1/aa_comment</li><ul>|HTTPエンドポイント|
|②|msgデバッグ|debug|<ul><li>対象：msgオブジェクト全体</li><li>出力先：デバッグウィンドウ</li><ul>|デバッグウィンドウにmsgオブジェクトの中身を全て表示する|
|③|投稿を表示|change|<ul><li>値の代入：msg.payload.response_type</li><li>対象の値：in_channel</li><ul>|コマンドからの応答をチャンネルに表示させる|
|④|msg.payload.textデバッグ|debug|<ul><li>対象：msg.payload.text</li><li>出力先：デバッグウィンドウ</li><ul>|デバッグウィンドウにmsgオブジェクトの中身を全て表示する|
|⑤|成功|http response|<ul><li>状態コード：200</li><ul>|レスポンスを送り返す|
 
- ❶アイコン設定  
    応答時のBotのアイコン画像を設定する。<br>コマンドを入力したユーザのアイコンになる。<br>※チャット内で画像を添付し、そのURLを設定することで固定画像にすることも可能。
    - ノード：function
    
```
msg.payload.icon_url = `https://[サーバー固有]/api/v4/users/${msg.payload.user_id}/image`;

return msg;
```

- ❷コメント有無判定
    msg.payload.textにコマンド以降の引数(コメント)が代入されるため、文字数で条件分岐する。
    - ノード：switch
![コメント有無判定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700857/26d38a71-cd3a-fae7-561b-0194a8fea256.png)


- ❸❹コメント有／無
    ❷の条件分岐でmsg.payload.text(コメント)の文字数が1以上だった場合と0だった場合の処理。<br>配列に複数のアスキーアートを記述しておき、その中からランダムでアスキーアートを選択する。文字数1以上の場合、吹き出しに埋め込むようにコメントと連結し、msg.payload.textに代入する。文字数0の場合は選択したアスキーアートをそのままmsg.payload.textに代入する。
    - ノード：function

```:コメント有
var comment;
var aa_box;
var rand_num;

comment = msg.payload.text

aa_box = [
    ["　|￣￣￣￣￣￣￣￣￣￣\n　| 　","\n　|＿＿＿＿＿＿＿＿＿＿\n　　　  ∧ ∧   ||\n　　　 ( ﾟдﾟ)||\n　　　 /　づΦ"],
    ["　　　ﾋﾞｼｯ!!\n　 ∧__∧ 　　 ／￣￣￣￣￣￣￣￣￣￣\n　(  ﾟДﾟ)　＜　","\n　( ⊃   ＼⊃    ＼＿＿＿＿＿＿＿＿＿＿\n　　＼　 )ρ\n　　 く く"]
    ];

rand_num = Math.floor( Math.random () * aa_box.length)
msg.payload.text = aa_box[rand_num][0];
msg.payload.text += comment;
msg.payload.text += aa_box[rand_num][1];

return msg;
```    
```:コメント無
var aa_box;

aa_box = [
    "　 ∧＿∧\n　(・∀・)  ／＼   < よっ！日本一！\n　ノ つ つ    ●  )\n⊂、　ノ　＼／\n　 し′",
    "　　　　　　　 　ﾍ　へ　　　　\n　　　　　　　　;| / ／　　　　\n　　　　　 　　 .;: \":;.　　　　\n　　∧,∧,..,.... ,,､., : 、\n　;' ﾟД ﾟ、､:、.:.: : ;:' 　\n　'､;: ...: ,:. :.:.､.: '　　 えび天\n　　｀\"∪ ∪''''ﾞ"
    ];

msg.payload.text = aa_box[Math.floor( Math.random () * aa_box.length)];

return msg;
```

# Mattermost側を作成
1. メインメニューから「統合機能」を選択
![統合機能](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700857/47c6f406-2352-d5bf-765e-5a57e57bb4e6.png)

2. 「スラッシュコマンド」を選択
![スラッシュコマンド](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700857/7e78a8c8-2980-8dae-2e78-c5efc6a27863.png)

3. 「スラッシュコマンドを追加する」を押下
![スラッシュコマンドを追加する](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700857/1f77809d-0c38-a01f-44ed-a45b7302395f.png)

4. 設定値を入力する
    - リクエストURL：http://[サーバー固有]/api/v1/aa_comment ※http inノードで設定したもの
    - 自動補完：チェック ※未チェックだと候補に表示されない
![設定値を入力する](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700857/97be3729-123f-d696-0d20-7ce025e58df8.png)

# 動作確認
- ```/aa_commend```を入力すると候補に表示される

![動作確認1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700857/8f3019db-d029-0a41-40dd-7df70f81c194.png)

- ```/aa_comment お疲れ様でした！```を入力

![動作確認2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700857/2f150744-bad9-0466-217a-725cdb834c68.png)
別のパターン
![動作確認3](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700857/19a1a4f2-44d4-1b45-e848-0081a5e1ed8d.png)

- ```/aa_comment```を入力

![動作確認4](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700857/661c3d5e-0062-5445-b97c-77368d8a4ad9.png)


# 上手くいってないところ・やりたいこと
下記項目は時間があるときに改善・改良していこうと思います。

- 上手くいってないところ
    - アスキーアートをブラウザからコピペすると表示がずれる
    - 特殊文字のエスケープが上手くいかない
    - ブラウザ版とアプリ版で見え方が違う
- やりたいこと
    - コメントの位置と吹き出しの大きさを揃えたい
    - アスキーアートを簡単に登録できるようにしたい

# おわりに
今回は、Node-REDを使ってアスキーアートを出力するMattermostのスラッシュコマンドを作成しました。
完成後すぐに多くの方に使ってもらえたので嬉しかったです。
また面白いスラッシュコマンド案ができたら作りたいと思います。
最後まで読んでいただきありがとうございました。