SREチームの中原です。 Zapier Tables でステート管理を行い Slack で人をアサインするときの重複排除する方法について書いてみます。
経緯
コードレビューや定常業務のアサインなどで Slackbot のカスタムレスポンスなどを使ってらっしゃる方も多いかとおもいます。 しかし、メンバーが少ないとどうしても乱数の偏りに困ったことも多いのではないでしょうか?
これまでは Google SpredSheet などをつかってかなりめんどくさい実装をしないとステート管理できないので諦めてたのですが、 Zapier が Zapier Tables という簡易DB機能を出してくれたので、これでいけるやん!とアサインが一巡するまで重複排除するようにしてみました。
Zapier Tables は 2023/06 現在でまだ beta であるため Zapier の最新のドキュメントなどもごらんください。
https://help.zapier.com/hc/en-us/categories/13398036609933-Tables
タスクをアサインする場合の実装
テーブルの作成
Zapier Tables でタスクをアサインするメンバーの Slack ID とアサイン状況のフラグを管理するテーブルを作成します。 また、利用状況にあわせて Share も行ってください。
- SLACK_ID: Text アサイン対象のメンバーの Slack ID
- DONE: Number アサイン済みかどうかのフラグ
- NAME: Text Slack ID だけだと誰かわからないので管理用にメンバーの名前いれとく(システム的には使わない)
Zap の作成
以下のような Zap を作成していきます。
Slack のメッセージをフック
Slack からキックするための Triger として Slack や Webhooks by Zapier などで Triger 設定を行ってください。 環境にあわせて適切な Slack チャンネルや WebHook URL を指定する必要があります。 弊社の場合、タスク依頼用の専用 Slack チャンネルでワークフローを設定したり、独自 Slack コマンド用の SlackBot の webhook を利用したりしてます。
ここでは Slack の特定のチャンネルで taskplz というプレフィックスのメッセージをフックするようにしてます。
Zapier Table から未アサインのメンバーを取得
DONE カラムでアサイン状態のフラグを管理しているので、 DONE カラムが 0 のデータを取ってくることで未アサインのメンバーのデータを取得できます。
Python でメンバーを抽選し出力メッセージを整形
Python で、取得したメンバーの抽選、メッセージの整形、残りの未アサインメンバー数の計算を行います。
import random arg = input_data['arg'] ids = input_data['ids'].split(',') remain = len(ids) id = random.choice(ids) message = '<@' + id + '>' + arg.replace('taskplz ','') output = [{'AssignID':id, 'message': message, 'remain':remain}]
Slack へメッセージをポスト
Slack へのメッセージをポストします。 メッセージの取得時と同様に適宜環境に合わせてください。
未アサインの人が残っている場合の処理
未アサイン人数が 1 より大きい(2以上)の場合、アサインされた人にアサイン済みフラグをつけます。 Zapier Table でレコードの更新を行うには独自のレコード毎の ID (Data ID) が必要なため、一度アサインされた人の Slack ID で検索してから更新を行う必要があります。
全員アサイン済みの場合の処理
未アサイン人数が 2 未満(最後の1人)だったときは、アサイン済みフラグが立っている全メンバーのフラグをループで 0 に更新してリセットします。
使い方
これで、対象チャンネルで以下のようなポストをすると、Zapier がアサインされたメンバーにメンションをとばしてくれるはずです。
taskplz 依頼内容
まとめ
といった感じで、 Zapier でステートを持った処理が簡単に実装できるようになったので、使いでがかなりありそうです。 ただ、まだ beta ということもあってかプリミティブな検索条件しか指定できなかったり、python からテーブルに直接アクセスできなかったり、使いづらい部分も残っています。 具体的にはレビュー依頼の実装しようとして、依頼者を除外して対応回数が最小のメンバーを抽出しようとしたのですが、SQL の count, min, max, avg に相当する処理はできなそうで、テーブルのデータをまるごと取得して python で処理する方法しかありませんでした。 今後に期待しましょう!