Slack Platform で絵文字の追加を通知する bot を作った
お悩み
全員がフルリモートワークの弊社では Slack を使用して日々のやり取りをしています
文字だけのやり取りだと寂しいので大量の絵文字を追加して彩りを与えてくれる職人が弊社にはいますが、職人が最高の絵文字を追加しても誰も気づかずそのまま絵文字の山に埋もれてしまう問題がありました
ということで、絵文字が追加されたら通知してくれるボットを Slack Platform で作ってみました
Slack Platform とは?
簡単に言うと今までの HTTP API ベースの処理ではなく、Trigger/Workflow/Function を定義していい感じに Slack のイベント処理ができる凄いやつです
言語は今最もアツい言語(※ワニ調べ)の Deno が採用されています
詳しくは公式サイトや Zenn に詳しく書いてくれている方がいるので読んでみてください
完成したもの
Slack Platform さえ使えたらどの環境でも使えると思うので、ぜひ皆さんの絵文字パーティー活動に活かしてください
絵文字が追加されるとこんな感じで通知されます
細かい実装については以下に書いていきます
フローチャート
絵文字の追加/削除/変更を行なうと各種 Trigger
が発火して Workflow
-> Function
とデータが流れて最終的にメッセージが Slack にポストされます
実装詳細
Trigger
Event Type
event
は emoji_changed
です
type: TriggerTypes.Event,
event: {
event_type: "slack#/events/emoji_changed",
filter
filter: {
version: 1,
root: {
statement: "{{data.subtype}} == add",
},
},
emoji_changed
は subtype
を add|remove|rename
の3種類で送ってくるので、それぞれの Trigger
に filter
を設定しています
Event Trigger
は特定のイベントをキャッチする機能ですが、イベントの内容で分岐は発生しないため filter
を使って subtype
を判定しています
filter
を設定しない場合、例えば add subtype
のイベントで rename trigger
が発火して input_paramrameters
の不整合によってエラーが発生したりします
最初は1つの Trigger
で全イベントを拾おうと考えていましたが、後述する Workflow
/Function
の input_parameter.required
の定義が難しいため subtype
ごとに Trigger
を作成しました
Workflow
input_parameters
input_parameters: {
properties: {
name: {
type: Schema.types.string,
},
value: {
type: Schema.types.string,
},
},
required: ["name", "value"],
}
subtype
ごとにワークフローを定義してあります
workflow
には input_parameter
に対して required
を設定できますが、subtype
ごとに以下のようにパラメータが異なります
すべての subtype
を1つの workflow
で扱おうとすると辛いコードになるため、subtype
ごとに workflow
を定義しました
addStep
RemoveWorkflow.addStep(SendMessageFunction, {
message: `emoji removed! ${RemoveWorkflow.inputs.names}`,
});
後続のメッセージ送信 function
に渡すメッセージを定義しています
subtype: remove
の場合は削除された絵文字に紐づくエイリアスも Trigger
から渡ってくるため、以下のように string[]
で定義されているのですが
names: {
type: Schema.types.array,
items: {
type: Schema.types.string,
},
},
addStep
のタイミングでは {{inputs.names}}
という文字列のまま評価されていないので Array.join(',')
などを噛ませる事ができず、以下のようなメッセージになっています
emoji removed! ["test-emoji"]
function
で処理することで対処できそうですが、今回はそこまで重要な処理でもない箇所のため許容することにしました
Workflow
内での解決策をご存じの方は教えてください
Function
export default SlackFunction(
SendMessageFunction,
async ({ inputs, env, client }) => {
const notifyChannelID = env["NOTIFY_CHANNEL_ID"];
if (notifyChannelID == null) {
return {
outputs: { notified: false, message: "env NOTIFY_CHANNEL_ID is empty" },
};
}
const { message } = inputs;
await client.chat.postMessage({
channel: notifyChannelID,
text: message,
});
return { outputs: { notified: true, message: message } };
},
);
env
から送信先のチャンネル ID を取得し、受け取った message
を送信するだけのシンプルな処理です
以上です
clone して env に送信先チャンネル ID を設定するだけで絵文字の追加を監視できるので、ぜひ使ってみてください
FB や改善希望等あればお気軽にコメントお願いします
Discussion