こんにちは、Slack の公式 SDK 開発と日本の Developer Relations を担当している瀬良 (@seratch) と申します
この記事は Slack の次世代プラットフォーム機能を少しずつ試しながら、ゆっくりと理解していくシリーズの記事です。
「次世代プラットフォーム機能って何?」という方は、以下の記事で詳しく解説しましたので、まずはそちらをお読みください。
この記事では、イベントトリガー(Event Trigger)の使い方をご紹介します。イベントトリガーは様々な種類がありますが、今回は新しいチャンネルが作られたときに発生する "channel_created" イベントを使ってワークフローを起動してみましょう。
ブランクプロジェクトを作成
いつものようにブランクプロジェクトを作成してゼロからコードを足していきましょう。slack create
コマンドを実行して、選択肢から「Blank Project」を選択してください。作成したプロジェクトの構成は以下の通りです。
$ tree
.
├── LICENSE
├── README.md
├── assets
│ └── default_new_app_icon.png
├── deno.jsonc
├── import_map.json
├── manifest.ts
└── slack.json
今回はトリガーがメインの記事ですので、ワークフローは非常にシンプルなものにしましょう。
ソースコードでトリガーを作る
以下の内容を example.ts
として保存してください。
// -------------------------
// ワークフロー定義
// -------------------------
import { DefineWorkflow, Schema } from "deno-slack-sdk/mod.ts";
export const workflow = DefineWorkflow({
callback_id: "example-workflow",
title: "Example Workflow",
input_parameters: {
properties: {
channel_id: { type: Schema.slack.types.channel_id },
channel_name: { type: Schema.types.string },
channel_type: { type: Schema.types.string },
creator_id: { type: Schema.slack.types.user_id },
created: { type: Schema.types.string },
},
required: [
"channel_id",
"channel_name",
"channel_type",
"creator_id",
"created",
],
},
});
workflow.addStep(Schema.slack.functions.SendMessage, {
channel_id: workflow.inputs.channel_id,
message:
`Hi <@${workflow.inputs.creator_id}>, thanks for creating this channel!`,
});
// -------------------------
// トリガー定義
// -------------------------
import { Trigger } from "deno-slack-api/types.ts";
const trigger: Trigger<typeof workflow.definition> = {
type: "event",
name: "Trigger the example workflow",
workflow: `#/workflows/${workflow.definition.callback_id}`,
event: { event_type: "slack#/events/channel_created" },
inputs: {
channel_id: { value: "{{data.channel_id}}" },
channel_name: { value: "{{data.channel_name}}" },
channel_type: { value: "{{data.channel_type}}" },
creator_id: { value: "{{data.creator_id}}" },
created: { value: "{{data.created}}" },
},
};
export default trigger;
そして manifest.ts
にこのワークフローを追加します。
import { Manifest } from "deno-slack-sdk/mod.ts";
import { workflow as ExampleWorkflow } from "./example.ts";
export default Manifest({
name: "distracted-bison-253",
description: "Example workflow",
icon: "assets/default_new_app_icon.png",
workflows: [ExampleWorkflow],
outgoingDomains: [],
botScopes: [
"commands", // 最低限一つの bot scope が必要
"channels:read", // channel_created トリガーに必要
"chat:write", // メッセージを投稿するための基本的な権限
"chat:write.public", // public channel に参加することなくメッセージを投稿する権限
],
});
前回の "reaction_added" イベントのトリガーの記事を読まれた方は、チャンネル ID をコード内に列挙しなければならなかったことを覚えているかもしれません。
イベントトリガーには二種類あり、"reaction_added" は n 個のチャンネルに紐づいて設定されていたのですが、今回の "channel_created" はワークスペースレベルでのイベントとなるため、channel_ids
を指定する必要はありません(・・・というか、まだ作られていないチャンネルなので、そもそも指定できませんよね )。
なお、この記事執筆時点でこの次世代プラットフォームはまだベータ版の段階で、イベントトリガーはパブリックチャンネルしかサポートしておりません。正式リリース前にこの記事を読まれている方は、パブリックチャンネルでお試しください。
ということで、今回は特にコードの変更は必要なく、ワークフロー実行の準備が完了しました。
slack triggers create --trigger-def ./example.ts
を実行します。選択肢から (dev)
という接尾辞がついている方を選択してください。
$ slack triggers create --trigger-def ./example.ts
? Choose an app seratch (dev) T03E*****
distracted-bison-253 (dev) A04FNE*****
⚡ Trigger created
Trigger ID: Ft04EJ8*****
Trigger Type: event
Trigger Name: Trigger the example workflow
トリガーが作成されたら、早速 slack run
を実行してアプリがイベントを受けられるようにしましょう。そして、新しくパブリックチャンネルを一つ作ってみてください。
以下のように Example Workflow の実行ログが出力されて、
$ slack run
? Choose a workspace seratch T03E94MJU
distracted-bison-253 A04FACHPQ5R
Updating dev app install for workspace "Acme Corp"
⚠️ Outgoing domains
No allowed outgoing domains are configured
If your function makes network requests, you will need to allow the outgoing domains
Learn more about upcoming changes to outgoing domains: https://api.slack.com/future/changelog
✨ seratch of Acme Corp
Connected, awaiting events
2022-12-15 14:10:28 [info] [Fn04FCVD67J8] (Trace=Tr04F4HN8XQW) Function execution started for workflow function 'Example Workflow'
2022-12-15 14:10:29 [info] [Wf04FP576X3K] (Trace=Tr04G0SD63EC) Execution started for workflow 'Example Workflow'
2022-12-15 14:10:29 [info] [Wf04FP576X3K] (Trace=Tr04G0SD63EC) Executing workflow step 1 of 1
2022-12-15 14:10:30 [info] [Fn0102] (Trace=Tr04G0SD63EC) Function execution started for builtin function 'Send a message'
2022-12-15 14:10:31 [info] [Fn0102] (Trace=Tr04G0SD63EC) Function execution completed for function 'Send a message'
2022-12-15 14:10:31 [info] [Wf04FP576X3K] (Trace=Tr04G0SD63EC) Execution completed for workflow step 'Send a message'
2022-12-15 14:10:32 [info] [Fn04FCVD67J8] (Trace=Tr04F4HN8XQW) Function execution completed for function 'Example Workflow'
2022-12-15 14:10:32 [info] [Wf04FP576X3K] (Trace=Tr04G0SD63EC) Execution completed for workflow 'Example Workflow'
アプリから以下のようなメッセージが投稿されれば成功です。
もちろん、これではあまり便利とは言えませんが、トリガーの使い方はご理解いただけたのではないかと思います。
より高度なワークフローを実装するために
より高度なことをしたい場合、もう少し工夫が必要となりますので、簡単にいくつかのポイントを解説しておきます。
チャンネル内のより詳細な情報を取得する
チャンネルベースのイベントトリガーの例をご紹介した以下の記事でも触れましたが、
旧来のイベント APIとは異なり、次世代プラットフォームのイベントトリガーは、必ずしもアプリのボットユーザーがそのチャンネルのメンバーであることを要求しません。
上記のような chat:write.public
scope を使って、パブリックチャンネルへの参加なしにメッセージを投稿するということは簡単にできますが、より高度な処理(例えば、規定のメンバーを自動的に招待する、チャンネルのトピックやブックマークを整備するなど)については、ボットをそのチャンネルに conversations.join
API を使って参加させてから実行する必要がありますので、ご注意ください。
終わりに
いかがだったでしょうか?今回はチャンネル ID を指定する必要がないイベントトリガーでしたので、記事内でご紹介したようにソースコードを使って作成するというアプローチで普通のユースケースには対応できるのではないかと思います。
もちろん、description などのメタデータをモーダルを開いてユーザーに入力してもらいたい、といった場合であれば、別途設定用のワークフローを用意して API でトリガーを作成するのもよいでしょう。
現在利用可能なイベントトリガーの一覧については以下のページをご参照ください。
それでは!