
Table of Contents
ユーザーインターフェース
Slack スラッシュコマンドを実行すると、
/reserve
予約候補が出てきて、
予約する
を押すと、予約が取れます。
システム構成
システム構成図を以下に描きます。

流れとしては、
- ユーザ: スラッシュコマンド実行
- Slack: POST リクエスト (Slash Command)
- Rails: Slack API でユーザの email を取得
- Rails: Microsoft Graph で会議室の空き時間検索
- Rails: 予約候補メッセージを返す
- Slack: POST リクエスト (Slash Command)
- ユーザー:
予約する
ボタンを押す- Slack: POST リクエスト (Interactive Component)
- Rails: Slack API でユーザの email を取得
- Rails: Microsoft Graph で予約作成
- Rails: HTTP 200 を返す
- Slack: POST リクエスト (Interactive Component)
という感じです。
注意
- Slack に登録しているメールアドレスが Outlook のものである必要があります。
- そうでない場合、Slack と Outlook のアカウントを紐付ける処理が追加で必要です。
- Microsoft Azure Active Directory アプリの権限付与に管理者の同意が必要です。
Slack まわりの詳しい説明
本システムでは、Slack API の 2 つの機能 Slash Command
と Interactive Component
を利用しています。
これらが実行されると、それぞれ別の URL に POST リクエストが発行されます。
この 2 つの URL を Rails で作成し、予約候補メッセージと、予約の作成を実現しています。

実装
概要はここまで、次は、実装方法について説明します。
以下の作業が必要です。
- Slack の設定
- Slack で
Slash Commands
、Interactive Components
の作成、および、Slack API からユーザのメールアドレスを取得する設定を行います。
- Slack で
- Microsoft365 の設定
- Rails で会議室の予定を取得/作成できるようにするための設定を行います。
- Rails: Slash Command の実装
Slash Commands
を受けて、会議室の予約ボタン付きメッセージを返します。
- Rails: Interactive Component の実装
Interactive Components
を受けて会議室を予約します。
※ Rails の実装に関しては「大体こんな感じ」というレベルの記載です。ご承知おきください。
Slack の設定
本システムに必要な Slack App を作成・設定するために、以下の作業を実施します。
Slash Commands の登録
Slash Command 実行時にリクエストする URL を登録します (Slash Commands 参照)。

Interactive Components の登録
予約する
ボタンを押した時にリクエストする URL を登録します (Handling user interaction 参照)。

Scopes の追加
Slack API からユーザのメールアドレスを取得するために、users:read
と users:read.email
の権限を付与します。

Token の取得
Slack API に使用するトークン Bot User OAuth Token
を確認します。

Microsoft365 の設定
本システムに必要な Microsoft Azure Active Directory でアプリの作成・設定をする為に、以下の作業を実施します。
アプリを登録する
ポータルでアプリを登録する を参照してください。
アプリへの権限付与
Outlook の予約を読み込み書込みするために登録したアプリに権限 Calendars.ReadWrite
を付与します (管理者の同意が必要です)。
※ User.Read
はアプリ登録時に付与されていたものです。今回の実装では使用しません。
Rails: Slash Command の実装
Slash Command が実行された時に動作する /slash/command
の処理の流れは、以下です。
Slash Command パラメータの取得
Slash Command のパラメータから、
- トークン
token
: リクエスト元の検証に利用 - ユーザ ID
user_id
: ユーザのメールアドレスを取得に利用 - コマンド引数
text
: オプション (開始時刻、利用時間指定など)
を取得します。
Slash Command のリクエストから取得できる情報は Preparing your app to receive Commands を参照。
Slack ユーザのメールアドレス取得
Microsoft Graph の利用において、実行ユーザのメールアドレスが必要なため、Slack API の users.info を使います (users.info 参照)。
- トークン
token
: Token の取得 - ユーザ ID
user_id
: Slash Command パラメータの取得
を指定します。
前述のとおり、Slack ユーザのメールアドレスが Outlook のものでなければ、別途、Outlook のメールアドレスを取得する処理が必要です。
Microsoft Graph アクセストークンの取得
Microsoft Graph の API を利用するためにアクセストークンを取得します (アクセス トークンを取得する 参照)。
ポータルから取得した、
- クライアント ID
client_id
- クライアントシークレット
client_secret
- テナント ID
tenant
を指定します。
アクセストークンには、期限がありますので、 access_token
と同時に返される expires_in
の値を確認し、期限が切れたら取り直しが必要です。
会議室の予定を取得
会議室の予定を取得するために、Microsoft Graph の API calendar: getSchedule
を使います (空き時間スケジュールを取得する 参照)。
- 実行者のメールアドレス
userPrincipalName
: Slack ユーザのメールアドレス取得 - 会議室のメールアドレスリスト
schedules
: 事前に確認 - 取得開始時刻
startTime
: 現在時刻 など - 取得終了時刻
endTime
: 定時 など - 取得インターバル
availabilityViewInterval
: 30 (分) など
を指定します。
レスポンスは以下のようなものが返ってくるのですが、今回は、availabilityView
を利用します。
{
"scheduleId": "sample@fusic.co.jp",
"availabilityView": "2000000",
"scheduleItems": [
{
"isPrivate": false,
"status": "busy",
"subject": "オンライン会議",
"location": "会議室 1",
"isMeeting": true,
"isRecurring": false,
"isException": false,
"isReminderSet": false,
"start": {
"dateTime": "2022-04-18T15:00:00.0000000",
"timeZone": "Tokyo Standard Time"
},
"end": {
"dateTime": "2022-04-18T16:00:00.0000000",
"timeZone": "Tokyo Standard Time"
}
}
]
}
availabilityView
は 2000000
のように、予定状況が数値列で返ってきます。
各数値の意味は、0
= free
, 1
= tentative
, 2
= busy
, 3
= out of office
, 4
= working elsewhere
です。
たとえば、
- 取得開始時刻: 12:00
- 取得終了時刻: 14:00
- 取得インターバル: 30
を指定して、
- availabilityView: 2200
だと、12:00-13:00 は予定があって、13:00-14:00 は空いている、という意味になります。
一見分かりづらいですが、各予定の開始・終了時刻を一個ずつ見ていくよりは楽だと思います。
ボタン付きメッセージの返答
今回は、以下のような json でレスポンスを返しています。
blocks: [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*satellite-1:* 12:00 - 12:30"
},
"accessory": {
"type": "button",
"text": {
"type": "plain_text",
"emoji": true,
"text": "予約する"
},
"style": "primary",
"value": "reserve_satellite-1_12:00-12:30"
}
}
]
mrkdwn
形式の text
の後に、button
を配置しています。
value
の値が 予約する
ボタンを押したときの POST リクエストで渡ってくるので、必要な情報を埋め込みます。
今回は アクション
部屋名
開始時刻
-終了時刻
を value
に設定しています。
詳細は Button element を参照してください。
Block Kit Builder という、Slack の Block メッセージをお試しできるサイトがあるので、そこで、 「メッセージがどう表示されるか」と「ボタンを押したときにどのような値が入るのか」が試せます。
Rails: Interactive Component の実装
予約する
ボタンが押された時に動作する /slack/interactive-endpoint
の処理の流れは、以下です。
2.
と 3.
の処理は Slash Commands
の実装と同じです。
Interactive Component パラメータの取得
Interactive Component
のパラメータ (payload
) から、
- トークン
payload['token']
: リクエスト元の検証に利用 - ユーザ ID
payload['user']['id']
: ユーザのメールアドレスを取得に利用 - ボタンの値
payload['actions'][0]['value']
: 会議室の予約に利用
を取得します。
ここの注意点としては、パラメータ payload
が json で与えられるので、json をパースする必要があるということです (私はハマりました)。
会議室を予約する
会議室を予約するために、Microsoft Graph の API events
を利用します (イベントを作成する 参照)。
/users/<実行者のメールアドレス>/events
に対して、attendees
に会議室のメールアドレスと以下を指定し、POST します。
- タイトル
subject
: テキトー - 開始時刻
start
: ボタンの値より取得 - 終了時刻
end
: ボタンの値より取得
予約ができたら、HTTP 200 OK となるようにテキトーにレスポンスを返します (メッセージを返しても Slack 上では表示されません)。
うまく実装できていれば、ちゃんと動くはずです!
まとめ
- Slack でボタンとか作れるよ!
- 管理者同意済みのアプリなら、ログインなしで色々できるよ!