Node-REDでSlackのSocket Modeを使ってみた


SlackのSocket Modeを使ってNode-RED上でSlackのイベントを取得するノードを実装したので、その紹介記事になります。

想定読者

やったこと

SlackでSocket ModeがGAされたので、公式のSDKを使ってNode-REDでSocket Modeを使ったEvents API用のノードを実装&公開しました。

開発環境

  • Ubuntu 18.04
    • 実際はWindows10上のWSL2で動かしています。
  • Node.js v12.20
  • Docker v20.10
    • WSL2 + Docker Desktop for Windowsで動かしています。
    • Node-REDを動かすのに利用しています。
  • docker-compose v1.27

使い方

Slackアプリケーションの作成

  • 公式ドキュメントの"Intro to Socket Mode"を参考にして、Slack用アプリケーションの作成とapp-level tokenの生成、ワークスペースへのアプリケーションのインストールを行います。
  • アプリ管理画面のOAuth & Permissions->Scopes->Add an OAuth scopeからイベント取得に必要な権限(スコープ)を設定します。
    • Socket Modeを有効にしている場合、デフォルトでapp_mentions:read(アプリケーション宛てのメンション)が追加されています。
    • メンションがない通常の投稿を拾いたい場合はchannels:history(Publicチャンネルの投稿取得)やgroups:history(Privateチャンネルの投稿取得)を追加します。
  • アプリ管理画面のEvent Subscriptions->Subscribe to bot events->Add Bot User Eventから取得するイベントの種類を選択します。
    • メンションを取得するイベントはapp_mention、Publicチャンネルの投稿イベントはmessage:channels、Privateチャンネルの投稿イベントはmessage:groupsを選択します。

Node-REDの起動とノードの追加

$ docker volume create nodered-test-vol
nodered-test-vol
$ docker run -d -p 1880:1880 -v nodered-test-vol:/data -v /etc/localtime:/etc/localtime:ro --name nodered-test nodered/node-red:latest-12-minimal
Unable to find image 'nodered/node-red:latest-12-minimal' locally
latest-12-minimal: Pulling from nodered/node-red
0a6724ff3fcd: Already exists
5fd2bdfdbf4b: Already exists
80b224d472a8: Already exists
e21405c347ae: Already exists
b6afffd6ee9d: Pull complete
78320e61ab74: Pull complete
ba2a0afb7fb7: Pull complete
09f8757c9445: Pull complete
db061e81eb3b: Pull complete
3c59eb56174f: Pull complete
a11846f67ffa: Pull complete
0b0bc0c51c26: Pull complete
Digest: sha256:4b7d40ab5aa0fe307f4dc7b10c6aa0da47f7001bd41e1ff794dde07bd351534e
Status: Downloaded newer image for nodered/node-red:latest-12-minimal
d5eb6de063b2c8e1f6523bccf9f91c1c30acb6e7d3054c435c88a0171c9ddb83
  • ブラウザで http://localhost:1880 にアクセスし、Node-REDの実装画面を開きます。

    • 上記のDockerを使った方法では以下のような警告コメントが表示されますが、無視してください。
  • 画面右上のメニュー展開ボタンをクリックし、パレットの管理->ノードを追加で検索バーにnode-red-contrib-slack-socketを入力し、出てきた項目のノードを追加ボタンをクリックします。(確認のポップアップが表示されるので追加をクリックします)

  • ノードのインストールが完了したら(「ノードをパレットに追加しました」というポップが表示されたら)画面左側のノードが羅列されているエリアの下のchatセクションにSlack Listenがあることを確認します。

ノードの設定

  • 画面中央にSlack Listenノードを配置(ドラッグ&ドロップ)し、配置したノードをダブルクリックして設定画面を表示します。

  • 設定画面のSettingsの行にある編集アイコン(鉛筆アイコン)をクリックしてトークンや取得するイベントの指定画面を表示します

  • 以下の通り情報を入力します。

    • Name:設定の名前(なんでもOKです)
    • Token:Slackアプリケーションを作成したときに生成したapp-level token
      • OAuthトークンではなく、xapp-から始まるトークンになるので注意してください。
      • なお、デフォルトではトークンを直接入力するようになっていますが、Node-REDのglobalContextや環境変数から指定できるようにもなっています。
        • 例えば、環境変数から指定する場合は入力欄左のアイコンをクリックして$ 環境変数を選択し、環境変数名(SLACK_APP_TOKENなど)を指定します。
    • Events:取得するイベント名
      • イベント名はSlackのAPI Event TypesにあるWorks with列にEvent APIと記載があるもの(例:app_mentionmessageなど)を指定します。
      • 複数のイベントを指定する場合はapp_mention,messageのようにカンマ区切りで指定します。
  • 設定画面右上の追加->完了をクリックします。

Slackイベントの取得

  • Slack Listenノードにdebugノードを接続し、画面右上のデプロイボタンをクリックします。

  • Slack Listenノードの下にconnectedと表示されることを確認したらSlackからアプリケーション宛てにメンションでメッセージを送ります。

    • connectedと表示されない場合は、Socket Modeが有効になっているか、トークンが有効なものか(Revokeされていないか、app-level tokenかなど)を確認してください。
  • 画面右側にあるデバッグアイコン(虫のアイコン)をクリックし、Slack Listenノードで取得したイベント情報(前項で送られたメッセージの情報)がdebugノードから出力されていることを確認します。

Slack Listenノードでは取得したイベント情報をそのまま出力しているので、出力内容を事前に知りたい場合はSlackの各Event APIの試用を参照してください。

また、取得したイベント情報の加工などを行う場合は適宜changeノードやfunctionノードなどをつないで処理を実装してください。(以下の例ではアプリケーション宛てのメンションからメッセージ部分のみを取得しています)

その他

イベントが取得できない場合は以下を確認してみてください。

  • Slack Listenノードの下にconnectedと表示されているかどうか
    • connected以外の場合は設定したトークンが正しいものかどうか確認してください
  • Slackのアプリ管理画面(OAuth & Permissions->Scopes)にてイベント取得のための権限が十分かどうか
  • Slackのアプリ管理画面(Event Subscriptions->Subscribe to bot events)にて取得可能なイベントがちゃんと指定されているかどうか

参考