> ## Documentation Index
> Fetch the complete documentation index at: https://www.chapterjs.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Permissions

> Check what a member can do, read what a role allows, and write permissions by name

Permissions are always written by name, like `'BanMembers'`: your editor completes them and refuses a typo. Nothing here sends a request: everything is computed from what the bot knows.

> [!NOTE]
>
> To require permissions before a command runs, declare them in the file of the command: see [Commands](https://www.chapterjs.org/commands.md). What ChapterJS answers when the bot itself lacks a permission is in [Errors](https://www.chapterjs.org/reference/errors.md#what-the-person-sees).

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
import type { GuildChannel, GuildMember } from 'chapterjs';

function canPost(member: GuildMember, channel: GuildChannel) {
  const permissions = member.permissionsIn(channel);
  const missing = permissions.missing(['SendMessages', 'AttachFiles']);
  return missing.length === 0 ? 'Go ahead' : `Missing: ${missing.join(', ')}`;
}
```

## Where permissions come from

| Read | Gives | Page |
| - | - | - |
| `member.permissions` | What the member can do in the server, from their roles | [GuildMember](https://www.chapterjs.org/reference/member.md) |
| `member.permissionsIn(channel)` | The same, changed by what the channel allows or denies | [GuildMember](https://www.chapterjs.org/reference/member.md#permissionsin) |
| `channel.permissionsFor(member)` | Same as `member.permissionsIn(channel)` | [Channels](https://www.chapterjs.org/reference/channels) |
| `role.permissions` | What the role allows in the server | [Role](https://www.chapterjs.org/reference/role.md) |
| `channel.permissionOverwrites` | What each role and member is allowed or denied in the channel | [PermissionOverwrite](https://www.chapterjs.org/reference/data.md#permissionoverwrite) |

To write permissions, pass names to `guild.createRole()`, `role.edit()` ([`RoleCreateOptions`](https://www.chapterjs.org/reference/options#rolecreateoptions), [`RoleEditOptions`](https://www.chapterjs.org/reference/options#roleeditoptions)) and `channel.setPermissions()`.

## How they are computed

The computation follows the [permission rules of Discord](https://docs.discord.com/developers/topics/permissions#permission-overwrites), in four steps:

1. **In the server.** The owner can do everything. Otherwise a member has what the @everyone role allows, plus what each of their roles allows; a member with `Administrator` can do everything.
2. **In a channel.** The overwrites of the channel change that: first the one for @everyone, then the ones for the roles of the member combined, then the one for the member themselves. Each one removes what it denies, then adds what it allows. An administrator is never affected by overwrites.
3. **What follows.** A member who can't `ViewChannel` can do nothing in it. A member who can't `SendMessages` can't `MentionEveryone`, `SendTtsMessages`, `AttachFiles` or `EmbedLinks` either.
4. **Timed out.** A timed out member only keeps `ViewChannel` and `ReadMessageHistory`, unless they are an administrator.

`member.permissions` applies steps 1 and 4; `member.permissionsIn(channel)` and `channel.permissionsFor(member)` apply all four. A thread uses the permissions of the channel it is in.

## Permissions

A set of permissions that never changes: every operation returns a new set. Discord serializes permissions as text because they don't fit in a regular number.

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
import { Permissions } from 'chapterjs';

const moderator = new Permissions(['KickMembers', 'BanMembers']);
moderator.has('KickMembers'); // true
moderator.add('ModerateMembers').toArray(); // ['KickMembers', 'BanMembers', 'ModerateMembers']
```

### Properties

**bits** `bigint` *required*

The permissions as one number, each bit being a permission.

### constructor

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
new Permissions(bits?: PermissionResolvable | string)
```

Builds a set from a name, a list of names, bits, another set, or the text Discord uses (`'2048'`). Without an argument, the set is empty. A name that is not a permission throws a `TypeError`:

```text theme={"theme":{"light":"github-light","dark":"vesper"}}
"BanMember" is not a permission. Permissions are: CreateInstantInvite, KickMembers, BanMembers, ...
```

### has()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
has(permission: PermissionResolvable, options?: { checkAdmin?: boolean }): boolean
```

Whether every given permission is in the set. An administrator has every permission, unless `{ checkAdmin: false }` is passed.

### any()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
any(permission: PermissionResolvable, options?: { checkAdmin?: boolean }): boolean
```

Whether at least one of the given permissions is in the set.

### missing()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
missing(permission: PermissionResolvable): PermissionName[]
```

The given permissions that are not in the set, by name.

### add()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
add(permission: PermissionResolvable): Permissions
```

A new set with the given permissions added.

### remove()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
remove(permission: PermissionResolvable): Permissions
```

A new set without the given permissions.

### toArray()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
toArray(): PermissionName[]
```

The names of the permissions in the set, in the order of the docs.

### toString()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
toString(): string
```

The text Discord expects in a request.

### toJSON()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
toJSON(): string
```

The text Discord expects in a request.

> [!NOTE]
>
> `has()`, `any()` and `missing()` answer for an administrator as if they had everything. Pass `{ checkAdmin: false }` to `has()` or `any()` to check the exact bit.

[Discord documentation](https://docs.discord.com/developers/topics/permissions)

## PermissionResolvable

A permission, or several: by name, as bits, or as a set.

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type PermissionResolvable =
  | PermissionName
  | bigint
  | Permissions
  | readonly (PermissionName | bigint)[]
```

Every method of `Permissions`, and every option that takes permissions, accepts one. Something else than a name, a bigint, a set or a list of those throws a `TypeError`:

```text theme={"theme":{"light":"github-light","dark":"vesper"}}
A permission is a name like "BanMembers", got number.
```

## PermissionName

The name of one permission: a key of `PermissionFlags`, as listed below.

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type PermissionName = keyof typeof PermissionFlags
```

| Name | What it allows |
| - | - |
| `CreateInstantInvite` | Creating invites |
| `KickMembers` | Kicking members |
| `BanMembers` | Banning members |
| `Administrator` | Everything, and ignoring the overwrites of channels |
| `ManageChannels` | Creating, editing and deleting channels |
| `ManageGuild` | Editing the server |
| `AddReactions` | Adding new reactions to messages (reacting with an existing reaction needs nothing) |
| `ViewAuditLog` | Reading the audit log |
| `PrioritySpeaker` | Being heard louder in a voice channel |
| `Stream` | Going live |
| `ViewChannel` | Seeing a channel: reading its messages, joining it if it is a voice channel |
| `SendMessages` | Sending messages in a channel and creating posts in a forum (not sending messages in threads) |
| `SendTtsMessages` | Sending `/tts` messages |
| `ManageMessages` | Deleting the messages of others |
| `EmbedLinks` | Having the links one sends previewed |
| `AttachFiles` | Uploading images and files |
| `ReadMessageHistory` | Reading older messages |
| `MentionEveryone` | Using `@everyone` and `@here` |
| `UseExternalEmojis` | Using the custom emojis of other servers |
| `ViewGuildInsights` | Reading the insights of the server |
| `Connect` | Joining a voice channel |
| `Speak` | Speaking in a voice channel |
| `MuteMembers` | Muting members in a voice channel |
| `DeafenMembers` | Deafening members in a voice channel |
| `MoveMembers` | Moving members between voice channels |
| `UseVad` | Using voice activity detection in a voice channel |
| `ChangeNickname` | Changing one's own nickname |
| `ManageNicknames` | Changing the nicknames of others |
| `ManageRoles` | Creating, editing and deleting roles |
| `ManageWebhooks` | Creating, editing and deleting webhooks |
| `ManageGuildExpressions` | Editing and deleting the emojis, stickers and sounds created by anyone |
| `UseApplicationCommands` | Using slash commands and context menu commands |
| `RequestToSpeak` | Asking to speak in a stage channel |
| `ManageEvents` | Editing and deleting the scheduled events created by anyone |
| `ManageThreads` | Deleting and archiving threads, and seeing every private thread |
| `CreatePublicThreads` | Creating public and announcement threads |
| `CreatePrivateThreads` | Creating private threads |
| `UseExternalStickers` | Using the custom stickers of other servers |
| `SendMessagesInThreads` | Sending messages in threads |
| `UseEmbeddedActivities` | Using activities (apps with the `EMBEDDED` flag) |
| `ModerateMembers` | Timing members out: they can't send or react in chat and threads, nor speak in voice and stage channels |
| `ViewCreatorMonetizationAnalytics` | Reading the role subscription insights |
| `UseSoundboard` | Using the soundboard in a voice channel |
| `CreateGuildExpressions` | Creating emojis, stickers and sounds, and editing and deleting one's own |
| `CreateEvents` | Creating scheduled events, and editing and deleting one's own |
| `UseExternalSounds` | Using the soundboard sounds of other servers |
| `SendVoiceMessages` | Sending voice messages |
| `SetVoiceChannelStatus` | Setting the status of a voice channel |
| `SendPolls` | Sending polls |
| `UseExternalApps` | Letting apps installed by users answer publicly; otherwise their answers are only visible to the person. Only for apps not also installed on the server |
| `PinMessages` | Pinning and unpinning messages |
| `BypassSlowmode` | Ignoring slowmode |

[Discord documentation](https://docs.discord.com/developers/topics/permissions#permissions-bitwise-permission-flags)

## PermissionFlags

The bit of every permission, by name: `PermissionFlags.BanMembers` is `4n` (`1n << 2n`). It is what `PermissionName` is made of, and what `bits` is read against.

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
import { PermissionFlags, Permissions } from 'chapterjs';

const bits = PermissionFlags.KickMembers | PermissionFlags.BanMembers;
new Permissions(bits).toArray(); // ['KickMembers', 'BanMembers']
```

You rarely need it: names do the same, readably. Use it when you work with the raw bits of Discord, for example to combine them with `|` or to compare with a number from elsewhere.

[Discord documentation](https://docs.discord.com/developers/topics/permissions#permissions-bitwise-permission-flags)

## The hierarchy

Having a permission is not always enough: a member can only kick, ban, rename or give roles to members whose highest role is below their own. `member.isHigherThan(other)` and `role.isHigherThan(other)` answer that. The same applies to your bot: its highest role must be above the member it moderates.

[Discord documentation](https://docs.discord.com/developers/topics/permissions#permission-hierarchy)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.