Slackのコマンドハンドラをモジュールベースにする

Why

slackbot.jsにhelp, search, create ... 全てのコマンドが書かれていたが行数が膨大になり、切り分けるときが来た。 コマンドの後の Interaction も共犯なのでこれも一緒にきれいにしていく。

変更後ファイル構成

  • コマンドハンドラ Service => server/service/slack-command-handler/
  • slack-command-handler/ => slack-command-handler & 各コマンドモジュール(search.js, create.js, togetter.js ...)
  • block-kit-builder => packages/slack/util
    • BlockKit に関わるメソッドを配置
  • 一つのコマンドのみに関わる処理 => 各コマンドモジュール
  • コマンド間で共通の処理 => packages/slack/util

変更後の仕様

  1. 命名規則
  • block_actions, viewsubmission で使用するaction_id, callback_id -> commandName:handlerName のフォーマットで命名 (handlerName イコール 実際のハンドラの名前)

  • state.values のみで使用するaction_id, callback_id -> :を使わないで Snake case で命名 (ex. oldest, page_path)

    • Snake caseにするのは、他のpayloadのプロパティと揃えるため
  1. ファイル
  • slackbot.js

    • handleCommand(), handleBlockActions(), handleViewSubmission() のみにする
      • handleCommand() はルート兼コントローラーの責務を負う(レスポンス役)
      • handleBlockActions(), handleViewSubmission() はそれぞれハンドリング
  • slack-command-handler.js

    • handleCommand(), handleBlockActions(), handleViewSubmission() の delegate
  • 各コマンドモジュール

    • delegate に従って実装
    • handleBlockActions(), handleViewSubmission()
      • メソッド名を commandName:actionHandlerName から抽出してそのまま実行
  1. エラーハンドリング
  • SlackbotError クラス

    • method, to, popupMessage, mainMessage をコンストラクタの引数として持ちます
      • method: 'postMessage' OR 'postEphemeral'
      • to: 'dm' OR 'channel'
      • popupMessage: 通知に表示されるメッセージ
      • mainMessage: dm か channel に送信されるメッセージ
  • slackbotResponce 関数

    • client, body, err を引数として持ちます
    • client: @slack/web-api WebClient
    • body: express の req.body
    • err: コントローラーで SlackbotError が throw される処理がある時は、catch した err を渡す
    • SlackbotError 以外の Error は throw します
  • 実装するファイル

  • models/vo/

    • slack-bot-error.js
      • constructor({method, to, popupMessage, mainMessage})
  • service/slack-command-handler/

    • slack-bot-response.js
      • slackbotResponse 関数
  1. モジュールをクラスベースにする Coming soon ...