Discordの権限設定について説明してみる

# [Discord Advent Calendar 2017](https://qiita.com/advent-calendar/2017/discord) の2日目！[^1]

1日目の記事で書きましたが、Discordで特に設定をしていない場合はすべてのユーザがすべてのチャンネルに自由にアクセスできる状況です。チャンネルごとにユーザの出入りを制限する場合はどうすればいいか。Discordでは「役割」および「ユーザ」毎に細かい権限の設定が出来ます。

## 権限の説明をする前に
権限の説明をする前に、関連する大事なDiscordの要素を説明します。

### ユーザと役職
サーバーには複数の「役職」を作成することができます。そして、ユーザにタグのような感覚で複数の役職を割り当てることができます。Discordの権限設定はこの役職単位の設定が基本となります。
全く役職を持たないユーザを含め、全ユーザは暗黙的に `@everyone` の役職を持っています。この役職は初期から存在しており、消すことはできません。
また、役職を持つユーザ群に対してmentionを飛ばすことも可能です。Slackの「User Groups」と似ていますね。

### チャンネルとチャンネルカテゴリー
Discordではチャンネルの整理を行いやすくするために、チャンネルをカテゴリごとに分けることができます[^2]。カテゴリーは個人の設定ではなくサーバー全体の設定になりますので、全ユーザに影響があります。
ただし、カテゴリー単位でチャンネルをMuteにしたり折り畳み表示するなど個人の設定もあります。

## 権限の設定
設定画面の一例がこちらになります。
![9456bd30-7276-4c81-b83c-5ccd41b0dae7.png](https://qiita-image-store.s3.amazonaws.com/0/126660/a8d2b551-c10d-337d-81fb-1fc3006101bb.png)
役職ごとに権限が設定できて、権限は機能ごとに細かく設定できることが分かりますね。

### 適用範囲
Discordでは下記の組み合わせで権限の設定ができます。

1. 「役職」に対してサーバー全体の権限
-  「役職」「ユーザ」に対してチャンネルカテゴリー単位の権限
-  「役職」「ユーザ」に対してチャンネル単位の権限

下に行くほど適用範囲が狭くなるわけですが、権限設定は「1->2」または「1->3」の順で上書きされていきます。 
`2. 3.` では機能単位で権限を「未設定」にもできます。例えば、`2.` で未設定にした権限は `1.` の設定が参照されます。オブジェクト指向的に言う継承というノリですね。

![e3028e0b-2e07-4bdd-959d-1e2f79f490a1.png](https://qiita-image-store.s3.amazonaws.com/0/126660/c1b505a8-a281-c3a0-e67d-d5d1fc5f91a7.png)
これはカテゴリー単位の権限設定ですが、`1.` には無かった真ん中の `／` が登場しています。これが先述した権限の「未設定」になります。

なお、カテゴリー単位とチャンネル単位の権限設定は継承の関係ではなく「同期を取る」形になっています。カテゴリーの下にチャンネルを作った場合、画像のような表示が出ます。
![5875b1fc-8cd3-40cc-8811-cbfbef46b781.png](https://qiita-image-store.s3.amazonaws.com/0/126660/e35918d3-7920-cd90-ada5-e76d692f4888.png)
カテゴリの下にありながら、チャンネル独自の設定がある場合はアラート気味に「同期していません！」と出ます。カテゴリ単位で整理する場合、チャンネル単位の設定は行わない前提がありそうです。

## 権限設定の例を考えてみる
開催予定のイベントコミュニティをDiscordで運用することを考えてみましょう。要件は以下のようなものです。
### 要件整理
- 管理者と、イベント運営のスタッフ、ユーザがサーバーに混在する前提とする
- サーバーには公式サイトやTwitterに記載の招待URLから自由に出入りできる
- ユーザが増えすぎてカオスになるのを防ぐため、一定のコンタクトが取れるまでユーザはゲストとして扱う
- ゲストユーザは専用チャンネルのみ閲覧・発言できる。そのチャンネルで権限をスタッフに要請する
- スタッフのみ参加できるチャンネルをいくつか用意する
- ユーザが閲覧できるが、書き込みができない「お知らせ」用のチャンネルを作る

## 作ってみる
まずは役職を作成しましょう。そのまま「管理者」「スタッフ」「ユーザー」とします。
チャンネルも用途に合わせていくつか作ります。内部向けのチャンネルは複数作るので、チャンネルカテゴリを作ってまとめます。こんな感じ。[^3]
![484c1d43-3282-4d33-a2d8-ec23602eae88.png](https://qiita-image-store.s3.amazonaws.com/0/126660/bcd3a478-dadb-f2b8-5485-b867b6e56da6.png)

### サーバ全体の権限設定
- `@everyone`
  - 下記を除いた全ての権限を**OFF**にしちゃいましょう。
      - メッセージ履歴を読む
      - ニックネームの変更
      - 埋め込みリンク
      - ファイルを添付
      - 外部の絵文字の使用
      - 音声：発言
      - 音声検出を使用
- `管理者`
  - `管理者` **ON** はこの役職だけ
  - メンションしてもらう必要は無いので、`@メンション` は**OFF**
- `スタッフ`
  - 全体設定を変えるまでの権限は不要なので `管理者` `サーバー管理` は**OFF**
  - `役職の管理` はゲスト⇒ユーザーの切り替えに必要なので、**ON**
  - ユーザーからメンションしてもらうため、`@メンション` は**ON**
  - 他、必要となりそうな権限をこまごまと**ON**にしておきましょう
- `ユーザー`
  - BAN機能や `管理` って付いてる権限は**OFF**にしておきましょう

### チャンネルカテゴリの権限設定
今回「内部事情」という名のカテゴリを用意しましたが、実はカテゴリ・チャンネルを作成するときにショートカット的な設定ができるようになっています。
![0408f1dc-06bd-46ef-a754-faca1711744f.png](https://qiita-image-store.s3.amazonaws.com/0/126660/12047250-12d9-b4a0-44b8-bb34d5c5f0cd.png)
後からこれと同じ設定をやりたい場合は下記の通り権限をセットアップします。

- `@everyone`
  - `テキストチャンネルの閲覧・ボイスチャンネルの一覧表示` **OFF**
  - `(音声の)接続` **OFF**
- `管理者` および `スタッフ`
  - `テキストチャンネルの閲覧・ボイスチャンネルの一覧表示` **ON**
  - `(音声の)接続` **ON**

### ゲストチャンネルの権限設定
概ねコントロールがそろってきましたが、今だと招待から入ってきたゲストが一切閲覧・発言できません。ゲストチャンネルの権限を作りましょう。

- `@everyone`
  - `メッセージを読む` `メッセージを送信` **ON**

ゲストは確認が取れ次第、スタッフがユーザ権限を付与するので最低限です。実際のコミュニティ運用ではここまで必要ない気がしますが、一例として。

### お知らせチャンネルの権限設定
ユーザの書き込み権限を無くしてもOKですが「スタッフ以上のみ書き込み可能」と設定するほうが柔軟性がありそうです。

- `@everyone`
  - `メッセージを送信` **OFF**
- `スタッフ` および `管理者`
  - `メッセージを送信` **ON**

### できたはずなので、確認してみる
###### 管理者、およびスタッフから見ると・・・
![bb307d9c-711a-4b1e-8a14-7dd485551c06.png](https://qiita-image-store.s3.amazonaws.com/0/126660/db062c3b-b08a-697b-b2e6-7267870e925e.png)
###### ユーザーから見ると・・・
![user.png](https://qiita-image-store.s3.amazonaws.com/0/126660/8831676f-c343-8f59-c800-2f96c97d8cd8.png)
###### ゲスト状態のユーザから見ると・・・
![guest.png](https://qiita-image-store.s3.amazonaws.com/0/126660/0aceae77-853b-0b9a-a0a7-f211171a7c7e.png)

イメージ通りになっていますね！
ユーザーの画面では、`#notify` チャンネルで発言ができないこともわかります。（カーソルを合わせると :no_entry_sign: が出て分かりやすいです）

## まとめ
役割とチャンネルカテゴリ、チャンネル単位の設定を活用すればSlackとはまた違った形のコントロールができます。パターンが増えると大変ですし、すこし設定を誤ると予想外の結果になったりすることもあるので、真面目な運用をする際はしっかりテストしながら設定することをお勧めします！
Slackの「Private Channnel」のような運用をしたい場合、先に役職を決めておくと最低限の操作で済みます。他のケースでも、役職を整理しておくことがキモではないかと思います。
あまり調べていないのですが、権限を運用するBotなんかもあるようです。詳しい方はぜひカレンダーに投稿してくださいね。

[^1]: 土曜日は余裕と思ってたら炬燵の魔力でこんな時間になってしまいました。
[^2]: 2017/09 くらいのアップデートで新規追加された機能です。
[^3]: チャンネルカテゴリ名は日本語を使えますが、チャンネル名はアルファベットと一部記号だけです。