これで初心者卒業!Slackで問い合わせ受付アプリを作ってみよう

Slackで作る問い合わせ受付アプリ

前回、簡単なオウム返しBotを作成しました。

思ったよりも簡単にオウム返しBotを作成できたと思いませんか?
しかし、オウム返しBotを使用して、業務効率化を図るのは難しいですよね。

そこで今回はレベルアップして、問い合わせ受付アプリの作成方法を解説します。オリジナルの問い合わせアプリが作れるようになれば、定型業務の効率化が図れます!

プログラミング経験1年の筆者が、初心者の方にもできるだけわかりやすいようにご説明します。

※Slackは、Slack Technologies,Incの商標および登録商標です。

Slack導入へ向けた提案書の書き方(無料)

Slack導入へ向けた提案書の書き方

Slack導入へ向けた提案書の書き方
Slackを導入のための提案書の書き方を解説した資料です。弊社の事例を踏まえて経営層への提案の仕方をまとめました。

問い合わせ受付アプリの完成イメージ

問い合わせ受付アプリの完成イメージ
  1. グローバルショートカットを使用して、アプリを起動
  2. モーダルに問い合わせ内容を入力
  3. 作成者、担当者、CCに追加されているユーザに問い合わせ内容の通知が行く

プラットフォーム:Glitch
フレームワーク:Bolt
言語:Node.js

Slackではモーダルというものを表示させることができます。

モーダルとは簡単にいうと、入力フォームのポップアップ画面のようなものです。
前回オウム返しBotの作成に使用したBoltフレームワークを使えば、簡単にモーダルを使ったBotを作成することができます。

今回はモーダルを使用した問い合わせ受付アプリ作成していきます!

事前準備:GlitchプロジェクトをRemixする

以下URLにアクセスし、Slack社が用意しているGlitchプロジェクトをRemixします。
https://glitch.com/edit/#!/remix/slack-bolt-hello-world

※上記URLにアクセスした後に表示されるページは閉じないでください。

Glitchに関する詳しい説明は前回の記事に載っているので、わからない方はチェックしてみてください。
【30分で完成】オウム返しBotから始めるSlackアプリの作り方
GlitchプロジェクトをRemixする

問い合わせ受付アプリを実際に作成してみよう!

Slackへのアプリ追加方法の詳しい説明は前回の記事の手順1~6をご参照ください。
【30分で完成】オウム返しBotから始めるSlackアプリの作り方
詳細手順

手順一覧

  1. 追加したアプリのBasic Informationへ移動する
  2. 開いた画面にある「Bots」を押下
  3. 「Review Scopes to Add」を押下
  4. 「Scopes」で「Add an OAuth Scope」を押下
  5. 「chat:write」を追加
  6. 左サイドバーから「App Home」を選択
  7. 「App Display Name」で「Edit」を押下
  8. 「Display Name(Bot Name)」にボット名、「Default username」に適当なユーザ名を入力し、「Add」を押下
  9. 左サイドバーから「Install App」を選択し、「Install to Workspace」を押下し「許可する」を押下
  10. 左サイドバーから「OAuth & Permissions」を選択し、「Bot User OAuth Token」をメモ
  11. 左サイドバーから「Basic Information」を選択し、「Signing Secret」項目の「Show」を押下し表示させたのち、内容をコピーしメモ
  12. 事前準備でRemixしたGlitchプロジェクト画面に戻り、「.env」ファイルの「SLACK_SIGING_SECRET」「SLACK_BOT_TOKEN」に先ほどコピーした内容を貼り付け
  13. 「Interactivity & Shortcuts」で「Interactivity」をオンにする
  14. 「Request URL」にURLを指定し、「Create New Shortcut」を押下
  15. 「Global」を選択
  16. ショートカットの名前、説明、Callback IDを決める
  17. Glitchに戻り、envファイルに「INQUIRE_MANAGER」行を追加
  18. Block Kit Builderにアクセス
  19. ページ右上の「Clear Blocks」を押下
  20. 左上のMessage Previewを「Modal Preview」に変更し、左サイドバーから使用したいブロックを選択
  21. Glitchに戻り「index.js」ファイルの内容を以下に変更

手順詳細

1. 追加したアプリのBasic Informationへ移動する

Basic Informationへ移動

2. 開いた画面にある「Bots」を押下

Botsを押下

3. 「Review Scopes to Add」を押下

ReviewScopesToAddを押下

4. 「Scopes」で「Add an OAuth Scope」を押下

AddAnOAuthScopeを押下

5. 「chat:write」を追加

chatwriteを追加

6. 左サイドバーから「App Home」を選択

AppHomeを選択

7. 「App Display Name」で「Edit」を押下

AppDisplayNameでEditを押下

8. 「Display Name(Bot Name)」にボット名、「Default username」に適当なユーザ名を入力し、「Add」を押下

DisplayNameで入力後にAdd押下

9. 左サイドバーから「Install App」を選択し、「Install to Workspace」を押下し「許可する」を押下

許可する押下

10. 左サイドバーから「OAuth & Permissions」を選択し、「Bot User OAuth Token」をメモ

メモは後ほど使用します。

BotUserOAuthTokenをメモ

11. 左サイドバーから「Basic Information」を選択し、「Signing Secret」項目の「Show」を押下し表示させたのち、内容をコピーしメモ

メモは後ほど使用します。

BasicInformationを選択

12. 事前準備でRemixしたGlitchプロジェクト画面に戻り、「.env」ファイルの「SLACK_SIGING_SECRET」「SLACK_BOT_TOKEN」に先ほどコピーした内容を貼り付け

Glitchプロジェクト画面で貼り付け

13. 「Interactivity & Shortcuts」で「Interactivity」をオンにする

Interactivityをオン

14. 「Request URL」にURLを指定し、「Create New Shortcut」を押下

CreateNewShortcut

Glitchの場合は「https://プロジェクト名.glitch.me/slack/events」を指定します。
プロジェクト名は事前準備でメモしておいたものです。

15. 「Global」を選択

Globalを選択

Global:Slackのトーク画面のどこからでもショートカットにアクセスできます。
On messages:特定のメッセージからアクセスします。
       →メッセージの内容を取得したい場合はこちらをお勧めします。

16. ショートカットの名前、説明、Callback IDを決める

ショートカットの名前CallbackID

Callback IDとは・・・?
 どのショートカットが起動したかを区別するための一意の値です。
 こちらは後ほどコード内で使用します。

17. Glitchに戻り、envファイルに「INQUIRE_MANAGER」行を追加

key(左側) :INQUIRE_MANAGER
value(右側) :問い合わせ受付担当者のSlackメンバーID

envファイルは何のためにある?

envファイルに追加されている値を環境変数といいます。
例えば
「いろんな組織でコードを使いまわしたいけど、値が組織によって違う」
といったときにこの環境変数を使用すると、解決することができます。
以下表の左列をkey、右列をvalueといいます。

INQUIRE_MANAGER行を追加

コード内では「key」を使用して実装します。
(参照するには「process.env.keyname」と書きます)
実際に使いたい値は「value」に指定すれば、コードを書き換えることなく、組織間で同じコードを使用することができます。

18.Block Kit Builderにアクセス

Block Kit Builderとは画面レイアウトのサンプル作成ツールです。

https://api.slack.com/tools/block-kit-builder

左画面のUIプレビューから右画面にJSONのサンプルコードを生成することができます。
使用したいブロックをドラッグ&ドロップで組み立てることができ、実際の完成イメージを確認することも可能です。

19. ページ右上の「Clear Blocks」を押下

20. 左上のMessage Previewを「Modal Preview」に変更し、左サイドバーから使用したいブロックを選択

今回使用するブロックは上から順に以下になっています。

plain text input短い入力ができる
static select選択肢を用意することができる
multiline plain text input長文を入力することができる
multi users selectワークスペースに存在するユーザを選択できる
ModalPreviewに変更

21. Glitchに戻り「index.js」ファイルの内容を以下に変更

Blocks部分に先ほどBlock Kit Builderで作成したBlocksの中身を貼り付けます。

const { App } = require('@slack/bolt');

const app = new App({
  signingSecret: process.env.SLACK_SIGNING_SECRET,
  token: process.env.SLACK_BOT_TOKEN
});

/*
*ショートカットで[問い合わせ作成]が押下された時に呼ばれるメソッド
*/
app.shortcut("q_create", async ({ shortcut, ack }) => {
  await ack();
  const trigger_id = shortcut.trigger_id;    //モーダルが呼び出された時に付与される
  const callback_id = shortcut.callback_id  //q_create
  const argument = {
    "trigger_id": trigger_id,
    "view": {
      "type": "modal",
      "callback_id": callback_id,
      "title": {
        "type": "plain_text",
        "text": "問い合わせフォーム",
        "emoji": true
      },
      "submit": {
        "type": "plain_text",
        "text": "提出",
        "emoji": true
      },
      "close": {
        "type": "plain_text",
        "text": "キャンセル",
        "emoji": true
      },
      "blocks": [ //手順20で作成したblocksを貼り付ける
        {
          "type": "input",
          "block_id": "subject",  //block_idは今回必ず指定
          "element": {
            "type": "plain_text_input",
            "action_id": "plain_text_input-action"
          },
          "label": {
            "type": "plain_text",
            "text": "件名",
            "emoji": true
          }
        },
        {
          "type": "input",
          "block_id": "category",
          "element": {
            "type": "static_select",
            "placeholder": {
              "type": "plain_text",
              "text": "選択してください",
              "emoji": true
            },
            "options": [
              {
                "text": {
                  "type": "plain_text",
                  "text": "福利厚生について",
                  "emoji": true
                },
                "value": "value-0"
              },
              {
                "text": {
                  "type": "plain_text",
                  "text": "パスワードの失念",
                  "emoji": true
                },
                "value": "value-1"
              },
              {
                "text": {
                  "type": "plain_text",
                  "text": "相談",
                  "emoji": true
                },
                "value": "value-2"
              }
            ],
            "action_id": "static_select-action"
          },
          "label": {
            "type": "plain_text",
            "text": "問い合わせ種別",
            "emoji": true
          }
        },
        {
          "type": "input",
          "block_id": "contents",
          "element": {
            "type": "plain_text_input",
            "multiline": true,
            "action_id": "plain_text_input-action"
          },
          "label": {
            "type": "plain_text",
            "text": "問い合わせ内容",
            "emoji": true
          }
        },
        {
          "type": "input",
          "block_id": "user_select",
          "element": {
            "type": "multi_users_select",
            "placeholder": {
              "type": "plain_text",
              "text": "ユーザ選択",
              "emoji": true
            },
            "action_id": "multi_users_select_action"
          },
          "label": {
            "type": "plain_text",
            "text": "CC",
            "emoji": true
          },
          "optional": true
        }
      ]
    }
  };
  await app.client.views.open(argument);
});
/*
*問い合わせが提出されたときに呼ばれるメソッド
*/
app.view("q_create", async ({ ack, body, view }) => {
  await ack();  
  const createUser = body.user.id; // 問い合わせ作成者
  const category   = view.state.values.category["static_select-action"].selected_option.text.text; // 問い合わせ種別
  const contents   = view.state.values.contents["plain_text_input-action"].value; // 問い合わせ内容
  const subject    = view.state.values.subject["plain_text_input-action"].value; // 問い合わせ件名
  const ccUsersArr = view.state.values.user_select.multi_users_select_action.selected_users; // CCに追加されたユーザのリスト
  const txt        = `作成者 :<@${createUser}>\n`+
                     `種別  :${category}\n`+
                     `件名  :${subject}\n`+
                     `内容  :${contents}`;
  const mentionList = []; //CCに追加されているユーザをメンション形式にしたものを格納するリスト
//ccユーザのメンション作成と通知送信
  for(let id of ccUsersArr){
    mentionList.push(`<@${id}>`);
    //CCに入っているユーザへ送信
    await app.client.chat.postMessage({
            channel: id,
            text:`<@${createUser}>が問い合わせを作成しました。\n${txt}`
    });
  }
  
  //問い合わせ担当者へ送信
  await app.client.chat.postMessage({
          channel: process.env.INQUIRE_MANAGER,
          text:`問い合わせがきました。\n${txt}`
  });
  
  //問い合わせ作成者へ送信
  await app.client.chat.postMessage({
          channel: createUser,
          text:`問い合わせを作成しました。\n${txt}\nCC    :${mentionList}`
  });
});
  
//アプリ起動時に呼ばれるメソッド
(async () => {
  await app.start(process.env.PORT || 3000);
  console.log('⚡️ Bolt app is running!');
})();
  • 「app.shortcut」の引数はショートカットを作成したときに設定したcallback IDをセットします。この関数はショートカットからモーダルを呼び出したときによばれます。
  • 「app.view」の引数はショートカットを作成したときに設定したcallback IDをセットします。この関数はモーダルで提出ボタンを押下したときに呼ばれます。
  • 「block_id」は指定することをおすすめします。
    指定しておくと各blockに入力された内容を容易に取得することができます。
    指定しないときはランダムな文字列が自動的に入ります。
  • 「chat.postMessage」はSlackへメッセージを送信したい時に使用する関数です。
    他にもSlackに対してアクションできる関数が多数用意されています。
    テスターなども容易されているのでWeb API methodsをチェックしてみてください。

これでアプリの準備が整いました。

問い合わせフォームから問い合わせすると、関係者に通知されることを確認

問い合わせ受付アプリの完成イメージ

参考
Bolt フレームワークを使って Slack Bot を作ろう

https://glitch.com/edit/#!/remix/slack-bolt-hello-world

まとめ

最後までご覧いただきありがとうございました。

オウム返しBotよりもかなりレベルアップしましたね。モーダルが使えるようになると、実用的なアプリの作成ができるようになります。Slackではモーダルだけでなく、AppHomeタブやチャット内に入力フォームを出すこともできます。

さらにレベルアップしたい方はSlackが公開しているリファレンスを参考にアプリを作成してみてください。

弊社でも多種多様なアプリを作成して業務効率化に取り組んでいます。
Slackに関する情報発信を引き続き行っていくので、チェックしてくださいね。

また、Slack導入や運用でお悩みの方は、こちらよりお気軽にご相談ください。