Slack プラットフォーム 2021 年のアップデートのふりかえり

こんにちは、Slack で公式 SDK 開発と日本の DevRel を担当しております @seratch と申します。

こちらの記事では、今年 Slack がリリースした新機能を振り返りたいと思います。

Slack プラットフォームに関する重要な変更は [CHANGELOG のページ（英語のみ）](https://api.slack.com/changelog)でアナウンスされているのですが、この記事では、そこに掲載されていなかったものや、補足情報も添えながら解説していきます。

それでは月毎に更新内容を見ていきましょう。

## 2021 年 1 月

### ソケットモード（Socket Mode）リリース

https://twitter.com/SlackAPI/status/1349080766139879424

Slack から受信する全てのペイロードを WebSocket コネクションで受け取り、WebSocket メッセージで応答することができる新しい通信方式、ソケットモードが GA リリースとなりました。Slack Platform Blog に[紹介記事（英語のみ）](https://medium.com/slack-developer-blog/socket-to-me-3d122f96d955)がありますので、そちらもご覧ください。

また、当時 Qiita で使い方を説明しましたので、そちらもご覧ください。

https://qiita.com/seratch/items/1a460c08c3e245b56441

https://qiita.com/seratch/items/c7d9aeb60ead5c126c01

上の記事でも少し触れていますが、RTM API やそれを内部的に使った Hubot の Slack アダプターでアプリを作ったことがある、あるいは今も運用している、という方も、今後はこのソケットモードを使うようにしてください。

なお、この GA 時ではまだなかった App Manifest (YAML 形式の設定ファイルで Slack アプリ設定をできる機能）であれば、さらに簡単にはじめることができるかもしれません。

以下はソケットモードと基本的な機能を有効にした設定例です。

```yaml
_metadata:
  major_version: 1
  minor_version: 1
display_information:
  name: my-first-socket-mode-app
features:
  bot_user:
    display_name: My First Socket Mode App
  slash_commands:
    - command: /hello-my-socket-mode-app
      description: Hi!
      usage_hint: Hi!
      should_escape: false
oauth_config:
  scopes:
    bot:
      - app_mentions:read
      - chat:write
      - commands
settings:
  event_subscriptions:
    bot_events:
      - app_mention
  interactivity:
    is_enabled: true
  socket_mode_enabled: true
```

ちなみに、このように App Manifest を使って設定する場合であっても、[`connections:write` scope](https://api.slack.com/scopes/connections:write) を持つ App-level token （ワークスペース単位ではなくアプリ単位で発行されるもので、ソケットモードの利用には必須）は必要です。そのトークンの発行は、アプリの管理画面から手動で発行してください。

### Events API にワークフローのカスタムステップ関連のイベントを追加

ワークフロービルダーで組み込むことができるステップには、標準のものに加えて App Directory で公開されている 3rd party のものや、[自分で自由に作ることができるカスタムステップ](https://api.slack.com/workflows/steps)があります。

この自分が作ったカスタムステップに関連するイベントが Events API に追加されました。

* [`workflow_published` (あなたのステップを含むワークフローが公開されたとき)](https://api.slack.com/events/workflow_published)
* [`workflow_unpublished` (あなたのステップを含むワークフローの公開が停止されたとき)](https://api.slack.com/events/workflow_unpublished)
* [`workflow_deleted` (あなたのステップを含むワークフローが削除されたとき)](https://api.slack.com/events/workflow_deleted)
* [`workflow_step_deleted` (あなたのステップがワークフローから削除されたとき)](https://api.slack.com/events/workflow_step_deleted)

### メッセージの Block Kit のブロックの中の URL も unfurl されるように

このタイミングまで、メッセージ内の Block Kit のブロックの中に含まれる URL が unfurl されることはありませんでしたが、デフォルトでは unfurl されるようになりました（unfurling とは URL のページのコンテンツの内容をプレビュー表示する機能のことです）。

この機能をオフにしてメッセージを投稿したい場合は、`chat.postMessage` などでメッセージを投稿するときに `    "unfurl_links": false, "unfurl_media": false` を指定することができます。

## 2021 年 2 月

### Events API にチャンネルの ID の変更を通知するイベントを追加

既存のチャンネルを Slack Connect チャンネルに切り替えた際、[チャンネル ID が変更される](https://api.slack.com/apis/channels-between-orgs#technical-considerations-supporting-slack-connect__same-channel-different-setting
)場合があります。このイベントを検知するために利用できる [channel_id_changed イベント](https://api.slack.com/events/channel_id_changed)が追加されました。

以下のようなペイロードが送信されますので、これを使ってデータベースなどに保持しているチャンネル ID を更新することができます。

```json
{
  "type": "channel_id_changed",
  "old_channel_id": "G012Y48650T",
  "new_channel_id": "C012Y48650T",
  "event_ts": "1612206778.000000"
}
```

詳細は英語のみとなりますが、以下のページを参考にしてください。

https://api.slack.com/apis/channels-between-orgs#technical-considerations-supporting-slack-connect__same-channel-different-setting

### `channels.*` などの利用を停止（`conversations.*` への完全移行）

一年以上の移行期間を経て、以下の API メソッドが全て提供終了となりました。

* `channels.*`
* `groups.*`
* `mpim.*`
* `im.*`

今後は `conversations.*` のみを利用いただくことになります。少し前の記事だと `channels.history` を使っている例なども見つかるかとは思いますが、そのままでは動かないので注意してください。

移行については、こちらの記事や英語のドキュメントを参考にしてください。

https://qiita.com/seratch/items/afd3928b208c618044de

### Events API のペイロードに紐づく OAuth 認可一覧の取得方法が変更に

https://api.slack.com/changelog/2020-09-15-events-api-truncate-authed-users

Events API のイベントが複数の OAuth 認可にひもづく場合、以前は、トップレベルに `authed_users`、`authed_teams` という項目があり、ここにワークスペースとユーザーがそれぞれ配列で含まれていました。

そして、複数のユーザーの権限（= bot ではなく user token scope という意味です）で [message イベント](https://api.slack.com/events/message)を subscribe している場合、仮にそのチャンネルにアプリをインストールしたユーザーが 100 人いた場合、Events API のペイロードに含まれる `authed_users` は 100 個の要素を持つ配列となっていました。

このデータ構造は、特に大規模な OrG やワークスペースで、ペイロードの肥大化・パフォーマンスの問題にもつながっていたことから `authorizations` という新しいフィールドに移行され、新しいフィールドでは基本的に一つだけの `authorization` が設定されるようになりました。

この新しい方式で、あるイベントに関する全ての認可情報を取得したい場合、[`apps.event.authorizations.list` という新しく追加された API](https://api.slack.com/methods/apps.event.authorizations.list
) に Events API のペイロードに含まれている `event_context` を渡します。なお、この API の呼び出しにはソケットモードでも出てきた App-level token が必要です（ワークスペース単位ではなくアプリ単位なのは Slack Connect にも対応しているためです）。`authorizations:read` という scope を付与した App-level token をつくって、それを使って API をコールしてください。

```python
from slack_sdk import WebClient
response = client.apps_event_authorizations_list(
    token="xapp-1-A111-111-xxx",
    event_context="4-eyJldCI6Im1lc3NhZ2UiLCJ0aWQiOiJUSktSOEg5TDIiLCJhaWQiOiJBMDJQMlNRSzRLQiIsImNpZCI6IkMwMTYwSFI4TTZGIn0",
)
```

そうすると API からは以下のような応答データが返ってきます。

```json
{
  "ok": true,
  "authorizations": [
    {
      "enterprise_id": "E1111111111",
      "team_id": "T1111111111",
      "user_id": "W1111111111",
      "is_bot": false
    },
    {
      "enterprise_id": null,
      "team_id": "T2222222222",
      "is_bot": true
    }
  ]
}
```

### アプリインストールなどを促すためのオプションを chat.unfurl に追加

[`chat.unfurl` API](https://api.slack.com/methods/chat.unfurl) がアップデートされ、以下のパラメーターを追加で利用できるようになりました。

`linked_shared` イベントのリスナーで、メッセージを指定する情報（`channel` と `ts`）に加えて以下のパラメーターを `chat.unfurl` API に渡します。そうすることで、アプリのインストール、ユーザーアカウントのひもづけを促すエフェメラルメッセージ（「あなただけに表示されています」と表示されるメッセージのことです）が送信されます。

|パラメーター|説明|
|---|---|
|`user_auth_required: boolean`|このフラグを true に設定して chat.unfurl をすると、固定のメッセージと三択のリンクが表示されます。<br/><br/>メッセージ例: `"{App Name} can show link previews for {the unfurling domain}. Would you like to install it, so you can always preview these links in Slack? Install from App Directory • Not now • Never ask me again"`|
|`user_auth_message: string`|`text` を使ってメッセージをカスタマイズできます。おそらくユーザーに何をしてもらうためのページへの導線をリンクとして埋め込むのが想定される利用方法です。ボタンなどは置くことができません。`Not now • Never ask me again` が末尾に自動で挿入されます。|
|`user_auth_blocks: List<Block>`|Block Kit のブロックを使ってよりリッチなメッセージを構築できます。おそらく url 属性を持ったボタンなどを置くのがよくあるユースケースになると思います。そのボタンをクリックするとブラウザを開いて OAuth フローに進む、などです。|
|`user_auth_url: string`|固定のメッセージの末尾に挿入される「`Yes, allow`」というリンクにここで指定された URL が設定されます。<br><br>メッセージ例: `"Hi there! Linking your Slack account to {App Name} will help you use {App Name} in Slack (and it only takes a click or two). Would you like to set it up? Yes, allow • No"`|

詳細は、英語のみとなりますが、[こちらのドキュメント](https://api.slack.com/reference/messaging/link-unfurling#authenticated_unfurls)も合わせて参考にしてください。

### その他の変更

#### (Grid) `admin.analytics.getFile` API にチャンネルの日別アクティビティデータを追加

Enterprise Grid 限定の機能となりますが、[`admin.analytics.getFile` API](https://api.slack.com/methods/admin.analytics.getFile) という日別のアクティビティデータを取得できる API があります。前年から各メンバーに関する日毎の集計データを提供していましたが、このタイミングからパブリックチャンネルに関する情報も取得できるようになりました。

なお、両者ともに、あくまでアクティビティのその日の総数のみを集計するものであり、個々のメッセージ内容などは含まれません。応答内容の詳細は[ドキュメント](https://api.slack.com/methods/admin.analytics.getFile)を参考にしてください。

#### Events API の `message` イベントに `channel_posting_permissions` サブタイプを追加

チャンネルの投稿可能なユーザーの設定が変更されたときのメッセージに対応する[サブタイプ](https://api.slack.com/events/message/channel_posting_permissions)が追加されました。

## 2021 年 3 月

### 新しく作られるプライベートチャンネルの ID の先頭文字が "C" に

新しく作られるプライベートチャンネルの先頭文字がこれまでの "G" ではなく "C" になりました。また、プライベートチャンネルかどうかを知るには、先頭文字ではなく [`conversations.info` API](https://api.slack.com/methods/conversations.info) などの応答に含まれる `is_private` というフラグで判定することができるようになっています。

既存のチャンネルは Slack Connect に移行するなどのイベントが発生しない限り変更されることはありません。

### その他の変更

#### (Grid) `admin.users.session.*` API を追加

Enterprise Grid 限定の機能となりますが、ユーザーのセッションに関する設定（セッションの有効期間など）に関する API が公開されました。

* [admin.users.session.setSettings](https://api.slack.com/methods/admin.users.session.setSettings)
* [admin.users.session.getSettings](https://api.slack.com/methods/admin.users.session.getSettings)
* [admin.users.session.clearSettings](https://api.slack.com/methods/admin.users.session.clearSettings)


## 2021 年 4 月

### Block Kit の `input` ブロックがメッセージ内でも利用できるように

これまでモーダルやホームタブでのみ利用可能だった [`input` ブロック](https://api.slack.com/reference/block-kit/blocks#input)がメッセージの中でも利用できるようになりました。

これにより 2021 年時点で利用可能なブロックは、メッセージ、ホームタブ、モーダルの全てで利用が可能となりました（ブロックエレメントの一部の設定などはモーダル限定のものがあります）。

## 2021 年 5 月

#### App Manifest の open beta を開始

https://twitter.com/SlackAPI/status/1446164266155843584

YAML 形式の Slack アプリ設定方法である App Manifest の open beta が始まりました。詳細は、英語のみとなりますが、以下のドキュメントを参考にしてください。

https://api.slack.com/reference/manifests

また、チュートリアルのトップページには App Manifest の設定例がいくつか公開されていますので、こちらも試してみてください。

https://api.slack.com/tutorials

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/51dcd32d-06c6-770a-3e79-e678847b528e.png" width=500 />

### その他の変更

#### (Grid) `admin.apps.uninstall` API を追加

Enterprise Grid 限定の機能となりますが、[`admin.apps.uninstall` API](https://api.slack.com/methods/admin.apps.uninstall) が追加されました。これはインストール済のアプリを OrG やワークスペースからアンインストールするための API です。

## 2021 年 6 月

### api.slack.com フルリニューアル

https://twitter.com/SlackAPI/status/1408451306319081472

https://api.slack.com/ のサイトデザインなどが大幅に刷新されました。見た目だけでなく、以下の一覧ページでの検索もやりやすくなるなどの改善されていますので、そちらも試してみてください。

* [Web API の一覧ページ](http://api.slack.com/methods)
* [Events API / RTM API のイベント一覧ページ](https://api.slack.com/events)
* [権限 (scope) の一覧ページ](https://api.slack.com/scopes)

### その他の変更

#### (Grid) `admin.auth.policy.*` API を追加

Enterprise Grid 限定の機能となりますが、[`admin.auth.policy.*` の 3 つの API](https://api.slack.com/methods?query=admin.auth.policy.) が追加されました。これはログイン方式に関するポリシーを設定するための API です。

## 2021 年 7 月

### OpenID Connect 互換の新しい Sign in with Slack を追加

https://twitter.com/seratch_ja/status/1420967458521772034

これまでの Sign in with Slack は独自の OAuth の仕組みでした。今回、新しいバージョン（そして今後のデフォルト）の Sign in with Slack を追加しました。この実装は [OpenID Connect](https://openid.net/specs/openid-connect-core-1_0.html) と完全な互換性を持ちます。

https://api.slack.com/authentication/sign-in-with-slack

標準仕様なので、既存のライブラリを使って楽に実装できるようになりましたが、以下の公式 SDK を使ったシンプルなサンプルも参考にしてみてください。

* [Node.js でのサンプル](https://github.com/slackapi/node-slack-sdk/tree/main/examples/openid-connect)
* [Python でのサンプル](https://github.com/slackapi/python-slack-sdk/tree/main/integration_tests/samples/openid_connect)
* [Java でのサンプル](https://github.com/slackapi/java-slack-sdk/blob/main/bolt-servlet/src/test/java/samples/OpenIDConnectSample.java)

### トークンのローテーションのサポートを開始

https://twitter.com/seratch_ja/status/1417347609367248899

Slack の OAuth アクセストークンは、長らく [refresh token](https://datatracker.ietf.org/doc/html/rfc6749#section-1.5) がなく、一度発行した access token は明に無効化（[`auth.revoke` API](https://api.slack.com/methods/auth.revoke) や[ワークスペースのアプリ管理画面](https://my.slack.com/apps)から revoke できます）しない限り、無期限で使える仕様でした。

しかし、2021 年に [refresh token とともに access token を発行する機能](https://api.slack.com/authentication/rotation)が提供されるようになりました。

https://api.slack.com/authentication/rotation

詳細は、[Slack API のトークンローテーション完全ガイド](https://qiita.com/seratch/items/610c14208772d49ac9e4)という日本語の記事を書きましたので、そちらを参考にしてみてください。

https://qiita.com/seratch/items/610c14208772d49ac9e4

### Slack Connect の招待・承認のための Web API とイベントを追加

Slack Connect のチャンネルの招待や承諾などの手順を API 経由でできるようになりました。例えば、確認済リストにあるワークスペースからの招待であれば、自動承認するなどの業務フローを実装できるようになりました。

詳細は、英語のみとなりますが、[こちらのドキュメント](https://api.slack.com/apis/connect)を参考にしてください。

## 2021 年 8 月

### メッセージ入力エリアでリンクが入力されたときに `link_shared` イベントが発火するように

メッセージ入力エリア（Message Composer）にリンクが入力された時点で `link_shared` イベントが発火するようになりました。これによってメッセージ投稿前に `chat.unfurl` API を使ってプレビューの見た目を設定することができるようになりました。

ペイロード内には `"source": "composer",` が設定され、チャンネル ID に該当する箇所は `"channel": "COMPOSER"` となります。

詳細は、英語のみとなりますが、[こちらのドキュメント](https://api.slack.com/changelog/2021-08-changes-to-unfurls)を参考にしてください。

## 2021 年 9 月

### Block Kit のタイムピッカーが GA に

Block Kit の時刻を指定するためのブロックエレメントである [timepicker エレメント](https://api.slack.com/reference/block-kit/block-elements#timepicker) がベータ期間を終了し、GA リリースとなりました。

### Slack Developer Tools がホームタブを使ったガイドを提供開始

Slack の Developer Relations チームが開発・運用している [Slack Developer Tools というアプリ](https://sdt.builtbyslack.com/)に、プラットフォームの使い方を学べるガイド機能が追加されました。このアプリのホームタブにアクセスして、以下のボタンから試してみてください。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19163/e54292d7-06d1-6433-052d-736dd071ce1d.png" width=350 />

### その他の変更

### (Grid) アプリインストール申請イベントに `developer_type` を追加

Enterprise Grid 限定の機能となりますが、[`admin.apps.*` API](https://api.slack.com/methods?query=admin.apps.) をより良く利用するために [app_requested イベント](https://api.skack.com/events/app_requested)や申請情報の API 応答に `developer_type` という属性が追加されました。これにより、社内アプリなのか、3rd party のベンダーによるアプリなのか、Slack によって開発されているアプリなのかを判別できるようになりました。

## 2021 年 10 月

### RTM API の `rtm.start` API が非推奨に

https://twitter.com/SlackAPI/status/1463570714951241729

RTM API を使ったアプリで WebSocket の接続 URL を取得する方法は、歴史的経緯から `rtm.connect` と `rtm.start` の二つがありましたが、このタイミングから新規のアプリは `rtm.start` は使えなくなり、既存のアプリに対しては `rtm.connect` だけを利用することを推奨することになりました。

`rtm.start` だけがレスポンスに含めていた情報の主要なものは、新しく追加された [`team.billing.info` API](https://api.slack.com/methods/team.billing.info) と [`team.preferences.list` API](https://api.slack.com/methods/team.preferences.list) で取得することができます。

詳細は、英語のみとなりますが、[こちらのドキュメント](https://api.slack.com/changelog/2021-10-rtm-start-to-stop)を参考にしてください。なお、これから新しく作るアプリに関しては RTM ではなくソケットモードを検討してください。

### App Manifest 関連の API の open beta を開始

[App Manifest を操作するための API](https://api.slack.com/reference/manifests#manifest_apis) のベータが開始されました。

こちらの API を利用するためには、App Configuration Token というトークンが必要ですので、[こちらのページ](https://api.slack.com/authentication/config-tokens)で発行して利用してください。


## 2021 年 11 月〜

### Frontiers にて次世代プラットフォーム基盤の構想を発表、closed beta を開始

https://twitter.com/SlackAPI/status/1463185881590685698

Slack がホスティング環境（アプリの動作環境と Tables API を使ったデータの保持）を提供する、ワークフロー構築のための次世代のプラットフォームを発表しました。

https://slack.com/intl/ja-jp/blog/developers/faster-simpler-way-build-apps

技術ドキュメントは、英語のみとなりますが、以下のページを参考にしてください。

https://api.slack.com/future

この次世代プラットフォームについては、オープンベータのタイミングあたりで、改めて日本語でも技術的な詳細をご紹介する予定です。

https://twitter.com/kani_b/status/1460703588502626311

### その他の変更

#### Block Kit の多くのエレメントに `focus_on_load` フラグを追加

Block Kit の入力系のブロックエレメントに `focus_on_load` というフラグが追加されました。これはモーダル内で使われる入力系ブロックのうち、どれか一つだけに true を設定すると、モーダルが表示されたときにそのブロックにカーソルがフォーカスされ、すぐに入力を始めることができるというものです。

詳細は Block Kit の[リファレンスガイド](https://api.slack.com/reference/block-kit/block-elements)を参考にしてください。

#### (Grid) `admin.users.session.resetBulk` API を追加

Enterprise Grid 限定の機能となりますが、[`admin.users.session.resetBulk` API](https://api.slack.com/methods/admin.users.session.resetBulk) というセッションを一括で無効化するための API が追加されました。

## まとめ

いかがだったでしょうか？

Slack プラットフォームは今年も多くの新機能と改善がリリースされました。また先日の Frontiers という年次イベントでは、ホスティング環境も備えた次世代のワークフロー構築・実行基盤も発表された年となりました :tada: 

この記事の中で気になった機能があったら、ぜひ今年のうちに試してみてください :wave: