こんにちは。鈴木商店の松内です。
今回は最近利用し始めたslack botについてのご紹介です。
社内でslackを使用していて、社外の方にはゲストアカウントを割り当てるケースは多いと思います。鈴木商店でも一部のプロジェクトでは客先の担当者やエンジニアにシングルチャンネルゲストとしてプロジェクト用のチャンネルに参加いただいていますが、ゲストユーザー関係なく『ユーザーグループメンションを利用したい』ということがありました。
社内で運用中のユーザーグループ (例:
@pj-engineer
)をゲストにも使ってほしい…・ ゲスト(客先)からの急を要する連絡や運用トラブルなどの連絡が個人宛(一部の担当者宛)になっていた。
・@here
や@channel
は開発者以外の関係者がいるため使いたくない
・ 関係者の入れ替わりや増減があるので、宛先はこちら(社内)の都合でメンテしたい
slackのゲストユーザーのユーザーグループに関わる制限について
以上の経緯を踏まえて、slackのユーザーグループの、運用上支障があると感じる仕様(ゲストに対する制限)についてまとめます。
①ユーザーグループに参加できない
ゲストユーザーはユーザーグループへ追加できません。
そのため、ゲストユーザーと社内のメンバーとを一括りにしたグループ作ってメンションすることができません。
②投稿されたユーザーグループ名が見えない
ゲストユーザーは通常メンバー(社内アカウント)が使用しているユーザーグループのメンションを見ることができません。
ゲストユーザーからは 不明なグループ
という表示となります。 (※ブラウザ表示では該当箇所が空白で表示されます。)
ゲストユーザーから見た、ユーザグループメンション (ブラウザ表示)
また、ゲストユーザーは @
入力後のサジェストにユーザーグループが表示されません。
③ユーザーグループのメンションを利用できない
ゲストユーザーがユーザーグループ (例:@pj-engineer
)を投稿してもメンションとしては機能しません。
ゲストユーザーがユーザーグループメンションを使用した例
ユーザーグループのメンションを補助するslackアプリ (slack bot)
前置きが長くなりましたが、さきほどの①〜③を回避するために、以下のようなslack botを作成しました。
・ 特定のゲストが特定のユーザーグループを使用した際に、同じスレッドへslackボットからメンションを返す
・ ゲストを含むユーザーグループ(slack外で定義)が投稿された場合、同じスレッドへslackボットからゲストを含めたユーザーのメンションを返す
その他の仕様
・社内の一部のチャンネルで使用するため、対象とするゲストユーザーやユーザーグループを指定できる
・通常ユーザーが社外のユーザーを含まないユーザーグループを使用した際は反応しないようにする
ボットの使用例
ゲストユーザーがユーザーグループを使用した例
通常ユーザーがゲストを含むユーザーグループを使用した例
slack上では設定できませんが、ゲストユーザー含めたメンションをボットが返します。
slack botは公式のこちらを参考にGlitch × Boltをベースに作成しました。
※公式の解説がとてもわかりやすいのでGlitchやslack APIのセットアップなどの説明は省略します。
スクリプト (メッセージへのメンション返信処理)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
const { App } = require("@slack/bolt"); const app = new App({ signingSecret: process.env.SLACK_SIGNING_SECRET, token: process.env.SLACK_BOT_TOKEN, }); // 対象とするゲストユーザーのアカウントID const targetGuestUsers = [ "{Uから始まるID}", // Slack ID ]; // グループに所属するユーザーのアカウントID const groupMembers = [ "<@{Uから始まるID}>", // <@"Slack ID"> ].join(" "); const userGroups = [ { id: "{Group ID}", // ユーザーグループID name: "****-pj-dev", // ユーザーグループ名 members: groupMembers, isIncludeGuest: false, // membersにGuestが含まれるかどうか }, { id: "{Group ID}", // ユーザーグループID name: "****-pj", // ユーザーグループ名 members: `${groupMembers} <@{Uから始まるID}>`, // グループメンバーのID + メンションに含めたいゲストユーザーID isIncludeGuest: true, // membersにGuestが含まれるかどうか }, ]; const sendSlack = async (message, context, text) => { try { await app.client.chat.postMessage({ token: context.botToken, channel: message.channel, thread_ts: message.event_ts, text: text, }); } catch (e) { console.error(e); } }; userGroups.forEach(({ id, name, members, isIncludeGuest }) => { // ① メッセージからユーザーグループ名の一致を購読 app.message(new RegExp(`^(?=.*${name}).*$`, "m"), ({ message, context }) => { // チャンネルゲストユーザーの場合に送信 // NOTE:重複を避けるためIDの一致 "'<!subteam^${id}|@${name}>'"を除外する if (message.text.indexOf(`<!subteam^${id}|@${name}>`) !== -1) { return; } // ゲストユーザーが含まれるグループ、もしくは対象となるゲストユーザーからのメッセージの場合メンションを返す if ( isIncludeGuest || targetGuestUsers.some((userId) => userId === message.user) ) { sendSlack( message, context, `<!subteam^${id}|@${name}> ${members || ""}` ); } }); // ② メッセージからユーザーグループIDの一致を購読 app.message(new RegExp(id), ({ message, context }) => { // チャンネルゲストユーザーの場合に送信 if ( isIncludeGuest || targetGuestUsers.some((userId) => userId === message.user) ) { sendSlack(message, context, `${name} ${members || ""}`); } }); }); // Start your app (async () => { await app.start(process.env.PORT || 3000); console.log("⚡️ Bolt app is running!"); })(); |
※ ユーザーIDやグループIDは{ ID }
など置換表記しています
概要
Boltのmessage() 関数で slackアプリが受信可能なメッセージイベントを購読し、グループに応じて指定したユーザー(members
として定義)へメンションを送っています。
それぞれのユースケースに対応するため、メッセージイベントを以下の2種類のパターンマッチにて購読しています。
・① ユーザーグループ名が含まれるメッセージイベント
・② ユーザーグループIDが含まれるメッセージイベント
①はゲストユーザーがグループメンションを使用した際のメッセージを拾うためのもので、
②はゲストを含むユーザーグループメンション(isIncludeGuest
にて定義)を使用した際のメッセージを拾うためのものです。
補足
・ 有効なグループメンションの場合、message関数内の message
には <!subteam^${groupId}|@${groupName}>
の文字列が流れてきます
・ slackのユーザーID (Uから始まる文字列)の確認方法はユーザープロフィール画面の3点リーダから メンバーIDをコピー にて取得できます
・ slackのユーザーグループIDの確認方法は (少し面倒ですが…) slackをブラウザで開き、ユーザーグループを入力した上でブラウザの検証画面でユーザーグループの箇所のHtmlタグに付与されているAttributeを確認する方法が一番簡単と思われます
最後に
いかがでしたでしょうか。
@
入力時にユーザーグループをサジェストさせることはできませんが、このボットによってゲストユーザーに事前に共有しているユーザーグループのメンションを利用してもらうことができました。
今回に限らず、slack公式の解説にあるように、Glitchでボットに必要な環境が一瞬で揃うので、もっと気軽にslack botをつくってみるのも良いかもしれません。
slackの運用で似たような課題を抱える方の参考になれば幸いです。