> ## 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.

# Channels

> Tell the kinds of channels apart, and use what every channel, every channel of a server and every channel with messages has

A channel is where things happen in Discord: a text channel, a voice channel, a category, a forum, a thread or a private conversation. Each kind has its own class, and they all share what `Channel` has. You get one from `guild.channels`, `message.channel`, the `channel` of a command, or a `channel` option.

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

async function announce(channel: Channel, text: string) {
  if (!channel.isTextBased()) return; // a category or a forum: no messages there
  await channel.send(text);

  if (channel.isThread() && channel.archived) await channel.unarchive();
}
```

> [!NOTE]
>
> How to send, edit and read messages is in [Sending messages](https://www.chapterjs.org/messages.md). This page lists what the channels have; each kind has its own page below.

## Which kind of channel

A channel you get from `guild.channels` or `message.channel` can be of any kind. Ask it before using what only one kind has: inside the `if`, your editor knows the kind.

| Method | True for | Class |
| - | - | - |
| `isText()` | A text or announcement channel of a server | [`TextChannel`](https://www.chapterjs.org/reference/channels/text) |
| `isVoice()` | A voice or stage channel | [`VoiceChannel`](https://www.chapterjs.org/reference/channels/voice) |
| `isCategory()` | A category, which groups channels | [`CategoryChannel`](https://www.chapterjs.org/reference/channels/category) |
| `isForum()` | A forum or media channel, made of posts | [`ForumChannel`](https://www.chapterjs.org/reference/channels/forum) |
| `isThread()` | A thread, or a post of a forum | [`ThreadChannel`](https://www.chapterjs.org/reference/channels/thread) |
| `isDM()` | A private conversation | [`DMChannel`](https://www.chapterjs.org/reference/channels/dm) |
| `isGuildChannel()` | Any channel of a server that is not a thread | [`GuildChannel`](#guildchannel) |
| `isTextBased()` | Any channel messages can be sent in | [`TextBasedChannel`](#textbasedchannel) |

`type` says the same thing as a value of [`ChannelType`](https://www.chapterjs.org/reference/enums#channeltype):

| `ChannelType` | Class |
| - | - |
| `GuildText`, `GuildAnnouncement` | `TextChannel` |
| `GuildVoice`, `GuildStageVoice` | `VoiceChannel` |
| `GuildCategory` | `CategoryChannel` |
| `GuildForum`, `GuildMedia` | `ForumChannel` |
| `AnnouncementThread`, `PublicThread`, `PrivateThread` | `ThreadChannel` |
| `Dm`, `GroupDm` | `DMChannel` |

A kind Discord added after this version is still usable: as a `GuildChannel` when it is in a server, as a `Channel` otherwise.

> [card] [TextChannel](https://www.chapterjs.org/reference/channels/text.md)
>
> A text or announcement channel of a server.

> [card] [VoiceChannel](https://www.chapterjs.org/reference/channels/voice.md)
>
> A voice or stage channel: people talk in it, and can write too.

> [card] [CategoryChannel](https://www.chapterjs.org/reference/channels/category.md)
>
> A category: it groups channels.

> [card] [ForumChannel](https://www.chapterjs.org/reference/channels/forum.md)
>
> A forum or media channel: it only contains posts, which are threads.

> [card] [ThreadChannel](https://www.chapterjs.org/reference/channels/thread.md)
>
> A thread, or a post of a forum.

> [card] [DMChannel](https://www.chapterjs.org/reference/channels/dm.md)
>
> A private conversation between the bot and a user.

## Channel

A channel of any kind. Use the `is...()` methods to know which kind it is and get the properties and actions of that kind. Every class of this section has what is listed here.

### Properties

**id** `Snowflake`

The unique id Discord gave it.

**createdAt** `Date`

When it was created: a Discord id contains its creation date.

**type** `ChannelType`

The kind of channel, as a value of `ChannelType`.

**guildId** `Snowflake | null`

The id of the server of the channel; `null` for a private one.

**guild** `Guild | null`

The server of the channel; `null` for a private one.

### Helpers

These read what the bot already knows: they never send a request.

#### isTextBased()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
isTextBased(): this is TextBasedChannel
```

Whether messages can be sent in it.

#### isGuildChannel()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
isGuildChannel(): this is GuildChannel
```

Whether it belongs to a server and is not a thread.

#### isText()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
isText(): this is TextChannel
```

A text or announcement channel of a server.

#### isVoice()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
isVoice(): this is VoiceChannel
```

A voice or stage channel.

#### isCategory()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
isCategory(): this is CategoryChannel
```

A category, which groups channels.

#### isForum()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
isForum(): this is ForumChannel
```

A forum or media channel, made of posts.

#### isThread()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
isThread(): this is ThreadChannel
```

A thread, or a post of a forum.

#### isDM()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
isDM(): this is DMChannel
```

A private conversation.

#### toString()

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

`<#id>`: links the channel when put in a message.

#### toJSON()

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

The data of Discord as a plain object, with camelCase names.

### Reading from Discord

#### fetch()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
fetch(): Promise<Channel>
```

Asks Discord for the latest data of the channel.

### Actions

#### delete()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
delete(reason?: string): Promise<void>
```

Deletes the channel (closes it, for a private conversation).

[Discord documentation](https://docs.discord.com/developers/resources/channel#deleteclose-channel)

## GuildChannel

A channel of a server (not a thread). `TextChannel`, `VoiceChannel`, `CategoryChannel` and `ForumChannel` have everything listed here, plus what [`Channel`](#channel) has.

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

async function lock(channel: TextChannel) {
  const everyone = channel.guild.everyoneRole;
  // Nobody can write any more, but everyone still reads.
  await channel.setPermissions(everyone, { deny: ['SendMessages'] }, 'Channel locked');
}
```

### Properties

**guildId** `Snowflake`

The id of the server of the channel.

**guild** `Guild`

The server of the channel.

**name** `string`

The name of the channel.

**position** `number`

Where the channel is in the list.

**parentId** `Snowflake | null`

The id of the category of the channel, when it is in one.

**parent** `CategoryChannel | null`

The category of the channel, when it is in one and it is known.

**nsfw** `boolean`

Whether the channel is age-restricted.

**permissionOverwrites** `PermissionOverwrite[]`

What roles and members are allowed or denied in this channel. Each entry is a [`PermissionOverwrite`](https://www.chapterjs.org/reference/data#permissionoverwrite).

### Helpers

#### permissionsFor()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
permissionsFor(member: GuildMember): Permissions
```

What a member can do in this channel: their permissions in the server, changed by the overwrites of the channel.

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

### Reading from Discord

#### fetchInvites()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
fetchInvites(): Promise<Invite[]>
```

The invites that lead to this channel.

[Discord documentation](https://docs.discord.com/developers/resources/channel#get-channel-invites)

#### fetchWebhooks()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
fetchWebhooks(): Promise<Webhook[]>
```

The webhooks that post in this channel.

[Discord documentation](https://docs.discord.com/developers/resources/webhook#get-channel-webhooks)

### Actions

#### edit()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
edit(options: GuildChannelEditOptions, reason?: string): Promise<this>
```

Changes the channel. The options are a [`GuildChannelEditOptions`](https://www.chapterjs.org/reference/options#guildchanneleditoptions).

[Discord documentation](https://docs.discord.com/developers/resources/channel#modify-channel)

#### setPermissions()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
setPermissions(
  target: Role | GuildMember | User,
  permissions: { allow?: PermissionResolvable; deny?: PermissionResolvable },
  reason?: string
): Promise<void>
```

Allows or denies permissions to a role or a member in this channel. Permissions that are in neither list follow the server.

[Discord documentation](https://docs.discord.com/developers/resources/channel#edit-channel-permissions)

#### deletePermissions()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
deletePermissions(target: Snowflake | { id: Snowflake }, reason?: string): Promise<void>
```

Removes what was set for a role or a member in this channel.

[Discord documentation](https://docs.discord.com/developers/resources/channel#delete-channel-permission)

#### createInvite()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
createInvite(options?: InviteCreateOptions, reason?: string): Promise<Invite>
```

Creates an invite to this channel. The options are an [`InviteCreateOptions`](https://www.chapterjs.org/reference/options#invitecreateoptions).

[Discord documentation](https://docs.discord.com/developers/resources/channel#create-channel-invite)

#### createWebhook()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
createWebhook(options: { name: string; avatar?: string | null }, reason?: string): Promise<Webhook>
```

Creates a webhook that posts in this channel: see [Webhook](https://www.chapterjs.org/reference/webhook.md).

**name** `string` *required*

The name of the webhook (1 to 80 characters).

**avatar** `string | null`

The image of the default avatar of the webhook, as a data URI (`data:image/png;base64,...`).

[Discord documentation](https://docs.discord.com/developers/resources/webhook#create-webhook)

## Channels with messages

`TextChannel`, `VoiceChannel`, `ThreadChannel` and `DMChannel` can all send and read messages: they share the properties and methods of this section. Together they are the [`TextBasedChannel`](#textbasedchannel) type.

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

async function clean(channel: TextChannel) {
  const messages = await channel.fetchMessages({ limit: 100 });
  const fromBots = messages.filter(message => message.author.bot);
  const deleted = await channel.bulkDelete(fromBots, 'Cleaning bot messages');
  await channel.send(`Deleted ${deleted} messages.`);
}
```

### Properties

**messages** `ReadonlyMap\<Snowflake, Message\>`

The messages of the channel the bot remembers.

**lastMessageId** `Snowflake | null`

The id of the last message sent in the channel, when known.

> [!NOTE]
>
> `messages` is empty unless one of your files asks for messages to be remembered: see [what the bot remembers](https://www.chapterjs.org/memory.md). `fetchMessage()` and `fetchMessages()` always work.

### Reading from Discord

#### fetchMessage()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
fetchMessage(id: Snowflake, options?: { force?: boolean }): Promise<Message>
```

A message of the channel: from what the bot remembers, or else from Discord.

[Discord documentation](https://docs.discord.com/developers/resources/message#get-channel-message)

#### fetchMessages()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
fetchMessages(options?: FetchMessagesOptions): Promise<Message[]>
```

The latest messages of the channel, newest first. The options are a [`FetchMessagesOptions`](https://www.chapterjs.org/reference/options#fetchmessagesoptions).

[Discord documentation](https://docs.discord.com/developers/resources/message#get-channel-messages)

#### fetchPins()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
fetchPins(): Promise<Message[]>
```

The pinned messages of the channel, latest pin first.

[Discord documentation](https://docs.discord.com/developers/resources/message#get-channel-pins)

### Actions

#### send()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
send(message: MessageInput): Promise<Message>
```

Sends a message in the channel. What it accepts is a [`MessageInput`](https://www.chapterjs.org/reference/message-options#messageinput).

[Discord documentation](https://docs.discord.com/developers/resources/message#create-message)

#### bulkDelete()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
bulkDelete(messages: readonly (Snowflake | { id: Snowflake })[], reason?: string): Promise<number>
```

Deletes several messages at once. Messages older than two weeks can't be deleted in bulk: they are left out, and their number is not counted in the result.

Returns how many messages were deleted.

[Discord documentation](https://docs.discord.com/developers/resources/message#bulk-delete-messages)

#### sendTyping()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
sendTyping(): Promise<void>
```

Shows "the bot is typing…" for 10 seconds, or until it sends a message.

[Discord documentation](https://docs.discord.com/developers/resources/channel#trigger-typing-indicator)

### Waiting

They wait for what comes next in the channel, while your bot runs: a restart ends the wait. How to use them is in the [guide](https://www.chapterjs.org/waiting.md).

#### waitForMessage()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
waitForMessage(options?: WaitForMessageOptions): Promise<Message | null>
```

Waits for the next message of the channel that fits: of a person (`from`), saying something (`matches`). Anyone's but a bot's by default. Resolves with the message, or `null` when `within` (one minute by default) passed first. A restart of the bot ends the wait.

#### collectMessages()

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
collectMessages(options?: CollectMessagesOptions): Promise<Message[]>
```

Gathers the messages of the channel that fit, until `within` (one minute by default) passed or `max` came. Resolves with them, in order.

## Types

### TextBasedChannel

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type TextBasedChannel = GuildTextBasedChannel | DMChannel
```

Any channel messages can be sent in. It is what `message.channel` and `interaction.channel` give; `isTextBased()` narrows a `Channel` to it.

### GuildTextBasedChannel

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type GuildTextBasedChannel = TextChannel | VoiceChannel | ThreadChannel
```

Any channel of a server messages can be sent in. It is the `channel` of a [`GuildMessage`](https://www.chapterjs.org/reference/message#guildmessage) and of a command used in a server.

### WaitForMessageOptions

What `waitForMessage()` takes.

**from** `PersonInput`

Only a message of this person. Anyone but a bot by default.

**matches** `string | RegExp | ((message: Message) =\> boolean)`

Only a message that says this: a text (the same, whatever the capitals and the spaces around), a regular expression, or a function of the message.

**within** `Duration`

How long to wait: `'30s'`, `'2m'`. One minute by default, a second at least, a day at most.

### CollectMessagesOptions

What `collectMessages()` takes: everything [`WaitForMessageOptions`](#waitformessageoptions) has, and:

**max** `number`

Stops once this many messages came. No limit by default: until `within`.

### PersonInput

```ts theme={"theme":{"light":"github-light","dark":"vesper"}}
type PersonInput = User | GuildMember | Snowflake
```

A person, as a wait takes it: a user, a member, or an id.

### Elsewhere

* [`PermissionOverwrite`](https://www.chapterjs.org/reference/data#permissionoverwrite): an entry of `permissionOverwrites`.
* [`GuildChannelEditOptions`](https://www.chapterjs.org/reference/options#guildchanneleditoptions), [`InviteCreateOptions`](https://www.chapterjs.org/reference/options#invitecreateoptions) and [`FetchMessagesOptions`](https://www.chapterjs.org/reference/options#fetchmessagesoptions): what `edit()`, `createInvite()` and `fetchMessages()` take.
* [`MessageInput`](https://www.chapterjs.org/reference/message-options#messageinput): what `send()` takes.


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