Skip to content

Channel

class ChannelHistory (AsyncIterator)

An async iterator for searching through a channel's history.

Attributes:

Name Type Description
channel 'BaseChannel'

The channel to search through

limit

The maximum number of messages to return (set to 0 for no limit)

before Snowflake_Type

get messages before this message ID

after Snowflake_Type

get messages after this message ID

around Snowflake_Type

get messages "around" this message ID

Source code in naff/models/discord/channel.py
class ChannelHistory(AsyncIterator):
    """
    An async iterator for searching through a channel's history.

    Attributes:
        channel: The channel to search through
        limit: The maximum number of messages to return (set to 0 for no limit)
        before: get messages before this message ID
        after: get messages after this message ID
        around: get messages "around" this message ID

    """

    def __init__(self, channel: "BaseChannel", limit=50, before=None, after=None, around=None) -> None:
        self.channel: "BaseChannel" = channel
        self.before: Snowflake_Type = before
        self.after: Snowflake_Type = after
        self.around: Snowflake_Type = around
        super().__init__(limit)

    async def fetch(self) -> List["models.Message"]:
        """
        Fetch additional objects.

        Your implementation of this method *must* return a list of objects.
        If no more objects are available, raise QueueEmpty

        Returns:
            List of objects

        Raises:
              QueueEmpty when no more objects are available.

        """
        if self.after:
            if not self.last:
                self.last = namedtuple("temp", "id")
                self.last.id = self.after
            messages = await self.channel.fetch_messages(limit=self.get_limit, after=self.last.id)
            messages.sort(key=lambda x: x.id)

        elif self.around:
            messages = await self.channel.fetch_messages(limit=self.get_limit, around=self.around)
            # todo: decide how getting *more* messages from `around` would work
            self._limit = 1  # stops history from getting more messages

        else:
            if self.before and not self.last:
                self.last = namedtuple("temp", "id")
                self.last.id = self.before

            messages = await self.channel.fetch_messages(limit=self.get_limit, before=self.last.id)
            messages.sort(key=lambda x: x.id, reverse=True)
        return messages

inherited property readonly get_limit: int

Get how the maximum number of items that should be retrieved.

inherited property readonly total_retrieved: int

Get the total number of objects this iterator has retrieved.

async inherited method add_object(self, obj)

Add an object to iterator's queue.

Source code in naff/models/discord/channel.py
async def add_object(self, obj) -> None:
    """Add an object to iterator's queue."""
    return await self._queue.put(obj)

async inherited method flatten(self)

Flatten this iterator into a list of objects.

Source code in naff/models/discord/channel.py
async def flatten(self) -> List:
    """Flatten this iterator into a list of objects."""
    return [elem async for elem in self]

async inherited method search(self, target_id)

Search the iterator for an object with the given ID.

Source code in naff/models/discord/channel.py
async def search(self, target_id: "snowflake.Snowflake_Type") -> bool:
    """Search the iterator for an object with the given ID."""
    target_id = snowflake.to_snowflake(target_id)

    if target_id in [o.id for o in self._retrieved_objects]:
        return True

    async for o in self:
        if o.id == target_id:
            return True
    return False

async method fetch(self)

Fetch additional objects.

Your implementation of this method must return a list of objects. If no more objects are available, raise QueueEmpty

Returns:

Type Description
List[models.Message]

List of objects

Source code in naff/models/discord/channel.py
async def fetch(self) -> List["models.Message"]:
    """
    Fetch additional objects.

    Your implementation of this method *must* return a list of objects.
    If no more objects are available, raise QueueEmpty

    Returns:
        List of objects

    Raises:
          QueueEmpty when no more objects are available.

    """
    if self.after:
        if not self.last:
            self.last = namedtuple("temp", "id")
            self.last.id = self.after
        messages = await self.channel.fetch_messages(limit=self.get_limit, after=self.last.id)
        messages.sort(key=lambda x: x.id)

    elif self.around:
        messages = await self.channel.fetch_messages(limit=self.get_limit, around=self.around)
        # todo: decide how getting *more* messages from `around` would work
        self._limit = 1  # stops history from getting more messages

    else:
        if self.before and not self.last:
            self.last = namedtuple("temp", "id")
            self.last.id = self.before

        messages = await self.channel.fetch_messages(limit=self.get_limit, before=self.last.id)
        messages.sort(key=lambda x: x.id, reverse=True)
    return messages

attrs class PermissionOverwrite (SnowflakeObject, DictSerializationMixin)

Channel Permissions Overwrite object.

Note

id here is not an attribute of the overwrite, it is the ID of the overwritten instance

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

type OverwriteTypes

Permission overwrite type (role or member)

allow Optional[Permissions]

Permissions to allow

deny Optional[Permissions]

Permissions to deny

Source code in naff/models/discord/channel.py
@define()
class PermissionOverwrite(SnowflakeObject, DictSerializationMixin):
    """
    Channel Permissions Overwrite object.

    !!! Note
        `id` here is not an attribute of the overwrite, it is the ID of the overwritten instance

    """

    type: "OverwriteTypes" = field(repr=True, converter=OverwriteTypes)
    """Permission overwrite type (role or member)"""
    allow: Optional["Permissions"] = field(repr=True, converter=optional_c(Permissions), kw_only=True, default=None)
    """Permissions to allow"""
    deny: Optional["Permissions"] = field(repr=True, converter=optional_c(Permissions), kw_only=True, default=None)
    """Permissions to deny"""

    @classmethod
    def for_target(cls, target_type: Union["models.Role", "models.Member", "models.User"]) -> "PermissionOverwrite":
        """
        Create a PermissionOverwrite for a role or member.

        Args:
            target_type: The type of the target (role or member)

        Returns:
            PermissionOverwrite

        """
        if isinstance(target_type, models.Role):
            return cls(type=OverwriteTypes.ROLE, id=target_type.id)
        elif isinstance(target_type, (models.Member, models.User)):
            return cls(type=OverwriteTypes.MEMBER, id=target_type.id)
        else:
            raise TypeError("target_type must be a Role, Member or User")

    def add_allows(self, *perms: "Permissions") -> None:
        """
        Add permissions to allow.

        Args:
            *perms: Permissions to add

        """
        if not self.allow:
            self.allow = Permissions.NONE
        for perm in perms:
            self.allow |= perm

    def add_denies(self, *perms: "Permissions") -> None:
        """
        Add permissions to deny.

        Args:
            *perms: Permissions to add

        """
        if not self.deny:
            self.deny = Permissions.NONE
        for perm in perms:
            self.deny |= perm

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data Dict[str, Any]

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self: Type[const.T], data: Dict[str, Any]) -> const.T:
    """
    Updates object attribute(s) with new json data received from discord api.

    Args:
        data: The json data received from discord api.

    Returns:
        The updated object class instance.

    """
    data = self._process_dict(data)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

classmethod method for_target(target_type)

Create a PermissionOverwrite for a role or member.

Parameters:

Name Type Description Default
target_type Union[models.Role, models.Member, models.User]

The type of the target (role or member)

required

Returns:

Type Description
PermissionOverwrite

PermissionOverwrite

Source code in naff/models/discord/channel.py
@classmethod
def for_target(cls, target_type: Union["models.Role", "models.Member", "models.User"]) -> "PermissionOverwrite":
    """
    Create a PermissionOverwrite for a role or member.

    Args:
        target_type: The type of the target (role or member)

    Returns:
        PermissionOverwrite

    """
    if isinstance(target_type, models.Role):
        return cls(type=OverwriteTypes.ROLE, id=target_type.id)
    elif isinstance(target_type, (models.Member, models.User)):
        return cls(type=OverwriteTypes.MEMBER, id=target_type.id)
    else:
        raise TypeError("target_type must be a Role, Member or User")

method add_allows(self, *perms)

Add permissions to allow.

Parameters:

Name Type Description Default
*perms Permissions

Permissions to add

()
Source code in naff/models/discord/channel.py
def add_allows(self, *perms: "Permissions") -> None:
    """
    Add permissions to allow.

    Args:
        *perms: Permissions to add

    """
    if not self.allow:
        self.allow = Permissions.NONE
    for perm in perms:
        self.allow |= perm

method add_denies(self, *perms)

Add permissions to deny.

Parameters:

Name Type Description Default
*perms Permissions

Permissions to add

()
Source code in naff/models/discord/channel.py
def add_denies(self, *perms: "Permissions") -> None:
    """
    Add permissions to deny.

    Args:
        *perms: Permissions to add

    """
    if not self.deny:
        self.deny = Permissions.NONE
    for perm in perms:
        self.deny |= perm

attrs class MessageableMixin (SendMixin)

Attr attributes:

Name Type Description
last_message_id Union[int, str, SnowflakeObject, SupportsInt]

The id of the last message sent in this channel (may not point to an existing or valid message)

default_auto_archive_duration int

Default duration that the clients (not the API) will use for newly created threads, in minutes, to automatically archive the thread after recent activity

last_pin_timestamp Optional[models.Timestamp]

When the last pinned message was pinned. This may be None when a message is not pinned.

Source code in naff/models/discord/channel.py
@define(slots=False)
class MessageableMixin(SendMixin):
    last_message_id: Optional[Snowflake_Type] = field(
        default=None
    )  # TODO May need to think of dynamically updating this.
    """The id of the last message sent in this channel (may not point to an existing or valid message)"""
    default_auto_archive_duration: int = field(default=AutoArchiveDuration.ONE_DAY)
    """Default duration that the clients (not the API) will use for newly created threads, in minutes, to automatically archive the thread after recent activity"""
    last_pin_timestamp: Optional["models.Timestamp"] = field(default=None, converter=optional_c(timestamp_converter))
    """When the last pinned message was pinned. This may be None when a message is not pinned."""

    async def _send_http_request(
        self, message_payload: Union[dict, "FormData"], files: list["UPLOADABLE_TYPE"] | None = None
    ) -> dict:
        return await self._client.http.create_message(message_payload, self.id, files=files)

    async def fetch_message(self, message_id: Snowflake_Type) -> Optional["models.Message"]:
        """
        Fetch a message from the channel.

        Args:
            message_id: ID of message to retrieve.

        Returns:
            The message object fetched. If the message is not found, returns None.

        """
        try:
            return await self._client.cache.fetch_message(self.id, message_id)
        except NotFound:
            return None

    def get_message(self, message_id: Snowflake_Type) -> "models.Message":
        """
        Get a message from the channel.

        Args:
            message_id: ID of message to retrieve.

        Returns:
            The message object fetched.

        """
        message_id = to_snowflake(message_id)
        message: "models.Message" = self._client.cache.get_message(self.id, message_id)
        return message

    def history(
        self,
        limit=100,
        before: Snowflake_Type = None,
        after: Snowflake_Type = None,
        around: Snowflake_Type = None,
    ) -> ChannelHistory:
        """
        Get an async iterator for the history of this channel.

        Args:
            limit: The maximum number of messages to return (set to 0 for no limit)
            before: get messages before this message ID
            after: get messages after this message ID
            around: get messages "around" this message ID

        ??? Hint "Example Usage:"
            ```python
            async for message in channel.history(limit=0):
                if message.author.id == 174918559539920897:
                    print("Found author's message")
                    # ...
                    break
            ```
            or
            ```python
            history = channel.history(limit=250)
            # Flatten the async iterator into a list
            messages = await history.flatten()
            ```

        Returns:
            ChannelHistory (AsyncIterator)

        """
        return ChannelHistory(self, limit, before, after, around)

    async def fetch_messages(
        self,
        limit: int = 50,
        around: Snowflake_Type = MISSING,
        before: Snowflake_Type = MISSING,
        after: Snowflake_Type = MISSING,
    ) -> List["models.Message"]:
        """
        Fetch multiple messages from the channel.

        Args:
            limit: Max number of messages to return, default `50`, max `100`
            around: Message to get messages around
            before: Message to get messages before
            after: Message to get messages after

        Returns:
            A list of messages fetched.

        """
        if limit > 100:
            raise ValueError("You cannot fetch more than 100 messages at once.")

        if around:
            around = to_snowflake(around)
        elif before:
            before = to_snowflake(before)
        elif after:
            after = to_snowflake(after)

        messages_data = await self._client.http.get_channel_messages(self.id, limit, around, before, after)
        for m in messages_data:
            m["guild_id"] = self._guild_id

        return [self._client.cache.place_message_data(m) for m in messages_data]

    async def fetch_pinned_messages(self) -> List["models.Message"]:
        """
        Fetch pinned messages from the channel.

        Returns:
            A list of messages fetched.

        """
        messages_data = await self._client.http.get_pinned_messages(self.id)
        return [self._client.cache.place_message_data(message_data) for message_data in messages_data]

    async def delete_messages(
        self, messages: List[Union[Snowflake_Type, "models.Message"]], reason: Absent[Optional[str]] = MISSING
    ) -> None:
        """
        Bulk delete messages from channel.

        Args:
            messages: List of messages or message IDs to delete.
            reason: The reason for this action. Used for audit logs.

        """
        message_ids = [to_snowflake(message) for message in messages]
        # TODO Add check for min/max and duplicates.

        if len(message_ids) == 1:
            # bulk delete messages will throw a http error if only 1 message is passed
            await self.delete_message(message_ids[0], reason)
        else:
            await self._client.http.bulk_delete_messages(self.id, message_ids, reason)

    async def delete_message(self, message: Union[Snowflake_Type, "models.Message"], reason: str = None) -> None:
        """
        Delete a single message from a channel.

        Args:
            message: The message to delete
            reason: The reason for this action

        """
        message = to_snowflake(message)
        await self._client.http.delete_message(self.id, message, reason=reason)

    async def purge(
        self,
        deletion_limit: int = 50,
        search_limit: int = 100,
        predicate: Callable[["models.Message"], bool] = MISSING,
        avoid_loading_msg: bool = True,
        before: Optional[Snowflake_Type] = MISSING,
        after: Optional[Snowflake_Type] = MISSING,
        around: Optional[Snowflake_Type] = MISSING,
        reason: Absent[Optional[str]] = MISSING,
    ) -> int:
        """
        Bulk delete messages within a channel. If a `predicate` is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the `deletion_limit`.

        ??? Hint "Example Usage:"
            ```python
            # this will delete the last 20 messages sent by a user with the given ID
            deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
            await channel.send(f"{deleted} messages deleted")
            ```

        Args:
            deletion_limit: The target amount of messages to delete
            search_limit: How many messages to search through
            predicate: A function that returns True or False, and takes a message as an argument
            avoid_loading_msg: Should the bot attempt to avoid deleting its own loading messages (recommended enabled)
            before: Search messages before this ID
            after: Search messages after this ID
            around: Search messages around this ID
            reason: The reason for this deletion

        Returns:
            The total amount of messages deleted

        """
        if not predicate:

            def predicate(m) -> bool:
                return True  # noqa

        to_delete = []

        # 1209600 14 days ago in seconds, 1420070400000 is used to convert to snowflake
        fourteen_days_ago = int((time.time() - 1209600) * 1000.0 - DISCORD_EPOCH) << 22
        async for message in self.history(limit=search_limit, before=before, after=after, around=around):
            if deletion_limit != 0 and len(to_delete) == deletion_limit:
                break

            if not predicate(message):
                # fails predicate
                continue

            if avoid_loading_msg:
                if message._author_id == self._client.user.id and MessageFlags.LOADING in message.flags:
                    continue

            if message.id < fourteen_days_ago:
                # message is too old to be purged
                continue

            to_delete.append(message.id)

        count = len(to_delete)
        while len(to_delete):
            iteration = [to_delete.pop() for i in range(min(100, len(to_delete)))]
            await self.delete_messages(iteration, reason=reason)
        return count

    async def trigger_typing(self) -> None:
        """Trigger a typing animation in this channel."""
        await self._client.http.trigger_typing_indicator(self.id)

    @property
    def typing(self) -> Typing:
        """A context manager to send a typing state to a given channel as long as long as the wrapped operation takes."""
        return Typing(self)

async inherited method send(self, content, embeds, embed, components, stickers, allowed_mentions, reply_to, files, file, tts, suppress_embeds, flags, delete_after, **kwargs)

Send a message.

Parameters:

Name Type Description Default
content Optional[str]

Message text content.

None
embeds Union[List[Union[Embed, dict]], Embed, dict]

Embedded rich content (up to 6000 characters).

None
embed Union[Embed, dict]

Embedded rich content (up to 6000 characters).

None
components Union[List[List[Union[BaseComponent, dict]]], List[Union[BaseComponent, dict]], BaseComponent, dict]

The components to include with the message.

None
stickers Union[List[Union[Sticker, Snowflake_Type]], Sticker, Snowflake_Type]

IDs of up to 3 stickers in the server to send in the message.

None
allowed_mentions Union[AllowedMentions, dict]

Allowed mentions for the message.

None
reply_to Union[MessageReference, Message, dict, Snowflake_Type]

Message to reference, must be from the same channel.

None
files Union[UPLOADABLE_TYPE, List[UPLOADABLE_TYPE]]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
file Optional[UPLOADABLE_TYPE]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
tts bool

Should this message use Text To Speech.

False
suppress_embeds bool

Should embeds be suppressed on this send

False
flags Union[int, MessageFlags]

Message flags to apply.

None
delete_after Optional[float]

Delete message after this many seconds.

None

Returns:

Type Description
Message

New message object that was sent.

Source code in naff/models/discord/channel.py
async def send(
    self,
    content: Optional[str] = None,
    embeds: Optional[Union[List[Union["Embed", dict]], Union["Embed", dict]]] = None,
    embed: Optional[Union["Embed", dict]] = None,
    components: Optional[
        Union[List[List[Union["BaseComponent", dict]]], List[Union["BaseComponent", dict]], "BaseComponent", dict]
    ] = None,
    stickers: Optional[Union[List[Union["Sticker", "Snowflake_Type"]], "Sticker", "Snowflake_Type"]] = None,
    allowed_mentions: Optional[Union["AllowedMentions", dict]] = None,
    reply_to: Optional[Union["MessageReference", "Message", dict, "Snowflake_Type"]] = None,
    files: Optional[Union["UPLOADABLE_TYPE", List["UPLOADABLE_TYPE"]]] = None,
    file: Optional["UPLOADABLE_TYPE"] = None,
    tts: bool = False,
    suppress_embeds: bool = False,
    flags: Optional[Union[int, "MessageFlags"]] = None,
    delete_after: Optional[float] = None,
    **kwargs,
) -> "Message":
    """
    Send a message.

    Args:
        content: Message text content.
        embeds: Embedded rich content (up to 6000 characters).
        embed: Embedded rich content (up to 6000 characters).
        components: The components to include with the message.
        stickers: IDs of up to 3 stickers in the server to send in the message.
        allowed_mentions: Allowed mentions for the message.
        reply_to: Message to reference, must be from the same channel.
        files: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        file: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        tts: Should this message use Text To Speech.
        suppress_embeds: Should embeds be suppressed on this send
        flags: Message flags to apply.
        delete_after: Delete message after this many seconds.

    Returns:
        New message object that was sent.

    """
    if not content and not (embeds or embed) and not (files or file) and not stickers:
        raise errors.EmptyMessageException(
            "You cannot send a message without any content, embeds, files, or stickers"
        )

    if suppress_embeds:
        if isinstance(flags, int):
            flags = MessageFlags(flags)
        flags = flags | MessageFlags.SUPPRESS_EMBEDS

    message_payload = models.discord.message.process_message_payload(
        content=content,
        embeds=embeds or embed,
        components=components,
        stickers=stickers,
        allowed_mentions=allowed_mentions,
        reply_to=reply_to,
        tts=tts,
        flags=flags,
        **kwargs,
    )

    message_data = await self._send_http_request(message_payload, files=files or file)
    if message_data:
        message = self._client.cache.place_message_data(message_data)
        if delete_after:
            await message.delete(delay=delete_after)
        return message

async method fetch_message(self, message_id)

Fetch a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
Optional[models.Message]

The message object fetched. If the message is not found, returns None.

Source code in naff/models/discord/channel.py
async def fetch_message(self, message_id: Snowflake_Type) -> Optional["models.Message"]:
    """
    Fetch a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched. If the message is not found, returns None.

    """
    try:
        return await self._client.cache.fetch_message(self.id, message_id)
    except NotFound:
        return None

method get_message(self, message_id)

Get a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
models.Message

The message object fetched.

Source code in naff/models/discord/channel.py
def get_message(self, message_id: Snowflake_Type) -> "models.Message":
    """
    Get a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched.

    """
    message_id = to_snowflake(message_id)
    message: "models.Message" = self._client.cache.get_message(self.id, message_id)
    return message

method history(self, limit, before, after, around)

Get an async iterator for the history of this channel.

Parameters:

Name Type Description Default
limit

The maximum number of messages to return (set to 0 for no limit)

100
before Union[int, str, SnowflakeObject, SupportsInt]

get messages before this message ID

None
after Union[int, str, SnowflakeObject, SupportsInt]

get messages after this message ID

None
around Union[int, str, SnowflakeObject, SupportsInt]

get messages "around" this message ID

None
Example Usage:

1
2
3
4
5
async for message in channel.history(limit=0):
    if message.author.id == 174918559539920897:
        print("Found author's message")
        # ...
        break
or
1
2
3
history = channel.history(limit=250)
# Flatten the async iterator into a list
messages = await history.flatten()

Returns:

Type Description
ChannelHistory

ChannelHistory (AsyncIterator)

Source code in naff/models/discord/channel.py
def history(
    self,
    limit=100,
    before: Snowflake_Type = None,
    after: Snowflake_Type = None,
    around: Snowflake_Type = None,
) -> ChannelHistory:
    """
    Get an async iterator for the history of this channel.

    Args:
        limit: The maximum number of messages to return (set to 0 for no limit)
        before: get messages before this message ID
        after: get messages after this message ID
        around: get messages "around" this message ID

    ??? Hint "Example Usage:"
        ```python
        async for message in channel.history(limit=0):
            if message.author.id == 174918559539920897:
                print("Found author's message")
                # ...
                break
        ```
        or
        ```python
        history = channel.history(limit=250)
        # Flatten the async iterator into a list
        messages = await history.flatten()
        ```

    Returns:
        ChannelHistory (AsyncIterator)

    """
    return ChannelHistory(self, limit, before, after, around)

async method fetch_messages(self, limit, around, before, after)

Fetch multiple messages from the channel.

Parameters:

Name Type Description Default
limit int

Max number of messages to return, default 50, max 100

50
around Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages around

Missing
before Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages before

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages after

Missing

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_messages(
    self,
    limit: int = 50,
    around: Snowflake_Type = MISSING,
    before: Snowflake_Type = MISSING,
    after: Snowflake_Type = MISSING,
) -> List["models.Message"]:
    """
    Fetch multiple messages from the channel.

    Args:
        limit: Max number of messages to return, default `50`, max `100`
        around: Message to get messages around
        before: Message to get messages before
        after: Message to get messages after

    Returns:
        A list of messages fetched.

    """
    if limit > 100:
        raise ValueError("You cannot fetch more than 100 messages at once.")

    if around:
        around = to_snowflake(around)
    elif before:
        before = to_snowflake(before)
    elif after:
        after = to_snowflake(after)

    messages_data = await self._client.http.get_channel_messages(self.id, limit, around, before, after)
    for m in messages_data:
        m["guild_id"] = self._guild_id

    return [self._client.cache.place_message_data(m) for m in messages_data]

async method fetch_pinned_messages(self)

Fetch pinned messages from the channel.

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_pinned_messages(self) -> List["models.Message"]:
    """
    Fetch pinned messages from the channel.

    Returns:
        A list of messages fetched.

    """
    messages_data = await self._client.http.get_pinned_messages(self.id)
    return [self._client.cache.place_message_data(message_data) for message_data in messages_data]

async method delete_messages(self, messages, reason)

Bulk delete messages from channel.

Parameters:

Name Type Description Default
messages List[Union[int, str, SnowflakeObject, SupportsInt, models.Message]]

List of messages or message IDs to delete.

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this action. Used for audit logs.

Missing
Source code in naff/models/discord/channel.py
async def delete_messages(
    self, messages: List[Union[Snowflake_Type, "models.Message"]], reason: Absent[Optional[str]] = MISSING
) -> None:
    """
    Bulk delete messages from channel.

    Args:
        messages: List of messages or message IDs to delete.
        reason: The reason for this action. Used for audit logs.

    """
    message_ids = [to_snowflake(message) for message in messages]
    # TODO Add check for min/max and duplicates.

    if len(message_ids) == 1:
        # bulk delete messages will throw a http error if only 1 message is passed
        await self.delete_message(message_ids[0], reason)
    else:
        await self._client.http.bulk_delete_messages(self.id, message_ids, reason)

async method delete_message(self, message, reason)

Delete a single message from a channel.

Parameters:

Name Type Description Default
message Union[int, str, SnowflakeObject, SupportsInt, models.Message]

The message to delete

required
reason str

The reason for this action

None
Source code in naff/models/discord/channel.py
async def delete_message(self, message: Union[Snowflake_Type, "models.Message"], reason: str = None) -> None:
    """
    Delete a single message from a channel.

    Args:
        message: The message to delete
        reason: The reason for this action

    """
    message = to_snowflake(message)
    await self._client.http.delete_message(self.id, message, reason=reason)

async method purge(self, deletion_limit, search_limit, predicate, avoid_loading_msg, before, after, around, reason)

Bulk delete messages within a channel. If a predicate is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the deletion_limit.

Example Usage:
1
2
3
# this will delete the last 20 messages sent by a user with the given ID
deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
await channel.send(f"{deleted} messages deleted")

Parameters:

Name Type Description Default
deletion_limit int

The target amount of messages to delete

50
search_limit int

How many messages to search through

100
predicate Callable[[models.Message], bool]

A function that returns True or False, and takes a message as an argument

Missing
avoid_loading_msg bool

Should the bot attempt to avoid deleting its own loading messages (recommended enabled)

True
before Union[int, str, SnowflakeObject, SupportsInt]

Search messages before this ID

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Search messages after this ID

Missing
around Union[int, str, SnowflakeObject, SupportsInt]

Search messages around this ID

Missing
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this deletion

Missing

Returns:

Type Description
int

The total amount of messages deleted

Source code in naff/models/discord/channel.py
async def purge(
    self,
    deletion_limit: int = 50,
    search_limit: int = 100,
    predicate: Callable[["models.Message"], bool] = MISSING,
    avoid_loading_msg: bool = True,
    before: Optional[Snowflake_Type] = MISSING,
    after: Optional[Snowflake_Type] = MISSING,
    around: Optional[Snowflake_Type] = MISSING,
    reason: Absent[Optional[str]] = MISSING,
) -> int:
    """
    Bulk delete messages within a channel. If a `predicate` is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the `deletion_limit`.

    ??? Hint "Example Usage:"
        ```python
        # this will delete the last 20 messages sent by a user with the given ID
        deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
        await channel.send(f"{deleted} messages deleted")
        ```

    Args:
        deletion_limit: The target amount of messages to delete
        search_limit: How many messages to search through
        predicate: A function that returns True or False, and takes a message as an argument
        avoid_loading_msg: Should the bot attempt to avoid deleting its own loading messages (recommended enabled)
        before: Search messages before this ID
        after: Search messages after this ID
        around: Search messages around this ID
        reason: The reason for this deletion

    Returns:
        The total amount of messages deleted

    """
    if not predicate:

        def predicate(m) -> bool:
            return True  # noqa

    to_delete = []

    # 1209600 14 days ago in seconds, 1420070400000 is used to convert to snowflake
    fourteen_days_ago = int((time.time() - 1209600) * 1000.0 - DISCORD_EPOCH) << 22
    async for message in self.history(limit=search_limit, before=before, after=after, around=around):
        if deletion_limit != 0 and len(to_delete) == deletion_limit:
            break

        if not predicate(message):
            # fails predicate
            continue

        if avoid_loading_msg:
            if message._author_id == self._client.user.id and MessageFlags.LOADING in message.flags:
                continue

        if message.id < fourteen_days_ago:
            # message is too old to be purged
            continue

        to_delete.append(message.id)

    count = len(to_delete)
    while len(to_delete):
        iteration = [to_delete.pop() for i in range(min(100, len(to_delete)))]
        await self.delete_messages(iteration, reason=reason)
    return count

async method trigger_typing(self)

Trigger a typing animation in this channel.

Source code in naff/models/discord/channel.py
async def trigger_typing(self) -> None:
    """Trigger a typing animation in this channel."""
    await self._client.http.trigger_typing_indicator(self.id)

property readonly typing: Typing

A context manager to send a typing state to a given channel as long as long as the wrapped operation takes.

attrs class InvitableMixin

Attr attributes:

Name Type Description
Source code in naff/models/discord/channel.py
@define(slots=False)
class InvitableMixin:
    async def create_invite(
        self,
        max_age: int = 86400,
        max_uses: int = 0,
        temporary: bool = False,
        unique: bool = False,
        target_type: Optional[InviteTargetTypes] = None,
        target_user: Optional[Union[Snowflake_Type, "models.User"]] = None,
        target_application: Optional[Union[Snowflake_Type, "models.Application"]] = None,
        reason: Optional[str] = None,
    ) -> "models.Invite":
        """
        Creates a new channel invite.

        Args:
            max_age: Max age of invite in seconds, default 86400 (24 hours).
            max_uses: Max uses of invite, default 0.
            temporary: Grants temporary membership, default False.
            unique: Invite is unique, default false.
            target_type: Target type for streams and embedded applications.
            target_user: Target User ID for Stream target type.
            target_application: Target Application ID for Embedded App target type.
            reason: The reason for creating this invite.

        Returns:
            Newly created Invite object.

        """
        if target_type:
            if target_type == InviteTargetTypes.STREAM and not target_user:
                raise ValueError("Stream target must include target user id.")
            elif target_type == InviteTargetTypes.EMBEDDED_APPLICATION and not target_application:
                raise ValueError("Embedded Application target must include target application id.")

        if target_user and target_application:
            raise ValueError("Invite target must be either User or Embedded Application, not both.")
        elif target_user:
            target_user = to_snowflake(target_user)
            target_type = InviteTargetTypes.STREAM
        elif target_application:
            target_application = to_snowflake(target_application)
            target_type = InviteTargetTypes.EMBEDDED_APPLICATION

        invite_data = await self._client.http.create_channel_invite(
            self.id, max_age, max_uses, temporary, unique, target_type, target_user, target_application, reason
        )
        return models.Invite.from_dict(invite_data, self._client)

    async def fetch_invites(self) -> List["models.Invite"]:
        """
        Fetches all invites (with invite metadata) for the channel.

        Returns:
            List of Invite objects.

        """
        invites_data = await self._client.http.get_channel_invites(self.id)
        return models.Invite.from_list(invites_data, self._client)

async method create_invite(self, max_age, max_uses, temporary, unique, target_type, target_user, target_application, reason)

Creates a new channel invite.

Parameters:

Name Type Description Default
max_age int

Max age of invite in seconds, default 86400 (24 hours).

86400
max_uses int

Max uses of invite, default 0.

0
temporary bool

Grants temporary membership, default False.

False
unique bool

Invite is unique, default false.

False
target_type Optional[naff.models.discord.enums.InviteTargetTypes]

Target type for streams and embedded applications.

None
target_user Union[int, str, SnowflakeObject, SupportsInt, models.User]

Target User ID for Stream target type.

None
target_application Union[int, str, SnowflakeObject, SupportsInt, models.Application]

Target Application ID for Embedded App target type.

None
reason Optional[str]

The reason for creating this invite.

None

Returns:

Type Description
models.Invite

Newly created Invite object.

Source code in naff/models/discord/channel.py
async def create_invite(
    self,
    max_age: int = 86400,
    max_uses: int = 0,
    temporary: bool = False,
    unique: bool = False,
    target_type: Optional[InviteTargetTypes] = None,
    target_user: Optional[Union[Snowflake_Type, "models.User"]] = None,
    target_application: Optional[Union[Snowflake_Type, "models.Application"]] = None,
    reason: Optional[str] = None,
) -> "models.Invite":
    """
    Creates a new channel invite.

    Args:
        max_age: Max age of invite in seconds, default 86400 (24 hours).
        max_uses: Max uses of invite, default 0.
        temporary: Grants temporary membership, default False.
        unique: Invite is unique, default false.
        target_type: Target type for streams and embedded applications.
        target_user: Target User ID for Stream target type.
        target_application: Target Application ID for Embedded App target type.
        reason: The reason for creating this invite.

    Returns:
        Newly created Invite object.

    """
    if target_type:
        if target_type == InviteTargetTypes.STREAM and not target_user:
            raise ValueError("Stream target must include target user id.")
        elif target_type == InviteTargetTypes.EMBEDDED_APPLICATION and not target_application:
            raise ValueError("Embedded Application target must include target application id.")

    if target_user and target_application:
        raise ValueError("Invite target must be either User or Embedded Application, not both.")
    elif target_user:
        target_user = to_snowflake(target_user)
        target_type = InviteTargetTypes.STREAM
    elif target_application:
        target_application = to_snowflake(target_application)
        target_type = InviteTargetTypes.EMBEDDED_APPLICATION

    invite_data = await self._client.http.create_channel_invite(
        self.id, max_age, max_uses, temporary, unique, target_type, target_user, target_application, reason
    )
    return models.Invite.from_dict(invite_data, self._client)

async method fetch_invites(self)

Fetches all invites (with invite metadata) for the channel.

Returns:

Type Description
List[models.Invite]

List of Invite objects.

Source code in naff/models/discord/channel.py
async def fetch_invites(self) -> List["models.Invite"]:
    """
    Fetches all invites (with invite metadata) for the channel.

    Returns:
        List of Invite objects.

    """
    invites_data = await self._client.http.get_channel_invites(self.id)
    return models.Invite.from_list(invites_data, self._client)

attrs class ThreadableMixin

Attr attributes:

Name Type Description
Source code in naff/models/discord/channel.py
@define(slots=False)
class ThreadableMixin:
    async def create_thread(
        self,
        name: str,
        message: Absent[Snowflake_Type] = MISSING,
        thread_type: Absent[ChannelTypes] = MISSING,
        invitable: Absent[bool] = MISSING,
        auto_archive_duration: AutoArchiveDuration = AutoArchiveDuration.ONE_DAY,
        reason: Absent[str] = None,
    ) -> "TYPE_THREAD_CHANNEL":
        """
        Creates a new thread in this channel. If a message is provided, it will be used as the initial message.

        Args:
            name: 1-100 character thread name
            message: The message to connect this thread to. Required for news channel.
            thread_type: Is the thread private or public. Not applicable to news channel, it will always be GUILD_NEWS_THREAD.
            invitable: whether non-moderators can add other non-moderators to a thread. Only applicable when creating a private thread.
            auto_archive_duration: Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.
            reason: The reason for creating this thread.

        Returns:
            The created thread, if successful

        """
        if self.type == ChannelTypes.GUILD_NEWS and not message:
            raise ValueError("News channel must include message to create thread from.")

        elif message and (thread_type or invitable):
            raise ValueError("Message cannot be used with thread_type or invitable.")

        elif thread_type != ChannelTypes.GUILD_PRIVATE_THREAD and invitable:
            raise ValueError("Invitable only applies to private threads.")

        thread_data = await self._client.http.create_thread(
            channel_id=self.id,
            name=name,
            thread_type=thread_type,
            invitable=invitable,
            auto_archive_duration=auto_archive_duration,
            message_id=to_optional_snowflake(message),
            reason=reason,
        )
        return self._client.cache.place_channel_data(thread_data)

    async def fetch_public_archived_threads(
        self, limit: int = None, before: Optional["models.Timestamp"] = None
    ) -> "models.ThreadList":
        """
        Get a `ThreadList` of archived **public** threads available in this channel.

        Args:
            limit: optional maximum number of threads to return
            before: Returns threads before this timestamp

        Returns:
            A `ThreadList` of archived threads.

        """
        threads_data = await self._client.http.list_public_archived_threads(
            channel_id=self.id, limit=limit, before=before
        )
        threads_data["id"] = self.id
        return models.ThreadList.from_dict(threads_data, self._client)

    async def fetch_private_archived_threads(
        self, limit: int = None, before: Optional["models.Timestamp"] = None
    ) -> "models.ThreadList":
        """
        Get a `ThreadList` of archived **private** threads available in this channel.

        Args:
            limit: optional maximum number of threads to return
            before: Returns threads before this timestamp

        Returns:
            A `ThreadList` of archived threads.

        """
        threads_data = await self._client.http.list_private_archived_threads(
            channel_id=self.id, limit=limit, before=before
        )
        threads_data["id"] = self.id
        return models.ThreadList.from_dict(threads_data, self._client)

    async def fetch_archived_threads(
        self, limit: int = None, before: Optional["models.Timestamp"] = None
    ) -> "models.ThreadList":
        """
        Get a `ThreadList` of archived threads available in this channel.

        Args:
            limit: optional maximum number of threads to return
            before: Returns threads before this timestamp

        Returns:
            A `ThreadList` of archived threads.

        """
        threads_data = await self._client.http.list_private_archived_threads(
            channel_id=self.id, limit=limit, before=before
        )
        threads_data.update(
            await self._client.http.list_public_archived_threads(channel_id=self.id, limit=limit, before=before)
        )
        threads_data["id"] = self.id
        return models.ThreadList.from_dict(threads_data, self._client)

    async def fetch_joined_private_archived_threads(
        self, limit: int = None, before: Optional["models.Timestamp"] = None
    ) -> "models.ThreadList":
        """
        Get a `ThreadList` of threads the bot is a participant of in this channel.

        Args:
            limit: optional maximum number of threads to return
            before: Returns threads before this timestamp

        Returns:
            A `ThreadList` of threads the bot is a participant of.

        """
        threads_data = await self._client.http.list_joined_private_archived_threads(
            channel_id=self.id, limit=limit, before=before
        )
        threads_data["id"] = self.id
        return models.ThreadList.from_dict(threads_data, self._client)

    async def fetch_active_threads(self) -> "models.ThreadList":
        """
        Gets all active threads in the channel, including public and private threads.

        Returns:
            A `ThreadList` of active threads.

        """
        threads_data = await self._client.http.list_active_threads(guild_id=self._guild_id)

        # delete the items where the channel_id does not match
        removed_thread_ids = []
        cleaned_threads_data_threads = []
        for thread in threads_data["threads"]:
            if thread["parent_id"] == str(self.id):
                cleaned_threads_data_threads.append(thread)
            else:
                removed_thread_ids.append(thread["id"])
        threads_data["threads"] = cleaned_threads_data_threads

        # delete the member data which is not needed
        cleaned_member_data_threads = []
        for thread_member in threads_data["members"]:
            if thread_member["id"] not in removed_thread_ids:
                cleaned_member_data_threads.append(thread_member)
        threads_data["members"] = cleaned_member_data_threads

        return models.ThreadList.from_dict(threads_data, self._client)

    async def fetch_all_threads(self) -> "models.ThreadList":
        """
        Gets all threads in the channel. Active and archived, including public and private threads.

        Returns:
            A `ThreadList` of all threads.

        """
        threads = await self.fetch_active_threads()

        # update that data with the archived threads
        archived_threads = await self.fetch_archived_threads()
        threads.threads.extend(archived_threads.threads)
        threads.members.extend(archived_threads.members)

        return threads

async method create_thread(self, name, message, thread_type, invitable, auto_archive_duration, reason)

Creates a new thread in this channel. If a message is provided, it will be used as the initial message.

Parameters:

Name Type Description Default
name str

1-100 character thread name

required
message Union[int, str, SnowflakeObject, SupportsInt, naff.client.const.Missing]

The message to connect this thread to. Required for news channel.

Missing
thread_type Union[naff.models.discord.enums.ChannelTypes, naff.client.const.Missing]

Is the thread private or public. Not applicable to news channel, it will always be GUILD_NEWS_THREAD.

Missing
invitable Union[bool, naff.client.const.Missing]

whether non-moderators can add other non-moderators to a thread. Only applicable when creating a private thread.

Missing
auto_archive_duration AutoArchiveDuration

Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.

<AutoArchiveDuration.ONE_DAY: 1440>
reason Union[str, naff.client.const.Missing]

The reason for creating this thread.

None

Returns:

Type Description
TYPE_THREAD_CHANNEL

The created thread, if successful

Source code in naff/models/discord/channel.py
async def create_thread(
    self,
    name: str,
    message: Absent[Snowflake_Type] = MISSING,
    thread_type: Absent[ChannelTypes] = MISSING,
    invitable: Absent[bool] = MISSING,
    auto_archive_duration: AutoArchiveDuration = AutoArchiveDuration.ONE_DAY,
    reason: Absent[str] = None,
) -> "TYPE_THREAD_CHANNEL":
    """
    Creates a new thread in this channel. If a message is provided, it will be used as the initial message.

    Args:
        name: 1-100 character thread name
        message: The message to connect this thread to. Required for news channel.
        thread_type: Is the thread private or public. Not applicable to news channel, it will always be GUILD_NEWS_THREAD.
        invitable: whether non-moderators can add other non-moderators to a thread. Only applicable when creating a private thread.
        auto_archive_duration: Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.
        reason: The reason for creating this thread.

    Returns:
        The created thread, if successful

    """
    if self.type == ChannelTypes.GUILD_NEWS and not message:
        raise ValueError("News channel must include message to create thread from.")

    elif message and (thread_type or invitable):
        raise ValueError("Message cannot be used with thread_type or invitable.")

    elif thread_type != ChannelTypes.GUILD_PRIVATE_THREAD and invitable:
        raise ValueError("Invitable only applies to private threads.")

    thread_data = await self._client.http.create_thread(
        channel_id=self.id,
        name=name,
        thread_type=thread_type,
        invitable=invitable,
        auto_archive_duration=auto_archive_duration,
        message_id=to_optional_snowflake(message),
        reason=reason,
    )
    return self._client.cache.place_channel_data(thread_data)

async method fetch_public_archived_threads(self, limit, before)

Get a ThreadList of archived public threads available in this channel.

Parameters:

Name Type Description Default
limit int

optional maximum number of threads to return

None
before Optional[models.Timestamp]

Returns threads before this timestamp

None

Returns:

Type Description
models.ThreadList

A ThreadList of archived threads.

Source code in naff/models/discord/channel.py
async def fetch_public_archived_threads(
    self, limit: int = None, before: Optional["models.Timestamp"] = None
) -> "models.ThreadList":
    """
    Get a `ThreadList` of archived **public** threads available in this channel.

    Args:
        limit: optional maximum number of threads to return
        before: Returns threads before this timestamp

    Returns:
        A `ThreadList` of archived threads.

    """
    threads_data = await self._client.http.list_public_archived_threads(
        channel_id=self.id, limit=limit, before=before
    )
    threads_data["id"] = self.id
    return models.ThreadList.from_dict(threads_data, self._client)

async method fetch_private_archived_threads(self, limit, before)

Get a ThreadList of archived private threads available in this channel.

Parameters:

Name Type Description Default
limit int

optional maximum number of threads to return

None
before Optional[models.Timestamp]

Returns threads before this timestamp

None

Returns:

Type Description
models.ThreadList

A ThreadList of archived threads.

Source code in naff/models/discord/channel.py
async def fetch_private_archived_threads(
    self, limit: int = None, before: Optional["models.Timestamp"] = None
) -> "models.ThreadList":
    """
    Get a `ThreadList` of archived **private** threads available in this channel.

    Args:
        limit: optional maximum number of threads to return
        before: Returns threads before this timestamp

    Returns:
        A `ThreadList` of archived threads.

    """
    threads_data = await self._client.http.list_private_archived_threads(
        channel_id=self.id, limit=limit, before=before
    )
    threads_data["id"] = self.id
    return models.ThreadList.from_dict(threads_data, self._client)

async method fetch_archived_threads(self, limit, before)

Get a ThreadList of archived threads available in this channel.

Parameters:

Name Type Description Default
limit int

optional maximum number of threads to return

None
before Optional[models.Timestamp]

Returns threads before this timestamp

None

Returns:

Type Description
models.ThreadList

A ThreadList of archived threads.

Source code in naff/models/discord/channel.py
async def fetch_archived_threads(
    self, limit: int = None, before: Optional["models.Timestamp"] = None
) -> "models.ThreadList":
    """
    Get a `ThreadList` of archived threads available in this channel.

    Args:
        limit: optional maximum number of threads to return
        before: Returns threads before this timestamp

    Returns:
        A `ThreadList` of archived threads.

    """
    threads_data = await self._client.http.list_private_archived_threads(
        channel_id=self.id, limit=limit, before=before
    )
    threads_data.update(
        await self._client.http.list_public_archived_threads(channel_id=self.id, limit=limit, before=before)
    )
    threads_data["id"] = self.id
    return models.ThreadList.from_dict(threads_data, self._client)

async method fetch_joined_private_archived_threads(self, limit, before)

Get a ThreadList of threads the bot is a participant of in this channel.

Parameters:

Name Type Description Default
limit int

optional maximum number of threads to return

None
before Optional[models.Timestamp]

Returns threads before this timestamp

None

Returns:

Type Description
models.ThreadList

A ThreadList of threads the bot is a participant of.

Source code in naff/models/discord/channel.py
async def fetch_joined_private_archived_threads(
    self, limit: int = None, before: Optional["models.Timestamp"] = None
) -> "models.ThreadList":
    """
    Get a `ThreadList` of threads the bot is a participant of in this channel.

    Args:
        limit: optional maximum number of threads to return
        before: Returns threads before this timestamp

    Returns:
        A `ThreadList` of threads the bot is a participant of.

    """
    threads_data = await self._client.http.list_joined_private_archived_threads(
        channel_id=self.id, limit=limit, before=before
    )
    threads_data["id"] = self.id
    return models.ThreadList.from_dict(threads_data, self._client)

async method fetch_active_threads(self)

Gets all active threads in the channel, including public and private threads.

Returns:

Type Description
models.ThreadList

A ThreadList of active threads.

Source code in naff/models/discord/channel.py
async def fetch_active_threads(self) -> "models.ThreadList":
    """
    Gets all active threads in the channel, including public and private threads.

    Returns:
        A `ThreadList` of active threads.

    """
    threads_data = await self._client.http.list_active_threads(guild_id=self._guild_id)

    # delete the items where the channel_id does not match
    removed_thread_ids = []
    cleaned_threads_data_threads = []
    for thread in threads_data["threads"]:
        if thread["parent_id"] == str(self.id):
            cleaned_threads_data_threads.append(thread)
        else:
            removed_thread_ids.append(thread["id"])
    threads_data["threads"] = cleaned_threads_data_threads

    # delete the member data which is not needed
    cleaned_member_data_threads = []
    for thread_member in threads_data["members"]:
        if thread_member["id"] not in removed_thread_ids:
            cleaned_member_data_threads.append(thread_member)
    threads_data["members"] = cleaned_member_data_threads

    return models.ThreadList.from_dict(threads_data, self._client)

async method fetch_all_threads(self)

Gets all threads in the channel. Active and archived, including public and private threads.

Returns:

Type Description
models.ThreadList

A ThreadList of all threads.

Source code in naff/models/discord/channel.py
async def fetch_all_threads(self) -> "models.ThreadList":
    """
    Gets all threads in the channel. Active and archived, including public and private threads.

    Returns:
        A `ThreadList` of all threads.

    """
    threads = await self.fetch_active_threads()

    # update that data with the archived threads
    archived_threads = await self.fetch_archived_threads()
    threads.threads.extend(archived_threads.threads)
    threads.members.extend(archived_threads.members)

    return threads

attrs class WebhookMixin

Attr attributes:

Name Type Description
Source code in naff/models/discord/channel.py
@define(slots=False)
class WebhookMixin:
    async def create_webhook(self, name: str, avatar: Absent[UPLOADABLE_TYPE] = MISSING) -> "models.Webhook":
        """
        Create a webhook in this channel.

        Args:
            name: The name of the webhook
            avatar: An optional default avatar image to use

        Returns:
            The created webhook object

        Raises:
            ValueError: If you try to name the webhook "Clyde"

        """
        return await models.Webhook.create(self._client, self, name, avatar)  # type: ignore

    async def delete_webhook(self, webhook: "models.Webhook") -> None:
        """
        Delete a given webhook in this channel.

        Args:
            webhook: The webhook to delete

        """
        return await webhook.delete()

    async def fetch_webhooks(self) -> List["models.Webhook"]:
        """
        Fetches all the webhooks for this channel.

        Returns:
            List of webhook objects

        """
        resp = await self._client.http.get_channel_webhooks(self.id)
        return [models.Webhook.from_dict(d, self._client) for d in resp]

async method create_webhook(self, name, avatar)

Create a webhook in this channel.

Parameters:

Name Type Description Default
name str

The name of the webhook

required
avatar Union[naff.models.discord.file.File, io.IOBase, BinaryIO, pathlib.Path, str, naff.client.const.Missing]

An optional default avatar image to use

Missing

Returns:

Type Description
models.Webhook

The created webhook object

Exceptions:

Type Description
ValueError

If you try to name the webhook "Clyde"

Source code in naff/models/discord/channel.py
async def create_webhook(self, name: str, avatar: Absent[UPLOADABLE_TYPE] = MISSING) -> "models.Webhook":
    """
    Create a webhook in this channel.

    Args:
        name: The name of the webhook
        avatar: An optional default avatar image to use

    Returns:
        The created webhook object

    Raises:
        ValueError: If you try to name the webhook "Clyde"

    """
    return await models.Webhook.create(self._client, self, name, avatar)  # type: ignore

async method delete_webhook(self, webhook)

Delete a given webhook in this channel.

Parameters:

Name Type Description Default
webhook models.Webhook

The webhook to delete

required
Source code in naff/models/discord/channel.py
async def delete_webhook(self, webhook: "models.Webhook") -> None:
    """
    Delete a given webhook in this channel.

    Args:
        webhook: The webhook to delete

    """
    return await webhook.delete()

async method fetch_webhooks(self)

Fetches all the webhooks for this channel.

Returns:

Type Description
List[models.Webhook]

List of webhook objects

Source code in naff/models/discord/channel.py
async def fetch_webhooks(self) -> List["models.Webhook"]:
    """
    Fetches all the webhooks for this channel.

    Returns:
        List of webhook objects

    """
    resp = await self._client.http.get_channel_webhooks(self.id)
    return [models.Webhook.from_dict(d, self._client) for d in resp]

attrs class BaseChannel (DiscordObject)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

name Optional[str]

The name of the channel (1-100 characters)

type Union[naff.models.discord.enums.ChannelTypes, int]

The channel topic (0-1024 characters)

Source code in naff/models/discord/channel.py
@define(slots=False)
class BaseChannel(DiscordObject):
    name: Optional[str] = field(repr=True, default=None)
    """The name of the channel (1-100 characters)"""
    type: Union[ChannelTypes, int] = field(repr=True, converter=ChannelTypes)
    """The channel topic (0-1024 characters)"""

    @classmethod
    def from_dict_factory(cls, data: dict, client: "Client") -> "TYPE_ALL_CHANNEL":
        """
        Creates a channel object of the appropriate type.

        Args:
            data: The channel data.
            client: The bot.

        Returns:
            The new channel object.

        """
        channel_type = data.get("type", None)
        channel_class = TYPE_CHANNEL_MAPPING.get(channel_type, None)
        if not channel_class:
            logger.error(f"Unsupported channel type for {data} ({channel_type}).")
            channel_class = BaseChannel

        return channel_class.from_dict(data, client)

    @property
    def mention(self) -> str:
        """Returns a string that would mention the channel."""
        return f"<#{self.id}>"

    async def edit(
        self,
        name: Absent[str] = MISSING,
        icon: Absent[UPLOADABLE_TYPE] = MISSING,
        type: Absent[ChannelTypes] = MISSING,
        position: Absent[int] = MISSING,
        topic: Absent[str] = MISSING,
        nsfw: Absent[bool] = MISSING,
        rate_limit_per_user: Absent[int] = MISSING,
        bitrate: Absent[int] = MISSING,
        user_limit: Absent[int] = MISSING,
        permission_overwrites: Absent[
            Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
        ] = MISSING,
        parent_id: Absent[Snowflake_Type] = MISSING,
        rtc_region: Absent[Union["models.VoiceRegion", str]] = MISSING,
        video_quality_mode: Absent[VideoQualityModes] = MISSING,
        default_auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
        archived: Absent[bool] = MISSING,
        auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
        locked: Absent[bool] = MISSING,
        invitable: Absent[bool] = MISSING,
        reason: Absent[str] = MISSING,
        **kwargs,
    ) -> "TYPE_ALL_CHANNEL":
        """
        Edits the channel.

        Args:
            name: 1-100 character channel name
            icon: DM Group icon
            type: The type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature
            position: The position of the channel in the left-hand listing
            topic: 0-1024 character channel topic
            nsfw: Whether the channel is nsfw
            rate_limit_per_user: Amount of seconds a user has to wait before sending another message (0-21600)
            bitrate: The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)
            user_limit: The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit
            permission_overwrites: Channel or category-specific permissions
            parent_id: The id of the new parent category for a channel
            rtc_region: Channel voice region id, automatic when set to None.
            video_quality_mode: The camera video quality mode of the voice channel
            default_auto_archive_duration: The default duration that the clients use (not the API) for newly created threads in the channel, in minutes, to automatically archive the thread after recent activity
            archived: Whether the thread is archived
            auto_archive_duration: Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080
            locked: Whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
            invitable: Whether non-moderators can add other non-moderators to a thread; only available on private threads
            reason: The reason for editing the channel

        Returns:
            The edited channel. May be a new object if the channel type changes.

        """
        payload = {
            "name": name,
            "icon": to_image_data(icon),
            "type": type,
            "position": position,
            "topic": topic,
            "nsfw": nsfw,
            "rate_limit_per_user": rate_limit_per_user,
            "bitrate": bitrate,
            "user_limit": user_limit,
            "permission_overwrites": process_permission_overwrites(permission_overwrites),
            "parent_id": to_optional_snowflake(parent_id),
            "rtc_region": rtc_region.id if isinstance(rtc_region, models.VoiceRegion) else rtc_region,
            "video_quality_mode": video_quality_mode,
            "default_auto_archive_duration": default_auto_archive_duration,
            "archived": archived,
            "auto_archive_duration": auto_archive_duration,
            "locked": locked,
            "invitable": invitable,
            **kwargs,
        }
        channel_data = await self._client.http.modify_channel(self.id, payload, reason)
        if not channel_data:
            raise TooManyChanges(
                "You have changed this channel too frequently, you need to wait a while before trying again."
            ) from None

        return self._client.cache.place_channel_data(channel_data)

    async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
        """
        Delete this channel.

        Args:
            reason: The reason for deleting this channel

        """
        await self._client.http.delete_channel(self.id, reason)

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

classmethod method from_dict_factory(data, client)

Creates a channel object of the appropriate type.

Parameters:

Name Type Description Default
data dict

The channel data.

required
client Client

The bot.

required

Returns:

Type Description
TYPE_ALL_CHANNEL

The new channel object.

Source code in naff/models/discord/channel.py
@classmethod
def from_dict_factory(cls, data: dict, client: "Client") -> "TYPE_ALL_CHANNEL":
    """
    Creates a channel object of the appropriate type.

    Args:
        data: The channel data.
        client: The bot.

    Returns:
        The new channel object.

    """
    channel_type = data.get("type", None)
    channel_class = TYPE_CHANNEL_MAPPING.get(channel_type, None)
    if not channel_class:
        logger.error(f"Unsupported channel type for {data} ({channel_type}).")
        channel_class = BaseChannel

    return channel_class.from_dict(data, client)

property readonly mention: str

Returns a string that would mention the channel.

async method edit(self, name, icon, type, position, topic, nsfw, rate_limit_per_user, bitrate, user_limit, permission_overwrites, parent_id, rtc_region, video_quality_mode, default_auto_archive_duration, archived, auto_archive_duration, locked, invitable, reason, **kwargs)

Edits the channel.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

1-100 character channel name

Missing
icon Union[naff.models.discord.file.File, io.IOBase, BinaryIO, pathlib.Path, str, naff.client.const.Missing]

DM Group icon

Missing
type Union[naff.models.discord.enums.ChannelTypes, naff.client.const.Missing]

The type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature

Missing
position Union[int, naff.client.const.Missing]

The position of the channel in the left-hand listing

Missing
topic Union[str, naff.client.const.Missing]

0-1024 character channel topic

Missing
nsfw Union[bool, naff.client.const.Missing]

Whether the channel is nsfw

Missing
rate_limit_per_user Union[int, naff.client.const.Missing]

Amount of seconds a user has to wait before sending another message (0-21600)

Missing
bitrate Union[int, naff.client.const.Missing]

The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)

Missing
user_limit Union[int, naff.client.const.Missing]

The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

Channel or category-specific permissions

Missing
parent_id Union[int, str, SnowflakeObject, SupportsInt, naff.client.const.Missing]

The id of the new parent category for a channel

Missing
rtc_region Union[models.VoiceRegion, str, naff.client.const.Missing]

Channel voice region id, automatic when set to None.

Missing
video_quality_mode Union[naff.models.discord.enums.VideoQualityModes, naff.client.const.Missing]

The camera video quality mode of the voice channel

Missing
default_auto_archive_duration Union[naff.models.discord.enums.AutoArchiveDuration, naff.client.const.Missing]

The default duration that the clients use (not the API) for newly created threads in the channel, in minutes, to automatically archive the thread after recent activity

Missing
archived Union[bool, naff.client.const.Missing]

Whether the thread is archived

Missing
auto_archive_duration Union[naff.models.discord.enums.AutoArchiveDuration, naff.client.const.Missing]

Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080

Missing
locked Union[bool, naff.client.const.Missing]

Whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it

Missing
invitable Union[bool, naff.client.const.Missing]

Whether non-moderators can add other non-moderators to a thread; only available on private threads

Missing
reason Union[str, naff.client.const.Missing]

The reason for editing the channel

Missing

Returns:

Type Description
TYPE_ALL_CHANNEL

The edited channel. May be a new object if the channel type changes.

Source code in naff/models/discord/channel.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    icon: Absent[UPLOADABLE_TYPE] = MISSING,
    type: Absent[ChannelTypes] = MISSING,
    position: Absent[int] = MISSING,
    topic: Absent[str] = MISSING,
    nsfw: Absent[bool] = MISSING,
    rate_limit_per_user: Absent[int] = MISSING,
    bitrate: Absent[int] = MISSING,
    user_limit: Absent[int] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    parent_id: Absent[Snowflake_Type] = MISSING,
    rtc_region: Absent[Union["models.VoiceRegion", str]] = MISSING,
    video_quality_mode: Absent[VideoQualityModes] = MISSING,
    default_auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
    archived: Absent[bool] = MISSING,
    auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
    locked: Absent[bool] = MISSING,
    invitable: Absent[bool] = MISSING,
    reason: Absent[str] = MISSING,
    **kwargs,
) -> "TYPE_ALL_CHANNEL":
    """
    Edits the channel.

    Args:
        name: 1-100 character channel name
        icon: DM Group icon
        type: The type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature
        position: The position of the channel in the left-hand listing
        topic: 0-1024 character channel topic
        nsfw: Whether the channel is nsfw
        rate_limit_per_user: Amount of seconds a user has to wait before sending another message (0-21600)
        bitrate: The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)
        user_limit: The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit
        permission_overwrites: Channel or category-specific permissions
        parent_id: The id of the new parent category for a channel
        rtc_region: Channel voice region id, automatic when set to None.
        video_quality_mode: The camera video quality mode of the voice channel
        default_auto_archive_duration: The default duration that the clients use (not the API) for newly created threads in the channel, in minutes, to automatically archive the thread after recent activity
        archived: Whether the thread is archived
        auto_archive_duration: Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080
        locked: Whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
        invitable: Whether non-moderators can add other non-moderators to a thread; only available on private threads
        reason: The reason for editing the channel

    Returns:
        The edited channel. May be a new object if the channel type changes.

    """
    payload = {
        "name": name,
        "icon": to_image_data(icon),
        "type": type,
        "position": position,
        "topic": topic,
        "nsfw": nsfw,
        "rate_limit_per_user": rate_limit_per_user,
        "bitrate": bitrate,
        "user_limit": user_limit,
        "permission_overwrites": process_permission_overwrites(permission_overwrites),
        "parent_id": to_optional_snowflake(parent_id),
        "rtc_region": rtc_region.id if isinstance(rtc_region, models.VoiceRegion) else rtc_region,
        "video_quality_mode": video_quality_mode,
        "default_auto_archive_duration": default_auto_archive_duration,
        "archived": archived,
        "auto_archive_duration": auto_archive_duration,
        "locked": locked,
        "invitable": invitable,
        **kwargs,
    }
    channel_data = await self._client.http.modify_channel(self.id, payload, reason)
    if not channel_data:
        raise TooManyChanges(
            "You have changed this channel too frequently, you need to wait a while before trying again."
        ) from None

    return self._client.cache.place_channel_data(channel_data)

async method delete(self, reason)

Delete this channel.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for deleting this channel

Missing
Source code in naff/models/discord/channel.py
async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Delete this channel.

    Args:
        reason: The reason for deleting this channel

    """
    await self._client.http.delete_channel(self.id, reason)

attrs class DMChannel (BaseChannel, MessageableMixin)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

recipients List[models.User]

The users of the DM that will receive messages sent

Source code in naff/models/discord/channel.py
@define(slots=False)
class DMChannel(BaseChannel, MessageableMixin):
    recipients: List["models.User"] = field(factory=list)
    """The users of the DM that will receive messages sent"""

    @classmethod
    def _process_dict(cls, data: Dict[str, Any], client: "Client") -> Dict[str, Any]:
        data = super()._process_dict(data, client)
        if recipients := data.get("recipients", None):
            data["recipients"] = [
                client.cache.place_user_data(recipient) if isinstance(recipient, dict) else recipient
                for recipient in recipients
            ]
        return data

    @property
    def members(self) -> List["models.User"]:
        """Returns a list of users that are in this DM channel."""
        return self.recipients

async inherited method send(self, content, embeds, embed, components, stickers, allowed_mentions, reply_to, files, file, tts, suppress_embeds, flags, delete_after, **kwargs)

Send a message.

Parameters:

Name Type Description Default
content Optional[str]

Message text content.

None
embeds Union[List[Union[Embed, dict]], Embed, dict]

Embedded rich content (up to 6000 characters).

None
embed Union[Embed, dict]

Embedded rich content (up to 6000 characters).

None
components Union[List[List[Union[BaseComponent, dict]]], List[Union[BaseComponent, dict]], BaseComponent, dict]

The components to include with the message.

None
stickers Union[List[Union[Sticker, Snowflake_Type]], Sticker, Snowflake_Type]

IDs of up to 3 stickers in the server to send in the message.

None
allowed_mentions Union[AllowedMentions, dict]

Allowed mentions for the message.

None
reply_to Union[MessageReference, Message, dict, Snowflake_Type]

Message to reference, must be from the same channel.

None
files Union[UPLOADABLE_TYPE, List[UPLOADABLE_TYPE]]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
file Optional[UPLOADABLE_TYPE]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
tts bool

Should this message use Text To Speech.

False
suppress_embeds bool

Should embeds be suppressed on this send

False
flags Union[int, MessageFlags]

Message flags to apply.

None
delete_after Optional[float]

Delete message after this many seconds.

None

Returns:

Type Description
Message

New message object that was sent.

Source code in naff/models/discord/channel.py
async def send(
    self,
    content: Optional[str] = None,
    embeds: Optional[Union[List[Union["Embed", dict]], Union["Embed", dict]]] = None,
    embed: Optional[Union["Embed", dict]] = None,
    components: Optional[
        Union[List[List[Union["BaseComponent", dict]]], List[Union["BaseComponent", dict]], "BaseComponent", dict]
    ] = None,
    stickers: Optional[Union[List[Union["Sticker", "Snowflake_Type"]], "Sticker", "Snowflake_Type"]] = None,
    allowed_mentions: Optional[Union["AllowedMentions", dict]] = None,
    reply_to: Optional[Union["MessageReference", "Message", dict, "Snowflake_Type"]] = None,
    files: Optional[Union["UPLOADABLE_TYPE", List["UPLOADABLE_TYPE"]]] = None,
    file: Optional["UPLOADABLE_TYPE"] = None,
    tts: bool = False,
    suppress_embeds: bool = False,
    flags: Optional[Union[int, "MessageFlags"]] = None,
    delete_after: Optional[float] = None,
    **kwargs,
) -> "Message":
    """
    Send a message.

    Args:
        content: Message text content.
        embeds: Embedded rich content (up to 6000 characters).
        embed: Embedded rich content (up to 6000 characters).
        components: The components to include with the message.
        stickers: IDs of up to 3 stickers in the server to send in the message.
        allowed_mentions: Allowed mentions for the message.
        reply_to: Message to reference, must be from the same channel.
        files: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        file: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        tts: Should this message use Text To Speech.
        suppress_embeds: Should embeds be suppressed on this send
        flags: Message flags to apply.
        delete_after: Delete message after this many seconds.

    Returns:
        New message object that was sent.

    """
    if not content and not (embeds or embed) and not (files or file) and not stickers:
        raise errors.EmptyMessageException(
            "You cannot send a message without any content, embeds, files, or stickers"
        )

    if suppress_embeds:
        if isinstance(flags, int):
            flags = MessageFlags(flags)
        flags = flags | MessageFlags.SUPPRESS_EMBEDS

    message_payload = models.discord.message.process_message_payload(
        content=content,
        embeds=embeds or embed,
        components=components,
        stickers=stickers,
        allowed_mentions=allowed_mentions,
        reply_to=reply_to,
        tts=tts,
        flags=flags,
        **kwargs,
    )

    message_data = await self._send_http_request(message_payload, files=files or file)
    if message_data:
        message = self._client.cache.place_message_data(message_data)
        if delete_after:
            await message.delete(delay=delete_after)
        return message

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

async inherited method fetch_message(self, message_id)

Fetch a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
Optional[models.Message]

The message object fetched. If the message is not found, returns None.

Source code in naff/models/discord/channel.py
async def fetch_message(self, message_id: Snowflake_Type) -> Optional["models.Message"]:
    """
    Fetch a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched. If the message is not found, returns None.

    """
    try:
        return await self._client.cache.fetch_message(self.id, message_id)
    except NotFound:
        return None

inherited method get_message(self, message_id)

Get a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
models.Message

The message object fetched.

Source code in naff/models/discord/channel.py
def get_message(self, message_id: Snowflake_Type) -> "models.Message":
    """
    Get a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched.

    """
    message_id = to_snowflake(message_id)
    message: "models.Message" = self._client.cache.get_message(self.id, message_id)
    return message

inherited method history(self, limit, before, after, around)

Get an async iterator for the history of this channel.

Parameters:

Name Type Description Default
limit

The maximum number of messages to return (set to 0 for no limit)

100
before Union[int, str, SnowflakeObject, SupportsInt]

get messages before this message ID

None
after Union[int, str, SnowflakeObject, SupportsInt]

get messages after this message ID

None
around Union[int, str, SnowflakeObject, SupportsInt]

get messages "around" this message ID

None
Example Usage:

1
2
3
4
5
async for message in channel.history(limit=0):
    if message.author.id == 174918559539920897:
        print("Found author's message")
        # ...
        break
or
1
2
3
history = channel.history(limit=250)
# Flatten the async iterator into a list
messages = await history.flatten()

Returns:

Type Description
ChannelHistory

ChannelHistory (AsyncIterator)

Source code in naff/models/discord/channel.py
def history(
    self,
    limit=100,
    before: Snowflake_Type = None,
    after: Snowflake_Type = None,
    around: Snowflake_Type = None,
) -> ChannelHistory:
    """
    Get an async iterator for the history of this channel.

    Args:
        limit: The maximum number of messages to return (set to 0 for no limit)
        before: get messages before this message ID
        after: get messages after this message ID
        around: get messages "around" this message ID

    ??? Hint "Example Usage:"
        ```python
        async for message in channel.history(limit=0):
            if message.author.id == 174918559539920897:
                print("Found author's message")
                # ...
                break
        ```
        or
        ```python
        history = channel.history(limit=250)
        # Flatten the async iterator into a list
        messages = await history.flatten()
        ```

    Returns:
        ChannelHistory (AsyncIterator)

    """
    return ChannelHistory(self, limit, before, after, around)

async inherited method fetch_messages(self, limit, around, before, after)

Fetch multiple messages from the channel.

Parameters:

Name Type Description Default
limit int

Max number of messages to return, default 50, max 100

50
around Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages around

Missing
before Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages before

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages after

Missing

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_messages(
    self,
    limit: int = 50,
    around: Snowflake_Type = MISSING,
    before: Snowflake_Type = MISSING,
    after: Snowflake_Type = MISSING,
) -> List["models.Message"]:
    """
    Fetch multiple messages from the channel.

    Args:
        limit: Max number of messages to return, default `50`, max `100`
        around: Message to get messages around
        before: Message to get messages before
        after: Message to get messages after

    Returns:
        A list of messages fetched.

    """
    if limit > 100:
        raise ValueError("You cannot fetch more than 100 messages at once.")

    if around:
        around = to_snowflake(around)
    elif before:
        before = to_snowflake(before)
    elif after:
        after = to_snowflake(after)

    messages_data = await self._client.http.get_channel_messages(self.id, limit, around, before, after)
    for m in messages_data:
        m["guild_id"] = self._guild_id

    return [self._client.cache.place_message_data(m) for m in messages_data]

async inherited method fetch_pinned_messages(self)

Fetch pinned messages from the channel.

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_pinned_messages(self) -> List["models.Message"]:
    """
    Fetch pinned messages from the channel.

    Returns:
        A list of messages fetched.

    """
    messages_data = await self._client.http.get_pinned_messages(self.id)
    return [self._client.cache.place_message_data(message_data) for message_data in messages_data]

async inherited method delete_messages(self, messages, reason)

Bulk delete messages from channel.

Parameters:

Name Type Description Default
messages List[Union[int, str, SnowflakeObject, SupportsInt, models.Message]]

List of messages or message IDs to delete.

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this action. Used for audit logs.

Missing
Source code in naff/models/discord/channel.py
async def delete_messages(
    self, messages: List[Union[Snowflake_Type, "models.Message"]], reason: Absent[Optional[str]] = MISSING
) -> None:
    """
    Bulk delete messages from channel.

    Args:
        messages: List of messages or message IDs to delete.
        reason: The reason for this action. Used for audit logs.

    """
    message_ids = [to_snowflake(message) for message in messages]
    # TODO Add check for min/max and duplicates.

    if len(message_ids) == 1:
        # bulk delete messages will throw a http error if only 1 message is passed
        await self.delete_message(message_ids[0], reason)
    else:
        await self._client.http.bulk_delete_messages(self.id, message_ids, reason)

async inherited method delete_message(self, message, reason)

Delete a single message from a channel.

Parameters:

Name Type Description Default
message Union[int, str, SnowflakeObject, SupportsInt, models.Message]

The message to delete

required
reason str

The reason for this action

None
Source code in naff/models/discord/channel.py
async def delete_message(self, message: Union[Snowflake_Type, "models.Message"], reason: str = None) -> None:
    """
    Delete a single message from a channel.

    Args:
        message: The message to delete
        reason: The reason for this action

    """
    message = to_snowflake(message)
    await self._client.http.delete_message(self.id, message, reason=reason)

async inherited method purge(self, deletion_limit, search_limit, predicate, avoid_loading_msg, before, after, around, reason)

Bulk delete messages within a channel. If a predicate is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the deletion_limit.

Example Usage:
1
2
3
# this will delete the last 20 messages sent by a user with the given ID
deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
await channel.send(f"{deleted} messages deleted")

Parameters:

Name Type Description Default
deletion_limit int

The target amount of messages to delete

50
search_limit int

How many messages to search through

100
predicate Callable[[models.Message], bool]

A function that returns True or False, and takes a message as an argument

Missing
avoid_loading_msg bool

Should the bot attempt to avoid deleting its own loading messages (recommended enabled)

True
before Union[int, str, SnowflakeObject, SupportsInt]

Search messages before this ID

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Search messages after this ID

Missing
around Union[int, str, SnowflakeObject, SupportsInt]

Search messages around this ID

Missing
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this deletion

Missing

Returns:

Type Description
int

The total amount of messages deleted

Source code in naff/models/discord/channel.py
async def purge(
    self,
    deletion_limit: int = 50,
    search_limit: int = 100,
    predicate: Callable[["models.Message"], bool] = MISSING,
    avoid_loading_msg: bool = True,
    before: Optional[Snowflake_Type] = MISSING,
    after: Optional[Snowflake_Type] = MISSING,
    around: Optional[Snowflake_Type] = MISSING,
    reason: Absent[Optional[str]] = MISSING,
) -> int:
    """
    Bulk delete messages within a channel. If a `predicate` is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the `deletion_limit`.

    ??? Hint "Example Usage:"
        ```python
        # this will delete the last 20 messages sent by a user with the given ID
        deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
        await channel.send(f"{deleted} messages deleted")
        ```

    Args:
        deletion_limit: The target amount of messages to delete
        search_limit: How many messages to search through
        predicate: A function that returns True or False, and takes a message as an argument
        avoid_loading_msg: Should the bot attempt to avoid deleting its own loading messages (recommended enabled)
        before: Search messages before this ID
        after: Search messages after this ID
        around: Search messages around this ID
        reason: The reason for this deletion

    Returns:
        The total amount of messages deleted

    """
    if not predicate:

        def predicate(m) -> bool:
            return True  # noqa

    to_delete = []

    # 1209600 14 days ago in seconds, 1420070400000 is used to convert to snowflake
    fourteen_days_ago = int((time.time() - 1209600) * 1000.0 - DISCORD_EPOCH) << 22
    async for message in self.history(limit=search_limit, before=before, after=after, around=around):
        if deletion_limit != 0 and len(to_delete) == deletion_limit:
            break

        if not predicate(message):
            # fails predicate
            continue

        if avoid_loading_msg:
            if message._author_id == self._client.user.id and MessageFlags.LOADING in message.flags:
                continue

        if message.id < fourteen_days_ago:
            # message is too old to be purged
            continue

        to_delete.append(message.id)

    count = len(to_delete)
    while len(to_delete):
        iteration = [to_delete.pop() for i in range(min(100, len(to_delete)))]
        await self.delete_messages(iteration, reason=reason)
    return count

async inherited method trigger_typing(self)

Trigger a typing animation in this channel.

Source code in naff/models/discord/channel.py
async def trigger_typing(self) -> None:
    """Trigger a typing animation in this channel."""
    await self._client.http.trigger_typing_indicator(self.id)

inherited property readonly typing: Typing

A context manager to send a typing state to a given channel as long as long as the wrapped operation takes.

inherited property readonly mention: str

Returns a string that would mention the channel.

async inherited method edit(self, name, icon, type, position, topic, nsfw, rate_limit_per_user, bitrate, user_limit, permission_overwrites, parent_id, rtc_region, video_quality_mode, default_auto_archive_duration, archived, auto_archive_duration, locked, invitable, reason, **kwargs)

Edits the channel.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

1-100 character channel name

Missing
icon Union[naff.models.discord.file.File, io.IOBase, BinaryIO, pathlib.Path, str, naff.client.const.Missing]

DM Group icon

Missing
type Union[naff.models.discord.enums.ChannelTypes, naff.client.const.Missing]

The type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature

Missing
position Union[int, naff.client.const.Missing]

The position of the channel in the left-hand listing

Missing
topic Union[str, naff.client.const.Missing]

0-1024 character channel topic

Missing
nsfw Union[bool, naff.client.const.Missing]

Whether the channel is nsfw

Missing
rate_limit_per_user Union[int, naff.client.const.Missing]

Amount of seconds a user has to wait before sending another message (0-21600)

Missing
bitrate Union[int, naff.client.const.Missing]

The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)

Missing
user_limit Union[int, naff.client.const.Missing]

The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

Channel or category-specific permissions

Missing
parent_id Union[int, str, SnowflakeObject, SupportsInt, naff.client.const.Missing]

The id of the new parent category for a channel

Missing
rtc_region Union[models.VoiceRegion, str, naff.client.const.Missing]

Channel voice region id, automatic when set to None.

Missing
video_quality_mode Union[naff.models.discord.enums.VideoQualityModes, naff.client.const.Missing]

The camera video quality mode of the voice channel

Missing
default_auto_archive_duration Union[naff.models.discord.enums.AutoArchiveDuration, naff.client.const.Missing]

The default duration that the clients use (not the API) for newly created threads in the channel, in minutes, to automatically archive the thread after recent activity

Missing
archived Union[bool, naff.client.const.Missing]

Whether the thread is archived

Missing
auto_archive_duration Union[naff.models.discord.enums.AutoArchiveDuration, naff.client.const.Missing]

Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080

Missing
locked Union[bool, naff.client.const.Missing]

Whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it

Missing
invitable Union[bool, naff.client.const.Missing]

Whether non-moderators can add other non-moderators to a thread; only available on private threads

Missing
reason Union[str, naff.client.const.Missing]

The reason for editing the channel

Missing

Returns:

Type Description
TYPE_ALL_CHANNEL

The edited channel. May be a new object if the channel type changes.

Source code in naff/models/discord/channel.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    icon: Absent[UPLOADABLE_TYPE] = MISSING,
    type: Absent[ChannelTypes] = MISSING,
    position: Absent[int] = MISSING,
    topic: Absent[str] = MISSING,
    nsfw: Absent[bool] = MISSING,
    rate_limit_per_user: Absent[int] = MISSING,
    bitrate: Absent[int] = MISSING,
    user_limit: Absent[int] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    parent_id: Absent[Snowflake_Type] = MISSING,
    rtc_region: Absent[Union["models.VoiceRegion", str]] = MISSING,
    video_quality_mode: Absent[VideoQualityModes] = MISSING,
    default_auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
    archived: Absent[bool] = MISSING,
    auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
    locked: Absent[bool] = MISSING,
    invitable: Absent[bool] = MISSING,
    reason: Absent[str] = MISSING,
    **kwargs,
) -> "TYPE_ALL_CHANNEL":
    """
    Edits the channel.

    Args:
        name: 1-100 character channel name
        icon: DM Group icon
        type: The type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature
        position: The position of the channel in the left-hand listing
        topic: 0-1024 character channel topic
        nsfw: Whether the channel is nsfw
        rate_limit_per_user: Amount of seconds a user has to wait before sending another message (0-21600)
        bitrate: The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)
        user_limit: The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit
        permission_overwrites: Channel or category-specific permissions
        parent_id: The id of the new parent category for a channel
        rtc_region: Channel voice region id, automatic when set to None.
        video_quality_mode: The camera video quality mode of the voice channel
        default_auto_archive_duration: The default duration that the clients use (not the API) for newly created threads in the channel, in minutes, to automatically archive the thread after recent activity
        archived: Whether the thread is archived
        auto_archive_duration: Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080
        locked: Whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
        invitable: Whether non-moderators can add other non-moderators to a thread; only available on private threads
        reason: The reason for editing the channel

    Returns:
        The edited channel. May be a new object if the channel type changes.

    """
    payload = {
        "name": name,
        "icon": to_image_data(icon),
        "type": type,
        "position": position,
        "topic": topic,
        "nsfw": nsfw,
        "rate_limit_per_user": rate_limit_per_user,
        "bitrate": bitrate,
        "user_limit": user_limit,
        "permission_overwrites": process_permission_overwrites(permission_overwrites),
        "parent_id": to_optional_snowflake(parent_id),
        "rtc_region": rtc_region.id if isinstance(rtc_region, models.VoiceRegion) else rtc_region,
        "video_quality_mode": video_quality_mode,
        "default_auto_archive_duration": default_auto_archive_duration,
        "archived": archived,
        "auto_archive_duration": auto_archive_duration,
        "locked": locked,
        "invitable": invitable,
        **kwargs,
    }
    channel_data = await self._client.http.modify_channel(self.id, payload, reason)
    if not channel_data:
        raise TooManyChanges(
            "You have changed this channel too frequently, you need to wait a while before trying again."
        ) from None

    return self._client.cache.place_channel_data(channel_data)

async inherited method delete(self, reason)

Delete this channel.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for deleting this channel

Missing
Source code in naff/models/discord/channel.py
async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Delete this channel.

    Args:
        reason: The reason for deleting this channel

    """
    await self._client.http.delete_channel(self.id, reason)

property readonly members: List[models.User]

Returns a list of users that are in this DM channel.

attrs class DM (DMChannel)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

Source code in naff/models/discord/channel.py
@define()
class DM(DMChannel):
    @property
    def recipient(self) -> "models.User":
        """Returns the user that is in this DM channel."""
        return self.recipients[0]

async inherited method send(self, content, embeds, embed, components, stickers, allowed_mentions, reply_to, files, file, tts, suppress_embeds, flags, delete_after, **kwargs)

Send a message.

Parameters:

Name Type Description Default
content Optional[str]

Message text content.

None
embeds Union[List[Union[Embed, dict]], Embed, dict]

Embedded rich content (up to 6000 characters).

None
embed Union[Embed, dict]

Embedded rich content (up to 6000 characters).

None
components Union[List[List[Union[BaseComponent, dict]]], List[Union[BaseComponent, dict]], BaseComponent, dict]

The components to include with the message.

None
stickers Union[List[Union[Sticker, Snowflake_Type]], Sticker, Snowflake_Type]

IDs of up to 3 stickers in the server to send in the message.

None
allowed_mentions Union[AllowedMentions, dict]

Allowed mentions for the message.

None
reply_to Union[MessageReference, Message, dict, Snowflake_Type]

Message to reference, must be from the same channel.

None
files Union[UPLOADABLE_TYPE, List[UPLOADABLE_TYPE]]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
file Optional[UPLOADABLE_TYPE]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
tts bool

Should this message use Text To Speech.

False
suppress_embeds bool

Should embeds be suppressed on this send

False
flags Union[int, MessageFlags]

Message flags to apply.

None
delete_after Optional[float]

Delete message after this many seconds.

None

Returns:

Type Description
Message

New message object that was sent.

Source code in naff/models/discord/channel.py
async def send(
    self,
    content: Optional[str] = None,
    embeds: Optional[Union[List[Union["Embed", dict]], Union["Embed", dict]]] = None,
    embed: Optional[Union["Embed", dict]] = None,
    components: Optional[
        Union[List[List[Union["BaseComponent", dict]]], List[Union["BaseComponent", dict]], "BaseComponent", dict]
    ] = None,
    stickers: Optional[Union[List[Union["Sticker", "Snowflake_Type"]], "Sticker", "Snowflake_Type"]] = None,
    allowed_mentions: Optional[Union["AllowedMentions", dict]] = None,
    reply_to: Optional[Union["MessageReference", "Message", dict, "Snowflake_Type"]] = None,
    files: Optional[Union["UPLOADABLE_TYPE", List["UPLOADABLE_TYPE"]]] = None,
    file: Optional["UPLOADABLE_TYPE"] = None,
    tts: bool = False,
    suppress_embeds: bool = False,
    flags: Optional[Union[int, "MessageFlags"]] = None,
    delete_after: Optional[float] = None,
    **kwargs,
) -> "Message":
    """
    Send a message.

    Args:
        content: Message text content.
        embeds: Embedded rich content (up to 6000 characters).
        embed: Embedded rich content (up to 6000 characters).
        components: The components to include with the message.
        stickers: IDs of up to 3 stickers in the server to send in the message.
        allowed_mentions: Allowed mentions for the message.
        reply_to: Message to reference, must be from the same channel.
        files: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        file: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        tts: Should this message use Text To Speech.
        suppress_embeds: Should embeds be suppressed on this send
        flags: Message flags to apply.
        delete_after: Delete message after this many seconds.

    Returns:
        New message object that was sent.

    """
    if not content and not (embeds or embed) and not (files or file) and not stickers:
        raise errors.EmptyMessageException(
            "You cannot send a message without any content, embeds, files, or stickers"
        )

    if suppress_embeds:
        if isinstance(flags, int):
            flags = MessageFlags(flags)
        flags = flags | MessageFlags.SUPPRESS_EMBEDS

    message_payload = models.discord.message.process_message_payload(
        content=content,
        embeds=embeds or embed,
        components=components,
        stickers=stickers,
        allowed_mentions=allowed_mentions,
        reply_to=reply_to,
        tts=tts,
        flags=flags,
        **kwargs,
    )

    message_data = await self._send_http_request(message_payload, files=files or file)
    if message_data:
        message = self._client.cache.place_message_data(message_data)
        if delete_after:
            await message.delete(delay=delete_after)
        return message

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

async inherited method fetch_message(self, message_id)

Fetch a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
Optional[models.Message]

The message object fetched. If the message is not found, returns None.

Source code in naff/models/discord/channel.py
async def fetch_message(self, message_id: Snowflake_Type) -> Optional["models.Message"]:
    """
    Fetch a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched. If the message is not found, returns None.

    """
    try:
        return await self._client.cache.fetch_message(self.id, message_id)
    except NotFound:
        return None

inherited method get_message(self, message_id)

Get a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
models.Message

The message object fetched.

Source code in naff/models/discord/channel.py
def get_message(self, message_id: Snowflake_Type) -> "models.Message":
    """
    Get a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched.

    """
    message_id = to_snowflake(message_id)
    message: "models.Message" = self._client.cache.get_message(self.id, message_id)
    return message

inherited method history(self, limit, before, after, around)

Get an async iterator for the history of this channel.

Parameters:

Name Type Description Default
limit

The maximum number of messages to return (set to 0 for no limit)

100
before Union[int, str, SnowflakeObject, SupportsInt]

get messages before this message ID

None
after Union[int, str, SnowflakeObject, SupportsInt]

get messages after this message ID

None
around Union[int, str, SnowflakeObject, SupportsInt]

get messages "around" this message ID

None
Example Usage:

1
2
3
4
5
async for message in channel.history(limit=0):
    if message.author.id == 174918559539920897:
        print("Found author's message")
        # ...
        break
or
1
2
3
history = channel.history(limit=250)
# Flatten the async iterator into a list
messages = await history.flatten()

Returns:

Type Description
ChannelHistory

ChannelHistory (AsyncIterator)

Source code in naff/models/discord/channel.py
def history(
    self,
    limit=100,
    before: Snowflake_Type = None,
    after: Snowflake_Type = None,
    around: Snowflake_Type = None,
) -> ChannelHistory:
    """
    Get an async iterator for the history of this channel.

    Args:
        limit: The maximum number of messages to return (set to 0 for no limit)
        before: get messages before this message ID
        after: get messages after this message ID
        around: get messages "around" this message ID

    ??? Hint "Example Usage:"
        ```python
        async for message in channel.history(limit=0):
            if message.author.id == 174918559539920897:
                print("Found author's message")
                # ...
                break
        ```
        or
        ```python
        history = channel.history(limit=250)
        # Flatten the async iterator into a list
        messages = await history.flatten()
        ```

    Returns:
        ChannelHistory (AsyncIterator)

    """
    return ChannelHistory(self, limit, before, after, around)

async inherited method fetch_messages(self, limit, around, before, after)

Fetch multiple messages from the channel.

Parameters:

Name Type Description Default
limit int

Max number of messages to return, default 50, max 100

50
around Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages around

Missing
before Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages before

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages after

Missing

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_messages(
    self,
    limit: int = 50,
    around: Snowflake_Type = MISSING,
    before: Snowflake_Type = MISSING,
    after: Snowflake_Type = MISSING,
) -> List["models.Message"]:
    """
    Fetch multiple messages from the channel.

    Args:
        limit: Max number of messages to return, default `50`, max `100`
        around: Message to get messages around
        before: Message to get messages before
        after: Message to get messages after

    Returns:
        A list of messages fetched.

    """
    if limit > 100:
        raise ValueError("You cannot fetch more than 100 messages at once.")

    if around:
        around = to_snowflake(around)
    elif before:
        before = to_snowflake(before)
    elif after:
        after = to_snowflake(after)

    messages_data = await self._client.http.get_channel_messages(self.id, limit, around, before, after)
    for m in messages_data:
        m["guild_id"] = self._guild_id

    return [self._client.cache.place_message_data(m) for m in messages_data]

async inherited method fetch_pinned_messages(self)

Fetch pinned messages from the channel.

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_pinned_messages(self) -> List["models.Message"]:
    """
    Fetch pinned messages from the channel.

    Returns:
        A list of messages fetched.

    """
    messages_data = await self._client.http.get_pinned_messages(self.id)
    return [self._client.cache.place_message_data(message_data) for message_data in messages_data]

async inherited method delete_messages(self, messages, reason)

Bulk delete messages from channel.

Parameters:

Name Type Description Default
messages List[Union[int, str, SnowflakeObject, SupportsInt, models.Message]]

List of messages or message IDs to delete.

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this action. Used for audit logs.

Missing
Source code in naff/models/discord/channel.py
async def delete_messages(
    self, messages: List[Union[Snowflake_Type, "models.Message"]], reason: Absent[Optional[str]] = MISSING
) -> None:
    """
    Bulk delete messages from channel.

    Args:
        messages: List of messages or message IDs to delete.
        reason: The reason for this action. Used for audit logs.

    """
    message_ids = [to_snowflake(message) for message in messages]
    # TODO Add check for min/max and duplicates.

    if len(message_ids) == 1:
        # bulk delete messages will throw a http error if only 1 message is passed
        await self.delete_message(message_ids[0], reason)
    else:
        await self._client.http.bulk_delete_messages(self.id, message_ids, reason)

async inherited method delete_message(self, message, reason)

Delete a single message from a channel.

Parameters:

Name Type Description Default
message Union[int, str, SnowflakeObject, SupportsInt, models.Message]

The message to delete

required
reason str

The reason for this action

None
Source code in naff/models/discord/channel.py
async def delete_message(self, message: Union[Snowflake_Type, "models.Message"], reason: str = None) -> None:
    """
    Delete a single message from a channel.

    Args:
        message: The message to delete
        reason: The reason for this action

    """
    message = to_snowflake(message)
    await self._client.http.delete_message(self.id, message, reason=reason)

async inherited method purge(self, deletion_limit, search_limit, predicate, avoid_loading_msg, before, after, around, reason)

Bulk delete messages within a channel. If a predicate is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the deletion_limit.

Example Usage:
1
2
3
# this will delete the last 20 messages sent by a user with the given ID
deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
await channel.send(f"{deleted} messages deleted")

Parameters:

Name Type Description Default
deletion_limit int

The target amount of messages to delete

50
search_limit int

How many messages to search through

100
predicate Callable[[models.Message], bool]

A function that returns True or False, and takes a message as an argument

Missing
avoid_loading_msg bool

Should the bot attempt to avoid deleting its own loading messages (recommended enabled)

True
before Union[int, str, SnowflakeObject, SupportsInt]

Search messages before this ID

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Search messages after this ID

Missing
around Union[int, str, SnowflakeObject, SupportsInt]

Search messages around this ID

Missing
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this deletion

Missing

Returns:

Type Description
int

The total amount of messages deleted

Source code in naff/models/discord/channel.py
async def purge(
    self,
    deletion_limit: int = 50,
    search_limit: int = 100,
    predicate: Callable[["models.Message"], bool] = MISSING,
    avoid_loading_msg: bool = True,
    before: Optional[Snowflake_Type] = MISSING,
    after: Optional[Snowflake_Type] = MISSING,
    around: Optional[Snowflake_Type] = MISSING,
    reason: Absent[Optional[str]] = MISSING,
) -> int:
    """
    Bulk delete messages within a channel. If a `predicate` is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the `deletion_limit`.

    ??? Hint "Example Usage:"
        ```python
        # this will delete the last 20 messages sent by a user with the given ID
        deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
        await channel.send(f"{deleted} messages deleted")
        ```

    Args:
        deletion_limit: The target amount of messages to delete
        search_limit: How many messages to search through
        predicate: A function that returns True or False, and takes a message as an argument
        avoid_loading_msg: Should the bot attempt to avoid deleting its own loading messages (recommended enabled)
        before: Search messages before this ID
        after: Search messages after this ID
        around: Search messages around this ID
        reason: The reason for this deletion

    Returns:
        The total amount of messages deleted

    """
    if not predicate:

        def predicate(m) -> bool:
            return True  # noqa

    to_delete = []

    # 1209600 14 days ago in seconds, 1420070400000 is used to convert to snowflake
    fourteen_days_ago = int((time.time() - 1209600) * 1000.0 - DISCORD_EPOCH) << 22
    async for message in self.history(limit=search_limit, before=before, after=after, around=around):
        if deletion_limit != 0 and len(to_delete) == deletion_limit:
            break

        if not predicate(message):
            # fails predicate
            continue

        if avoid_loading_msg:
            if message._author_id == self._client.user.id and MessageFlags.LOADING in message.flags:
                continue

        if message.id < fourteen_days_ago:
            # message is too old to be purged
            continue

        to_delete.append(message.id)

    count = len(to_delete)
    while len(to_delete):
        iteration = [to_delete.pop() for i in range(min(100, len(to_delete)))]
        await self.delete_messages(iteration, reason=reason)
    return count

async inherited method trigger_typing(self)

Trigger a typing animation in this channel.

Source code in naff/models/discord/channel.py
async def trigger_typing(self) -> None:
    """Trigger a typing animation in this channel."""
    await self._client.http.trigger_typing_indicator(self.id)

inherited property readonly typing: Typing

A context manager to send a typing state to a given channel as long as long as the wrapped operation takes.

inherited property readonly mention: str

Returns a string that would mention the channel.

async inherited method edit(self, name, icon, type, position, topic, nsfw, rate_limit_per_user, bitrate, user_limit, permission_overwrites, parent_id, rtc_region, video_quality_mode, default_auto_archive_duration, archived, auto_archive_duration, locked, invitable, reason, **kwargs)

Edits the channel.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

1-100 character channel name

Missing
icon Union[naff.models.discord.file.File, io.IOBase, BinaryIO, pathlib.Path, str, naff.client.const.Missing]

DM Group icon

Missing
type Union[naff.models.discord.enums.ChannelTypes, naff.client.const.Missing]

The type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature

Missing
position Union[int, naff.client.const.Missing]

The position of the channel in the left-hand listing

Missing
topic Union[str, naff.client.const.Missing]

0-1024 character channel topic

Missing
nsfw Union[bool, naff.client.const.Missing]

Whether the channel is nsfw

Missing
rate_limit_per_user Union[int, naff.client.const.Missing]

Amount of seconds a user has to wait before sending another message (0-21600)

Missing
bitrate Union[int, naff.client.const.Missing]

The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)

Missing
user_limit Union[int, naff.client.const.Missing]

The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

Channel or category-specific permissions

Missing
parent_id Union[int, str, SnowflakeObject, SupportsInt, naff.client.const.Missing]

The id of the new parent category for a channel

Missing
rtc_region Union[models.VoiceRegion, str, naff.client.const.Missing]

Channel voice region id, automatic when set to None.

Missing
video_quality_mode Union[naff.models.discord.enums.VideoQualityModes, naff.client.const.Missing]

The camera video quality mode of the voice channel

Missing
default_auto_archive_duration Union[naff.models.discord.enums.AutoArchiveDuration, naff.client.const.Missing]

The default duration that the clients use (not the API) for newly created threads in the channel, in minutes, to automatically archive the thread after recent activity

Missing
archived Union[bool, naff.client.const.Missing]

Whether the thread is archived

Missing
auto_archive_duration Union[naff.models.discord.enums.AutoArchiveDuration, naff.client.const.Missing]

Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080

Missing
locked Union[bool, naff.client.const.Missing]

Whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it

Missing
invitable Union[bool, naff.client.const.Missing]

Whether non-moderators can add other non-moderators to a thread; only available on private threads

Missing
reason Union[str, naff.client.const.Missing]

The reason for editing the channel

Missing

Returns:

Type Description
TYPE_ALL_CHANNEL

The edited channel. May be a new object if the channel type changes.

Source code in naff/models/discord/channel.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    icon: Absent[UPLOADABLE_TYPE] = MISSING,
    type: Absent[ChannelTypes] = MISSING,
    position: Absent[int] = MISSING,
    topic: Absent[str] = MISSING,
    nsfw: Absent[bool] = MISSING,
    rate_limit_per_user: Absent[int] = MISSING,
    bitrate: Absent[int] = MISSING,
    user_limit: Absent[int] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    parent_id: Absent[Snowflake_Type] = MISSING,
    rtc_region: Absent[Union["models.VoiceRegion", str]] = MISSING,
    video_quality_mode: Absent[VideoQualityModes] = MISSING,
    default_auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
    archived: Absent[bool] = MISSING,
    auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
    locked: Absent[bool] = MISSING,
    invitable: Absent[bool] = MISSING,
    reason: Absent[str] = MISSING,
    **kwargs,
) -> "TYPE_ALL_CHANNEL":
    """
    Edits the channel.

    Args:
        name: 1-100 character channel name
        icon: DM Group icon
        type: The type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature
        position: The position of the channel in the left-hand listing
        topic: 0-1024 character channel topic
        nsfw: Whether the channel is nsfw
        rate_limit_per_user: Amount of seconds a user has to wait before sending another message (0-21600)
        bitrate: The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)
        user_limit: The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit
        permission_overwrites: Channel or category-specific permissions
        parent_id: The id of the new parent category for a channel
        rtc_region: Channel voice region id, automatic when set to None.
        video_quality_mode: The camera video quality mode of the voice channel
        default_auto_archive_duration: The default duration that the clients use (not the API) for newly created threads in the channel, in minutes, to automatically archive the thread after recent activity
        archived: Whether the thread is archived
        auto_archive_duration: Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080
        locked: Whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
        invitable: Whether non-moderators can add other non-moderators to a thread; only available on private threads
        reason: The reason for editing the channel

    Returns:
        The edited channel. May be a new object if the channel type changes.

    """
    payload = {
        "name": name,
        "icon": to_image_data(icon),
        "type": type,
        "position": position,
        "topic": topic,
        "nsfw": nsfw,
        "rate_limit_per_user": rate_limit_per_user,
        "bitrate": bitrate,
        "user_limit": user_limit,
        "permission_overwrites": process_permission_overwrites(permission_overwrites),
        "parent_id": to_optional_snowflake(parent_id),
        "rtc_region": rtc_region.id if isinstance(rtc_region, models.VoiceRegion) else rtc_region,
        "video_quality_mode": video_quality_mode,
        "default_auto_archive_duration": default_auto_archive_duration,
        "archived": archived,
        "auto_archive_duration": auto_archive_duration,
        "locked": locked,
        "invitable": invitable,
        **kwargs,
    }
    channel_data = await self._client.http.modify_channel(self.id, payload, reason)
    if not channel_data:
        raise TooManyChanges(
            "You have changed this channel too frequently, you need to wait a while before trying again."
        ) from None

    return self._client.cache.place_channel_data(channel_data)

async inherited method delete(self, reason)

Delete this channel.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for deleting this channel

Missing
Source code in naff/models/discord/channel.py
async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Delete this channel.

    Args:
        reason: The reason for deleting this channel

    """
    await self._client.http.delete_channel(self.id, reason)

inherited property readonly members: List[models.User]

Returns a list of users that are in this DM channel.

property readonly recipient: models.User

Returns the user that is in this DM channel.

attrs class DMGroup (DMChannel)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

owner_id Union[int, str, SnowflakeObject, SupportsInt]

id of the creator of the group DM

application_id Union[int, str, SnowflakeObject, SupportsInt]

Application id of the group DM creator if it is bot-created

Source code in naff/models/discord/channel.py
@define()
class DMGroup(DMChannel):
    owner_id: Snowflake_Type = field(repr=True)
    """id of the creator of the group DM"""
    application_id: Optional[Snowflake_Type] = field(default=None)
    """Application id of the group DM creator if it is bot-created"""

    async def edit(
        self,
        name: Absent[str] = MISSING,
        icon: Absent[UPLOADABLE_TYPE] = MISSING,
        reason: Absent[str] = MISSING,
        **kwargs,
    ) -> "DMGroup":
        """
        Edit this DM Channel.

        Args:
            name: 1-100 character channel name
            icon: An icon to use
            reason: The reason for this change
        """
        return await super().edit(name=name, icon=icon, reason=reason, **kwargs)

    async def fetch_owner(self) -> "models.User":
        """Fetch the owner of this DM group"""
        return await self._client.cache.fetch_user(self.owner_id)

    def get_owner(self) -> "models.User":
        """Get the owner of this DM group"""
        return self._client.cache.get_user(self.owner_id)

    async def add_recipient(
        self, user: Union["models.User", Snowflake_Type], access_token: str, nickname: Absent[Optional[str]] = MISSING
    ) -> None:
        """
        Add a recipient to this DM Group.

        Args:
            user: The user to add
            access_token: access token of a user that has granted your app the gdm.join scope
            nickname: nickname to apply to the user being added

        """
        user = await self._client.cache.fetch_user(user)
        await self._client.http.group_dm_add_recipient(self.id, user.id, access_token, nickname)
        self.recipients.append(user)

    async def remove_recipient(self, user: Union["models.User", Snowflake_Type]) -> None:
        """
        Remove a recipient from this DM Group.

        Args:
            user: The user to remove

        """
        user = await self._client.cache.fetch_user(user)
        await self._client.http.group_dm_remove_recipient(self.id, user.id)
        self.recipients.remove(user)

async inherited method send(self, content, embeds, embed, components, stickers, allowed_mentions, reply_to, files, file, tts, suppress_embeds, flags, delete_after, **kwargs)

Send a message.

Parameters:

Name Type Description Default
content Optional[str]

Message text content.

None
embeds Union[List[Union[Embed, dict]], Embed, dict]

Embedded rich content (up to 6000 characters).

None
embed Union[Embed, dict]

Embedded rich content (up to 6000 characters).

None
components Union[List[List[Union[BaseComponent, dict]]], List[Union[BaseComponent, dict]], BaseComponent, dict]

The components to include with the message.

None
stickers Union[List[Union[Sticker, Snowflake_Type]], Sticker, Snowflake_Type]

IDs of up to 3 stickers in the server to send in the message.

None
allowed_mentions Union[AllowedMentions, dict]

Allowed mentions for the message.

None
reply_to Union[MessageReference, Message, dict, Snowflake_Type]

Message to reference, must be from the same channel.

None
files Union[UPLOADABLE_TYPE, List[UPLOADABLE_TYPE]]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
file Optional[UPLOADABLE_TYPE]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
tts bool

Should this message use Text To Speech.

False
suppress_embeds bool

Should embeds be suppressed on this send

False
flags Union[int, MessageFlags]

Message flags to apply.

None
delete_after Optional[float]

Delete message after this many seconds.

None

Returns:

Type Description
Message

New message object that was sent.

Source code in naff/models/discord/channel.py
async def send(
    self,
    content: Optional[str] = None,
    embeds: Optional[Union[List[Union["Embed", dict]], Union["Embed", dict]]] = None,
    embed: Optional[Union["Embed", dict]] = None,
    components: Optional[
        Union[List[List[Union["BaseComponent", dict]]], List[Union["BaseComponent", dict]], "BaseComponent", dict]
    ] = None,
    stickers: Optional[Union[List[Union["Sticker", "Snowflake_Type"]], "Sticker", "Snowflake_Type"]] = None,
    allowed_mentions: Optional[Union["AllowedMentions", dict]] = None,
    reply_to: Optional[Union["MessageReference", "Message", dict, "Snowflake_Type"]] = None,
    files: Optional[Union["UPLOADABLE_TYPE", List["UPLOADABLE_TYPE"]]] = None,
    file: Optional["UPLOADABLE_TYPE"] = None,
    tts: bool = False,
    suppress_embeds: bool = False,
    flags: Optional[Union[int, "MessageFlags"]] = None,
    delete_after: Optional[float] = None,
    **kwargs,
) -> "Message":
    """
    Send a message.

    Args:
        content: Message text content.
        embeds: Embedded rich content (up to 6000 characters).
        embed: Embedded rich content (up to 6000 characters).
        components: The components to include with the message.
        stickers: IDs of up to 3 stickers in the server to send in the message.
        allowed_mentions: Allowed mentions for the message.
        reply_to: Message to reference, must be from the same channel.
        files: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        file: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        tts: Should this message use Text To Speech.
        suppress_embeds: Should embeds be suppressed on this send
        flags: Message flags to apply.
        delete_after: Delete message after this many seconds.

    Returns:
        New message object that was sent.

    """
    if not content and not (embeds or embed) and not (files or file) and not stickers:
        raise errors.EmptyMessageException(
            "You cannot send a message without any content, embeds, files, or stickers"
        )

    if suppress_embeds:
        if isinstance(flags, int):
            flags = MessageFlags(flags)
        flags = flags | MessageFlags.SUPPRESS_EMBEDS

    message_payload = models.discord.message.process_message_payload(
        content=content,
        embeds=embeds or embed,
        components=components,
        stickers=stickers,
        allowed_mentions=allowed_mentions,
        reply_to=reply_to,
        tts=tts,
        flags=flags,
        **kwargs,
    )

    message_data = await self._send_http_request(message_payload, files=files or file)
    if message_data:
        message = self._client.cache.place_message_data(message_data)
        if delete_after:
            await message.delete(delay=delete_after)
        return message

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

async inherited method fetch_message(self, message_id)

Fetch a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
Optional[models.Message]

The message object fetched. If the message is not found, returns None.

Source code in naff/models/discord/channel.py
async def fetch_message(self, message_id: Snowflake_Type) -> Optional["models.Message"]:
    """
    Fetch a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched. If the message is not found, returns None.

    """
    try:
        return await self._client.cache.fetch_message(self.id, message_id)
    except NotFound:
        return None

inherited method get_message(self, message_id)

Get a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
models.Message

The message object fetched.

Source code in naff/models/discord/channel.py
def get_message(self, message_id: Snowflake_Type) -> "models.Message":
    """
    Get a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched.

    """
    message_id = to_snowflake(message_id)
    message: "models.Message" = self._client.cache.get_message(self.id, message_id)
    return message

inherited method history(self, limit, before, after, around)

Get an async iterator for the history of this channel.

Parameters:

Name Type Description Default
limit

The maximum number of messages to return (set to 0 for no limit)

100
before Union[int, str, SnowflakeObject, SupportsInt]

get messages before this message ID

None
after Union[int, str, SnowflakeObject, SupportsInt]

get messages after this message ID

None
around Union[int, str, SnowflakeObject, SupportsInt]

get messages "around" this message ID

None
Example Usage:

1
2
3
4
5
async for message in channel.history(limit=0):
    if message.author.id == 174918559539920897:
        print("Found author's message")
        # ...
        break
or
1
2
3
history = channel.history(limit=250)
# Flatten the async iterator into a list
messages = await history.flatten()

Returns:

Type Description
ChannelHistory

ChannelHistory (AsyncIterator)

Source code in naff/models/discord/channel.py
def history(
    self,
    limit=100,
    before: Snowflake_Type = None,
    after: Snowflake_Type = None,
    around: Snowflake_Type = None,
) -> ChannelHistory:
    """
    Get an async iterator for the history of this channel.

    Args:
        limit: The maximum number of messages to return (set to 0 for no limit)
        before: get messages before this message ID
        after: get messages after this message ID
        around: get messages "around" this message ID

    ??? Hint "Example Usage:"
        ```python
        async for message in channel.history(limit=0):
            if message.author.id == 174918559539920897:
                print("Found author's message")
                # ...
                break
        ```
        or
        ```python
        history = channel.history(limit=250)
        # Flatten the async iterator into a list
        messages = await history.flatten()
        ```

    Returns:
        ChannelHistory (AsyncIterator)

    """
    return ChannelHistory(self, limit, before, after, around)

async inherited method fetch_messages(self, limit, around, before, after)

Fetch multiple messages from the channel.

Parameters:

Name Type Description Default
limit int

Max number of messages to return, default 50, max 100

50
around Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages around

Missing
before Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages before

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages after

Missing

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_messages(
    self,
    limit: int = 50,
    around: Snowflake_Type = MISSING,
    before: Snowflake_Type = MISSING,
    after: Snowflake_Type = MISSING,
) -> List["models.Message"]:
    """
    Fetch multiple messages from the channel.

    Args:
        limit: Max number of messages to return, default `50`, max `100`
        around: Message to get messages around
        before: Message to get messages before
        after: Message to get messages after

    Returns:
        A list of messages fetched.

    """
    if limit > 100:
        raise ValueError("You cannot fetch more than 100 messages at once.")

    if around:
        around = to_snowflake(around)
    elif before:
        before = to_snowflake(before)
    elif after:
        after = to_snowflake(after)

    messages_data = await self._client.http.get_channel_messages(self.id, limit, around, before, after)
    for m in messages_data:
        m["guild_id"] = self._guild_id

    return [self._client.cache.place_message_data(m) for m in messages_data]

async inherited method fetch_pinned_messages(self)

Fetch pinned messages from the channel.

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_pinned_messages(self) -> List["models.Message"]:
    """
    Fetch pinned messages from the channel.

    Returns:
        A list of messages fetched.

    """
    messages_data = await self._client.http.get_pinned_messages(self.id)
    return [self._client.cache.place_message_data(message_data) for message_data in messages_data]

async inherited method delete_messages(self, messages, reason)

Bulk delete messages from channel.

Parameters:

Name Type Description Default
messages List[Union[int, str, SnowflakeObject, SupportsInt, models.Message]]

List of messages or message IDs to delete.

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this action. Used for audit logs.

Missing
Source code in naff/models/discord/channel.py
async def delete_messages(
    self, messages: List[Union[Snowflake_Type, "models.Message"]], reason: Absent[Optional[str]] = MISSING
) -> None:
    """
    Bulk delete messages from channel.

    Args:
        messages: List of messages or message IDs to delete.
        reason: The reason for this action. Used for audit logs.

    """
    message_ids = [to_snowflake(message) for message in messages]
    # TODO Add check for min/max and duplicates.

    if len(message_ids) == 1:
        # bulk delete messages will throw a http error if only 1 message is passed
        await self.delete_message(message_ids[0], reason)
    else:
        await self._client.http.bulk_delete_messages(self.id, message_ids, reason)

async inherited method delete_message(self, message, reason)

Delete a single message from a channel.

Parameters:

Name Type Description Default
message Union[int, str, SnowflakeObject, SupportsInt, models.Message]

The message to delete

required
reason str

The reason for this action

None
Source code in naff/models/discord/channel.py
async def delete_message(self, message: Union[Snowflake_Type, "models.Message"], reason: str = None) -> None:
    """
    Delete a single message from a channel.

    Args:
        message: The message to delete
        reason: The reason for this action

    """
    message = to_snowflake(message)
    await self._client.http.delete_message(self.id, message, reason=reason)

async inherited method purge(self, deletion_limit, search_limit, predicate, avoid_loading_msg, before, after, around, reason)

Bulk delete messages within a channel. If a predicate is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the deletion_limit.

Example Usage:
1
2
3
# this will delete the last 20 messages sent by a user with the given ID
deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
await channel.send(f"{deleted} messages deleted")

Parameters:

Name Type Description Default
deletion_limit int

The target amount of messages to delete

50
search_limit int

How many messages to search through

100
predicate Callable[[models.Message], bool]

A function that returns True or False, and takes a message as an argument

Missing
avoid_loading_msg bool

Should the bot attempt to avoid deleting its own loading messages (recommended enabled)

True
before Union[int, str, SnowflakeObject, SupportsInt]

Search messages before this ID

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Search messages after this ID

Missing
around Union[int, str, SnowflakeObject, SupportsInt]

Search messages around this ID

Missing
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this deletion

Missing

Returns:

Type Description
int

The total amount of messages deleted

Source code in naff/models/discord/channel.py
async def purge(
    self,
    deletion_limit: int = 50,
    search_limit: int = 100,
    predicate: Callable[["models.Message"], bool] = MISSING,
    avoid_loading_msg: bool = True,
    before: Optional[Snowflake_Type] = MISSING,
    after: Optional[Snowflake_Type] = MISSING,
    around: Optional[Snowflake_Type] = MISSING,
    reason: Absent[Optional[str]] = MISSING,
) -> int:
    """
    Bulk delete messages within a channel. If a `predicate` is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the `deletion_limit`.

    ??? Hint "Example Usage:"
        ```python
        # this will delete the last 20 messages sent by a user with the given ID
        deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
        await channel.send(f"{deleted} messages deleted")
        ```

    Args:
        deletion_limit: The target amount of messages to delete
        search_limit: How many messages to search through
        predicate: A function that returns True or False, and takes a message as an argument
        avoid_loading_msg: Should the bot attempt to avoid deleting its own loading messages (recommended enabled)
        before: Search messages before this ID
        after: Search messages after this ID
        around: Search messages around this ID
        reason: The reason for this deletion

    Returns:
        The total amount of messages deleted

    """
    if not predicate:

        def predicate(m) -> bool:
            return True  # noqa

    to_delete = []

    # 1209600 14 days ago in seconds, 1420070400000 is used to convert to snowflake
    fourteen_days_ago = int((time.time() - 1209600) * 1000.0 - DISCORD_EPOCH) << 22
    async for message in self.history(limit=search_limit, before=before, after=after, around=around):
        if deletion_limit != 0 and len(to_delete) == deletion_limit:
            break

        if not predicate(message):
            # fails predicate
            continue

        if avoid_loading_msg:
            if message._author_id == self._client.user.id and MessageFlags.LOADING in message.flags:
                continue

        if message.id < fourteen_days_ago:
            # message is too old to be purged
            continue

        to_delete.append(message.id)

    count = len(to_delete)
    while len(to_delete):
        iteration = [to_delete.pop() for i in range(min(100, len(to_delete)))]
        await self.delete_messages(iteration, reason=reason)
    return count

async inherited method trigger_typing(self)

Trigger a typing animation in this channel.

Source code in naff/models/discord/channel.py
async def trigger_typing(self) -> None:
    """Trigger a typing animation in this channel."""
    await self._client.http.trigger_typing_indicator(self.id)

inherited property readonly typing: Typing

A context manager to send a typing state to a given channel as long as long as the wrapped operation takes.

inherited property readonly mention: str

Returns a string that would mention the channel.

async inherited method delete(self, reason)

Delete this channel.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for deleting this channel

Missing
Source code in naff/models/discord/channel.py
async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Delete this channel.

    Args:
        reason: The reason for deleting this channel

    """
    await self._client.http.delete_channel(self.id, reason)

inherited property readonly members: List[models.User]

Returns a list of users that are in this DM channel.

async method edit(self, name, icon, reason, **kwargs)

Edit this DM Channel.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

1-100 character channel name

Missing
icon Union[naff.models.discord.file.File, io.IOBase, BinaryIO, pathlib.Path, str, naff.client.const.Missing]

An icon to use

Missing
reason Union[str, naff.client.const.Missing]

The reason for this change

Missing
Source code in naff/models/discord/channel.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    icon: Absent[UPLOADABLE_TYPE] = MISSING,
    reason: Absent[str] = MISSING,
    **kwargs,
) -> "DMGroup":
    """
    Edit this DM Channel.

    Args:
        name: 1-100 character channel name
        icon: An icon to use
        reason: The reason for this change
    """
    return await super().edit(name=name, icon=icon, reason=reason, **kwargs)

async method fetch_owner(self)

Fetch the owner of this DM group

Source code in naff/models/discord/channel.py
async def fetch_owner(self) -> "models.User":
    """Fetch the owner of this DM group"""
    return await self._client.cache.fetch_user(self.owner_id)

method get_owner(self)

Get the owner of this DM group

Source code in naff/models/discord/channel.py
def get_owner(self) -> "models.User":
    """Get the owner of this DM group"""
    return self._client.cache.get_user(self.owner_id)

async method add_recipient(self, user, access_token, nickname)

Add a recipient to this DM Group.

Parameters:

Name Type Description Default
user Union[models.User, int, str, SnowflakeObject, SupportsInt]

The user to add

required
access_token str

access token of a user that has granted your app the gdm.join scope

required
nickname Union[str, NoneType, naff.client.const.Missing]

nickname to apply to the user being added

Missing
Source code in naff/models/discord/channel.py
async def add_recipient(
    self, user: Union["models.User", Snowflake_Type], access_token: str, nickname: Absent[Optional[str]] = MISSING
) -> None:
    """
    Add a recipient to this DM Group.

    Args:
        user: The user to add
        access_token: access token of a user that has granted your app the gdm.join scope
        nickname: nickname to apply to the user being added

    """
    user = await self._client.cache.fetch_user(user)
    await self._client.http.group_dm_add_recipient(self.id, user.id, access_token, nickname)
    self.recipients.append(user)

async method remove_recipient(self, user)

Remove a recipient from this DM Group.

Parameters:

Name Type Description Default
user Union[models.User, int, str, SnowflakeObject, SupportsInt]

The user to remove

required
Source code in naff/models/discord/channel.py
async def remove_recipient(self, user: Union["models.User", Snowflake_Type]) -> None:
    """
    Remove a recipient from this DM Group.

    Args:
        user: The user to remove

    """
    user = await self._client.cache.fetch_user(user)
    await self._client.http.group_dm_remove_recipient(self.id, user.id)
    self.recipients.remove(user)

attrs class GuildChannel (BaseChannel)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

position Optional[int]

Sorting position of the channel

nsfw bool

Whether the channel is nsfw

parent_id Union[int, str, SnowflakeObject, SupportsInt]

id of the parent category for a channel (each parent category can contain up to 50 channels)

permission_overwrites list

A list of the overwritten permissions for the members and roles

Source code in naff/models/discord/channel.py
@define(slots=False)
class GuildChannel(BaseChannel):
    position: Optional[int] = field(default=0)
    """Sorting position of the channel"""
    nsfw: bool = field(default=False)
    """Whether the channel is nsfw"""
    parent_id: Optional[Snowflake_Type] = field(default=None, converter=optional_c(to_snowflake))
    """id of the parent category for a channel (each parent category can contain up to 50 channels)"""
    permission_overwrites: list[PermissionOverwrite] = field(factory=list)
    """A list of the overwritten permissions for the members and roles"""

    _guild_id: Optional[Snowflake_Type] = field(default=None, converter=optional_c(to_snowflake))

    @property
    def guild(self) -> "models.Guild":
        """The guild this channel belongs to."""
        return self._client.cache.get_guild(self._guild_id)

    @property
    def category(self) -> Optional["GuildCategory"]:
        """The parent category of this channel."""
        return self._client.cache.get_channel(self.parent_id)

    @property
    def gui_position(self) -> int:
        """The position of this channel in the Discord interface."""
        return self.guild.get_channel_gui_position(self.id)

    @classmethod
    def _process_dict(cls, data: Dict[str, Any], client: "Client") -> Dict[str, Any]:
        data = super()._process_dict(data, client)
        if overwrites := data.get("permission_overwrites"):
            data["permission_overwrites"] = PermissionOverwrite.from_list(overwrites)
        return data

    def permissions_for(self, instance: Snowflake_Type) -> Permissions:
        """
        Calculates permissions for an instance

        Args:
            instance: Member or Role instance (or its ID)

        Returns:
            Permissions data

        Raises:
            ValueError: If could not find any member or role by given ID
            RuntimeError: If given instance is from another guild

        """
        if (is_member := isinstance(instance, models.Member)) or isinstance(instance, models.Role):
            if instance._guild_id != self._guild_id:
                raise RuntimeError("Unable to calculate permissions for the instance from different guild")

            if is_member:
                return instance.channel_permissions(self)

            else:
                permissions = instance.permissions

                for overwrite in self.permission_overwrites:
                    if overwrite.id == instance.id:
                        permissions &= ~overwrite.deny
                        permissions |= overwrite.allow
                        break

                return permissions

        else:
            instance = to_snowflake(instance)
            guild = self.guild
            instance = guild.get_member(instance) or guild.get_role(instance)

            if not instance:
                raise ValueError("Unable to find any member or role by given instance ID")

            return self.permissions_for(instance)

    async def add_permission(
        self,
        target: Union["PermissionOverwrite", "models.Role", "models.User", "models.Member", "Snowflake_Type"],
        type: Optional["OverwriteTypes"] = None,
        allow: Optional[List["Permissions"] | int] = None,
        deny: Optional[List["Permissions"] | int] = None,
        reason: Optional[str] = None,
    ) -> None:
        """
        Add a permission to this channel.

        Args:
            target: The updated PermissionOverwrite object, or the Role or User object/id to update
            type: The type of permission overwrite. Only applicable if target is an id
            allow: List of permissions to allow. Only applicable if target is not an PermissionOverwrite object
            deny: List of permissions to deny. Only applicable if target is not an PermissionOverwrite object
            reason: The reason for this change

        Raises:
            ValueError: Invalid target for permission

        """
        allow = allow or []
        deny = deny or []
        if not isinstance(target, PermissionOverwrite):
            if isinstance(target, (models.User, models.Member)):
                target = target.id
                type = OverwriteTypes.MEMBER
            elif isinstance(target, models.Role):
                target = target.id
                type = OverwriteTypes.ROLE
            elif type and isinstance(target, Snowflake_Type):
                target = to_snowflake(target)
            else:
                raise ValueError("Invalid target and/or type for permission")
            overwrite = PermissionOverwrite(id=target, type=type, allow=Permissions.NONE, deny=Permissions.NONE)
            if isinstance(allow, int):
                overwrite.allow |= allow
            else:
                for perm in allow:
                    overwrite.allow |= perm
            if isinstance(deny, int):
                overwrite.deny |= deny
            else:
                for perm in deny:
                    overwrite.deny |= perm
        else:
            overwrite = target

        if exists := get(self.permission_overwrites, id=overwrite.id, type=overwrite.type):
            exists.deny = (exists.deny | overwrite.deny) & ~overwrite.allow
            exists.allow = (exists.allow | overwrite.allow) & ~overwrite.deny
            await self.edit_permission(exists, reason)
        else:
            permission_overwrites = self.permission_overwrites
            permission_overwrites.append(overwrite)
            await self.edit(permission_overwrites=permission_overwrites)

    async def edit_permission(self, overwrite: PermissionOverwrite, reason: Optional[str] = None) -> None:
        """
        Edit the permissions for this channel.

        Args:
            overwrite: The permission overwrite to apply
            reason: The reason for this change
        """
        await self._client.http.edit_channel_permission(
            self.id, overwrite.id, overwrite.allow, overwrite.deny, overwrite.type, reason
        )

    async def delete_permission(
        self,
        target: Union["PermissionOverwrite", "models.Role", "models.User"],
        reason: Absent[Optional[str]] = MISSING,
    ) -> None:
        """
        Delete a permission overwrite for this channel.

        Args:
            target: The permission overwrite to delete
            reason: The reason for this change

        """
        target = to_snowflake(target)
        await self._client.http.delete_channel_permission(self.id, target, reason)

    async def set_permission(
        self,
        target: Union["models.Role", "models.Member", "models.User"],
        *,
        add_reactions: bool | None = None,
        administrator: bool | None = None,
        attach_files: bool | None = None,
        ban_members: bool | None = None,
        change_nickname: bool | None = None,
        connect: bool | None = None,
        create_instant_invite: bool | None = None,
        deafen_members: bool | None = None,
        embed_links: bool | None = None,
        kick_members: bool | None = None,
        manage_channels: bool | None = None,
        manage_emojis_and_stickers: bool | None = None,
        manage_events: bool | None = None,
        manage_guild: bool | None = None,
        manage_messages: bool | None = None,
        manage_nicknames: bool | None = None,
        manage_roles: bool | None = None,
        manage_threads: bool | None = None,
        manage_webhooks: bool | None = None,
        mention_everyone: bool | None = None,
        moderate_members: bool | None = None,
        move_members: bool | None = None,
        mute_members: bool | None = None,
        priority_speaker: bool | None = None,
        read_message_history: bool | None = None,
        request_to_speak: bool | None = None,
        send_messages: bool | None = None,
        send_messages_in_threads: bool | None = None,
        send_tts_messages: bool | None = None,
        speak: bool | None = None,
        start_embedded_activities: bool | None = None,
        stream: bool | None = None,
        use_application_commands: bool | None = None,
        use_external_emojis: bool | None = None,
        use_external_stickers: bool | None = None,
        use_private_threads: bool | None = None,
        use_public_threads: bool | None = None,
        use_vad: bool | None = None,
        view_audit_log: bool | None = None,
        view_channel: bool | None = None,
        view_guild_insights: bool | None = None,
        reason: str = None,
    ) -> None:
        """
        Set the Permission Overwrites for a given target.

        Args:
            target: The target to set permission overwrites for
            add_reactions: Allows for the addition of reactions to messages
            administrator: Allows all permissions and bypasses channel permission overwrites
            attach_files: Allows for uploading images and files
            ban_members: Allows banning members
            change_nickname: Allows for modification of own nickname
            connect: Allows for joining of a voice channel
            create_instant_invite: Allows creation of instant invites
            deafen_members: Allows for deafening of members in a voice channel
            embed_links: Links sent by users with this permission will be auto-embedded
            kick_members: Allows kicking members
            manage_channels: Allows management and editing of channels
            manage_emojis_and_stickers: Allows management and editing of emojis and stickers
            manage_events: Allows for creating, editing, and deleting scheduled events
            manage_guild: Allows management and editing of the guild
            manage_messages: Allows for deletion of other users messages
            manage_nicknames: Allows for modification of other users nicknames
            manage_roles: Allows management and editing of roles
            manage_threads: Allows for deleting and archiving threads, and viewing all private threads
            manage_webhooks: Allows management and editing of webhooks
            mention_everyone: Allows for using the `@everyone` tag to notify all users in a channel, and the `@here` tag to notify all online users in a channel
            moderate_members: Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels
            move_members: Allows for moving of members between voice channels
            mute_members: Allows for muting members in a voice channel
            priority_speaker: Allows for using priority speaker in a voice channel
            read_message_history: Allows for reading of message history
            request_to_speak: Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)
            send_messages:  Allows for sending messages in a channel (does not allow sending messages in threads)
            send_messages_in_threads: Allows for sending messages in threads
            send_tts_messages:  Allows for sending of `/tts` messages
            speak: Allows for speaking in a voice channel
            start_embedded_activities: Allows for using Activities (applications with the `EMBEDDED` flag) in a voice channel
            stream: Allows the user to go live
            use_application_commands: Allows members to use application commands, including slash commands and context menu commands
            use_external_emojis: Allows the usage of custom emojis from other servers
            use_external_stickers: Allows the usage of custom stickers from other servers
            use_private_threads: Allows for creating private threads
            use_public_threads:  Allows for creating public and announcement threads
            use_vad: Allows for using voice-activity-detection in a voice channel
            view_audit_log: Allows for viewing of audit logs
            view_channel: Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels
            view_guild_insights: Allows for viewing guild insights
            reason: The reason for creating this overwrite
        """
        overwrite = PermissionOverwrite.for_target(target)

        allow: Permissions = Permissions.NONE
        deny: Permissions = Permissions.NONE

        for name, val in locals().items():
            if isinstance(val, bool):
                if val:
                    allow |= getattr(Permissions, name.upper())
                else:
                    deny |= getattr(Permissions, name.upper())

        overwrite.add_allows(allow)
        overwrite.add_denies(deny)

        await self.edit_permission(overwrite, reason)

    @property
    def members(self) -> List["models.Member"]:
        """Returns a list of members that can see this channel."""
        return [m for m in self.guild.members if Permissions.VIEW_CHANNEL in m.channel_permissions(self)]  # type: ignore

    @property
    def bots(self) -> List["models.Member"]:
        """Returns a list of bots that can see this channel."""
        return [m for m in self.guild.members if m.bot and Permissions.VIEW_CHANNEL in m.channel_permissions(self)]  # type: ignore

    @property
    def humans(self) -> List["models.Member"]:
        """Returns a list of humans that can see this channel."""
        return [m for m in self.guild.members if not m.bot and Permissions.VIEW_CHANNEL in m.channel_permissions(self)]  # type: ignore

    async def clone(self, name: Optional[str] = None, reason: Absent[Optional[str]] = MISSING) -> "TYPE_GUILD_CHANNEL":
        """
        Clone this channel and create a new one.

        Args:
            name: The name of the new channel. Defaults to the current name
            reason: The reason for creating this channel

        Returns:
            The newly created channel.

        """
        return await self.guild.create_channel(
            channel_type=self.type,
            name=name if name else self.name,
            topic=getattr(self, "topic", MISSING),
            position=self.position,
            permission_overwrites=self.permission_overwrites,
            category=self.category,
            nsfw=self.nsfw,
            bitrate=getattr(self, "bitrate", 64000),
            user_limit=getattr(self, "user_limit", 0),
            rate_limit_per_user=getattr(self, "rate_limit_per_user", 0),
            reason=reason,
        )

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

inherited property readonly mention: str

Returns a string that would mention the channel.

async inherited method edit(self, name, icon, type, position, topic, nsfw, rate_limit_per_user, bitrate, user_limit, permission_overwrites, parent_id, rtc_region, video_quality_mode, default_auto_archive_duration, archived, auto_archive_duration, locked, invitable, reason, **kwargs)

Edits the channel.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

1-100 character channel name

Missing
icon Union[naff.models.discord.file.File, io.IOBase, BinaryIO, pathlib.Path, str, naff.client.const.Missing]

DM Group icon

Missing
type Union[naff.models.discord.enums.ChannelTypes, naff.client.const.Missing]

The type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature

Missing
position Union[int, naff.client.const.Missing]

The position of the channel in the left-hand listing

Missing
topic Union[str, naff.client.const.Missing]

0-1024 character channel topic

Missing
nsfw Union[bool, naff.client.const.Missing]

Whether the channel is nsfw

Missing
rate_limit_per_user Union[int, naff.client.const.Missing]

Amount of seconds a user has to wait before sending another message (0-21600)

Missing
bitrate Union[int, naff.client.const.Missing]

The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)

Missing
user_limit Union[int, naff.client.const.Missing]

The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

Channel or category-specific permissions

Missing
parent_id Union[int, str, SnowflakeObject, SupportsInt, naff.client.const.Missing]

The id of the new parent category for a channel

Missing
rtc_region Union[models.VoiceRegion, str, naff.client.const.Missing]

Channel voice region id, automatic when set to None.

Missing
video_quality_mode Union[naff.models.discord.enums.VideoQualityModes, naff.client.const.Missing]

The camera video quality mode of the voice channel

Missing
default_auto_archive_duration Union[naff.models.discord.enums.AutoArchiveDuration, naff.client.const.Missing]

The default duration that the clients use (not the API) for newly created threads in the channel, in minutes, to automatically archive the thread after recent activity

Missing
archived Union[bool, naff.client.const.Missing]

Whether the thread is archived

Missing
auto_archive_duration Union[naff.models.discord.enums.AutoArchiveDuration, naff.client.const.Missing]

Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080

Missing
locked Union[bool, naff.client.const.Missing]

Whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it

Missing
invitable Union[bool, naff.client.const.Missing]

Whether non-moderators can add other non-moderators to a thread; only available on private threads

Missing
reason Union[str, naff.client.const.Missing]

The reason for editing the channel

Missing

Returns:

Type Description
TYPE_ALL_CHANNEL

The edited channel. May be a new object if the channel type changes.

Source code in naff/models/discord/channel.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    icon: Absent[UPLOADABLE_TYPE] = MISSING,
    type: Absent[ChannelTypes] = MISSING,
    position: Absent[int] = MISSING,
    topic: Absent[str] = MISSING,
    nsfw: Absent[bool] = MISSING,
    rate_limit_per_user: Absent[int] = MISSING,
    bitrate: Absent[int] = MISSING,
    user_limit: Absent[int] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    parent_id: Absent[Snowflake_Type] = MISSING,
    rtc_region: Absent[Union["models.VoiceRegion", str]] = MISSING,
    video_quality_mode: Absent[VideoQualityModes] = MISSING,
    default_auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
    archived: Absent[bool] = MISSING,
    auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
    locked: Absent[bool] = MISSING,
    invitable: Absent[bool] = MISSING,
    reason: Absent[str] = MISSING,
    **kwargs,
) -> "TYPE_ALL_CHANNEL":
    """
    Edits the channel.

    Args:
        name: 1-100 character channel name
        icon: DM Group icon
        type: The type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature
        position: The position of the channel in the left-hand listing
        topic: 0-1024 character channel topic
        nsfw: Whether the channel is nsfw
        rate_limit_per_user: Amount of seconds a user has to wait before sending another message (0-21600)
        bitrate: The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)
        user_limit: The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit
        permission_overwrites: Channel or category-specific permissions
        parent_id: The id of the new parent category for a channel
        rtc_region: Channel voice region id, automatic when set to None.
        video_quality_mode: The camera video quality mode of the voice channel
        default_auto_archive_duration: The default duration that the clients use (not the API) for newly created threads in the channel, in minutes, to automatically archive the thread after recent activity
        archived: Whether the thread is archived
        auto_archive_duration: Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080
        locked: Whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
        invitable: Whether non-moderators can add other non-moderators to a thread; only available on private threads
        reason: The reason for editing the channel

    Returns:
        The edited channel. May be a new object if the channel type changes.

    """
    payload = {
        "name": name,
        "icon": to_image_data(icon),
        "type": type,
        "position": position,
        "topic": topic,
        "nsfw": nsfw,
        "rate_limit_per_user": rate_limit_per_user,
        "bitrate": bitrate,
        "user_limit": user_limit,
        "permission_overwrites": process_permission_overwrites(permission_overwrites),
        "parent_id": to_optional_snowflake(parent_id),
        "rtc_region": rtc_region.id if isinstance(rtc_region, models.VoiceRegion) else rtc_region,
        "video_quality_mode": video_quality_mode,
        "default_auto_archive_duration": default_auto_archive_duration,
        "archived": archived,
        "auto_archive_duration": auto_archive_duration,
        "locked": locked,
        "invitable": invitable,
        **kwargs,
    }
    channel_data = await self._client.http.modify_channel(self.id, payload, reason)
    if not channel_data:
        raise TooManyChanges(
            "You have changed this channel too frequently, you need to wait a while before trying again."
        ) from None

    return self._client.cache.place_channel_data(channel_data)

async inherited method delete(self, reason)

Delete this channel.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for deleting this channel

Missing
Source code in naff/models/discord/channel.py
async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Delete this channel.

    Args:
        reason: The reason for deleting this channel

    """
    await self._client.http.delete_channel(self.id, reason)

property readonly guild: models.Guild

The guild this channel belongs to.

property readonly category: Optional[GuildCategory]

The parent category of this channel.

property readonly gui_position: int

The position of this channel in the Discord interface.

method permissions_for(self, instance)

Calculates permissions for an instance

Parameters:

Name Type Description Default
instance Union[int, str, SnowflakeObject, SupportsInt]

Member or Role instance (or its ID)

required

Returns:

Type Description
Permissions

Permissions data

Exceptions:

Type Description
ValueError

If could not find any member or role by given ID

RuntimeError

If given instance is from another guild

Source code in naff/models/discord/channel.py
def permissions_for(self, instance: Snowflake_Type) -> Permissions:
    """
    Calculates permissions for an instance

    Args:
        instance: Member or Role instance (or its ID)

    Returns:
        Permissions data

    Raises:
        ValueError: If could not find any member or role by given ID
        RuntimeError: If given instance is from another guild

    """
    if (is_member := isinstance(instance, models.Member)) or isinstance(instance, models.Role):
        if instance._guild_id != self._guild_id:
            raise RuntimeError("Unable to calculate permissions for the instance from different guild")

        if is_member:
            return instance.channel_permissions(self)

        else:
            permissions = instance.permissions

            for overwrite in self.permission_overwrites:
                if overwrite.id == instance.id:
                    permissions &= ~overwrite.deny
                    permissions |= overwrite.allow
                    break

            return permissions

    else:
        instance = to_snowflake(instance)
        guild = self.guild
        instance = guild.get_member(instance) or guild.get_role(instance)

        if not instance:
            raise ValueError("Unable to find any member or role by given instance ID")

        return self.permissions_for(instance)

async method add_permission(self, target, type, allow, deny, reason)

Add a permission to this channel.

Parameters:

Name Type Description Default
target Union[PermissionOverwrite, models.Role, models.User, models.Member, Snowflake_Type]

The updated PermissionOverwrite object, or the Role or User object/id to update

required
type Optional[OverwriteTypes]

The type of permission overwrite. Only applicable if target is an id

None
allow Union[List[Permissions], int]

List of permissions to allow. Only applicable if target is not an PermissionOverwrite object

None
deny Union[List[Permissions], int]

List of permissions to deny. Only applicable if target is not an PermissionOverwrite object

None
reason Optional[str]

The reason for this change

None

Exceptions:

Type Description
ValueError

Invalid target for permission

Source code in naff/models/discord/channel.py
async def add_permission(
    self,
    target: Union["PermissionOverwrite", "models.Role", "models.User", "models.Member", "Snowflake_Type"],
    type: Optional["OverwriteTypes"] = None,
    allow: Optional[List["Permissions"] | int] = None,
    deny: Optional[List["Permissions"] | int] = None,
    reason: Optional[str] = None,
) -> None:
    """
    Add a permission to this channel.

    Args:
        target: The updated PermissionOverwrite object, or the Role or User object/id to update
        type: The type of permission overwrite. Only applicable if target is an id
        allow: List of permissions to allow. Only applicable if target is not an PermissionOverwrite object
        deny: List of permissions to deny. Only applicable if target is not an PermissionOverwrite object
        reason: The reason for this change

    Raises:
        ValueError: Invalid target for permission

    """
    allow = allow or []
    deny = deny or []
    if not isinstance(target, PermissionOverwrite):
        if isinstance(target, (models.User, models.Member)):
            target = target.id
            type = OverwriteTypes.MEMBER
        elif isinstance(target, models.Role):
            target = target.id
            type = OverwriteTypes.ROLE
        elif type and isinstance(target, Snowflake_Type):
            target = to_snowflake(target)
        else:
            raise ValueError("Invalid target and/or type for permission")
        overwrite = PermissionOverwrite(id=target, type=type, allow=Permissions.NONE, deny=Permissions.NONE)
        if isinstance(allow, int):
            overwrite.allow |= allow
        else:
            for perm in allow:
                overwrite.allow |= perm
        if isinstance(deny, int):
            overwrite.deny |= deny
        else:
            for perm in deny:
                overwrite.deny |= perm
    else:
        overwrite = target

    if exists := get(self.permission_overwrites, id=overwrite.id, type=overwrite.type):
        exists.deny = (exists.deny | overwrite.deny) & ~overwrite.allow
        exists.allow = (exists.allow | overwrite.allow) & ~overwrite.deny
        await self.edit_permission(exists, reason)
    else:
        permission_overwrites = self.permission_overwrites
        permission_overwrites.append(overwrite)
        await self.edit(permission_overwrites=permission_overwrites)

async method edit_permission(self, overwrite, reason)

Edit the permissions for this channel.

Parameters:

Name Type Description Default
overwrite PermissionOverwrite

The permission overwrite to apply

required
reason Optional[str]

The reason for this change

None
Source code in naff/models/discord/channel.py
async def edit_permission(self, overwrite: PermissionOverwrite, reason: Optional[str] = None) -> None:
    """
    Edit the permissions for this channel.

    Args:
        overwrite: The permission overwrite to apply
        reason: The reason for this change
    """
    await self._client.http.edit_channel_permission(
        self.id, overwrite.id, overwrite.allow, overwrite.deny, overwrite.type, reason
    )

async method delete_permission(self, target, reason)

Delete a permission overwrite for this channel.

Parameters:

Name Type Description Default
target Union[PermissionOverwrite, models.Role, models.User]

The permission overwrite to delete

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this change

Missing
Source code in naff/models/discord/channel.py
async def delete_permission(
    self,
    target: Union["PermissionOverwrite", "models.Role", "models.User"],
    reason: Absent[Optional[str]] = MISSING,
) -> None:
    """
    Delete a permission overwrite for this channel.

    Args:
        target: The permission overwrite to delete
        reason: The reason for this change

    """
    target = to_snowflake(target)
    await self._client.http.delete_channel_permission(self.id, target, reason)

async method set_permission(self, target, *, add_reactions, administrator, attach_files, ban_members, change_nickname, connect, create_instant_invite, deafen_members, embed_links, kick_members, manage_channels, manage_emojis_and_stickers, manage_events, manage_guild, manage_messages, manage_nicknames, manage_roles, manage_threads, manage_webhooks, mention_everyone, moderate_members, move_members, mute_members, priority_speaker, read_message_history, request_to_speak, send_messages, send_messages_in_threads, send_tts_messages, speak, start_embedded_activities, stream, use_application_commands, use_external_emojis, use_external_stickers, use_private_threads, use_public_threads, use_vad, view_audit_log, view_channel, view_guild_insights, reason)

Set the Permission Overwrites for a given target.

Parameters:

Name Type Description Default
target Union[models.Role, models.Member, models.User]

The target to set permission overwrites for

required
add_reactions bool | None

Allows for the addition of reactions to messages

None
administrator bool | None

Allows all permissions and bypasses channel permission overwrites

None
attach_files bool | None

Allows for uploading images and files

None
ban_members bool | None

Allows banning members

None
change_nickname bool | None

Allows for modification of own nickname

None
connect bool | None

Allows for joining of a voice channel

None
create_instant_invite bool | None

Allows creation of instant invites

None
deafen_members bool | None

Allows for deafening of members in a voice channel

None
embed_links bool | None

Links sent by users with this permission will be auto-embedded

None
kick_members bool | None

Allows kicking members

None
manage_channels bool | None

Allows management and editing of channels

None
manage_emojis_and_stickers bool | None

Allows management and editing of emojis and stickers

None
manage_events bool | None

Allows for creating, editing, and deleting scheduled events

None
manage_guild bool | None

Allows management and editing of the guild

None
manage_messages bool | None

Allows for deletion of other users messages

None
manage_nicknames bool | None

Allows for modification of other users nicknames

None
manage_roles bool | None

Allows management and editing of roles

None
manage_threads bool | None

Allows for deleting and archiving threads, and viewing all private threads

None
manage_webhooks bool | None

Allows management and editing of webhooks

None
mention_everyone bool | None

Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all online users in a channel

None
moderate_members bool | None

Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels

None
move_members bool | None

Allows for moving of members between voice channels

None
mute_members bool | None

Allows for muting members in a voice channel

None
priority_speaker bool | None

Allows for using priority speaker in a voice channel

None
read_message_history bool | None

Allows for reading of message history

None
request_to_speak bool | None

Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)

None
send_messages bool | None

Allows for sending messages in a channel (does not allow sending messages in threads)

None
send_messages_in_threads bool | None

Allows for sending messages in threads

None
send_tts_messages bool | None

Allows for sending of /tts messages

None
speak bool | None

Allows for speaking in a voice channel

None
start_embedded_activities bool | None

Allows for using Activities (applications with the EMBEDDED flag) in a voice channel

None
stream bool | None

Allows the user to go live

None
use_application_commands bool | None

Allows members to use application commands, including slash commands and context menu commands

None
use_external_emojis bool | None

Allows the usage of custom emojis from other servers

None
use_external_stickers bool | None

Allows the usage of custom stickers from other servers

None
use_private_threads bool | None

Allows for creating private threads

None
use_public_threads bool | None

Allows for creating public and announcement threads

None
use_vad bool | None

Allows for using voice-activity-detection in a voice channel

None
view_audit_log bool | None

Allows for viewing of audit logs

None
view_channel bool | None

Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels

None
view_guild_insights bool | None

Allows for viewing guild insights

None
reason str

The reason for creating this overwrite

None
Source code in naff/models/discord/channel.py
async def set_permission(
    self,
    target: Union["models.Role", "models.Member", "models.User"],
    *,
    add_reactions: bool | None = None,
    administrator: bool | None = None,
    attach_files: bool | None = None,
    ban_members: bool | None = None,
    change_nickname: bool | None = None,
    connect: bool | None = None,
    create_instant_invite: bool | None = None,
    deafen_members: bool | None = None,
    embed_links: bool | None = None,
    kick_members: bool | None = None,
    manage_channels: bool | None = None,
    manage_emojis_and_stickers: bool | None = None,
    manage_events: bool | None = None,
    manage_guild: bool | None = None,
    manage_messages: bool | None = None,
    manage_nicknames: bool | None = None,
    manage_roles: bool | None = None,
    manage_threads: bool | None = None,
    manage_webhooks: bool | None = None,
    mention_everyone: bool | None = None,
    moderate_members: bool | None = None,
    move_members: bool | None = None,
    mute_members: bool | None = None,
    priority_speaker: bool | None = None,
    read_message_history: bool | None = None,
    request_to_speak: bool | None = None,
    send_messages: bool | None = None,
    send_messages_in_threads: bool | None = None,
    send_tts_messages: bool | None = None,
    speak: bool | None = None,
    start_embedded_activities: bool | None = None,
    stream: bool | None = None,
    use_application_commands: bool | None = None,
    use_external_emojis: bool | None = None,
    use_external_stickers: bool | None = None,
    use_private_threads: bool | None = None,
    use_public_threads: bool | None = None,
    use_vad: bool | None = None,
    view_audit_log: bool | None = None,
    view_channel: bool | None = None,
    view_guild_insights: bool | None = None,
    reason: str = None,
) -> None:
    """
    Set the Permission Overwrites for a given target.

    Args:
        target: The target to set permission overwrites for
        add_reactions: Allows for the addition of reactions to messages
        administrator: Allows all permissions and bypasses channel permission overwrites
        attach_files: Allows for uploading images and files
        ban_members: Allows banning members
        change_nickname: Allows for modification of own nickname
        connect: Allows for joining of a voice channel
        create_instant_invite: Allows creation of instant invites
        deafen_members: Allows for deafening of members in a voice channel
        embed_links: Links sent by users with this permission will be auto-embedded
        kick_members: Allows kicking members
        manage_channels: Allows management and editing of channels
        manage_emojis_and_stickers: Allows management and editing of emojis and stickers
        manage_events: Allows for creating, editing, and deleting scheduled events
        manage_guild: Allows management and editing of the guild
        manage_messages: Allows for deletion of other users messages
        manage_nicknames: Allows for modification of other users nicknames
        manage_roles: Allows management and editing of roles
        manage_threads: Allows for deleting and archiving threads, and viewing all private threads
        manage_webhooks: Allows management and editing of webhooks
        mention_everyone: Allows for using the `@everyone` tag to notify all users in a channel, and the `@here` tag to notify all online users in a channel
        moderate_members: Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels
        move_members: Allows for moving of members between voice channels
        mute_members: Allows for muting members in a voice channel
        priority_speaker: Allows for using priority speaker in a voice channel
        read_message_history: Allows for reading of message history
        request_to_speak: Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)
        send_messages:  Allows for sending messages in a channel (does not allow sending messages in threads)
        send_messages_in_threads: Allows for sending messages in threads
        send_tts_messages:  Allows for sending of `/tts` messages
        speak: Allows for speaking in a voice channel
        start_embedded_activities: Allows for using Activities (applications with the `EMBEDDED` flag) in a voice channel
        stream: Allows the user to go live
        use_application_commands: Allows members to use application commands, including slash commands and context menu commands
        use_external_emojis: Allows the usage of custom emojis from other servers
        use_external_stickers: Allows the usage of custom stickers from other servers
        use_private_threads: Allows for creating private threads
        use_public_threads:  Allows for creating public and announcement threads
        use_vad: Allows for using voice-activity-detection in a voice channel
        view_audit_log: Allows for viewing of audit logs
        view_channel: Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels
        view_guild_insights: Allows for viewing guild insights
        reason: The reason for creating this overwrite
    """
    overwrite = PermissionOverwrite.for_target(target)

    allow: Permissions = Permissions.NONE
    deny: Permissions = Permissions.NONE

    for name, val in locals().items():
        if isinstance(val, bool):
            if val:
                allow |= getattr(Permissions, name.upper())
            else:
                deny |= getattr(Permissions, name.upper())

    overwrite.add_allows(allow)
    overwrite.add_denies(deny)

    await self.edit_permission(overwrite, reason)

property readonly members: List[models.Member]

Returns a list of members that can see this channel.

property readonly bots: List[models.Member]

Returns a list of bots that can see this channel.

property readonly humans: List[models.Member]

Returns a list of humans that can see this channel.

async method clone(self, name, reason)

Clone this channel and create a new one.

Parameters:

Name Type Description Default
name Optional[str]

The name of the new channel. Defaults to the current name

None
reason Union[str, NoneType, naff.client.const.Missing]

The reason for creating this channel

Missing

Returns:

Type Description
TYPE_GUILD_CHANNEL

The newly created channel.

Source code in naff/models/discord/channel.py
async def clone(self, name: Optional[str] = None, reason: Absent[Optional[str]] = MISSING) -> "TYPE_GUILD_CHANNEL":
    """
    Clone this channel and create a new one.

    Args:
        name: The name of the new channel. Defaults to the current name
        reason: The reason for creating this channel

    Returns:
        The newly created channel.

    """
    return await self.guild.create_channel(
        channel_type=self.type,
        name=name if name else self.name,
        topic=getattr(self, "topic", MISSING),
        position=self.position,
        permission_overwrites=self.permission_overwrites,
        category=self.category,
        nsfw=self.nsfw,
        bitrate=getattr(self, "bitrate", 64000),
        user_limit=getattr(self, "user_limit", 0),
        rate_limit_per_user=getattr(self, "rate_limit_per_user", 0),
        reason=reason,
    )

attrs class GuildCategory (GuildChannel)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

Source code in naff/models/discord/channel.py
@define()
class GuildCategory(GuildChannel):
    @property
    def channels(self) -> List["TYPE_GUILD_CHANNEL"]:
        """Get all channels within the category"""
        return [channel for channel in self.guild.channels if channel.parent_id == self.id]

    @property
    def voice_channels(self) -> List["GuildVoice"]:
        """Get all voice channels within the category"""
        return [
            channel
            for channel in self.channels
            if isinstance(channel, GuildVoice) and not isinstance(channel, GuildStageVoice)
        ]

    @property
    def stage_channels(self) -> List["GuildStageVoice"]:
        """Get all stage channels within the category"""
        return [channel for channel in self.channels if isinstance(channel, GuildStageVoice)]

    @property
    def text_channels(self) -> List["GuildText"]:
        """Get all text channels within the category"""
        return [channel for channel in self.channels if isinstance(channel, GuildText)]

    @property
    def news_channels(self) -> List["GuildNews"]:
        """Get all news channels within the category"""
        return [channel for channel in self.channels if isinstance(channel, GuildNews)]

    async def edit(
        self,
        name: Absent[str] = MISSING,
        position: Absent[int] = MISSING,
        permission_overwrites: Absent[
            Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
        ] = MISSING,
        reason: Absent[str] = MISSING,
        **kwargs,
    ) -> "GuildCategory":
        """
        Edit this channel.

        Args:
            name: 1-100 character channel name
            position: the position of the channel in the left-hand listing
            permission_overwrites: channel or category-specific permissions
            reason: the reason for this change

        Returns:
            The updated channel object.

        """
        return await super().edit(
            name=name,
            position=position,
            permission_overwrites=permission_overwrites,
            reason=reason,
            **kwargs,
        )

    async def create_channel(
        self,
        channel_type: Union[ChannelTypes, int],
        name: str,
        topic: Absent[Optional[str]] = MISSING,
        position: Absent[Optional[int]] = MISSING,
        permission_overwrites: Absent[
            Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
        ] = MISSING,
        nsfw: bool = False,
        bitrate: int = 64000,
        user_limit: int = 0,
        rate_limit_per_user: int = 0,
        reason: Absent[Optional[str]] = MISSING,
    ) -> "TYPE_GUILD_CHANNEL":
        """
        Create a guild channel within this category, allows for explicit channel type setting.

        Args:
            channel_type: The type of channel to create
            name: The name of the channel
            topic: The topic of the channel
            position: The position of the channel in the channel list
            permission_overwrites: Permission overwrites to apply to the channel
            nsfw: Should this channel be marked nsfw
            bitrate: The bitrate of this channel, only for voice
            user_limit: The max users that can be in this channel, only for voice
            rate_limit_per_user: The time users must wait between sending messages
            reason: The reason for creating this channel

        Returns:
            The newly created channel.

        """
        return await self.guild.create_channel(
            channel_type=channel_type,
            name=name,
            topic=topic,
            position=position,
            permission_overwrites=permission_overwrites,
            category=self.id,
            nsfw=nsfw,
            bitrate=bitrate,
            user_limit=user_limit,
            rate_limit_per_user=rate_limit_per_user,
            reason=reason,
        )

    async def create_text_channel(
        self,
        name: str,
        topic: Absent[Optional[str]] = MISSING,
        position: Absent[Optional[int]] = MISSING,
        permission_overwrites: Absent[
            Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
        ] = MISSING,
        nsfw: bool = False,
        rate_limit_per_user: int = 0,
        reason: Absent[Optional[str]] = MISSING,
    ) -> "GuildText":
        """
        Create a text channel in this guild within this category.

        Args:
            name: The name of the channel
            topic: The topic of the channel
            position: The position of the channel in the channel list
            permission_overwrites: Permission overwrites to apply to the channel
            nsfw: Should this channel be marked nsfw
            rate_limit_per_user: The time users must wait between sending messages
            reason: The reason for creating this channel

        Returns:
           The newly created text channel.

        """
        return await self.create_channel(
            channel_type=ChannelTypes.GUILD_TEXT,
            name=name,
            topic=topic,
            position=position,
            permission_overwrites=permission_overwrites,
            nsfw=nsfw,
            rate_limit_per_user=rate_limit_per_user,
            reason=reason,
        )

    async def create_news_channel(
        self,
        name: str,
        topic: Absent[Optional[str]] = MISSING,
        position: Absent[Optional[int]] = MISSING,
        permission_overwrites: Absent[
            Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
        ] = MISSING,
        nsfw: bool = False,
        reason: Absent[Optional[str]] = MISSING,
    ) -> "GuildNews":
        """
        Create a news channel in this guild within this category.

        Args:
            name: The name of the channel
            topic: The topic of the channel
            position: The position of the channel in the channel list
            permission_overwrites: Permission overwrites to apply to the channel
            nsfw: Should this channel be marked nsfw
            reason: The reason for creating this channel

        Returns:
           The newly created news channel.

        """
        return await self.create_channel(
            channel_type=ChannelTypes.GUILD_NEWS,
            name=name,
            topic=topic,
            position=position,
            permission_overwrites=permission_overwrites,
            nsfw=nsfw,
            reason=reason,
        )

    async def create_voice_channel(
        self,
        name: str,
        topic: Absent[Optional[str]] = MISSING,
        position: Absent[Optional[int]] = MISSING,
        permission_overwrites: Absent[
            Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
        ] = MISSING,
        nsfw: bool = False,
        bitrate: int = 64000,
        user_limit: int = 0,
        reason: Absent[Optional[str]] = MISSING,
    ) -> "GuildVoice":
        """
        Create a guild voice channel within this category.

        Args:
            name: The name of the channel
            topic: The topic of the channel
            position: The position of the channel in the channel list
            permission_overwrites: Permission overwrites to apply to the channel
            nsfw: Should this channel be marked nsfw
            bitrate: The bitrate of this channel, only for voice
            user_limit: The max users that can be in this channel, only for voice
            reason: The reason for creating this channel

        Returns:
           The newly created voice channel.

        """
        return await self.create_channel(
            channel_type=ChannelTypes.GUILD_VOICE,
            name=name,
            topic=topic,
            position=position,
            permission_overwrites=permission_overwrites,
            nsfw=nsfw,
            bitrate=bitrate,
            user_limit=user_limit,
            reason=reason,
        )

    async def create_stage_channel(
        self,
        name: str,
        topic: Absent[Optional[str]] = MISSING,
        position: Absent[Optional[int]] = MISSING,
        permission_overwrites: Absent[
            Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
        ] = MISSING,
        bitrate: int = 64000,
        user_limit: int = 0,
        reason: Absent[Optional[str]] = MISSING,
    ) -> "GuildStageVoice":
        """
        Create a guild stage channel within this category.

        Args:
            name: The name of the channel
            topic: The topic of the channel
            position: The position of the channel in the channel list
            permission_overwrites: Permission overwrites to apply to the channel
            bitrate: The bitrate of this channel, only for voice
            user_limit: The max users that can be in this channel, only for voice
            reason: The reason for creating this channel

        Returns:
            The newly created stage channel.

        """
        return await self.create_channel(
            channel_type=ChannelTypes.GUILD_STAGE_VOICE,
            name=name,
            topic=topic,
            position=position,
            permission_overwrites=permission_overwrites,
            bitrate=bitrate,
            user_limit=user_limit,
            reason=reason,
        )

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

inherited property readonly mention: str

Returns a string that would mention the channel.

async inherited method delete(self, reason)

Delete this channel.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for deleting this channel

Missing
Source code in naff/models/discord/channel.py
async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Delete this channel.

    Args:
        reason: The reason for deleting this channel

    """
    await self._client.http.delete_channel(self.id, reason)

inherited property readonly guild: models.Guild

The guild this channel belongs to.

inherited property readonly category: Optional[GuildCategory]

The parent category of this channel.

inherited property readonly gui_position: int

The position of this channel in the Discord interface.

inherited method permissions_for(self, instance)

Calculates permissions for an instance

Parameters:

Name Type Description Default
instance Union[int, str, SnowflakeObject, SupportsInt]

Member or Role instance (or its ID)

required

Returns:

Type Description
Permissions

Permissions data

Exceptions:

Type Description
ValueError

If could not find any member or role by given ID

RuntimeError

If given instance is from another guild

Source code in naff/models/discord/channel.py
def permissions_for(self, instance: Snowflake_Type) -> Permissions:
    """
    Calculates permissions for an instance

    Args:
        instance: Member or Role instance (or its ID)

    Returns:
        Permissions data

    Raises:
        ValueError: If could not find any member or role by given ID
        RuntimeError: If given instance is from another guild

    """
    if (is_member := isinstance(instance, models.Member)) or isinstance(instance, models.Role):
        if instance._guild_id != self._guild_id:
            raise RuntimeError("Unable to calculate permissions for the instance from different guild")

        if is_member:
            return instance.channel_permissions(self)

        else:
            permissions = instance.permissions

            for overwrite in self.permission_overwrites:
                if overwrite.id == instance.id:
                    permissions &= ~overwrite.deny
                    permissions |= overwrite.allow
                    break

            return permissions

    else:
        instance = to_snowflake(instance)
        guild = self.guild
        instance = guild.get_member(instance) or guild.get_role(instance)

        if not instance:
            raise ValueError("Unable to find any member or role by given instance ID")

        return self.permissions_for(instance)

async inherited method add_permission(self, target, type, allow, deny, reason)

Add a permission to this channel.

Parameters:

Name Type Description Default
target Union[PermissionOverwrite, models.Role, models.User, models.Member, Snowflake_Type]

The updated PermissionOverwrite object, or the Role or User object/id to update

required
type Optional[OverwriteTypes]

The type of permission overwrite. Only applicable if target is an id

None
allow Union[List[Permissions], int]

List of permissions to allow. Only applicable if target is not an PermissionOverwrite object

None
deny Union[List[Permissions], int]

List of permissions to deny. Only applicable if target is not an PermissionOverwrite object

None
reason Optional[str]

The reason for this change

None

Exceptions:

Type Description
ValueError

Invalid target for permission

Source code in naff/models/discord/channel.py
async def add_permission(
    self,
    target: Union["PermissionOverwrite", "models.Role", "models.User", "models.Member", "Snowflake_Type"],
    type: Optional["OverwriteTypes"] = None,
    allow: Optional[List["Permissions"] | int] = None,
    deny: Optional[List["Permissions"] | int] = None,
    reason: Optional[str] = None,
) -> None:
    """
    Add a permission to this channel.

    Args:
        target: The updated PermissionOverwrite object, or the Role or User object/id to update
        type: The type of permission overwrite. Only applicable if target is an id
        allow: List of permissions to allow. Only applicable if target is not an PermissionOverwrite object
        deny: List of permissions to deny. Only applicable if target is not an PermissionOverwrite object
        reason: The reason for this change

    Raises:
        ValueError: Invalid target for permission

    """
    allow = allow or []
    deny = deny or []
    if not isinstance(target, PermissionOverwrite):
        if isinstance(target, (models.User, models.Member)):
            target = target.id
            type = OverwriteTypes.MEMBER
        elif isinstance(target, models.Role):
            target = target.id
            type = OverwriteTypes.ROLE
        elif type and isinstance(target, Snowflake_Type):
            target = to_snowflake(target)
        else:
            raise ValueError("Invalid target and/or type for permission")
        overwrite = PermissionOverwrite(id=target, type=type, allow=Permissions.NONE, deny=Permissions.NONE)
        if isinstance(allow, int):
            overwrite.allow |= allow
        else:
            for perm in allow:
                overwrite.allow |= perm
        if isinstance(deny, int):
            overwrite.deny |= deny
        else:
            for perm in deny:
                overwrite.deny |= perm
    else:
        overwrite = target

    if exists := get(self.permission_overwrites, id=overwrite.id, type=overwrite.type):
        exists.deny = (exists.deny | overwrite.deny) & ~overwrite.allow
        exists.allow = (exists.allow | overwrite.allow) & ~overwrite.deny
        await self.edit_permission(exists, reason)
    else:
        permission_overwrites = self.permission_overwrites
        permission_overwrites.append(overwrite)
        await self.edit(permission_overwrites=permission_overwrites)

async inherited method edit_permission(self, overwrite, reason)

Edit the permissions for this channel.

Parameters:

Name Type Description Default
overwrite PermissionOverwrite

The permission overwrite to apply

required
reason Optional[str]

The reason for this change

None
Source code in naff/models/discord/channel.py
async def edit_permission(self, overwrite: PermissionOverwrite, reason: Optional[str] = None) -> None:
    """
    Edit the permissions for this channel.

    Args:
        overwrite: The permission overwrite to apply
        reason: The reason for this change
    """
    await self._client.http.edit_channel_permission(
        self.id, overwrite.id, overwrite.allow, overwrite.deny, overwrite.type, reason
    )

async inherited method delete_permission(self, target, reason)

Delete a permission overwrite for this channel.

Parameters:

Name Type Description Default
target Union[PermissionOverwrite, models.Role, models.User]

The permission overwrite to delete

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this change

Missing
Source code in naff/models/discord/channel.py
async def delete_permission(
    self,
    target: Union["PermissionOverwrite", "models.Role", "models.User"],
    reason: Absent[Optional[str]] = MISSING,
) -> None:
    """
    Delete a permission overwrite for this channel.

    Args:
        target: The permission overwrite to delete
        reason: The reason for this change

    """
    target = to_snowflake(target)
    await self._client.http.delete_channel_permission(self.id, target, reason)

async inherited method set_permission(self, target, *, add_reactions, administrator, attach_files, ban_members, change_nickname, connect, create_instant_invite, deafen_members, embed_links, kick_members, manage_channels, manage_emojis_and_stickers, manage_events, manage_guild, manage_messages, manage_nicknames, manage_roles, manage_threads, manage_webhooks, mention_everyone, moderate_members, move_members, mute_members, priority_speaker, read_message_history, request_to_speak, send_messages, send_messages_in_threads, send_tts_messages, speak, start_embedded_activities, stream, use_application_commands, use_external_emojis, use_external_stickers, use_private_threads, use_public_threads, use_vad, view_audit_log, view_channel, view_guild_insights, reason)

Set the Permission Overwrites for a given target.

Parameters:

Name Type Description Default
target Union[models.Role, models.Member, models.User]

The target to set permission overwrites for

required
add_reactions bool | None

Allows for the addition of reactions to messages

None
administrator bool | None

Allows all permissions and bypasses channel permission overwrites

None
attach_files bool | None

Allows for uploading images and files

None
ban_members bool | None

Allows banning members

None
change_nickname bool | None

Allows for modification of own nickname

None
connect bool | None

Allows for joining of a voice channel

None
create_instant_invite bool | None

Allows creation of instant invites

None
deafen_members bool | None

Allows for deafening of members in a voice channel

None
embed_links bool | None

Links sent by users with this permission will be auto-embedded

None
kick_members bool | None

Allows kicking members

None
manage_channels bool | None

Allows management and editing of channels

None
manage_emojis_and_stickers bool | None

Allows management and editing of emojis and stickers

None
manage_events bool | None

Allows for creating, editing, and deleting scheduled events

None
manage_guild bool | None

Allows management and editing of the guild

None
manage_messages bool | None

Allows for deletion of other users messages

None
manage_nicknames bool | None

Allows for modification of other users nicknames

None
manage_roles bool | None

Allows management and editing of roles

None
manage_threads bool | None

Allows for deleting and archiving threads, and viewing all private threads

None
manage_webhooks bool | None

Allows management and editing of webhooks

None
mention_everyone bool | None

Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all online users in a channel

None
moderate_members bool | None

Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels

None
move_members bool | None

Allows for moving of members between voice channels

None
mute_members bool | None

Allows for muting members in a voice channel

None
priority_speaker bool | None

Allows for using priority speaker in a voice channel

None
read_message_history bool | None

Allows for reading of message history

None
request_to_speak bool | None

Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)

None
send_messages bool | None

Allows for sending messages in a channel (does not allow sending messages in threads)

None
send_messages_in_threads bool | None

Allows for sending messages in threads

None
send_tts_messages bool | None

Allows for sending of /tts messages

None
speak bool | None

Allows for speaking in a voice channel

None
start_embedded_activities bool | None

Allows for using Activities (applications with the EMBEDDED flag) in a voice channel

None
stream bool | None

Allows the user to go live

None
use_application_commands bool | None

Allows members to use application commands, including slash commands and context menu commands

None
use_external_emojis bool | None

Allows the usage of custom emojis from other servers

None
use_external_stickers bool | None

Allows the usage of custom stickers from other servers

None
use_private_threads bool | None

Allows for creating private threads

None
use_public_threads bool | None

Allows for creating public and announcement threads

None
use_vad bool | None

Allows for using voice-activity-detection in a voice channel

None
view_audit_log bool | None

Allows for viewing of audit logs

None
view_channel bool | None

Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels

None
view_guild_insights bool | None

Allows for viewing guild insights

None
reason str

The reason for creating this overwrite

None
Source code in naff/models/discord/channel.py
async def set_permission(
    self,
    target: Union["models.Role", "models.Member", "models.User"],
    *,
    add_reactions: bool | None = None,
    administrator: bool | None = None,
    attach_files: bool | None = None,
    ban_members: bool | None = None,
    change_nickname: bool | None = None,
    connect: bool | None = None,
    create_instant_invite: bool | None = None,
    deafen_members: bool | None = None,
    embed_links: bool | None = None,
    kick_members: bool | None = None,
    manage_channels: bool | None = None,
    manage_emojis_and_stickers: bool | None = None,
    manage_events: bool | None = None,
    manage_guild: bool | None = None,
    manage_messages: bool | None = None,
    manage_nicknames: bool | None = None,
    manage_roles: bool | None = None,
    manage_threads: bool | None = None,
    manage_webhooks: bool | None = None,
    mention_everyone: bool | None = None,
    moderate_members: bool | None = None,
    move_members: bool | None = None,
    mute_members: bool | None = None,
    priority_speaker: bool | None = None,
    read_message_history: bool | None = None,
    request_to_speak: bool | None = None,
    send_messages: bool | None = None,
    send_messages_in_threads: bool | None = None,
    send_tts_messages: bool | None = None,
    speak: bool | None = None,
    start_embedded_activities: bool | None = None,
    stream: bool | None = None,
    use_application_commands: bool | None = None,
    use_external_emojis: bool | None = None,
    use_external_stickers: bool | None = None,
    use_private_threads: bool | None = None,
    use_public_threads: bool | None = None,
    use_vad: bool | None = None,
    view_audit_log: bool | None = None,
    view_channel: bool | None = None,
    view_guild_insights: bool | None = None,
    reason: str = None,
) -> None:
    """
    Set the Permission Overwrites for a given target.

    Args:
        target: The target to set permission overwrites for
        add_reactions: Allows for the addition of reactions to messages
        administrator: Allows all permissions and bypasses channel permission overwrites
        attach_files: Allows for uploading images and files
        ban_members: Allows banning members
        change_nickname: Allows for modification of own nickname
        connect: Allows for joining of a voice channel
        create_instant_invite: Allows creation of instant invites
        deafen_members: Allows for deafening of members in a voice channel
        embed_links: Links sent by users with this permission will be auto-embedded
        kick_members: Allows kicking members
        manage_channels: Allows management and editing of channels
        manage_emojis_and_stickers: Allows management and editing of emojis and stickers
        manage_events: Allows for creating, editing, and deleting scheduled events
        manage_guild: Allows management and editing of the guild
        manage_messages: Allows for deletion of other users messages
        manage_nicknames: Allows for modification of other users nicknames
        manage_roles: Allows management and editing of roles
        manage_threads: Allows for deleting and archiving threads, and viewing all private threads
        manage_webhooks: Allows management and editing of webhooks
        mention_everyone: Allows for using the `@everyone` tag to notify all users in a channel, and the `@here` tag to notify all online users in a channel
        moderate_members: Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels
        move_members: Allows for moving of members between voice channels
        mute_members: Allows for muting members in a voice channel
        priority_speaker: Allows for using priority speaker in a voice channel
        read_message_history: Allows for reading of message history
        request_to_speak: Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)
        send_messages:  Allows for sending messages in a channel (does not allow sending messages in threads)
        send_messages_in_threads: Allows for sending messages in threads
        send_tts_messages:  Allows for sending of `/tts` messages
        speak: Allows for speaking in a voice channel
        start_embedded_activities: Allows for using Activities (applications with the `EMBEDDED` flag) in a voice channel
        stream: Allows the user to go live
        use_application_commands: Allows members to use application commands, including slash commands and context menu commands
        use_external_emojis: Allows the usage of custom emojis from other servers
        use_external_stickers: Allows the usage of custom stickers from other servers
        use_private_threads: Allows for creating private threads
        use_public_threads:  Allows for creating public and announcement threads
        use_vad: Allows for using voice-activity-detection in a voice channel
        view_audit_log: Allows for viewing of audit logs
        view_channel: Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels
        view_guild_insights: Allows for viewing guild insights
        reason: The reason for creating this overwrite
    """
    overwrite = PermissionOverwrite.for_target(target)

    allow: Permissions = Permissions.NONE
    deny: Permissions = Permissions.NONE

    for name, val in locals().items():
        if isinstance(val, bool):
            if val:
                allow |= getattr(Permissions, name.upper())
            else:
                deny |= getattr(Permissions, name.upper())

    overwrite.add_allows(allow)
    overwrite.add_denies(deny)

    await self.edit_permission(overwrite, reason)

inherited property readonly members: List[models.Member]

Returns a list of members that can see this channel.

inherited property readonly bots: List[models.Member]

Returns a list of bots that can see this channel.

inherited property readonly humans: List[models.Member]

Returns a list of humans that can see this channel.

async inherited method clone(self, name, reason)

Clone this channel and create a new one.

Parameters:

Name Type Description Default
name Optional[str]

The name of the new channel. Defaults to the current name

None
reason Union[str, NoneType, naff.client.const.Missing]

The reason for creating this channel

Missing

Returns:

Type Description
TYPE_GUILD_CHANNEL

The newly created channel.

Source code in naff/models/discord/channel.py
async def clone(self, name: Optional[str] = None, reason: Absent[Optional[str]] = MISSING) -> "TYPE_GUILD_CHANNEL":
    """
    Clone this channel and create a new one.

    Args:
        name: The name of the new channel. Defaults to the current name
        reason: The reason for creating this channel

    Returns:
        The newly created channel.

    """
    return await self.guild.create_channel(
        channel_type=self.type,
        name=name if name else self.name,
        topic=getattr(self, "topic", MISSING),
        position=self.position,
        permission_overwrites=self.permission_overwrites,
        category=self.category,
        nsfw=self.nsfw,
        bitrate=getattr(self, "bitrate", 64000),
        user_limit=getattr(self, "user_limit", 0),
        rate_limit_per_user=getattr(self, "rate_limit_per_user", 0),
        reason=reason,
    )

property readonly channels: List[TYPE_GUILD_CHANNEL]

Get all channels within the category

property readonly voice_channels: List[GuildVoice]

Get all voice channels within the category

property readonly stage_channels: List[GuildStageVoice]

Get all stage channels within the category

property readonly text_channels: List[GuildText]

Get all text channels within the category

property readonly news_channels: List[GuildNews]

Get all news channels within the category

async method edit(self, name, position, permission_overwrites, reason, **kwargs)

Edit this channel.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

1-100 character channel name

Missing
position Union[int, naff.client.const.Missing]

the position of the channel in the left-hand listing

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

channel or category-specific permissions

Missing
reason Union[str, naff.client.const.Missing]

the reason for this change

Missing

Returns:

Type Description
GuildCategory

The updated channel object.

Source code in naff/models/discord/channel.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    position: Absent[int] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    reason: Absent[str] = MISSING,
    **kwargs,
) -> "GuildCategory":
    """
    Edit this channel.

    Args:
        name: 1-100 character channel name
        position: the position of the channel in the left-hand listing
        permission_overwrites: channel or category-specific permissions
        reason: the reason for this change

    Returns:
        The updated channel object.

    """
    return await super().edit(
        name=name,
        position=position,
        permission_overwrites=permission_overwrites,
        reason=reason,
        **kwargs,
    )

async method create_channel(self, channel_type, name, topic, position, permission_overwrites, nsfw, bitrate, user_limit, rate_limit_per_user, reason)

Create a guild channel within this category, allows for explicit channel type setting.

Parameters:

Name Type Description Default
channel_type Union[naff.models.discord.enums.ChannelTypes, int]

The type of channel to create

required
name str

The name of the channel

required
topic Union[str, NoneType, naff.client.const.Missing]

The topic of the channel

Missing
position Union[int, NoneType, naff.client.const.Missing]

The position of the channel in the channel list

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

Permission overwrites to apply to the channel

Missing
nsfw bool

Should this channel be marked nsfw

False
bitrate int

The bitrate of this channel, only for voice

64000
user_limit int

The max users that can be in this channel, only for voice

0
rate_limit_per_user int

The time users must wait between sending messages

0
reason Union[str, NoneType, naff.client.const.Missing]

The reason for creating this channel

Missing

Returns:

Type Description
TYPE_GUILD_CHANNEL

The newly created channel.

Source code in naff/models/discord/channel.py
async def create_channel(
    self,
    channel_type: Union[ChannelTypes, int],
    name: str,
    topic: Absent[Optional[str]] = MISSING,
    position: Absent[Optional[int]] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    nsfw: bool = False,
    bitrate: int = 64000,
    user_limit: int = 0,
    rate_limit_per_user: int = 0,
    reason: Absent[Optional[str]] = MISSING,
) -> "TYPE_GUILD_CHANNEL":
    """
    Create a guild channel within this category, allows for explicit channel type setting.

    Args:
        channel_type: The type of channel to create
        name: The name of the channel
        topic: The topic of the channel
        position: The position of the channel in the channel list
        permission_overwrites: Permission overwrites to apply to the channel
        nsfw: Should this channel be marked nsfw
        bitrate: The bitrate of this channel, only for voice
        user_limit: The max users that can be in this channel, only for voice
        rate_limit_per_user: The time users must wait between sending messages
        reason: The reason for creating this channel

    Returns:
        The newly created channel.

    """
    return await self.guild.create_channel(
        channel_type=channel_type,
        name=name,
        topic=topic,
        position=position,
        permission_overwrites=permission_overwrites,
        category=self.id,
        nsfw=nsfw,
        bitrate=bitrate,
        user_limit=user_limit,
        rate_limit_per_user=rate_limit_per_user,
        reason=reason,
    )

async method create_text_channel(self, name, topic, position, permission_overwrites, nsfw, rate_limit_per_user, reason)

Create a text channel in this guild within this category.

Parameters:

Name Type Description Default
name str

The name of the channel

required
topic Union[str, NoneType, naff.client.const.Missing]

The topic of the channel

Missing
position Union[int, NoneType, naff.client.const.Missing]

The position of the channel in the channel list

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

Permission overwrites to apply to the channel

Missing
nsfw bool

Should this channel be marked nsfw

False
rate_limit_per_user int

The time users must wait between sending messages

0
reason Union[str, NoneType, naff.client.const.Missing]

The reason for creating this channel

Missing

Returns:

Type Description
GuildText

The newly created text channel.

Source code in naff/models/discord/channel.py
async def create_text_channel(
    self,
    name: str,
    topic: Absent[Optional[str]] = MISSING,
    position: Absent[Optional[int]] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    nsfw: bool = False,
    rate_limit_per_user: int = 0,
    reason: Absent[Optional[str]] = MISSING,
) -> "GuildText":
    """
    Create a text channel in this guild within this category.

    Args:
        name: The name of the channel
        topic: The topic of the channel
        position: The position of the channel in the channel list
        permission_overwrites: Permission overwrites to apply to the channel
        nsfw: Should this channel be marked nsfw
        rate_limit_per_user: The time users must wait between sending messages
        reason: The reason for creating this channel

    Returns:
       The newly created text channel.

    """
    return await self.create_channel(
        channel_type=ChannelTypes.GUILD_TEXT,
        name=name,
        topic=topic,
        position=position,
        permission_overwrites=permission_overwrites,
        nsfw=nsfw,
        rate_limit_per_user=rate_limit_per_user,
        reason=reason,
    )

async method create_news_channel(self, name, topic, position, permission_overwrites, nsfw, reason)

Create a news channel in this guild within this category.

Parameters:

Name Type Description Default
name str

The name of the channel

required
topic Union[str, NoneType, naff.client.const.Missing]

The topic of the channel

Missing
position Union[int, NoneType, naff.client.const.Missing]

The position of the channel in the channel list

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

Permission overwrites to apply to the channel

Missing
nsfw bool

Should this channel be marked nsfw

False
reason Union[str, NoneType, naff.client.const.Missing]

The reason for creating this channel

Missing

Returns:

Type Description
GuildNews

The newly created news channel.

Source code in naff/models/discord/channel.py
async def create_news_channel(
    self,
    name: str,
    topic: Absent[Optional[str]] = MISSING,
    position: Absent[Optional[int]] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    nsfw: bool = False,
    reason: Absent[Optional[str]] = MISSING,
) -> "GuildNews":
    """
    Create a news channel in this guild within this category.

    Args:
        name: The name of the channel
        topic: The topic of the channel
        position: The position of the channel in the channel list
        permission_overwrites: Permission overwrites to apply to the channel
        nsfw: Should this channel be marked nsfw
        reason: The reason for creating this channel

    Returns:
       The newly created news channel.

    """
    return await self.create_channel(
        channel_type=ChannelTypes.GUILD_NEWS,
        name=name,
        topic=topic,
        position=position,
        permission_overwrites=permission_overwrites,
        nsfw=nsfw,
        reason=reason,
    )

async method create_voice_channel(self, name, topic, position, permission_overwrites, nsfw, bitrate, user_limit, reason)

Create a guild voice channel within this category.

Parameters:

Name Type Description Default
name str

The name of the channel

required
topic Union[str, NoneType, naff.client.const.Missing]

The topic of the channel

Missing
position Union[int, NoneType, naff.client.const.Missing]

The position of the channel in the channel list

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

Permission overwrites to apply to the channel

Missing
nsfw bool

Should this channel be marked nsfw

False
bitrate int

The bitrate of this channel, only for voice

64000
user_limit int

The max users that can be in this channel, only for voice

0
reason Union[str, NoneType, naff.client.const.Missing]

The reason for creating this channel

Missing

Returns:

Type Description
GuildVoice

The newly created voice channel.

Source code in naff/models/discord/channel.py
async def create_voice_channel(
    self,
    name: str,
    topic: Absent[Optional[str]] = MISSING,
    position: Absent[Optional[int]] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    nsfw: bool = False,
    bitrate: int = 64000,
    user_limit: int = 0,
    reason: Absent[Optional[str]] = MISSING,
) -> "GuildVoice":
    """
    Create a guild voice channel within this category.

    Args:
        name: The name of the channel
        topic: The topic of the channel
        position: The position of the channel in the channel list
        permission_overwrites: Permission overwrites to apply to the channel
        nsfw: Should this channel be marked nsfw
        bitrate: The bitrate of this channel, only for voice
        user_limit: The max users that can be in this channel, only for voice
        reason: The reason for creating this channel

    Returns:
       The newly created voice channel.

    """
    return await self.create_channel(
        channel_type=ChannelTypes.GUILD_VOICE,
        name=name,
        topic=topic,
        position=position,
        permission_overwrites=permission_overwrites,
        nsfw=nsfw,
        bitrate=bitrate,
        user_limit=user_limit,
        reason=reason,
    )

async method create_stage_channel(self, name, topic, position, permission_overwrites, bitrate, user_limit, reason)

Create a guild stage channel within this category.

Parameters:

Name Type Description Default
name str

The name of the channel

required
topic Union[str, NoneType, naff.client.const.Missing]

The topic of the channel

Missing
position Union[int, NoneType, naff.client.const.Missing]

The position of the channel in the channel list

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

Permission overwrites to apply to the channel

Missing
bitrate int

The bitrate of this channel, only for voice

64000
user_limit int

The max users that can be in this channel, only for voice

0
reason Union[str, NoneType, naff.client.const.Missing]

The reason for creating this channel

Missing

Returns:

Type Description
GuildStageVoice

The newly created stage channel.

Source code in naff/models/discord/channel.py
async def create_stage_channel(
    self,
    name: str,
    topic: Absent[Optional[str]] = MISSING,
    position: Absent[Optional[int]] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    bitrate: int = 64000,
    user_limit: int = 0,
    reason: Absent[Optional[str]] = MISSING,
) -> "GuildStageVoice":
    """
    Create a guild stage channel within this category.

    Args:
        name: The name of the channel
        topic: The topic of the channel
        position: The position of the channel in the channel list
        permission_overwrites: Permission overwrites to apply to the channel
        bitrate: The bitrate of this channel, only for voice
        user_limit: The max users that can be in this channel, only for voice
        reason: The reason for creating this channel

    Returns:
        The newly created stage channel.

    """
    return await self.create_channel(
        channel_type=ChannelTypes.GUILD_STAGE_VOICE,
        name=name,
        topic=topic,
        position=position,
        permission_overwrites=permission_overwrites,
        bitrate=bitrate,
        user_limit=user_limit,
        reason=reason,
    )

attrs class GuildNews (GuildChannel, MessageableMixin, InvitableMixin, ThreadableMixin, WebhookMixin)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

topic Optional[str]

The channel topic (0-1024 characters)

Source code in naff/models/discord/channel.py
@define()
class GuildNews(GuildChannel, MessageableMixin, InvitableMixin, ThreadableMixin, WebhookMixin):
    topic: Optional[str] = field(default=None)
    """The channel topic (0-1024 characters)"""

    async def edit(
        self,
        name: Absent[str] = MISSING,
        position: Absent[int] = MISSING,
        permission_overwrites: Absent[
            Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
        ] = MISSING,
        parent_id: Absent[Snowflake_Type] = MISSING,
        nsfw: Absent[bool] = MISSING,
        topic: Absent[str] = MISSING,
        channel_type: Absent["ChannelTypes"] = MISSING,
        default_auto_archive_duration: Absent["AutoArchiveDuration"] = MISSING,
        reason: Absent[str] = MISSING,
        **kwargs,
    ) -> Union["GuildNews", "GuildText"]:
        """
        Edit the guild text channel.

        Args:
            name: 1-100 character channel name
            position: the position of the channel in the left-hand listing
            permission_overwrites: a list of PermissionOverwrite
            parent_id:  the parent category `Snowflake_Type` for the channel
            nsfw: whether the channel is nsfw
            topic: 0-1024 character channel topic
            channel_type: the type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature
            default_auto_archive_duration: optional AutoArchiveDuration
            reason: An optional reason for the audit log

        Returns:
            The edited channel.

        """
        return await super().edit(
            name=name,
            position=position,
            permission_overwrites=permission_overwrites,
            parent_id=parent_id,
            nsfw=nsfw,
            topic=topic,
            type=channel_type,
            default_auto_archive_duration=default_auto_archive_duration,
            reason=reason,
            **kwargs,
        )

    async def follow(self, webhook_channel_id: Snowflake_Type) -> None:
        """
        Follow this channel.

        Args:
            webhook_channel_id: The ID of the channel to post messages from this channel to

        """
        await self._client.http.follow_news_channel(self.id, webhook_channel_id)

    async def create_thread_from_message(
        self,
        name: str,
        message: Snowflake_Type,
        auto_archive_duration: AutoArchiveDuration = AutoArchiveDuration.ONE_DAY,
        reason: Absent[str] = None,
    ) -> "GuildNewsThread":
        """
        Creates a new news thread in this channel.

        Args:
            name: 1-100 character thread name.
            message: The message to connect this thread to.
            auto_archive_duration: Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.
            reason: The reason for creating this thread.

        Returns:
            The created public thread, if successful

        """
        return await self.create_thread(
            name=name,
            message=message,
            auto_archive_duration=auto_archive_duration,
            reason=reason,
        )

async inherited method send(self, content, embeds, embed, components, stickers, allowed_mentions, reply_to, files, file, tts, suppress_embeds, flags, delete_after, **kwargs)

Send a message.

Parameters:

Name Type Description Default
content Optional[str]

Message text content.

None
embeds Union[List[Union[Embed, dict]], Embed, dict]

Embedded rich content (up to 6000 characters).

None
embed Union[Embed, dict]

Embedded rich content (up to 6000 characters).

None
components Union[List[List[Union[BaseComponent, dict]]], List[Union[BaseComponent, dict]], BaseComponent, dict]

The components to include with the message.

None
stickers Union[List[Union[Sticker, Snowflake_Type]], Sticker, Snowflake_Type]

IDs of up to 3 stickers in the server to send in the message.

None
allowed_mentions Union[AllowedMentions, dict]

Allowed mentions for the message.

None
reply_to Union[MessageReference, Message, dict, Snowflake_Type]

Message to reference, must be from the same channel.

None
files Union[UPLOADABLE_TYPE, List[UPLOADABLE_TYPE]]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
file Optional[UPLOADABLE_TYPE]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
tts bool

Should this message use Text To Speech.

False
suppress_embeds bool

Should embeds be suppressed on this send

False
flags Union[int, MessageFlags]

Message flags to apply.

None
delete_after Optional[float]

Delete message after this many seconds.

None

Returns:

Type Description
Message

New message object that was sent.

Source code in naff/models/discord/channel.py
async def send(
    self,
    content: Optional[str] = None,
    embeds: Optional[Union[List[Union["Embed", dict]], Union["Embed", dict]]] = None,
    embed: Optional[Union["Embed", dict]] = None,
    components: Optional[
        Union[List[List[Union["BaseComponent", dict]]], List[Union["BaseComponent", dict]], "BaseComponent", dict]
    ] = None,
    stickers: Optional[Union[List[Union["Sticker", "Snowflake_Type"]], "Sticker", "Snowflake_Type"]] = None,
    allowed_mentions: Optional[Union["AllowedMentions", dict]] = None,
    reply_to: Optional[Union["MessageReference", "Message", dict, "Snowflake_Type"]] = None,
    files: Optional[Union["UPLOADABLE_TYPE", List["UPLOADABLE_TYPE"]]] = None,
    file: Optional["UPLOADABLE_TYPE"] = None,
    tts: bool = False,
    suppress_embeds: bool = False,
    flags: Optional[Union[int, "MessageFlags"]] = None,
    delete_after: Optional[float] = None,
    **kwargs,
) -> "Message":
    """
    Send a message.

    Args:
        content: Message text content.
        embeds: Embedded rich content (up to 6000 characters).
        embed: Embedded rich content (up to 6000 characters).
        components: The components to include with the message.
        stickers: IDs of up to 3 stickers in the server to send in the message.
        allowed_mentions: Allowed mentions for the message.
        reply_to: Message to reference, must be from the same channel.
        files: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        file: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        tts: Should this message use Text To Speech.
        suppress_embeds: Should embeds be suppressed on this send
        flags: Message flags to apply.
        delete_after: Delete message after this many seconds.

    Returns:
        New message object that was sent.

    """
    if not content and not (embeds or embed) and not (files or file) and not stickers:
        raise errors.EmptyMessageException(
            "You cannot send a message without any content, embeds, files, or stickers"
        )

    if suppress_embeds:
        if isinstance(flags, int):
            flags = MessageFlags(flags)
        flags = flags | MessageFlags.SUPPRESS_EMBEDS

    message_payload = models.discord.message.process_message_payload(
        content=content,
        embeds=embeds or embed,
        components=components,
        stickers=stickers,
        allowed_mentions=allowed_mentions,
        reply_to=reply_to,
        tts=tts,
        flags=flags,
        **kwargs,
    )

    message_data = await self._send_http_request(message_payload, files=files or file)
    if message_data:
        message = self._client.cache.place_message_data(message_data)
        if delete_after:
            await message.delete(delay=delete_after)
        return message

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

async inherited method fetch_message(self, message_id)

Fetch a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
Optional[models.Message]

The message object fetched. If the message is not found, returns None.

Source code in naff/models/discord/channel.py
async def fetch_message(self, message_id: Snowflake_Type) -> Optional["models.Message"]:
    """
    Fetch a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched. If the message is not found, returns None.

    """
    try:
        return await self._client.cache.fetch_message(self.id, message_id)
    except NotFound:
        return None

inherited method get_message(self, message_id)

Get a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
models.Message

The message object fetched.

Source code in naff/models/discord/channel.py
def get_message(self, message_id: Snowflake_Type) -> "models.Message":
    """
    Get a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched.

    """
    message_id = to_snowflake(message_id)
    message: "models.Message" = self._client.cache.get_message(self.id, message_id)
    return message

inherited method history(self, limit, before, after, around)

Get an async iterator for the history of this channel.

Parameters:

Name Type Description Default
limit

The maximum number of messages to return (set to 0 for no limit)

100
before Union[int, str, SnowflakeObject, SupportsInt]

get messages before this message ID

None
after Union[int, str, SnowflakeObject, SupportsInt]

get messages after this message ID

None
around Union[int, str, SnowflakeObject, SupportsInt]

get messages "around" this message ID

None
Example Usage:

1
2
3
4
5
async for message in channel.history(limit=0):
    if message.author.id == 174918559539920897:
        print("Found author's message")
        # ...
        break
or
1
2
3
history = channel.history(limit=250)
# Flatten the async iterator into a list
messages = await history.flatten()

Returns:

Type Description
ChannelHistory

ChannelHistory (AsyncIterator)

Source code in naff/models/discord/channel.py
def history(
    self,
    limit=100,
    before: Snowflake_Type = None,
    after: Snowflake_Type = None,
    around: Snowflake_Type = None,
) -> ChannelHistory:
    """
    Get an async iterator for the history of this channel.

    Args:
        limit: The maximum number of messages to return (set to 0 for no limit)
        before: get messages before this message ID
        after: get messages after this message ID
        around: get messages "around" this message ID

    ??? Hint "Example Usage:"
        ```python
        async for message in channel.history(limit=0):
            if message.author.id == 174918559539920897:
                print("Found author's message")
                # ...
                break
        ```
        or
        ```python
        history = channel.history(limit=250)
        # Flatten the async iterator into a list
        messages = await history.flatten()
        ```

    Returns:
        ChannelHistory (AsyncIterator)

    """
    return ChannelHistory(self, limit, before, after, around)

async inherited method fetch_messages(self, limit, around, before, after)

Fetch multiple messages from the channel.

Parameters:

Name Type Description Default
limit int

Max number of messages to return, default 50, max 100

50
around Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages around

Missing
before Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages before

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages after

Missing

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_messages(
    self,
    limit: int = 50,
    around: Snowflake_Type = MISSING,
    before: Snowflake_Type = MISSING,
    after: Snowflake_Type = MISSING,
) -> List["models.Message"]:
    """
    Fetch multiple messages from the channel.

    Args:
        limit: Max number of messages to return, default `50`, max `100`
        around: Message to get messages around
        before: Message to get messages before
        after: Message to get messages after

    Returns:
        A list of messages fetched.

    """
    if limit > 100:
        raise ValueError("You cannot fetch more than 100 messages at once.")

    if around:
        around = to_snowflake(around)
    elif before:
        before = to_snowflake(before)
    elif after:
        after = to_snowflake(after)

    messages_data = await self._client.http.get_channel_messages(self.id, limit, around, before, after)
    for m in messages_data:
        m["guild_id"] = self._guild_id

    return [self._client.cache.place_message_data(m) for m in messages_data]

async inherited method fetch_pinned_messages(self)

Fetch pinned messages from the channel.

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_pinned_messages(self) -> List["models.Message"]:
    """
    Fetch pinned messages from the channel.

    Returns:
        A list of messages fetched.

    """
    messages_data = await self._client.http.get_pinned_messages(self.id)
    return [self._client.cache.place_message_data(message_data) for message_data in messages_data]

async inherited method delete_messages(self, messages, reason)

Bulk delete messages from channel.

Parameters:

Name Type Description Default
messages List[Union[int, str, SnowflakeObject, SupportsInt, models.Message]]

List of messages or message IDs to delete.

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this action. Used for audit logs.

Missing
Source code in naff/models/discord/channel.py
async def delete_messages(
    self, messages: List[Union[Snowflake_Type, "models.Message"]], reason: Absent[Optional[str]] = MISSING
) -> None:
    """
    Bulk delete messages from channel.

    Args:
        messages: List of messages or message IDs to delete.
        reason: The reason for this action. Used for audit logs.

    """
    message_ids = [to_snowflake(message) for message in messages]
    # TODO Add check for min/max and duplicates.

    if len(message_ids) == 1:
        # bulk delete messages will throw a http error if only 1 message is passed
        await self.delete_message(message_ids[0], reason)
    else:
        await self._client.http.bulk_delete_messages(self.id, message_ids, reason)

async inherited method delete_message(self, message, reason)

Delete a single message from a channel.

Parameters:

Name Type Description Default
message Union[int, str, SnowflakeObject, SupportsInt, models.Message]

The message to delete

required
reason str

The reason for this action

None
Source code in naff/models/discord/channel.py
async def delete_message(self, message: Union[Snowflake_Type, "models.Message"], reason: str = None) -> None:
    """
    Delete a single message from a channel.

    Args:
        message: The message to delete
        reason: The reason for this action

    """
    message = to_snowflake(message)
    await self._client.http.delete_message(self.id, message, reason=reason)

async inherited method purge(self, deletion_limit, search_limit, predicate, avoid_loading_msg, before, after, around, reason)

Bulk delete messages within a channel. If a predicate is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the deletion_limit.

Example Usage:
1
2
3
# this will delete the last 20 messages sent by a user with the given ID
deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
await channel.send(f"{deleted} messages deleted")

Parameters:

Name Type Description Default
deletion_limit int

The target amount of messages to delete

50
search_limit int

How many messages to search through

100
predicate Callable[[models.Message], bool]

A function that returns True or False, and takes a message as an argument

Missing
avoid_loading_msg bool

Should the bot attempt to avoid deleting its own loading messages (recommended enabled)

True
before Union[int, str, SnowflakeObject, SupportsInt]

Search messages before this ID

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Search messages after this ID

Missing
around Union[int, str, SnowflakeObject, SupportsInt]

Search messages around this ID

Missing
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this deletion

Missing

Returns:

Type Description
int

The total amount of messages deleted

Source code in naff/models/discord/channel.py
async def purge(
    self,
    deletion_limit: int = 50,
    search_limit: int = 100,
    predicate: Callable[["models.Message"], bool] = MISSING,
    avoid_loading_msg: bool = True,
    before: Optional[Snowflake_Type] = MISSING,
    after: Optional[Snowflake_Type] = MISSING,
    around: Optional[Snowflake_Type] = MISSING,
    reason: Absent[Optional[str]] = MISSING,
) -> int:
    """
    Bulk delete messages within a channel. If a `predicate` is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the `deletion_limit`.

    ??? Hint "Example Usage:"
        ```python
        # this will delete the last 20 messages sent by a user with the given ID
        deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
        await channel.send(f"{deleted} messages deleted")
        ```

    Args:
        deletion_limit: The target amount of messages to delete
        search_limit: How many messages to search through
        predicate: A function that returns True or False, and takes a message as an argument
        avoid_loading_msg: Should the bot attempt to avoid deleting its own loading messages (recommended enabled)
        before: Search messages before this ID
        after: Search messages after this ID
        around: Search messages around this ID
        reason: The reason for this deletion

    Returns:
        The total amount of messages deleted

    """
    if not predicate:

        def predicate(m) -> bool:
            return True  # noqa

    to_delete = []

    # 1209600 14 days ago in seconds, 1420070400000 is used to convert to snowflake
    fourteen_days_ago = int((time.time() - 1209600) * 1000.0 - DISCORD_EPOCH) << 22
    async for message in self.history(limit=search_limit, before=before, after=after, around=around):
        if deletion_limit != 0 and len(to_delete) == deletion_limit:
            break

        if not predicate(message):
            # fails predicate
            continue

        if avoid_loading_msg:
            if message._author_id == self._client.user.id and MessageFlags.LOADING in message.flags:
                continue

        if message.id < fourteen_days_ago:
            # message is too old to be purged
            continue

        to_delete.append(message.id)

    count = len(to_delete)
    while len(to_delete):
        iteration = [to_delete.pop() for i in range(min(100, len(to_delete)))]
        await self.delete_messages(iteration, reason=reason)
    return count

async inherited method trigger_typing(self)

Trigger a typing animation in this channel.

Source code in naff/models/discord/channel.py
async def trigger_typing(self) -> None:
    """Trigger a typing animation in this channel."""
    await self._client.http.trigger_typing_indicator(self.id)

inherited property readonly typing: Typing

A context manager to send a typing state to a given channel as long as long as the wrapped operation takes.

async inherited method create_invite(self, max_age, max_uses, temporary, unique, target_type, target_user, target_application, reason)

Creates a new channel invite.

Parameters:

Name Type Description Default
max_age int

Max age of invite in seconds, default 86400 (24 hours).

86400
max_uses int

Max uses of invite, default 0.

0
temporary bool

Grants temporary membership, default False.

False
unique bool

Invite is unique, default false.

False
target_type Optional[naff.models.discord.enums.InviteTargetTypes]

Target type for streams and embedded applications.

None
target_user Union[int, str, SnowflakeObject, SupportsInt, models.User]

Target User ID for Stream target type.

None
target_application Union[int, str, SnowflakeObject, SupportsInt, models.Application]

Target Application ID for Embedded App target type.

None
reason Optional[str]

The reason for creating this invite.

None

Returns:

Type Description
models.Invite

Newly created Invite object.

Source code in naff/models/discord/channel.py
async def create_invite(
    self,
    max_age: int = 86400,
    max_uses: int = 0,
    temporary: bool = False,
    unique: bool = False,
    target_type: Optional[InviteTargetTypes] = None,
    target_user: Optional[Union[Snowflake_Type, "models.User"]] = None,
    target_application: Optional[Union[Snowflake_Type, "models.Application"]] = None,
    reason: Optional[str] = None,
) -> "models.Invite":
    """
    Creates a new channel invite.

    Args:
        max_age: Max age of invite in seconds, default 86400 (24 hours).
        max_uses: Max uses of invite, default 0.
        temporary: Grants temporary membership, default False.
        unique: Invite is unique, default false.
        target_type: Target type for streams and embedded applications.
        target_user: Target User ID for Stream target type.
        target_application: Target Application ID for Embedded App target type.
        reason: The reason for creating this invite.

    Returns:
        Newly created Invite object.

    """
    if target_type:
        if target_type == InviteTargetTypes.STREAM and not target_user:
            raise ValueError("Stream target must include target user id.")
        elif target_type == InviteTargetTypes.EMBEDDED_APPLICATION and not target_application:
            raise ValueError("Embedded Application target must include target application id.")

    if target_user and target_application:
        raise ValueError("Invite target must be either User or Embedded Application, not both.")
    elif target_user:
        target_user = to_snowflake(target_user)
        target_type = InviteTargetTypes.STREAM
    elif target_application:
        target_application = to_snowflake(target_application)
        target_type = InviteTargetTypes.EMBEDDED_APPLICATION

    invite_data = await self._client.http.create_channel_invite(
        self.id, max_age, max_uses, temporary, unique, target_type, target_user, target_application, reason
    )
    return models.Invite.from_dict(invite_data, self._client)

async inherited method fetch_invites(self)

Fetches all invites (with invite metadata) for the channel.

Returns:

Type Description
List[models.Invite]

List of Invite objects.

Source code in naff/models/discord/channel.py
async def fetch_invites(self) -> List["models.Invite"]:
    """
    Fetches all invites (with invite metadata) for the channel.

    Returns:
        List of Invite objects.

    """
    invites_data = await self._client.http.get_channel_invites(self.id)
    return models.Invite.from_list(invites_data, self._client)

async inherited method create_thread(self, name, message, thread_type, invitable, auto_archive_duration, reason)

Creates a new thread in this channel. If a message is provided, it will be used as the initial message.

Parameters:

Name Type Description Default
name str

1-100 character thread name

required
message Union[int, str, SnowflakeObject, SupportsInt, naff.client.const.Missing]

The message to connect this thread to. Required for news channel.

Missing
thread_type Union[naff.models.discord.enums.ChannelTypes, naff.client.const.Missing]

Is the thread private or public. Not applicable to news channel, it will always be GUILD_NEWS_THREAD.

Missing
invitable Union[bool, naff.client.const.Missing]

whether non-moderators can add other non-moderators to a thread. Only applicable when creating a private thread.

Missing
auto_archive_duration AutoArchiveDuration

Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.

<AutoArchiveDuration.ONE_DAY: 1440>
reason Union[str, naff.client.const.Missing]

The reason for creating this thread.

None

Returns:

Type Description
TYPE_THREAD_CHANNEL

The created thread, if successful

Source code in naff/models/discord/channel.py
async def create_thread(
    self,
    name: str,
    message: Absent[Snowflake_Type] = MISSING,
    thread_type: Absent[ChannelTypes] = MISSING,
    invitable: Absent[bool] = MISSING,
    auto_archive_duration: AutoArchiveDuration = AutoArchiveDuration.ONE_DAY,
    reason: Absent[str] = None,
) -> "TYPE_THREAD_CHANNEL":
    """
    Creates a new thread in this channel. If a message is provided, it will be used as the initial message.

    Args:
        name: 1-100 character thread name
        message: The message to connect this thread to. Required for news channel.
        thread_type: Is the thread private or public. Not applicable to news channel, it will always be GUILD_NEWS_THREAD.
        invitable: whether non-moderators can add other non-moderators to a thread. Only applicable when creating a private thread.
        auto_archive_duration: Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.
        reason: The reason for creating this thread.

    Returns:
        The created thread, if successful

    """
    if self.type == ChannelTypes.GUILD_NEWS and not message:
        raise ValueError("News channel must include message to create thread from.")

    elif message and (thread_type or invitable):
        raise ValueError("Message cannot be used with thread_type or invitable.")

    elif thread_type != ChannelTypes.GUILD_PRIVATE_THREAD and invitable:
        raise ValueError("Invitable only applies to private threads.")

    thread_data = await self._client.http.create_thread(
        channel_id=self.id,
        name=name,
        thread_type=thread_type,
        invitable=invitable,
        auto_archive_duration=auto_archive_duration,
        message_id=to_optional_snowflake(message),
        reason=reason,
    )
    return self._client.cache.place_channel_data(thread_data)

async inherited method fetch_public_archived_threads(self, limit, before)

Get a ThreadList of archived public threads available in this channel.

Parameters:

Name Type Description Default
limit int

optional maximum number of threads to return

None
before Optional[models.Timestamp]

Returns threads before this timestamp

None

Returns:

Type Description
models.ThreadList

A ThreadList of archived threads.

Source code in naff/models/discord/channel.py
async def fetch_public_archived_threads(
    self, limit: int = None, before: Optional["models.Timestamp"] = None
) -> "models.ThreadList":
    """
    Get a `ThreadList` of archived **public** threads available in this channel.

    Args:
        limit: optional maximum number of threads to return
        before: Returns threads before this timestamp

    Returns:
        A `ThreadList` of archived threads.

    """
    threads_data = await self._client.http.list_public_archived_threads(
        channel_id=self.id, limit=limit, before=before
    )
    threads_data["id"] = self.id
    return models.ThreadList.from_dict(threads_data, self._client)

async inherited method fetch_private_archived_threads(self, limit, before)

Get a ThreadList of archived private threads available in this channel.

Parameters:

Name Type Description Default
limit int

optional maximum number of threads to return

None
before Optional[models.Timestamp]

Returns threads before this timestamp

None

Returns:

Type Description
models.ThreadList

A ThreadList of archived threads.

Source code in naff/models/discord/channel.py
async def fetch_private_archived_threads(
    self, limit: int = None, before: Optional["models.Timestamp"] = None
) -> "models.ThreadList":
    """
    Get a `ThreadList` of archived **private** threads available in this channel.

    Args:
        limit: optional maximum number of threads to return
        before: Returns threads before this timestamp

    Returns:
        A `ThreadList` of archived threads.

    """
    threads_data = await self._client.http.list_private_archived_threads(
        channel_id=self.id, limit=limit, before=before
    )
    threads_data["id"] = self.id
    return models.ThreadList.from_dict(threads_data, self._client)

async inherited method fetch_archived_threads(self, limit, before)

Get a ThreadList of archived threads available in this channel.

Parameters:

Name Type Description Default
limit int

optional maximum number of threads to return

None
before Optional[models.Timestamp]

Returns threads before this timestamp

None

Returns:

Type Description
models.ThreadList

A ThreadList of archived threads.

Source code in naff/models/discord/channel.py
async def fetch_archived_threads(
    self, limit: int = None, before: Optional["models.Timestamp"] = None
) -> "models.ThreadList":
    """
    Get a `ThreadList` of archived threads available in this channel.

    Args:
        limit: optional maximum number of threads to return
        before: Returns threads before this timestamp

    Returns:
        A `ThreadList` of archived threads.

    """
    threads_data = await self._client.http.list_private_archived_threads(
        channel_id=self.id, limit=limit, before=before
    )
    threads_data.update(
        await self._client.http.list_public_archived_threads(channel_id=self.id, limit=limit, before=before)
    )
    threads_data["id"] = self.id
    return models.ThreadList.from_dict(threads_data, self._client)

async inherited method fetch_joined_private_archived_threads(self, limit, before)

Get a ThreadList of threads the bot is a participant of in this channel.

Parameters:

Name Type Description Default
limit int

optional maximum number of threads to return

None
before Optional[models.Timestamp]

Returns threads before this timestamp

None

Returns:

Type Description
models.ThreadList

A ThreadList of threads the bot is a participant of.

Source code in naff/models/discord/channel.py
async def fetch_joined_private_archived_threads(
    self, limit: int = None, before: Optional["models.Timestamp"] = None
) -> "models.ThreadList":
    """
    Get a `ThreadList` of threads the bot is a participant of in this channel.

    Args:
        limit: optional maximum number of threads to return
        before: Returns threads before this timestamp

    Returns:
        A `ThreadList` of threads the bot is a participant of.

    """
    threads_data = await self._client.http.list_joined_private_archived_threads(
        channel_id=self.id, limit=limit, before=before
    )
    threads_data["id"] = self.id
    return models.ThreadList.from_dict(threads_data, self._client)

async inherited method fetch_active_threads(self)

Gets all active threads in the channel, including public and private threads.

Returns:

Type Description
models.ThreadList

A ThreadList of active threads.

Source code in naff/models/discord/channel.py
async def fetch_active_threads(self) -> "models.ThreadList":
    """
    Gets all active threads in the channel, including public and private threads.

    Returns:
        A `ThreadList` of active threads.

    """
    threads_data = await self._client.http.list_active_threads(guild_id=self._guild_id)

    # delete the items where the channel_id does not match
    removed_thread_ids = []
    cleaned_threads_data_threads = []
    for thread in threads_data["threads"]:
        if thread["parent_id"] == str(self.id):
            cleaned_threads_data_threads.append(thread)
        else:
            removed_thread_ids.append(thread["id"])
    threads_data["threads"] = cleaned_threads_data_threads

    # delete the member data which is not needed
    cleaned_member_data_threads = []
    for thread_member in threads_data["members"]:
        if thread_member["id"] not in removed_thread_ids:
            cleaned_member_data_threads.append(thread_member)
    threads_data["members"] = cleaned_member_data_threads

    return models.ThreadList.from_dict(threads_data, self._client)

async inherited method fetch_all_threads(self)

Gets all threads in the channel. Active and archived, including public and private threads.

Returns:

Type Description
models.ThreadList

A ThreadList of all threads.

Source code in naff/models/discord/channel.py
async def fetch_all_threads(self) -> "models.ThreadList":
    """
    Gets all threads in the channel. Active and archived, including public and private threads.

    Returns:
        A `ThreadList` of all threads.

    """
    threads = await self.fetch_active_threads()

    # update that data with the archived threads
    archived_threads = await self.fetch_archived_threads()
    threads.threads.extend(archived_threads.threads)
    threads.members.extend(archived_threads.members)

    return threads

async inherited method create_webhook(self, name, avatar)

Create a webhook in this channel.

Parameters:

Name Type Description Default
name str

The name of the webhook

required
avatar Union[naff.models.discord.file.File, io.IOBase, BinaryIO, pathlib.Path, str, naff.client.const.Missing]

An optional default avatar image to use

Missing

Returns:

Type Description
models.Webhook

The created webhook object

Exceptions:

Type Description
ValueError

If you try to name the webhook "Clyde"

Source code in naff/models/discord/channel.py
async def create_webhook(self, name: str, avatar: Absent[UPLOADABLE_TYPE] = MISSING) -> "models.Webhook":
    """
    Create a webhook in this channel.

    Args:
        name: The name of the webhook
        avatar: An optional default avatar image to use

    Returns:
        The created webhook object

    Raises:
        ValueError: If you try to name the webhook "Clyde"

    """
    return await models.Webhook.create(self._client, self, name, avatar)  # type: ignore

async inherited method delete_webhook(self, webhook)

Delete a given webhook in this channel.

Parameters:

Name Type Description Default
webhook models.Webhook

The webhook to delete

required
Source code in naff/models/discord/channel.py
async def delete_webhook(self, webhook: "models.Webhook") -> None:
    """
    Delete a given webhook in this channel.

    Args:
        webhook: The webhook to delete

    """
    return await webhook.delete()

async inherited method fetch_webhooks(self)

Fetches all the webhooks for this channel.

Returns:

Type Description
List[models.Webhook]

List of webhook objects

Source code in naff/models/discord/channel.py
async def fetch_webhooks(self) -> List["models.Webhook"]:
    """
    Fetches all the webhooks for this channel.

    Returns:
        List of webhook objects

    """
    resp = await self._client.http.get_channel_webhooks(self.id)
    return [models.Webhook.from_dict(d, self._client) for d in resp]

inherited property readonly mention: str

Returns a string that would mention the channel.

async inherited method delete(self, reason)

Delete this channel.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for deleting this channel

Missing
Source code in naff/models/discord/channel.py
async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Delete this channel.

    Args:
        reason: The reason for deleting this channel

    """
    await self._client.http.delete_channel(self.id, reason)

inherited property readonly guild: models.Guild

The guild this channel belongs to.

inherited property readonly category: Optional[GuildCategory]

The parent category of this channel.

inherited property readonly gui_position: int

The position of this channel in the Discord interface.

inherited method permissions_for(self, instance)

Calculates permissions for an instance

Parameters:

Name Type Description Default
instance Union[int, str, SnowflakeObject, SupportsInt]

Member or Role instance (or its ID)

required

Returns:

Type Description
Permissions

Permissions data

Exceptions:

Type Description
ValueError

If could not find any member or role by given ID

RuntimeError

If given instance is from another guild

Source code in naff/models/discord/channel.py
def permissions_for(self, instance: Snowflake_Type) -> Permissions:
    """
    Calculates permissions for an instance

    Args:
        instance: Member or Role instance (or its ID)

    Returns:
        Permissions data

    Raises:
        ValueError: If could not find any member or role by given ID
        RuntimeError: If given instance is from another guild

    """
    if (is_member := isinstance(instance, models.Member)) or isinstance(instance, models.Role):
        if instance._guild_id != self._guild_id:
            raise RuntimeError("Unable to calculate permissions for the instance from different guild")

        if is_member:
            return instance.channel_permissions(self)

        else:
            permissions = instance.permissions

            for overwrite in self.permission_overwrites:
                if overwrite.id == instance.id:
                    permissions &= ~overwrite.deny
                    permissions |= overwrite.allow
                    break

            return permissions

    else:
        instance = to_snowflake(instance)
        guild = self.guild
        instance = guild.get_member(instance) or guild.get_role(instance)

        if not instance:
            raise ValueError("Unable to find any member or role by given instance ID")

        return self.permissions_for(instance)

async inherited method add_permission(self, target, type, allow, deny, reason)

Add a permission to this channel.

Parameters:

Name Type Description Default
target Union[PermissionOverwrite, models.Role, models.User, models.Member, Snowflake_Type]

The updated PermissionOverwrite object, or the Role or User object/id to update

required
type Optional[OverwriteTypes]

The type of permission overwrite. Only applicable if target is an id

None
allow Union[List[Permissions], int]

List of permissions to allow. Only applicable if target is not an PermissionOverwrite object

None
deny Union[List[Permissions], int]

List of permissions to deny. Only applicable if target is not an PermissionOverwrite object

None
reason Optional[str]

The reason for this change

None

Exceptions:

Type Description
ValueError

Invalid target for permission

Source code in naff/models/discord/channel.py
async def add_permission(
    self,
    target: Union["PermissionOverwrite", "models.Role", "models.User", "models.Member", "Snowflake_Type"],
    type: Optional["OverwriteTypes"] = None,
    allow: Optional[List["Permissions"] | int] = None,
    deny: Optional[List["Permissions"] | int] = None,
    reason: Optional[str] = None,
) -> None:
    """
    Add a permission to this channel.

    Args:
        target: The updated PermissionOverwrite object, or the Role or User object/id to update
        type: The type of permission overwrite. Only applicable if target is an id
        allow: List of permissions to allow. Only applicable if target is not an PermissionOverwrite object
        deny: List of permissions to deny. Only applicable if target is not an PermissionOverwrite object
        reason: The reason for this change

    Raises:
        ValueError: Invalid target for permission

    """
    allow = allow or []
    deny = deny or []
    if not isinstance(target, PermissionOverwrite):
        if isinstance(target, (models.User, models.Member)):
            target = target.id
            type = OverwriteTypes.MEMBER
        elif isinstance(target, models.Role):
            target = target.id
            type = OverwriteTypes.ROLE
        elif type and isinstance(target, Snowflake_Type):
            target = to_snowflake(target)
        else:
            raise ValueError("Invalid target and/or type for permission")
        overwrite = PermissionOverwrite(id=target, type=type, allow=Permissions.NONE, deny=Permissions.NONE)
        if isinstance(allow, int):
            overwrite.allow |= allow
        else:
            for perm in allow:
                overwrite.allow |= perm
        if isinstance(deny, int):
            overwrite.deny |= deny
        else:
            for perm in deny:
                overwrite.deny |= perm
    else:
        overwrite = target

    if exists := get(self.permission_overwrites, id=overwrite.id, type=overwrite.type):
        exists.deny = (exists.deny | overwrite.deny) & ~overwrite.allow
        exists.allow = (exists.allow | overwrite.allow) & ~overwrite.deny
        await self.edit_permission(exists, reason)
    else:
        permission_overwrites = self.permission_overwrites
        permission_overwrites.append(overwrite)
        await self.edit(permission_overwrites=permission_overwrites)

async inherited method edit_permission(self, overwrite, reason)

Edit the permissions for this channel.

Parameters:

Name Type Description Default
overwrite PermissionOverwrite

The permission overwrite to apply

required
reason Optional[str]

The reason for this change

None
Source code in naff/models/discord/channel.py
async def edit_permission(self, overwrite: PermissionOverwrite, reason: Optional[str] = None) -> None:
    """
    Edit the permissions for this channel.

    Args:
        overwrite: The permission overwrite to apply
        reason: The reason for this change
    """
    await self._client.http.edit_channel_permission(
        self.id, overwrite.id, overwrite.allow, overwrite.deny, overwrite.type, reason
    )

async inherited method delete_permission(self, target, reason)

Delete a permission overwrite for this channel.

Parameters:

Name Type Description Default
target Union[PermissionOverwrite, models.Role, models.User]

The permission overwrite to delete

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this change

Missing
Source code in naff/models/discord/channel.py
async def delete_permission(
    self,
    target: Union["PermissionOverwrite", "models.Role", "models.User"],
    reason: Absent[Optional[str]] = MISSING,
) -> None:
    """
    Delete a permission overwrite for this channel.

    Args:
        target: The permission overwrite to delete
        reason: The reason for this change

    """
    target = to_snowflake(target)
    await self._client.http.delete_channel_permission(self.id, target, reason)

async inherited method set_permission(self, target, *, add_reactions, administrator, attach_files, ban_members, change_nickname, connect, create_instant_invite, deafen_members, embed_links, kick_members, manage_channels, manage_emojis_and_stickers, manage_events, manage_guild, manage_messages, manage_nicknames, manage_roles, manage_threads, manage_webhooks, mention_everyone, moderate_members, move_members, mute_members, priority_speaker, read_message_history, request_to_speak, send_messages, send_messages_in_threads, send_tts_messages, speak, start_embedded_activities, stream, use_application_commands, use_external_emojis, use_external_stickers, use_private_threads, use_public_threads, use_vad, view_audit_log, view_channel, view_guild_insights, reason)

Set the Permission Overwrites for a given target.

Parameters:

Name Type Description Default
target Union[models.Role, models.Member, models.User]

The target to set permission overwrites for

required
add_reactions bool | None

Allows for the addition of reactions to messages

None
administrator bool | None

Allows all permissions and bypasses channel permission overwrites

None
attach_files bool | None

Allows for uploading images and files

None
ban_members bool | None

Allows banning members

None
change_nickname bool | None

Allows for modification of own nickname

None
connect bool | None

Allows for joining of a voice channel

None
create_instant_invite bool | None

Allows creation of instant invites

None
deafen_members bool | None

Allows for deafening of members in a voice channel

None
embed_links bool | None

Links sent by users with this permission will be auto-embedded

None
kick_members bool | None

Allows kicking members

None
manage_channels bool | None

Allows management and editing of channels

None
manage_emojis_and_stickers bool | None

Allows management and editing of emojis and stickers

None
manage_events bool | None

Allows for creating, editing, and deleting scheduled events

None
manage_guild bool | None

Allows management and editing of the guild

None
manage_messages bool | None

Allows for deletion of other users messages

None
manage_nicknames bool | None

Allows for modification of other users nicknames

None
manage_roles bool | None

Allows management and editing of roles

None
manage_threads bool | None

Allows for deleting and archiving threads, and viewing all private threads

None
manage_webhooks bool | None

Allows management and editing of webhooks

None
mention_everyone bool | None

Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all online users in a channel

None
moderate_members bool | None

Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels

None
move_members bool | None

Allows for moving of members between voice channels

None
mute_members bool | None

Allows for muting members in a voice channel

None
priority_speaker bool | None

Allows for using priority speaker in a voice channel

None
read_message_history bool | None

Allows for reading of message history

None
request_to_speak bool | None

Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)

None
send_messages bool | None

Allows for sending messages in a channel (does not allow sending messages in threads)

None
send_messages_in_threads bool | None

Allows for sending messages in threads

None
send_tts_messages bool | None

Allows for sending of /tts messages

None
speak bool | None

Allows for speaking in a voice channel

None
start_embedded_activities bool | None

Allows for using Activities (applications with the EMBEDDED flag) in a voice channel

None
stream bool | None

Allows the user to go live

None
use_application_commands bool | None

Allows members to use application commands, including slash commands and context menu commands

None
use_external_emojis bool | None

Allows the usage of custom emojis from other servers

None
use_external_stickers bool | None

Allows the usage of custom stickers from other servers

None
use_private_threads bool | None

Allows for creating private threads

None
use_public_threads bool | None

Allows for creating public and announcement threads

None
use_vad bool | None

Allows for using voice-activity-detection in a voice channel

None
view_audit_log bool | None

Allows for viewing of audit logs

None
view_channel bool | None

Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels

None
view_guild_insights bool | None

Allows for viewing guild insights

None
reason str

The reason for creating this overwrite

None
Source code in naff/models/discord/channel.py
async def set_permission(
    self,
    target: Union["models.Role", "models.Member", "models.User"],
    *,
    add_reactions: bool | None = None,
    administrator: bool | None = None,
    attach_files: bool | None = None,
    ban_members: bool | None = None,
    change_nickname: bool | None = None,
    connect: bool | None = None,
    create_instant_invite: bool | None = None,
    deafen_members: bool | None = None,
    embed_links: bool | None = None,
    kick_members: bool | None = None,
    manage_channels: bool | None = None,
    manage_emojis_and_stickers: bool | None = None,
    manage_events: bool | None = None,
    manage_guild: bool | None = None,
    manage_messages: bool | None = None,
    manage_nicknames: bool | None = None,
    manage_roles: bool | None = None,
    manage_threads: bool | None = None,
    manage_webhooks: bool | None = None,
    mention_everyone: bool | None = None,
    moderate_members: bool | None = None,
    move_members: bool | None = None,
    mute_members: bool | None = None,
    priority_speaker: bool | None = None,
    read_message_history: bool | None = None,
    request_to_speak: bool | None = None,
    send_messages: bool | None = None,
    send_messages_in_threads: bool | None = None,
    send_tts_messages: bool | None = None,
    speak: bool | None = None,
    start_embedded_activities: bool | None = None,
    stream: bool | None = None,
    use_application_commands: bool | None = None,
    use_external_emojis: bool | None = None,
    use_external_stickers: bool | None = None,
    use_private_threads: bool | None = None,
    use_public_threads: bool | None = None,
    use_vad: bool | None = None,
    view_audit_log: bool | None = None,
    view_channel: bool | None = None,
    view_guild_insights: bool | None = None,
    reason: str = None,
) -> None:
    """
    Set the Permission Overwrites for a given target.

    Args:
        target: The target to set permission overwrites for
        add_reactions: Allows for the addition of reactions to messages
        administrator: Allows all permissions and bypasses channel permission overwrites
        attach_files: Allows for uploading images and files
        ban_members: Allows banning members
        change_nickname: Allows for modification of own nickname
        connect: Allows for joining of a voice channel
        create_instant_invite: Allows creation of instant invites
        deafen_members: Allows for deafening of members in a voice channel
        embed_links: Links sent by users with this permission will be auto-embedded
        kick_members: Allows kicking members
        manage_channels: Allows management and editing of channels
        manage_emojis_and_stickers: Allows management and editing of emojis and stickers
        manage_events: Allows for creating, editing, and deleting scheduled events
        manage_guild: Allows management and editing of the guild
        manage_messages: Allows for deletion of other users messages
        manage_nicknames: Allows for modification of other users nicknames
        manage_roles: Allows management and editing of roles
        manage_threads: Allows for deleting and archiving threads, and viewing all private threads
        manage_webhooks: Allows management and editing of webhooks
        mention_everyone: Allows for using the `@everyone` tag to notify all users in a channel, and the `@here` tag to notify all online users in a channel
        moderate_members: Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels
        move_members: Allows for moving of members between voice channels
        mute_members: Allows for muting members in a voice channel
        priority_speaker: Allows for using priority speaker in a voice channel
        read_message_history: Allows for reading of message history
        request_to_speak: Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)
        send_messages:  Allows for sending messages in a channel (does not allow sending messages in threads)
        send_messages_in_threads: Allows for sending messages in threads
        send_tts_messages:  Allows for sending of `/tts` messages
        speak: Allows for speaking in a voice channel
        start_embedded_activities: Allows for using Activities (applications with the `EMBEDDED` flag) in a voice channel
        stream: Allows the user to go live
        use_application_commands: Allows members to use application commands, including slash commands and context menu commands
        use_external_emojis: Allows the usage of custom emojis from other servers
        use_external_stickers: Allows the usage of custom stickers from other servers
        use_private_threads: Allows for creating private threads
        use_public_threads:  Allows for creating public and announcement threads
        use_vad: Allows for using voice-activity-detection in a voice channel
        view_audit_log: Allows for viewing of audit logs
        view_channel: Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels
        view_guild_insights: Allows for viewing guild insights
        reason: The reason for creating this overwrite
    """
    overwrite = PermissionOverwrite.for_target(target)

    allow: Permissions = Permissions.NONE
    deny: Permissions = Permissions.NONE

    for name, val in locals().items():
        if isinstance(val, bool):
            if val:
                allow |= getattr(Permissions, name.upper())
            else:
                deny |= getattr(Permissions, name.upper())

    overwrite.add_allows(allow)
    overwrite.add_denies(deny)

    await self.edit_permission(overwrite, reason)

inherited property readonly members: List[models.Member]

Returns a list of members that can see this channel.

inherited property readonly bots: List[models.Member]

Returns a list of bots that can see this channel.

inherited property readonly humans: List[models.Member]

Returns a list of humans that can see this channel.

async inherited method clone(self, name, reason)

Clone this channel and create a new one.

Parameters:

Name Type Description Default
name Optional[str]

The name of the new channel. Defaults to the current name

None
reason Union[str, NoneType, naff.client.const.Missing]

The reason for creating this channel

Missing

Returns:

Type Description
TYPE_GUILD_CHANNEL

The newly created channel.

Source code in naff/models/discord/channel.py
async def clone(self, name: Optional[str] = None, reason: Absent[Optional[str]] = MISSING) -> "TYPE_GUILD_CHANNEL":
    """
    Clone this channel and create a new one.

    Args:
        name: The name of the new channel. Defaults to the current name
        reason: The reason for creating this channel

    Returns:
        The newly created channel.

    """
    return await self.guild.create_channel(
        channel_type=self.type,
        name=name if name else self.name,
        topic=getattr(self, "topic", MISSING),
        position=self.position,
        permission_overwrites=self.permission_overwrites,
        category=self.category,
        nsfw=self.nsfw,
        bitrate=getattr(self, "bitrate", 64000),
        user_limit=getattr(self, "user_limit", 0),
        rate_limit_per_user=getattr(self, "rate_limit_per_user", 0),
        reason=reason,
    )

async method edit(self, name, position, permission_overwrites, parent_id, nsfw, topic, channel_type, default_auto_archive_duration, reason, **kwargs)

Edit the guild text channel.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

1-100 character channel name

Missing
position Union[int, naff.client.const.Missing]

the position of the channel in the left-hand listing

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

a list of PermissionOverwrite

Missing
parent_id Union[int, str, SnowflakeObject, SupportsInt, naff.client.const.Missing]

the parent category Snowflake_Type for the channel

Missing
nsfw Union[bool, naff.client.const.Missing]

whether the channel is nsfw

Missing
topic Union[str, naff.client.const.Missing]

0-1024 character channel topic

Missing
channel_type Union[ChannelTypes, naff.client.const.Missing]

the type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature

Missing
default_auto_archive_duration Union[AutoArchiveDuration, naff.client.const.Missing]

optional AutoArchiveDuration

Missing
reason Union[str, naff.client.const.Missing]

An optional reason for the audit log

Missing

Returns:

Type Description
Union[GuildNews, GuildText]

The edited channel.

Source code in naff/models/discord/channel.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    position: Absent[int] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    parent_id: Absent[Snowflake_Type] = MISSING,
    nsfw: Absent[bool] = MISSING,
    topic: Absent[str] = MISSING,
    channel_type: Absent["ChannelTypes"] = MISSING,
    default_auto_archive_duration: Absent["AutoArchiveDuration"] = MISSING,
    reason: Absent[str] = MISSING,
    **kwargs,
) -> Union["GuildNews", "GuildText"]:
    """
    Edit the guild text channel.

    Args:
        name: 1-100 character channel name
        position: the position of the channel in the left-hand listing
        permission_overwrites: a list of PermissionOverwrite
        parent_id:  the parent category `Snowflake_Type` for the channel
        nsfw: whether the channel is nsfw
        topic: 0-1024 character channel topic
        channel_type: the type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature
        default_auto_archive_duration: optional AutoArchiveDuration
        reason: An optional reason for the audit log

    Returns:
        The edited channel.

    """
    return await super().edit(
        name=name,
        position=position,
        permission_overwrites=permission_overwrites,
        parent_id=parent_id,
        nsfw=nsfw,
        topic=topic,
        type=channel_type,
        default_auto_archive_duration=default_auto_archive_duration,
        reason=reason,
        **kwargs,
    )

async method follow(self, webhook_channel_id)

Follow this channel.

Parameters:

Name Type Description Default
webhook_channel_id Union[int, str, SnowflakeObject, SupportsInt]

The ID of the channel to post messages from this channel to

required
Source code in naff/models/discord/channel.py
async def follow(self, webhook_channel_id: Snowflake_Type) -> None:
    """
    Follow this channel.

    Args:
        webhook_channel_id: The ID of the channel to post messages from this channel to

    """
    await self._client.http.follow_news_channel(self.id, webhook_channel_id)

async method create_thread_from_message(self, name, message, auto_archive_duration, reason)

Creates a new news thread in this channel.

Parameters:

Name Type Description Default
name str

1-100 character thread name.

required
message Union[int, str, SnowflakeObject, SupportsInt]

The message to connect this thread to.

required
auto_archive_duration AutoArchiveDuration

Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.

<AutoArchiveDuration.ONE_DAY: 1440>
reason Union[str, naff.client.const.Missing]

The reason for creating this thread.

None

Returns:

Type Description
GuildNewsThread

The created public thread, if successful

Source code in naff/models/discord/channel.py
async def create_thread_from_message(
    self,
    name: str,
    message: Snowflake_Type,
    auto_archive_duration: AutoArchiveDuration = AutoArchiveDuration.ONE_DAY,
    reason: Absent[str] = None,
) -> "GuildNewsThread":
    """
    Creates a new news thread in this channel.

    Args:
        name: 1-100 character thread name.
        message: The message to connect this thread to.
        auto_archive_duration: Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.
        reason: The reason for creating this thread.

    Returns:
        The created public thread, if successful

    """
    return await self.create_thread(
        name=name,
        message=message,
        auto_archive_duration=auto_archive_duration,
        reason=reason,
    )

attrs class GuildText (GuildChannel, MessageableMixin, InvitableMixin, ThreadableMixin, WebhookMixin)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

topic Optional[str]

The channel topic (0-1024 characters)

rate_limit_per_user int

Amount of seconds a user has to wait before sending another message (0-21600)

Source code in naff/models/discord/channel.py
@define()
class GuildText(GuildChannel, MessageableMixin, InvitableMixin, ThreadableMixin, WebhookMixin):
    topic: Optional[str] = field(default=None)
    """The channel topic (0-1024 characters)"""
    rate_limit_per_user: int = field(default=0)
    """Amount of seconds a user has to wait before sending another message (0-21600)"""

    async def edit(
        self,
        name: Absent[str] = MISSING,
        position: Absent[int] = MISSING,
        permission_overwrites: Absent[
            Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
        ] = MISSING,
        parent_id: Absent[Snowflake_Type] = MISSING,
        nsfw: Absent[bool] = MISSING,
        topic: Absent[str] = MISSING,
        channel_type: Absent["ChannelTypes"] = MISSING,
        default_auto_archive_duration: Absent["AutoArchiveDuration"] = MISSING,
        rate_limit_per_user: Absent[int] = MISSING,
        reason: Absent[str] = MISSING,
        **kwargs,
    ) -> Union["GuildText", "GuildNews"]:
        """
        Edit the guild text channel.

        Args:
            name: 1-100 character channel name
            position: the position of the channel in the left-hand listing
            permission_overwrites: a list of PermissionOverwrite
            parent_id:  the parent category `Snowflake_Type` for the channel
            nsfw: whether the channel is nsfw
            topic: 0-1024 character channel topic
            channel_type: the type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature
            default_auto_archive_duration: optional AutoArchiveDuration
            rate_limit_per_user: amount of seconds a user has to wait before sending another message (0-21600)
            reason: An optional reason for the audit log

        Returns:
            The edited channel.

        """
        return await super().edit(
            name=name,
            position=position,
            permission_overwrites=permission_overwrites,
            parent_id=parent_id,
            nsfw=nsfw,
            topic=topic,
            type=channel_type,
            default_auto_archive_duration=default_auto_archive_duration,
            reason=reason,
            **kwargs,
        )

    async def create_public_thread(
        self,
        name: str,
        auto_archive_duration: AutoArchiveDuration = AutoArchiveDuration.ONE_DAY,
        reason: Absent[str] = None,
    ) -> "GuildPublicThread":
        """
        Creates a new public thread in this channel.

        Args:
            name: 1-100 character thread name.
            thread_type: Is the thread private or public.
            auto_archive_duration: Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.
            reason: The reason for creating this thread.

        Returns:
            The created public thread, if successful

        """
        return await self.create_thread(
            name=name,
            thread_type=ChannelTypes.GUILD_PUBLIC_THREAD,
            auto_archive_duration=auto_archive_duration,
            reason=reason,
        )

    async def create_private_thread(
        self,
        name: str,
        invitable: Absent[bool] = MISSING,
        auto_archive_duration: AutoArchiveDuration = AutoArchiveDuration.ONE_DAY,
        reason: Absent[str] = None,
    ) -> "GuildPrivateThread":
        """
        Creates a new private thread in this channel.

        Args:
            name: 1-100 character thread name.
            message: The message to connect this thread to.
            invitable: whether non-moderators can add other non-moderators to a thread.
            auto_archive_duration: Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.
            reason: The reason for creating this thread.

        Returns:
            The created thread, if successful

        """
        return await self.create_thread(
            name=name,
            thread_type=ChannelTypes.GUILD_PRIVATE_THREAD,
            invitable=invitable,
            auto_archive_duration=auto_archive_duration,
            reason=reason,
        )

    async def create_thread_from_message(
        self,
        name: str,
        message: Snowflake_Type,
        auto_archive_duration: AutoArchiveDuration = AutoArchiveDuration.ONE_DAY,
        reason: Absent[str] = None,
    ) -> "GuildPublicThread":
        """
        Creates a new public thread in this channel.

        Args:
            name: 1-100 character thread name.
            message: The message to connect this thread to.
            auto_archive_duration: Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.
            reason: The reason for creating this thread.

        Returns:
            The created public thread, if successful

        """
        return await self.create_thread(
            name=name,
            message=message,
            auto_archive_duration=auto_archive_duration,
            reason=reason,
        )

async inherited method send(self, content, embeds, embed, components, stickers, allowed_mentions, reply_to, files, file, tts, suppress_embeds, flags, delete_after, **kwargs)

Send a message.

Parameters:

Name Type Description Default
content Optional[str]

Message text content.

None
embeds Union[List[Union[Embed, dict]], Embed, dict]

Embedded rich content (up to 6000 characters).

None
embed Union[Embed, dict]

Embedded rich content (up to 6000 characters).

None
components Union[List[List[Union[BaseComponent, dict]]], List[Union[BaseComponent, dict]], BaseComponent, dict]

The components to include with the message.

None
stickers Union[List[Union[Sticker, Snowflake_Type]], Sticker, Snowflake_Type]

IDs of up to 3 stickers in the server to send in the message.

None
allowed_mentions Union[AllowedMentions, dict]

Allowed mentions for the message.

None
reply_to Union[MessageReference, Message, dict, Snowflake_Type]

Message to reference, must be from the same channel.

None
files Union[UPLOADABLE_TYPE, List[UPLOADABLE_TYPE]]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
file Optional[UPLOADABLE_TYPE]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
tts bool

Should this message use Text To Speech.

False
suppress_embeds bool

Should embeds be suppressed on this send

False
flags Union[int, MessageFlags]

Message flags to apply.

None
delete_after Optional[float]

Delete message after this many seconds.

None

Returns:

Type Description
Message

New message object that was sent.

Source code in naff/models/discord/channel.py
async def send(
    self,
    content: Optional[str] = None,
    embeds: Optional[Union[List[Union["Embed", dict]], Union["Embed", dict]]] = None,
    embed: Optional[Union["Embed", dict]] = None,
    components: Optional[
        Union[List[List[Union["BaseComponent", dict]]], List[Union["BaseComponent", dict]], "BaseComponent", dict]
    ] = None,
    stickers: Optional[Union[List[Union["Sticker", "Snowflake_Type"]], "Sticker", "Snowflake_Type"]] = None,
    allowed_mentions: Optional[Union["AllowedMentions", dict]] = None,
    reply_to: Optional[Union["MessageReference", "Message", dict, "Snowflake_Type"]] = None,
    files: Optional[Union["UPLOADABLE_TYPE", List["UPLOADABLE_TYPE"]]] = None,
    file: Optional["UPLOADABLE_TYPE"] = None,
    tts: bool = False,
    suppress_embeds: bool = False,
    flags: Optional[Union[int, "MessageFlags"]] = None,
    delete_after: Optional[float] = None,
    **kwargs,
) -> "Message":
    """
    Send a message.

    Args:
        content: Message text content.
        embeds: Embedded rich content (up to 6000 characters).
        embed: Embedded rich content (up to 6000 characters).
        components: The components to include with the message.
        stickers: IDs of up to 3 stickers in the server to send in the message.
        allowed_mentions: Allowed mentions for the message.
        reply_to: Message to reference, must be from the same channel.
        files: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        file: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        tts: Should this message use Text To Speech.
        suppress_embeds: Should embeds be suppressed on this send
        flags: Message flags to apply.
        delete_after: Delete message after this many seconds.

    Returns:
        New message object that was sent.

    """
    if not content and not (embeds or embed) and not (files or file) and not stickers:
        raise errors.EmptyMessageException(
            "You cannot send a message without any content, embeds, files, or stickers"
        )

    if suppress_embeds:
        if isinstance(flags, int):
            flags = MessageFlags(flags)
        flags = flags | MessageFlags.SUPPRESS_EMBEDS

    message_payload = models.discord.message.process_message_payload(
        content=content,
        embeds=embeds or embed,
        components=components,
        stickers=stickers,
        allowed_mentions=allowed_mentions,
        reply_to=reply_to,
        tts=tts,
        flags=flags,
        **kwargs,
    )

    message_data = await self._send_http_request(message_payload, files=files or file)
    if message_data:
        message = self._client.cache.place_message_data(message_data)
        if delete_after:
            await message.delete(delay=delete_after)
        return message

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

async inherited method fetch_message(self, message_id)

Fetch a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
Optional[models.Message]

The message object fetched. If the message is not found, returns None.

Source code in naff/models/discord/channel.py
async def fetch_message(self, message_id: Snowflake_Type) -> Optional["models.Message"]:
    """
    Fetch a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched. If the message is not found, returns None.

    """
    try:
        return await self._client.cache.fetch_message(self.id, message_id)
    except NotFound:
        return None

inherited method get_message(self, message_id)

Get a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
models.Message

The message object fetched.

Source code in naff/models/discord/channel.py
def get_message(self, message_id: Snowflake_Type) -> "models.Message":
    """
    Get a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched.

    """
    message_id = to_snowflake(message_id)
    message: "models.Message" = self._client.cache.get_message(self.id, message_id)
    return message

inherited method history(self, limit, before, after, around)

Get an async iterator for the history of this channel.

Parameters:

Name Type Description Default
limit

The maximum number of messages to return (set to 0 for no limit)

100
before Union[int, str, SnowflakeObject, SupportsInt]

get messages before this message ID

None
after Union[int, str, SnowflakeObject, SupportsInt]

get messages after this message ID

None
around Union[int, str, SnowflakeObject, SupportsInt]

get messages "around" this message ID

None
Example Usage:

1
2
3
4
5
async for message in channel.history(limit=0):
    if message.author.id == 174918559539920897:
        print("Found author's message")
        # ...
        break
or
1
2
3
history = channel.history(limit=250)
# Flatten the async iterator into a list
messages = await history.flatten()

Returns:

Type Description
ChannelHistory

ChannelHistory (AsyncIterator)

Source code in naff/models/discord/channel.py
def history(
    self,
    limit=100,
    before: Snowflake_Type = None,
    after: Snowflake_Type = None,
    around: Snowflake_Type = None,
) -> ChannelHistory:
    """
    Get an async iterator for the history of this channel.

    Args:
        limit: The maximum number of messages to return (set to 0 for no limit)
        before: get messages before this message ID
        after: get messages after this message ID
        around: get messages "around" this message ID

    ??? Hint "Example Usage:"
        ```python
        async for message in channel.history(limit=0):
            if message.author.id == 174918559539920897:
                print("Found author's message")
                # ...
                break
        ```
        or
        ```python
        history = channel.history(limit=250)
        # Flatten the async iterator into a list
        messages = await history.flatten()
        ```

    Returns:
        ChannelHistory (AsyncIterator)

    """
    return ChannelHistory(self, limit, before, after, around)

async inherited method fetch_messages(self, limit, around, before, after)

Fetch multiple messages from the channel.

Parameters:

Name Type Description Default
limit int

Max number of messages to return, default 50, max 100

50
around Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages around

Missing
before Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages before

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages after

Missing

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_messages(
    self,
    limit: int = 50,
    around: Snowflake_Type = MISSING,
    before: Snowflake_Type = MISSING,
    after: Snowflake_Type = MISSING,
) -> List["models.Message"]:
    """
    Fetch multiple messages from the channel.

    Args:
        limit: Max number of messages to return, default `50`, max `100`
        around: Message to get messages around
        before: Message to get messages before
        after: Message to get messages after

    Returns:
        A list of messages fetched.

    """
    if limit > 100:
        raise ValueError("You cannot fetch more than 100 messages at once.")

    if around:
        around = to_snowflake(around)
    elif before:
        before = to_snowflake(before)
    elif after:
        after = to_snowflake(after)

    messages_data = await self._client.http.get_channel_messages(self.id, limit, around, before, after)
    for m in messages_data:
        m["guild_id"] = self._guild_id

    return [self._client.cache.place_message_data(m) for m in messages_data]

async inherited method fetch_pinned_messages(self)

Fetch pinned messages from the channel.

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_pinned_messages(self) -> List["models.Message"]:
    """
    Fetch pinned messages from the channel.

    Returns:
        A list of messages fetched.

    """
    messages_data = await self._client.http.get_pinned_messages(self.id)
    return [self._client.cache.place_message_data(message_data) for message_data in messages_data]

async inherited method delete_messages(self, messages, reason)

Bulk delete messages from channel.

Parameters:

Name Type Description Default
messages List[Union[int, str, SnowflakeObject, SupportsInt, models.Message]]

List of messages or message IDs to delete.

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this action. Used for audit logs.

Missing
Source code in naff/models/discord/channel.py
async def delete_messages(
    self, messages: List[Union[Snowflake_Type, "models.Message"]], reason: Absent[Optional[str]] = MISSING
) -> None:
    """
    Bulk delete messages from channel.

    Args:
        messages: List of messages or message IDs to delete.
        reason: The reason for this action. Used for audit logs.

    """
    message_ids = [to_snowflake(message) for message in messages]
    # TODO Add check for min/max and duplicates.

    if len(message_ids) == 1:
        # bulk delete messages will throw a http error if only 1 message is passed
        await self.delete_message(message_ids[0], reason)
    else:
        await self._client.http.bulk_delete_messages(self.id, message_ids, reason)

async inherited method delete_message(self, message, reason)

Delete a single message from a channel.

Parameters:

Name Type Description Default
message Union[int, str, SnowflakeObject, SupportsInt, models.Message]

The message to delete

required
reason str

The reason for this action

None
Source code in naff/models/discord/channel.py
async def delete_message(self, message: Union[Snowflake_Type, "models.Message"], reason: str = None) -> None:
    """
    Delete a single message from a channel.

    Args:
        message: The message to delete
        reason: The reason for this action

    """
    message = to_snowflake(message)
    await self._client.http.delete_message(self.id, message, reason=reason)

async inherited method purge(self, deletion_limit, search_limit, predicate, avoid_loading_msg, before, after, around, reason)

Bulk delete messages within a channel. If a predicate is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the deletion_limit.

Example Usage:
1
2
3
# this will delete the last 20 messages sent by a user with the given ID
deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
await channel.send(f"{deleted} messages deleted")

Parameters:

Name Type Description Default
deletion_limit int

The target amount of messages to delete

50
search_limit int

How many messages to search through

100
predicate Callable[[models.Message], bool]

A function that returns True or False, and takes a message as an argument

Missing
avoid_loading_msg bool

Should the bot attempt to avoid deleting its own loading messages (recommended enabled)

True
before Union[int, str, SnowflakeObject, SupportsInt]

Search messages before this ID

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Search messages after this ID

Missing
around Union[int, str, SnowflakeObject, SupportsInt]

Search messages around this ID

Missing
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this deletion

Missing

Returns:

Type Description
int

The total amount of messages deleted

Source code in naff/models/discord/channel.py
async def purge(
    self,
    deletion_limit: int = 50,
    search_limit: int = 100,
    predicate: Callable[["models.Message"], bool] = MISSING,
    avoid_loading_msg: bool = True,
    before: Optional[Snowflake_Type] = MISSING,
    after: Optional[Snowflake_Type] = MISSING,
    around: Optional[Snowflake_Type] = MISSING,
    reason: Absent[Optional[str]] = MISSING,
) -> int:
    """
    Bulk delete messages within a channel. If a `predicate` is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the `deletion_limit`.

    ??? Hint "Example Usage:"
        ```python
        # this will delete the last 20 messages sent by a user with the given ID
        deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
        await channel.send(f"{deleted} messages deleted")
        ```

    Args:
        deletion_limit: The target amount of messages to delete
        search_limit: How many messages to search through
        predicate: A function that returns True or False, and takes a message as an argument
        avoid_loading_msg: Should the bot attempt to avoid deleting its own loading messages (recommended enabled)
        before: Search messages before this ID
        after: Search messages after this ID
        around: Search messages around this ID
        reason: The reason for this deletion

    Returns:
        The total amount of messages deleted

    """
    if not predicate:

        def predicate(m) -> bool:
            return True  # noqa

    to_delete = []

    # 1209600 14 days ago in seconds, 1420070400000 is used to convert to snowflake
    fourteen_days_ago = int((time.time() - 1209600) * 1000.0 - DISCORD_EPOCH) << 22
    async for message in self.history(limit=search_limit, before=before, after=after, around=around):
        if deletion_limit != 0 and len(to_delete) == deletion_limit:
            break

        if not predicate(message):
            # fails predicate
            continue

        if avoid_loading_msg:
            if message._author_id == self._client.user.id and MessageFlags.LOADING in message.flags:
                continue

        if message.id < fourteen_days_ago:
            # message is too old to be purged
            continue

        to_delete.append(message.id)

    count = len(to_delete)
    while len(to_delete):
        iteration = [to_delete.pop() for i in range(min(100, len(to_delete)))]
        await self.delete_messages(iteration, reason=reason)
    return count

async inherited method trigger_typing(self)

Trigger a typing animation in this channel.

Source code in naff/models/discord/channel.py
async def trigger_typing(self) -> None:
    """Trigger a typing animation in this channel."""
    await self._client.http.trigger_typing_indicator(self.id)

inherited property readonly typing: Typing

A context manager to send a typing state to a given channel as long as long as the wrapped operation takes.

async inherited method create_invite(self, max_age, max_uses, temporary, unique, target_type, target_user, target_application, reason)

Creates a new channel invite.

Parameters:

Name Type Description Default
max_age int

Max age of invite in seconds, default 86400 (24 hours).

86400
max_uses int

Max uses of invite, default 0.

0
temporary bool

Grants temporary membership, default False.

False
unique bool

Invite is unique, default false.

False
target_type Optional[naff.models.discord.enums.InviteTargetTypes]

Target type for streams and embedded applications.

None
target_user Union[int, str, SnowflakeObject, SupportsInt, models.User]

Target User ID for Stream target type.

None
target_application Union[int, str, SnowflakeObject, SupportsInt, models.Application]

Target Application ID for Embedded App target type.

None
reason Optional[str]

The reason for creating this invite.

None

Returns:

Type Description
models.Invite

Newly created Invite object.

Source code in naff/models/discord/channel.py
async def create_invite(
    self,
    max_age: int = 86400,
    max_uses: int = 0,
    temporary: bool = False,
    unique: bool = False,
    target_type: Optional[InviteTargetTypes] = None,
    target_user: Optional[Union[Snowflake_Type, "models.User"]] = None,
    target_application: Optional[Union[Snowflake_Type, "models.Application"]] = None,
    reason: Optional[str] = None,
) -> "models.Invite":
    """
    Creates a new channel invite.

    Args:
        max_age: Max age of invite in seconds, default 86400 (24 hours).
        max_uses: Max uses of invite, default 0.
        temporary: Grants temporary membership, default False.
        unique: Invite is unique, default false.
        target_type: Target type for streams and embedded applications.
        target_user: Target User ID for Stream target type.
        target_application: Target Application ID for Embedded App target type.
        reason: The reason for creating this invite.

    Returns:
        Newly created Invite object.

    """
    if target_type:
        if target_type == InviteTargetTypes.STREAM and not target_user:
            raise ValueError("Stream target must include target user id.")
        elif target_type == InviteTargetTypes.EMBEDDED_APPLICATION and not target_application:
            raise ValueError("Embedded Application target must include target application id.")

    if target_user and target_application:
        raise ValueError("Invite target must be either User or Embedded Application, not both.")
    elif target_user:
        target_user = to_snowflake(target_user)
        target_type = InviteTargetTypes.STREAM
    elif target_application:
        target_application = to_snowflake(target_application)
        target_type = InviteTargetTypes.EMBEDDED_APPLICATION

    invite_data = await self._client.http.create_channel_invite(
        self.id, max_age, max_uses, temporary, unique, target_type, target_user, target_application, reason
    )
    return models.Invite.from_dict(invite_data, self._client)

async inherited method fetch_invites(self)

Fetches all invites (with invite metadata) for the channel.

Returns:

Type Description
List[models.Invite]

List of Invite objects.

Source code in naff/models/discord/channel.py
async def fetch_invites(self) -> List["models.Invite"]:
    """
    Fetches all invites (with invite metadata) for the channel.

    Returns:
        List of Invite objects.

    """
    invites_data = await self._client.http.get_channel_invites(self.id)
    return models.Invite.from_list(invites_data, self._client)

async inherited method create_thread(self, name, message, thread_type, invitable, auto_archive_duration, reason)

Creates a new thread in this channel. If a message is provided, it will be used as the initial message.

Parameters:

Name Type Description Default
name str

1-100 character thread name

required
message Union[int, str, SnowflakeObject, SupportsInt, naff.client.const.Missing]

The message to connect this thread to. Required for news channel.

Missing
thread_type Union[naff.models.discord.enums.ChannelTypes, naff.client.const.Missing]

Is the thread private or public. Not applicable to news channel, it will always be GUILD_NEWS_THREAD.

Missing
invitable Union[bool, naff.client.const.Missing]

whether non-moderators can add other non-moderators to a thread. Only applicable when creating a private thread.

Missing
auto_archive_duration AutoArchiveDuration

Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.

<AutoArchiveDuration.ONE_DAY: 1440>
reason Union[str, naff.client.const.Missing]

The reason for creating this thread.

None

Returns:

Type Description
TYPE_THREAD_CHANNEL

The created thread, if successful

Source code in naff/models/discord/channel.py
async def create_thread(
    self,
    name: str,
    message: Absent[Snowflake_Type] = MISSING,
    thread_type: Absent[ChannelTypes] = MISSING,
    invitable: Absent[bool] = MISSING,
    auto_archive_duration: AutoArchiveDuration = AutoArchiveDuration.ONE_DAY,
    reason: Absent[str] = None,
) -> "TYPE_THREAD_CHANNEL":
    """
    Creates a new thread in this channel. If a message is provided, it will be used as the initial message.

    Args:
        name: 1-100 character thread name
        message: The message to connect this thread to. Required for news channel.
        thread_type: Is the thread private or public. Not applicable to news channel, it will always be GUILD_NEWS_THREAD.
        invitable: whether non-moderators can add other non-moderators to a thread. Only applicable when creating a private thread.
        auto_archive_duration: Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.
        reason: The reason for creating this thread.

    Returns:
        The created thread, if successful

    """
    if self.type == ChannelTypes.GUILD_NEWS and not message:
        raise ValueError("News channel must include message to create thread from.")

    elif message and (thread_type or invitable):
        raise ValueError("Message cannot be used with thread_type or invitable.")

    elif thread_type != ChannelTypes.GUILD_PRIVATE_THREAD and invitable:
        raise ValueError("Invitable only applies to private threads.")

    thread_data = await self._client.http.create_thread(
        channel_id=self.id,
        name=name,
        thread_type=thread_type,
        invitable=invitable,
        auto_archive_duration=auto_archive_duration,
        message_id=to_optional_snowflake(message),
        reason=reason,
    )
    return self._client.cache.place_channel_data(thread_data)

async inherited method fetch_public_archived_threads(self, limit, before)

Get a ThreadList of archived public threads available in this channel.

Parameters:

Name Type Description Default
limit int

optional maximum number of threads to return

None
before Optional[models.Timestamp]

Returns threads before this timestamp

None

Returns:

Type Description
models.ThreadList

A ThreadList of archived threads.

Source code in naff/models/discord/channel.py
async def fetch_public_archived_threads(
    self, limit: int = None, before: Optional["models.Timestamp"] = None
) -> "models.ThreadList":
    """
    Get a `ThreadList` of archived **public** threads available in this channel.

    Args:
        limit: optional maximum number of threads to return
        before: Returns threads before this timestamp

    Returns:
        A `ThreadList` of archived threads.

    """
    threads_data = await self._client.http.list_public_archived_threads(
        channel_id=self.id, limit=limit, before=before
    )
    threads_data["id"] = self.id
    return models.ThreadList.from_dict(threads_data, self._client)

async inherited method fetch_private_archived_threads(self, limit, before)

Get a ThreadList of archived private threads available in this channel.

Parameters:

Name Type Description Default
limit int

optional maximum number of threads to return

None
before Optional[models.Timestamp]

Returns threads before this timestamp

None

Returns:

Type Description
models.ThreadList

A ThreadList of archived threads.

Source code in naff/models/discord/channel.py
async def fetch_private_archived_threads(
    self, limit: int = None, before: Optional["models.Timestamp"] = None
) -> "models.ThreadList":
    """
    Get a `ThreadList` of archived **private** threads available in this channel.

    Args:
        limit: optional maximum number of threads to return
        before: Returns threads before this timestamp

    Returns:
        A `ThreadList` of archived threads.

    """
    threads_data = await self._client.http.list_private_archived_threads(
        channel_id=self.id, limit=limit, before=before
    )
    threads_data["id"] = self.id
    return models.ThreadList.from_dict(threads_data, self._client)

async inherited method fetch_archived_threads(self, limit, before)

Get a ThreadList of archived threads available in this channel.

Parameters:

Name Type Description Default
limit int

optional maximum number of threads to return

None
before Optional[models.Timestamp]

Returns threads before this timestamp

None

Returns:

Type Description
models.ThreadList

A ThreadList of archived threads.

Source code in naff/models/discord/channel.py
async def fetch_archived_threads(
    self, limit: int = None, before: Optional["models.Timestamp"] = None
) -> "models.ThreadList":
    """
    Get a `ThreadList` of archived threads available in this channel.

    Args:
        limit: optional maximum number of threads to return
        before: Returns threads before this timestamp

    Returns:
        A `ThreadList` of archived threads.

    """
    threads_data = await self._client.http.list_private_archived_threads(
        channel_id=self.id, limit=limit, before=before
    )
    threads_data.update(
        await self._client.http.list_public_archived_threads(channel_id=self.id, limit=limit, before=before)
    )
    threads_data["id"] = self.id
    return models.ThreadList.from_dict(threads_data, self._client)

async inherited method fetch_joined_private_archived_threads(self, limit, before)

Get a ThreadList of threads the bot is a participant of in this channel.

Parameters:

Name Type Description Default
limit int

optional maximum number of threads to return

None
before Optional[models.Timestamp]

Returns threads before this timestamp

None

Returns:

Type Description
models.ThreadList

A ThreadList of threads the bot is a participant of.

Source code in naff/models/discord/channel.py
async def fetch_joined_private_archived_threads(
    self, limit: int = None, before: Optional["models.Timestamp"] = None
) -> "models.ThreadList":
    """
    Get a `ThreadList` of threads the bot is a participant of in this channel.

    Args:
        limit: optional maximum number of threads to return
        before: Returns threads before this timestamp

    Returns:
        A `ThreadList` of threads the bot is a participant of.

    """
    threads_data = await self._client.http.list_joined_private_archived_threads(
        channel_id=self.id, limit=limit, before=before
    )
    threads_data["id"] = self.id
    return models.ThreadList.from_dict(threads_data, self._client)

async inherited method fetch_active_threads(self)

Gets all active threads in the channel, including public and private threads.

Returns:

Type Description
models.ThreadList

A ThreadList of active threads.

Source code in naff/models/discord/channel.py
async def fetch_active_threads(self) -> "models.ThreadList":
    """
    Gets all active threads in the channel, including public and private threads.

    Returns:
        A `ThreadList` of active threads.

    """
    threads_data = await self._client.http.list_active_threads(guild_id=self._guild_id)

    # delete the items where the channel_id does not match
    removed_thread_ids = []
    cleaned_threads_data_threads = []
    for thread in threads_data["threads"]:
        if thread["parent_id"] == str(self.id):
            cleaned_threads_data_threads.append(thread)
        else:
            removed_thread_ids.append(thread["id"])
    threads_data["threads"] = cleaned_threads_data_threads

    # delete the member data which is not needed
    cleaned_member_data_threads = []
    for thread_member in threads_data["members"]:
        if thread_member["id"] not in removed_thread_ids:
            cleaned_member_data_threads.append(thread_member)
    threads_data["members"] = cleaned_member_data_threads

    return models.ThreadList.from_dict(threads_data, self._client)

async inherited method fetch_all_threads(self)

Gets all threads in the channel. Active and archived, including public and private threads.

Returns:

Type Description
models.ThreadList

A ThreadList of all threads.

Source code in naff/models/discord/channel.py
async def fetch_all_threads(self) -> "models.ThreadList":
    """
    Gets all threads in the channel. Active and archived, including public and private threads.

    Returns:
        A `ThreadList` of all threads.

    """
    threads = await self.fetch_active_threads()

    # update that data with the archived threads
    archived_threads = await self.fetch_archived_threads()
    threads.threads.extend(archived_threads.threads)
    threads.members.extend(archived_threads.members)

    return threads

async inherited method create_webhook(self, name, avatar)

Create a webhook in this channel.

Parameters:

Name Type Description Default
name str

The name of the webhook

required
avatar Union[naff.models.discord.file.File, io.IOBase, BinaryIO, pathlib.Path, str, naff.client.const.Missing]

An optional default avatar image to use

Missing

Returns:

Type Description
models.Webhook

The created webhook object

Exceptions:

Type Description
ValueError

If you try to name the webhook "Clyde"

Source code in naff/models/discord/channel.py
async def create_webhook(self, name: str, avatar: Absent[UPLOADABLE_TYPE] = MISSING) -> "models.Webhook":
    """
    Create a webhook in this channel.

    Args:
        name: The name of the webhook
        avatar: An optional default avatar image to use

    Returns:
        The created webhook object

    Raises:
        ValueError: If you try to name the webhook "Clyde"

    """
    return await models.Webhook.create(self._client, self, name, avatar)  # type: ignore

async inherited method delete_webhook(self, webhook)

Delete a given webhook in this channel.

Parameters:

Name Type Description Default
webhook models.Webhook

The webhook to delete

required
Source code in naff/models/discord/channel.py
async def delete_webhook(self, webhook: "models.Webhook") -> None:
    """
    Delete a given webhook in this channel.

    Args:
        webhook: The webhook to delete

    """
    return await webhook.delete()

async inherited method fetch_webhooks(self)

Fetches all the webhooks for this channel.

Returns:

Type Description
List[models.Webhook]

List of webhook objects

Source code in naff/models/discord/channel.py
async def fetch_webhooks(self) -> List["models.Webhook"]:
    """
    Fetches all the webhooks for this channel.

    Returns:
        List of webhook objects

    """
    resp = await self._client.http.get_channel_webhooks(self.id)
    return [models.Webhook.from_dict(d, self._client) for d in resp]

inherited property readonly mention: str

Returns a string that would mention the channel.

async inherited method delete(self, reason)

Delete this channel.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for deleting this channel

Missing
Source code in naff/models/discord/channel.py
async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Delete this channel.

    Args:
        reason: The reason for deleting this channel

    """
    await self._client.http.delete_channel(self.id, reason)

inherited property readonly guild: models.Guild

The guild this channel belongs to.

inherited property readonly category: Optional[GuildCategory]

The parent category of this channel.

inherited property readonly gui_position: int

The position of this channel in the Discord interface.

inherited method permissions_for(self, instance)

Calculates permissions for an instance

Parameters:

Name Type Description Default
instance Union[int, str, SnowflakeObject, SupportsInt]

Member or Role instance (or its ID)

required

Returns:

Type Description
Permissions

Permissions data

Exceptions:

Type Description
ValueError

If could not find any member or role by given ID

RuntimeError

If given instance is from another guild

Source code in naff/models/discord/channel.py
def permissions_for(self, instance: Snowflake_Type) -> Permissions:
    """
    Calculates permissions for an instance

    Args:
        instance: Member or Role instance (or its ID)

    Returns:
        Permissions data

    Raises:
        ValueError: If could not find any member or role by given ID
        RuntimeError: If given instance is from another guild

    """
    if (is_member := isinstance(instance, models.Member)) or isinstance(instance, models.Role):
        if instance._guild_id != self._guild_id:
            raise RuntimeError("Unable to calculate permissions for the instance from different guild")

        if is_member:
            return instance.channel_permissions(self)

        else:
            permissions = instance.permissions

            for overwrite in self.permission_overwrites:
                if overwrite.id == instance.id:
                    permissions &= ~overwrite.deny
                    permissions |= overwrite.allow
                    break

            return permissions

    else:
        instance = to_snowflake(instance)
        guild = self.guild
        instance = guild.get_member(instance) or guild.get_role(instance)

        if not instance:
            raise ValueError("Unable to find any member or role by given instance ID")

        return self.permissions_for(instance)

async inherited method add_permission(self, target, type, allow, deny, reason)

Add a permission to this channel.

Parameters:

Name Type Description Default
target Union[PermissionOverwrite, models.Role, models.User, models.Member, Snowflake_Type]

The updated PermissionOverwrite object, or the Role or User object/id to update

required
type Optional[OverwriteTypes]

The type of permission overwrite. Only applicable if target is an id

None
allow Union[List[Permissions], int]

List of permissions to allow. Only applicable if target is not an PermissionOverwrite object

None
deny Union[List[Permissions], int]

List of permissions to deny. Only applicable if target is not an PermissionOverwrite object

None
reason Optional[str]

The reason for this change

None

Exceptions:

Type Description
ValueError

Invalid target for permission

Source code in naff/models/discord/channel.py
async def add_permission(
    self,
    target: Union["PermissionOverwrite", "models.Role", "models.User", "models.Member", "Snowflake_Type"],
    type: Optional["OverwriteTypes"] = None,
    allow: Optional[List["Permissions"] | int] = None,
    deny: Optional[List["Permissions"] | int] = None,
    reason: Optional[str] = None,
) -> None:
    """
    Add a permission to this channel.

    Args:
        target: The updated PermissionOverwrite object, or the Role or User object/id to update
        type: The type of permission overwrite. Only applicable if target is an id
        allow: List of permissions to allow. Only applicable if target is not an PermissionOverwrite object
        deny: List of permissions to deny. Only applicable if target is not an PermissionOverwrite object
        reason: The reason for this change

    Raises:
        ValueError: Invalid target for permission

    """
    allow = allow or []
    deny = deny or []
    if not isinstance(target, PermissionOverwrite):
        if isinstance(target, (models.User, models.Member)):
            target = target.id
            type = OverwriteTypes.MEMBER
        elif isinstance(target, models.Role):
            target = target.id
            type = OverwriteTypes.ROLE
        elif type and isinstance(target, Snowflake_Type):
            target = to_snowflake(target)
        else:
            raise ValueError("Invalid target and/or type for permission")
        overwrite = PermissionOverwrite(id=target, type=type, allow=Permissions.NONE, deny=Permissions.NONE)
        if isinstance(allow, int):
            overwrite.allow |= allow
        else:
            for perm in allow:
                overwrite.allow |= perm
        if isinstance(deny, int):
            overwrite.deny |= deny
        else:
            for perm in deny:
                overwrite.deny |= perm
    else:
        overwrite = target

    if exists := get(self.permission_overwrites, id=overwrite.id, type=overwrite.type):
        exists.deny = (exists.deny | overwrite.deny) & ~overwrite.allow
        exists.allow = (exists.allow | overwrite.allow) & ~overwrite.deny
        await self.edit_permission(exists, reason)
    else:
        permission_overwrites = self.permission_overwrites
        permission_overwrites.append(overwrite)
        await self.edit(permission_overwrites=permission_overwrites)

async inherited method edit_permission(self, overwrite, reason)

Edit the permissions for this channel.

Parameters:

Name Type Description Default
overwrite PermissionOverwrite

The permission overwrite to apply

required
reason Optional[str]

The reason for this change

None
Source code in naff/models/discord/channel.py
async def edit_permission(self, overwrite: PermissionOverwrite, reason: Optional[str] = None) -> None:
    """
    Edit the permissions for this channel.

    Args:
        overwrite: The permission overwrite to apply
        reason: The reason for this change
    """
    await self._client.http.edit_channel_permission(
        self.id, overwrite.id, overwrite.allow, overwrite.deny, overwrite.type, reason
    )

async inherited method delete_permission(self, target, reason)

Delete a permission overwrite for this channel.

Parameters:

Name Type Description Default
target Union[PermissionOverwrite, models.Role, models.User]

The permission overwrite to delete

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this change

Missing
Source code in naff/models/discord/channel.py
async def delete_permission(
    self,
    target: Union["PermissionOverwrite", "models.Role", "models.User"],
    reason: Absent[Optional[str]] = MISSING,
) -> None:
    """
    Delete a permission overwrite for this channel.

    Args:
        target: The permission overwrite to delete
        reason: The reason for this change

    """
    target = to_snowflake(target)
    await self._client.http.delete_channel_permission(self.id, target, reason)

async inherited method set_permission(self, target, *, add_reactions, administrator, attach_files, ban_members, change_nickname, connect, create_instant_invite, deafen_members, embed_links, kick_members, manage_channels, manage_emojis_and_stickers, manage_events, manage_guild, manage_messages, manage_nicknames, manage_roles, manage_threads, manage_webhooks, mention_everyone, moderate_members, move_members, mute_members, priority_speaker, read_message_history, request_to_speak, send_messages, send_messages_in_threads, send_tts_messages, speak, start_embedded_activities, stream, use_application_commands, use_external_emojis, use_external_stickers, use_private_threads, use_public_threads, use_vad, view_audit_log, view_channel, view_guild_insights, reason)

Set the Permission Overwrites for a given target.

Parameters:

Name Type Description Default
target Union[models.Role, models.Member, models.User]

The target to set permission overwrites for

required
add_reactions bool | None

Allows for the addition of reactions to messages

None
administrator bool | None

Allows all permissions and bypasses channel permission overwrites

None
attach_files bool | None

Allows for uploading images and files

None
ban_members bool | None

Allows banning members

None
change_nickname bool | None

Allows for modification of own nickname

None
connect bool | None

Allows for joining of a voice channel

None
create_instant_invite bool | None

Allows creation of instant invites

None
deafen_members bool | None

Allows for deafening of members in a voice channel

None
embed_links bool | None

Links sent by users with this permission will be auto-embedded

None
kick_members bool | None

Allows kicking members

None
manage_channels bool | None

Allows management and editing of channels

None
manage_emojis_and_stickers bool | None

Allows management and editing of emojis and stickers

None
manage_events bool | None

Allows for creating, editing, and deleting scheduled events

None
manage_guild bool | None

Allows management and editing of the guild

None
manage_messages bool | None

Allows for deletion of other users messages

None
manage_nicknames bool | None

Allows for modification of other users nicknames

None
manage_roles bool | None

Allows management and editing of roles

None
manage_threads bool | None

Allows for deleting and archiving threads, and viewing all private threads

None
manage_webhooks bool | None

Allows management and editing of webhooks

None
mention_everyone bool | None

Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all online users in a channel

None
moderate_members bool | None

Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels

None
move_members bool | None

Allows for moving of members between voice channels

None
mute_members bool | None

Allows for muting members in a voice channel

None
priority_speaker bool | None

Allows for using priority speaker in a voice channel

None
read_message_history bool | None

Allows for reading of message history

None
request_to_speak bool | None

Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)

None
send_messages bool | None

Allows for sending messages in a channel (does not allow sending messages in threads)

None
send_messages_in_threads bool | None

Allows for sending messages in threads

None
send_tts_messages bool | None

Allows for sending of /tts messages

None
speak bool | None

Allows for speaking in a voice channel

None
start_embedded_activities bool | None

Allows for using Activities (applications with the EMBEDDED flag) in a voice channel

None
stream bool | None

Allows the user to go live

None
use_application_commands bool | None

Allows members to use application commands, including slash commands and context menu commands

None
use_external_emojis bool | None

Allows the usage of custom emojis from other servers

None
use_external_stickers bool | None

Allows the usage of custom stickers from other servers

None
use_private_threads bool | None

Allows for creating private threads

None
use_public_threads bool | None

Allows for creating public and announcement threads

None
use_vad bool | None

Allows for using voice-activity-detection in a voice channel

None
view_audit_log bool | None

Allows for viewing of audit logs

None
view_channel bool | None

Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels

None
view_guild_insights bool | None

Allows for viewing guild insights

None
reason str

The reason for creating this overwrite

None
Source code in naff/models/discord/channel.py
async def set_permission(
    self,
    target: Union["models.Role", "models.Member", "models.User"],
    *,
    add_reactions: bool | None = None,
    administrator: bool | None = None,
    attach_files: bool | None = None,
    ban_members: bool | None = None,
    change_nickname: bool | None = None,
    connect: bool | None = None,
    create_instant_invite: bool | None = None,
    deafen_members: bool | None = None,
    embed_links: bool | None = None,
    kick_members: bool | None = None,
    manage_channels: bool | None = None,
    manage_emojis_and_stickers: bool | None = None,
    manage_events: bool | None = None,
    manage_guild: bool | None = None,
    manage_messages: bool | None = None,
    manage_nicknames: bool | None = None,
    manage_roles: bool | None = None,
    manage_threads: bool | None = None,
    manage_webhooks: bool | None = None,
    mention_everyone: bool | None = None,
    moderate_members: bool | None = None,
    move_members: bool | None = None,
    mute_members: bool | None = None,
    priority_speaker: bool | None = None,
    read_message_history: bool | None = None,
    request_to_speak: bool | None = None,
    send_messages: bool | None = None,
    send_messages_in_threads: bool | None = None,
    send_tts_messages: bool | None = None,
    speak: bool | None = None,
    start_embedded_activities: bool | None = None,
    stream: bool | None = None,
    use_application_commands: bool | None = None,
    use_external_emojis: bool | None = None,
    use_external_stickers: bool | None = None,
    use_private_threads: bool | None = None,
    use_public_threads: bool | None = None,
    use_vad: bool | None = None,
    view_audit_log: bool | None = None,
    view_channel: bool | None = None,
    view_guild_insights: bool | None = None,
    reason: str = None,
) -> None:
    """
    Set the Permission Overwrites for a given target.

    Args:
        target: The target to set permission overwrites for
        add_reactions: Allows for the addition of reactions to messages
        administrator: Allows all permissions and bypasses channel permission overwrites
        attach_files: Allows for uploading images and files
        ban_members: Allows banning members
        change_nickname: Allows for modification of own nickname
        connect: Allows for joining of a voice channel
        create_instant_invite: Allows creation of instant invites
        deafen_members: Allows for deafening of members in a voice channel
        embed_links: Links sent by users with this permission will be auto-embedded
        kick_members: Allows kicking members
        manage_channels: Allows management and editing of channels
        manage_emojis_and_stickers: Allows management and editing of emojis and stickers
        manage_events: Allows for creating, editing, and deleting scheduled events
        manage_guild: Allows management and editing of the guild
        manage_messages: Allows for deletion of other users messages
        manage_nicknames: Allows for modification of other users nicknames
        manage_roles: Allows management and editing of roles
        manage_threads: Allows for deleting and archiving threads, and viewing all private threads
        manage_webhooks: Allows management and editing of webhooks
        mention_everyone: Allows for using the `@everyone` tag to notify all users in a channel, and the `@here` tag to notify all online users in a channel
        moderate_members: Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels
        move_members: Allows for moving of members between voice channels
        mute_members: Allows for muting members in a voice channel
        priority_speaker: Allows for using priority speaker in a voice channel
        read_message_history: Allows for reading of message history
        request_to_speak: Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)
        send_messages:  Allows for sending messages in a channel (does not allow sending messages in threads)
        send_messages_in_threads: Allows for sending messages in threads
        send_tts_messages:  Allows for sending of `/tts` messages
        speak: Allows for speaking in a voice channel
        start_embedded_activities: Allows for using Activities (applications with the `EMBEDDED` flag) in a voice channel
        stream: Allows the user to go live
        use_application_commands: Allows members to use application commands, including slash commands and context menu commands
        use_external_emojis: Allows the usage of custom emojis from other servers
        use_external_stickers: Allows the usage of custom stickers from other servers
        use_private_threads: Allows for creating private threads
        use_public_threads:  Allows for creating public and announcement threads
        use_vad: Allows for using voice-activity-detection in a voice channel
        view_audit_log: Allows for viewing of audit logs
        view_channel: Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels
        view_guild_insights: Allows for viewing guild insights
        reason: The reason for creating this overwrite
    """
    overwrite = PermissionOverwrite.for_target(target)

    allow: Permissions = Permissions.NONE
    deny: Permissions = Permissions.NONE

    for name, val in locals().items():
        if isinstance(val, bool):
            if val:
                allow |= getattr(Permissions, name.upper())
            else:
                deny |= getattr(Permissions, name.upper())

    overwrite.add_allows(allow)
    overwrite.add_denies(deny)

    await self.edit_permission(overwrite, reason)

inherited property readonly members: List[models.Member]

Returns a list of members that can see this channel.

inherited property readonly bots: List[models.Member]

Returns a list of bots that can see this channel.

inherited property readonly humans: List[models.Member]

Returns a list of humans that can see this channel.

async inherited method clone(self, name, reason)

Clone this channel and create a new one.

Parameters:

Name Type Description Default
name Optional[str]

The name of the new channel. Defaults to the current name

None
reason Union[str, NoneType, naff.client.const.Missing]

The reason for creating this channel

Missing

Returns:

Type Description
TYPE_GUILD_CHANNEL

The newly created channel.

Source code in naff/models/discord/channel.py
async def clone(self, name: Optional[str] = None, reason: Absent[Optional[str]] = MISSING) -> "TYPE_GUILD_CHANNEL":
    """
    Clone this channel and create a new one.

    Args:
        name: The name of the new channel. Defaults to the current name
        reason: The reason for creating this channel

    Returns:
        The newly created channel.

    """
    return await self.guild.create_channel(
        channel_type=self.type,
        name=name if name else self.name,
        topic=getattr(self, "topic", MISSING),
        position=self.position,
        permission_overwrites=self.permission_overwrites,
        category=self.category,
        nsfw=self.nsfw,
        bitrate=getattr(self, "bitrate", 64000),
        user_limit=getattr(self, "user_limit", 0),
        rate_limit_per_user=getattr(self, "rate_limit_per_user", 0),
        reason=reason,
    )

async method edit(self, name, position, permission_overwrites, parent_id, nsfw, topic, channel_type, default_auto_archive_duration, rate_limit_per_user, reason, **kwargs)

Edit the guild text channel.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

1-100 character channel name

Missing
position Union[int, naff.client.const.Missing]

the position of the channel in the left-hand listing

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

a list of PermissionOverwrite

Missing
parent_id Union[int, str, SnowflakeObject, SupportsInt, naff.client.const.Missing]

the parent category Snowflake_Type for the channel

Missing
nsfw Union[bool, naff.client.const.Missing]

whether the channel is nsfw

Missing
topic Union[str, naff.client.const.Missing]

0-1024 character channel topic

Missing
channel_type Union[ChannelTypes, naff.client.const.Missing]

the type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature

Missing
default_auto_archive_duration Union[AutoArchiveDuration, naff.client.const.Missing]

optional AutoArchiveDuration

Missing
rate_limit_per_user Union[int, naff.client.const.Missing]

amount of seconds a user has to wait before sending another message (0-21600)

Missing
reason Union[str, naff.client.const.Missing]

An optional reason for the audit log

Missing

Returns:

Type Description
Union[GuildText, GuildNews]

The edited channel.

Source code in naff/models/discord/channel.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    position: Absent[int] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    parent_id: Absent[Snowflake_Type] = MISSING,
    nsfw: Absent[bool] = MISSING,
    topic: Absent[str] = MISSING,
    channel_type: Absent["ChannelTypes"] = MISSING,
    default_auto_archive_duration: Absent["AutoArchiveDuration"] = MISSING,
    rate_limit_per_user: Absent[int] = MISSING,
    reason: Absent[str] = MISSING,
    **kwargs,
) -> Union["GuildText", "GuildNews"]:
    """
    Edit the guild text channel.

    Args:
        name: 1-100 character channel name
        position: the position of the channel in the left-hand listing
        permission_overwrites: a list of PermissionOverwrite
        parent_id:  the parent category `Snowflake_Type` for the channel
        nsfw: whether the channel is nsfw
        topic: 0-1024 character channel topic
        channel_type: the type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature
        default_auto_archive_duration: optional AutoArchiveDuration
        rate_limit_per_user: amount of seconds a user has to wait before sending another message (0-21600)
        reason: An optional reason for the audit log

    Returns:
        The edited channel.

    """
    return await super().edit(
        name=name,
        position=position,
        permission_overwrites=permission_overwrites,
        parent_id=parent_id,
        nsfw=nsfw,
        topic=topic,
        type=channel_type,
        default_auto_archive_duration=default_auto_archive_duration,
        reason=reason,
        **kwargs,
    )

async method create_public_thread(self, name, auto_archive_duration, reason)

Creates a new public thread in this channel.

Parameters:

Name Type Description Default
name str

1-100 character thread name.

required
thread_type

Is the thread private or public.

required
auto_archive_duration AutoArchiveDuration

Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.

<AutoArchiveDuration.ONE_DAY: 1440>
reason Union[str, naff.client.const.Missing]

The reason for creating this thread.

None

Returns:

Type Description
GuildPublicThread

The created public thread, if successful

Source code in naff/models/discord/channel.py
async def create_public_thread(
    self,
    name: str,
    auto_archive_duration: AutoArchiveDuration = AutoArchiveDuration.ONE_DAY,
    reason: Absent[str] = None,
) -> "GuildPublicThread":
    """
    Creates a new public thread in this channel.

    Args:
        name: 1-100 character thread name.
        thread_type: Is the thread private or public.
        auto_archive_duration: Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.
        reason: The reason for creating this thread.

    Returns:
        The created public thread, if successful

    """
    return await self.create_thread(
        name=name,
        thread_type=ChannelTypes.GUILD_PUBLIC_THREAD,
        auto_archive_duration=auto_archive_duration,
        reason=reason,
    )

async method create_private_thread(self, name, invitable, auto_archive_duration, reason)

Creates a new private thread in this channel.

Parameters:

Name Type Description Default
name str

1-100 character thread name.

required
message

The message to connect this thread to.

required
invitable Union[bool, naff.client.const.Missing]

whether non-moderators can add other non-moderators to a thread.

Missing
auto_archive_duration AutoArchiveDuration

Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.

<AutoArchiveDuration.ONE_DAY: 1440>
reason Union[str, naff.client.const.Missing]

The reason for creating this thread.

None

Returns:

Type Description
GuildPrivateThread

The created thread, if successful

Source code in naff/models/discord/channel.py
async def create_private_thread(
    self,
    name: str,
    invitable: Absent[bool] = MISSING,
    auto_archive_duration: AutoArchiveDuration = AutoArchiveDuration.ONE_DAY,
    reason: Absent[str] = None,
) -> "GuildPrivateThread":
    """
    Creates a new private thread in this channel.

    Args:
        name: 1-100 character thread name.
        message: The message to connect this thread to.
        invitable: whether non-moderators can add other non-moderators to a thread.
        auto_archive_duration: Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.
        reason: The reason for creating this thread.

    Returns:
        The created thread, if successful

    """
    return await self.create_thread(
        name=name,
        thread_type=ChannelTypes.GUILD_PRIVATE_THREAD,
        invitable=invitable,
        auto_archive_duration=auto_archive_duration,
        reason=reason,
    )

async method create_thread_from_message(self, name, message, auto_archive_duration, reason)

Creates a new public thread in this channel.

Parameters:

Name Type Description Default
name str

1-100 character thread name.

required
message Union[int, str, SnowflakeObject, SupportsInt]

The message to connect this thread to.

required
auto_archive_duration AutoArchiveDuration

Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.

<AutoArchiveDuration.ONE_DAY: 1440>
reason Union[str, naff.client.const.Missing]

The reason for creating this thread.

None

Returns:

Type Description
GuildPublicThread

The created public thread, if successful

Source code in naff/models/discord/channel.py
async def create_thread_from_message(
    self,
    name: str,
    message: Snowflake_Type,
    auto_archive_duration: AutoArchiveDuration = AutoArchiveDuration.ONE_DAY,
    reason: Absent[str] = None,
) -> "GuildPublicThread":
    """
    Creates a new public thread in this channel.

    Args:
        name: 1-100 character thread name.
        message: The message to connect this thread to.
        auto_archive_duration: Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.
        reason: The reason for creating this thread.

    Returns:
        The created public thread, if successful

    """
    return await self.create_thread(
        name=name,
        message=message,
        auto_archive_duration=auto_archive_duration,
        reason=reason,
    )

attrs class ThreadChannel (BaseChannel, MessageableMixin, WebhookMixin)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

parent_id Union[int, str, SnowflakeObject, SupportsInt]

id of the text channel this thread was created

owner_id Union[int, str, SnowflakeObject, SupportsInt]

id of the creator of the thread

topic Optional[str]

The thread topic (0-1024 characters)

message_count int

An approximate count of messages in a thread, stops counting at 50

member_count int

An approximate count of users in a thread, stops counting at 50

archived bool

Whether the thread is archived

auto_archive_duration int

Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080

locked bool

Whether the thread is locked

archive_timestamp Optional[models.Timestamp]

Timestamp when the thread's archive status was last changed, used for calculating recent activity

create_timestamp Optional[models.Timestamp]

Timestamp when the thread was created

flags ChannelFlags

Flags for the thread

Source code in naff/models/discord/channel.py
@define(slots=False)
class ThreadChannel(BaseChannel, MessageableMixin, WebhookMixin):
    parent_id: Snowflake_Type = field(default=None, converter=optional_c(to_snowflake))
    """id of the text channel this thread was created"""
    owner_id: Snowflake_Type = field(default=None, converter=optional_c(to_snowflake))
    """id of the creator of the thread"""
    topic: Optional[str] = field(default=None)
    """The thread topic (0-1024 characters)"""
    message_count: int = field(default=0)
    """An approximate count of messages in a thread, stops counting at 50"""
    member_count: int = field(default=0)
    """An approximate count of users in a thread, stops counting at 50"""
    archived: bool = field(default=False)
    """Whether the thread is archived"""
    auto_archive_duration: int = field(
        default=attrs.Factory(lambda self: self.default_auto_archive_duration, takes_self=True)
    )
    """Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080"""
    locked: bool = field(default=False)
    """Whether the thread is locked"""
    archive_timestamp: Optional["models.Timestamp"] = field(default=None, converter=optional_c(timestamp_converter))
    """Timestamp when the thread's archive status was last changed, used for calculating recent activity"""
    create_timestamp: Optional["models.Timestamp"] = field(default=None, converter=optional_c(timestamp_converter))
    """Timestamp when the thread was created"""
    flags: ChannelFlags = field(default=ChannelFlags.NONE, converter=ChannelFlags)
    """Flags for the thread"""

    _guild_id: Snowflake_Type = field(default=None, converter=optional_c(to_snowflake))

    @classmethod
    def _process_dict(cls, data: Dict[str, Any], client: "Client") -> Dict[str, Any]:
        data = super()._process_dict(data, client)
        thread_metadata: dict = data.get("thread_metadata", {})
        data.update(thread_metadata)
        return data

    @property
    def is_private(self) -> bool:
        """Is this a private thread?"""
        return self.type == ChannelTypes.GUILD_PRIVATE_THREAD

    @property
    def guild(self) -> "models.Guild":
        """The guild this channel belongs to."""
        return self._client.cache.get_guild(self._guild_id)

    @property
    def parent_channel(self) -> Union[GuildText, "GuildForum"]:
        """The channel this thread is a child of."""
        return self._client.cache.get_channel(self.parent_id)

    @property
    def parent_message(self) -> Optional["Message"]:
        """The message this thread is a child of."""
        return self._client.cache.get_message(self.parent_id, self.id)

    @property
    def mention(self) -> str:
        """Returns a string that would mention this thread."""
        return f"<#{self.id}>"

    @property
    def permission_overwrites(self) -> List["PermissionOverwrite"]:
        """The permission overwrites for this channel."""
        return []

    async def fetch_members(self) -> List["models.ThreadMember"]:
        """Get the members that have access to this thread."""
        members_data = await self._client.http.list_thread_members(self.id)
        return models.ThreadMember.from_list(members_data, self._client)

    async def add_member(self, member: Union["models.Member", Snowflake_Type]) -> None:
        """
        Add a member to this thread.

        Args:
            member: The member to add

        """
        await self._client.http.add_thread_member(self.id, to_snowflake(member))

    async def remove_member(self, member: Union["models.Member", Snowflake_Type]) -> None:
        """
        Remove a member from this thread.

        Args:
            member: The member to remove

        """
        await self._client.http.remove_thread_member(self.id, to_snowflake(member))

    async def join(self) -> None:
        """Join this thread."""
        await self._client.http.join_thread(self.id)

    async def leave(self) -> None:
        """Leave this thread."""
        await self._client.http.leave_thread(self.id)

    async def archive(self, locked: bool = False, reason: Absent[str] = MISSING) -> "TYPE_THREAD_CHANNEL":
        """
        Helper method to archive this thread.

        Args:
            locked: whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
            reason: The reason for this archive

        Returns:
            The archived thread channel object.

        """
        return await super().edit(locked=locked, archived=True, reason=reason)

async inherited method send(self, content, embeds, embed, components, stickers, allowed_mentions, reply_to, files, file, tts, suppress_embeds, flags, delete_after, **kwargs)

Send a message.

Parameters:

Name Type Description Default
content Optional[str]

Message text content.

None
embeds Union[List[Union[Embed, dict]], Embed, dict]

Embedded rich content (up to 6000 characters).

None
embed Union[Embed, dict]

Embedded rich content (up to 6000 characters).

None
components Union[List[List[Union[BaseComponent, dict]]], List[Union[BaseComponent, dict]], BaseComponent, dict]

The components to include with the message.

None
stickers Union[List[Union[Sticker, Snowflake_Type]], Sticker, Snowflake_Type]

IDs of up to 3 stickers in the server to send in the message.

None
allowed_mentions Union[AllowedMentions, dict]

Allowed mentions for the message.

None
reply_to Union[MessageReference, Message, dict, Snowflake_Type]

Message to reference, must be from the same channel.

None
files Union[UPLOADABLE_TYPE, List[UPLOADABLE_TYPE]]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
file Optional[UPLOADABLE_TYPE]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
tts bool

Should this message use Text To Speech.

False
suppress_embeds bool

Should embeds be suppressed on this send

False
flags Union[int, MessageFlags]

Message flags to apply.

None
delete_after Optional[float]

Delete message after this many seconds.

None

Returns:

Type Description
Message

New message object that was sent.

Source code in naff/models/discord/channel.py
async def send(
    self,
    content: Optional[str] = None,
    embeds: Optional[Union[List[Union["Embed", dict]], Union["Embed", dict]]] = None,
    embed: Optional[Union["Embed", dict]] = None,
    components: Optional[
        Union[List[List[Union["BaseComponent", dict]]], List[Union["BaseComponent", dict]], "BaseComponent", dict]
    ] = None,
    stickers: Optional[Union[List[Union["Sticker", "Snowflake_Type"]], "Sticker", "Snowflake_Type"]] = None,
    allowed_mentions: Optional[Union["AllowedMentions", dict]] = None,
    reply_to: Optional[Union["MessageReference", "Message", dict, "Snowflake_Type"]] = None,
    files: Optional[Union["UPLOADABLE_TYPE", List["UPLOADABLE_TYPE"]]] = None,
    file: Optional["UPLOADABLE_TYPE"] = None,
    tts: bool = False,
    suppress_embeds: bool = False,
    flags: Optional[Union[int, "MessageFlags"]] = None,
    delete_after: Optional[float] = None,
    **kwargs,
) -> "Message":
    """
    Send a message.

    Args:
        content: Message text content.
        embeds: Embedded rich content (up to 6000 characters).
        embed: Embedded rich content (up to 6000 characters).
        components: The components to include with the message.
        stickers: IDs of up to 3 stickers in the server to send in the message.
        allowed_mentions: Allowed mentions for the message.
        reply_to: Message to reference, must be from the same channel.
        files: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        file: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        tts: Should this message use Text To Speech.
        suppress_embeds: Should embeds be suppressed on this send
        flags: Message flags to apply.
        delete_after: Delete message after this many seconds.

    Returns:
        New message object that was sent.

    """
    if not content and not (embeds or embed) and not (files or file) and not stickers:
        raise errors.EmptyMessageException(
            "You cannot send a message without any content, embeds, files, or stickers"
        )

    if suppress_embeds:
        if isinstance(flags, int):
            flags = MessageFlags(flags)
        flags = flags | MessageFlags.SUPPRESS_EMBEDS

    message_payload = models.discord.message.process_message_payload(
        content=content,
        embeds=embeds or embed,
        components=components,
        stickers=stickers,
        allowed_mentions=allowed_mentions,
        reply_to=reply_to,
        tts=tts,
        flags=flags,
        **kwargs,
    )

    message_data = await self._send_http_request(message_payload, files=files or file)
    if message_data:
        message = self._client.cache.place_message_data(message_data)
        if delete_after:
            await message.delete(delay=delete_after)
        return message

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

async inherited method fetch_message(self, message_id)

Fetch a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
Optional[models.Message]

The message object fetched. If the message is not found, returns None.

Source code in naff/models/discord/channel.py
async def fetch_message(self, message_id: Snowflake_Type) -> Optional["models.Message"]:
    """
    Fetch a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched. If the message is not found, returns None.

    """
    try:
        return await self._client.cache.fetch_message(self.id, message_id)
    except NotFound:
        return None

inherited method get_message(self, message_id)

Get a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
models.Message

The message object fetched.

Source code in naff/models/discord/channel.py
def get_message(self, message_id: Snowflake_Type) -> "models.Message":
    """
    Get a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched.

    """
    message_id = to_snowflake(message_id)
    message: "models.Message" = self._client.cache.get_message(self.id, message_id)
    return message

inherited method history(self, limit, before, after, around)

Get an async iterator for the history of this channel.

Parameters:

Name Type Description Default
limit

The maximum number of messages to return (set to 0 for no limit)

100
before Union[int, str, SnowflakeObject, SupportsInt]

get messages before this message ID

None
after Union[int, str, SnowflakeObject, SupportsInt]

get messages after this message ID

None
around Union[int, str, SnowflakeObject, SupportsInt]

get messages "around" this message ID

None
Example Usage:

1
2
3
4
5
async for message in channel.history(limit=0):
    if message.author.id == 174918559539920897:
        print("Found author's message")
        # ...
        break
or
1
2
3
history = channel.history(limit=250)
# Flatten the async iterator into a list
messages = await history.flatten()

Returns:

Type Description
ChannelHistory

ChannelHistory (AsyncIterator)

Source code in naff/models/discord/channel.py
def history(
    self,
    limit=100,
    before: Snowflake_Type = None,
    after: Snowflake_Type = None,
    around: Snowflake_Type = None,
) -> ChannelHistory:
    """
    Get an async iterator for the history of this channel.

    Args:
        limit: The maximum number of messages to return (set to 0 for no limit)
        before: get messages before this message ID
        after: get messages after this message ID
        around: get messages "around" this message ID

    ??? Hint "Example Usage:"
        ```python
        async for message in channel.history(limit=0):
            if message.author.id == 174918559539920897:
                print("Found author's message")
                # ...
                break
        ```
        or
        ```python
        history = channel.history(limit=250)
        # Flatten the async iterator into a list
        messages = await history.flatten()
        ```

    Returns:
        ChannelHistory (AsyncIterator)

    """
    return ChannelHistory(self, limit, before, after, around)

async inherited method fetch_messages(self, limit, around, before, after)

Fetch multiple messages from the channel.

Parameters:

Name Type Description Default
limit int

Max number of messages to return, default 50, max 100

50
around Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages around

Missing
before Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages before

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages after

Missing

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_messages(
    self,
    limit: int = 50,
    around: Snowflake_Type = MISSING,
    before: Snowflake_Type = MISSING,
    after: Snowflake_Type = MISSING,
) -> List["models.Message"]:
    """
    Fetch multiple messages from the channel.

    Args:
        limit: Max number of messages to return, default `50`, max `100`
        around: Message to get messages around
        before: Message to get messages before
        after: Message to get messages after

    Returns:
        A list of messages fetched.

    """
    if limit > 100:
        raise ValueError("You cannot fetch more than 100 messages at once.")

    if around:
        around = to_snowflake(around)
    elif before:
        before = to_snowflake(before)
    elif after:
        after = to_snowflake(after)

    messages_data = await self._client.http.get_channel_messages(self.id, limit, around, before, after)
    for m in messages_data:
        m["guild_id"] = self._guild_id

    return [self._client.cache.place_message_data(m) for m in messages_data]

async inherited method fetch_pinned_messages(self)

Fetch pinned messages from the channel.

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_pinned_messages(self) -> List["models.Message"]:
    """
    Fetch pinned messages from the channel.

    Returns:
        A list of messages fetched.

    """
    messages_data = await self._client.http.get_pinned_messages(self.id)
    return [self._client.cache.place_message_data(message_data) for message_data in messages_data]

async inherited method delete_messages(self, messages, reason)

Bulk delete messages from channel.

Parameters:

Name Type Description Default
messages List[Union[int, str, SnowflakeObject, SupportsInt, models.Message]]

List of messages or message IDs to delete.

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this action. Used for audit logs.

Missing
Source code in naff/models/discord/channel.py
async def delete_messages(
    self, messages: List[Union[Snowflake_Type, "models.Message"]], reason: Absent[Optional[str]] = MISSING
) -> None:
    """
    Bulk delete messages from channel.

    Args:
        messages: List of messages or message IDs to delete.
        reason: The reason for this action. Used for audit logs.

    """
    message_ids = [to_snowflake(message) for message in messages]
    # TODO Add check for min/max and duplicates.

    if len(message_ids) == 1:
        # bulk delete messages will throw a http error if only 1 message is passed
        await self.delete_message(message_ids[0], reason)
    else:
        await self._client.http.bulk_delete_messages(self.id, message_ids, reason)

async inherited method delete_message(self, message, reason)

Delete a single message from a channel.

Parameters:

Name Type Description Default
message Union[int, str, SnowflakeObject, SupportsInt, models.Message]

The message to delete

required
reason str

The reason for this action

None
Source code in naff/models/discord/channel.py
async def delete_message(self, message: Union[Snowflake_Type, "models.Message"], reason: str = None) -> None:
    """
    Delete a single message from a channel.

    Args:
        message: The message to delete
        reason: The reason for this action

    """
    message = to_snowflake(message)
    await self._client.http.delete_message(self.id, message, reason=reason)

async inherited method purge(self, deletion_limit, search_limit, predicate, avoid_loading_msg, before, after, around, reason)

Bulk delete messages within a channel. If a predicate is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the deletion_limit.

Example Usage:
1
2
3
# this will delete the last 20 messages sent by a user with the given ID
deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
await channel.send(f"{deleted} messages deleted")

Parameters:

Name Type Description Default
deletion_limit int

The target amount of messages to delete

50
search_limit int

How many messages to search through

100
predicate Callable[[models.Message], bool]

A function that returns True or False, and takes a message as an argument

Missing
avoid_loading_msg bool

Should the bot attempt to avoid deleting its own loading messages (recommended enabled)

True
before Union[int, str, SnowflakeObject, SupportsInt]

Search messages before this ID

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Search messages after this ID

Missing
around Union[int, str, SnowflakeObject, SupportsInt]

Search messages around this ID

Missing
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this deletion

Missing

Returns:

Type Description
int

The total amount of messages deleted

Source code in naff/models/discord/channel.py
async def purge(
    self,
    deletion_limit: int = 50,
    search_limit: int = 100,
    predicate: Callable[["models.Message"], bool] = MISSING,
    avoid_loading_msg: bool = True,
    before: Optional[Snowflake_Type] = MISSING,
    after: Optional[Snowflake_Type] = MISSING,
    around: Optional[Snowflake_Type] = MISSING,
    reason: Absent[Optional[str]] = MISSING,
) -> int:
    """
    Bulk delete messages within a channel. If a `predicate` is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the `deletion_limit`.

    ??? Hint "Example Usage:"
        ```python
        # this will delete the last 20 messages sent by a user with the given ID
        deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
        await channel.send(f"{deleted} messages deleted")
        ```

    Args:
        deletion_limit: The target amount of messages to delete
        search_limit: How many messages to search through
        predicate: A function that returns True or False, and takes a message as an argument
        avoid_loading_msg: Should the bot attempt to avoid deleting its own loading messages (recommended enabled)
        before: Search messages before this ID
        after: Search messages after this ID
        around: Search messages around this ID
        reason: The reason for this deletion

    Returns:
        The total amount of messages deleted

    """
    if not predicate:

        def predicate(m) -> bool:
            return True  # noqa

    to_delete = []

    # 1209600 14 days ago in seconds, 1420070400000 is used to convert to snowflake
    fourteen_days_ago = int((time.time() - 1209600) * 1000.0 - DISCORD_EPOCH) << 22
    async for message in self.history(limit=search_limit, before=before, after=after, around=around):
        if deletion_limit != 0 and len(to_delete) == deletion_limit:
            break

        if not predicate(message):
            # fails predicate
            continue

        if avoid_loading_msg:
            if message._author_id == self._client.user.id and MessageFlags.LOADING in message.flags:
                continue

        if message.id < fourteen_days_ago:
            # message is too old to be purged
            continue

        to_delete.append(message.id)

    count = len(to_delete)
    while len(to_delete):
        iteration = [to_delete.pop() for i in range(min(100, len(to_delete)))]
        await self.delete_messages(iteration, reason=reason)
    return count

async inherited method trigger_typing(self)

Trigger a typing animation in this channel.

Source code in naff/models/discord/channel.py
async def trigger_typing(self) -> None:
    """Trigger a typing animation in this channel."""
    await self._client.http.trigger_typing_indicator(self.id)

inherited property readonly typing: Typing

A context manager to send a typing state to a given channel as long as long as the wrapped operation takes.

async inherited method create_webhook(self, name, avatar)

Create a webhook in this channel.

Parameters:

Name Type Description Default
name str

The name of the webhook

required
avatar Union[naff.models.discord.file.File, io.IOBase, BinaryIO, pathlib.Path, str, naff.client.const.Missing]

An optional default avatar image to use

Missing

Returns:

Type Description
models.Webhook

The created webhook object

Exceptions:

Type Description
ValueError

If you try to name the webhook "Clyde"

Source code in naff/models/discord/channel.py
async def create_webhook(self, name: str, avatar: Absent[UPLOADABLE_TYPE] = MISSING) -> "models.Webhook":
    """
    Create a webhook in this channel.

    Args:
        name: The name of the webhook
        avatar: An optional default avatar image to use

    Returns:
        The created webhook object

    Raises:
        ValueError: If you try to name the webhook "Clyde"

    """
    return await models.Webhook.create(self._client, self, name, avatar)  # type: ignore

async inherited method delete_webhook(self, webhook)

Delete a given webhook in this channel.

Parameters:

Name Type Description Default
webhook models.Webhook

The webhook to delete

required
Source code in naff/models/discord/channel.py
async def delete_webhook(self, webhook: "models.Webhook") -> None:
    """
    Delete a given webhook in this channel.

    Args:
        webhook: The webhook to delete

    """
    return await webhook.delete()

async inherited method fetch_webhooks(self)

Fetches all the webhooks for this channel.

Returns:

Type Description
List[models.Webhook]

List of webhook objects

Source code in naff/models/discord/channel.py
async def fetch_webhooks(self) -> List["models.Webhook"]:
    """
    Fetches all the webhooks for this channel.

    Returns:
        List of webhook objects

    """
    resp = await self._client.http.get_channel_webhooks(self.id)
    return [models.Webhook.from_dict(d, self._client) for d in resp]

async inherited method edit(self, name, icon, type, position, topic, nsfw, rate_limit_per_user, bitrate, user_limit, permission_overwrites, parent_id, rtc_region, video_quality_mode, default_auto_archive_duration, archived, auto_archive_duration, locked, invitable, reason, **kwargs)

Edits the channel.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

1-100 character channel name

Missing
icon Union[naff.models.discord.file.File, io.IOBase, BinaryIO, pathlib.Path, str, naff.client.const.Missing]

DM Group icon

Missing
type Union[naff.models.discord.enums.ChannelTypes, naff.client.const.Missing]

The type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature

Missing
position Union[int, naff.client.const.Missing]

The position of the channel in the left-hand listing

Missing
topic Union[str, naff.client.const.Missing]

0-1024 character channel topic

Missing
nsfw Union[bool, naff.client.const.Missing]

Whether the channel is nsfw

Missing
rate_limit_per_user Union[int, naff.client.const.Missing]

Amount of seconds a user has to wait before sending another message (0-21600)

Missing
bitrate Union[int, naff.client.const.Missing]

The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)

Missing
user_limit Union[int, naff.client.const.Missing]

The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

Channel or category-specific permissions

Missing
parent_id Union[int, str, SnowflakeObject, SupportsInt, naff.client.const.Missing]

The id of the new parent category for a channel

Missing
rtc_region Union[models.VoiceRegion, str, naff.client.const.Missing]

Channel voice region id, automatic when set to None.

Missing
video_quality_mode Union[naff.models.discord.enums.VideoQualityModes, naff.client.const.Missing]

The camera video quality mode of the voice channel

Missing
default_auto_archive_duration Union[naff.models.discord.enums.AutoArchiveDuration, naff.client.const.Missing]

The default duration that the clients use (not the API) for newly created threads in the channel, in minutes, to automatically archive the thread after recent activity

Missing
archived Union[bool, naff.client.const.Missing]

Whether the thread is archived

Missing
auto_archive_duration Union[naff.models.discord.enums.AutoArchiveDuration, naff.client.const.Missing]

Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080

Missing
locked Union[bool, naff.client.const.Missing]

Whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it

Missing
invitable Union[bool, naff.client.const.Missing]

Whether non-moderators can add other non-moderators to a thread; only available on private threads

Missing
reason Union[str, naff.client.const.Missing]

The reason for editing the channel

Missing

Returns:

Type Description
TYPE_ALL_CHANNEL

The edited channel. May be a new object if the channel type changes.

Source code in naff/models/discord/channel.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    icon: Absent[UPLOADABLE_TYPE] = MISSING,
    type: Absent[ChannelTypes] = MISSING,
    position: Absent[int] = MISSING,
    topic: Absent[str] = MISSING,
    nsfw: Absent[bool] = MISSING,
    rate_limit_per_user: Absent[int] = MISSING,
    bitrate: Absent[int] = MISSING,
    user_limit: Absent[int] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    parent_id: Absent[Snowflake_Type] = MISSING,
    rtc_region: Absent[Union["models.VoiceRegion", str]] = MISSING,
    video_quality_mode: Absent[VideoQualityModes] = MISSING,
    default_auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
    archived: Absent[bool] = MISSING,
    auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
    locked: Absent[bool] = MISSING,
    invitable: Absent[bool] = MISSING,
    reason: Absent[str] = MISSING,
    **kwargs,
) -> "TYPE_ALL_CHANNEL":
    """
    Edits the channel.

    Args:
        name: 1-100 character channel name
        icon: DM Group icon
        type: The type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature
        position: The position of the channel in the left-hand listing
        topic: 0-1024 character channel topic
        nsfw: Whether the channel is nsfw
        rate_limit_per_user: Amount of seconds a user has to wait before sending another message (0-21600)
        bitrate: The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)
        user_limit: The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit
        permission_overwrites: Channel or category-specific permissions
        parent_id: The id of the new parent category for a channel
        rtc_region: Channel voice region id, automatic when set to None.
        video_quality_mode: The camera video quality mode of the voice channel
        default_auto_archive_duration: The default duration that the clients use (not the API) for newly created threads in the channel, in minutes, to automatically archive the thread after recent activity
        archived: Whether the thread is archived
        auto_archive_duration: Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080
        locked: Whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
        invitable: Whether non-moderators can add other non-moderators to a thread; only available on private threads
        reason: The reason for editing the channel

    Returns:
        The edited channel. May be a new object if the channel type changes.

    """
    payload = {
        "name": name,
        "icon": to_image_data(icon),
        "type": type,
        "position": position,
        "topic": topic,
        "nsfw": nsfw,
        "rate_limit_per_user": rate_limit_per_user,
        "bitrate": bitrate,
        "user_limit": user_limit,
        "permission_overwrites": process_permission_overwrites(permission_overwrites),
        "parent_id": to_optional_snowflake(parent_id),
        "rtc_region": rtc_region.id if isinstance(rtc_region, models.VoiceRegion) else rtc_region,
        "video_quality_mode": video_quality_mode,
        "default_auto_archive_duration": default_auto_archive_duration,
        "archived": archived,
        "auto_archive_duration": auto_archive_duration,
        "locked": locked,
        "invitable": invitable,
        **kwargs,
    }
    channel_data = await self._client.http.modify_channel(self.id, payload, reason)
    if not channel_data:
        raise TooManyChanges(
            "You have changed this channel too frequently, you need to wait a while before trying again."
        ) from None

    return self._client.cache.place_channel_data(channel_data)

async inherited method delete(self, reason)

Delete this channel.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for deleting this channel

Missing
Source code in naff/models/discord/channel.py
async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Delete this channel.

    Args:
        reason: The reason for deleting this channel

    """
    await self._client.http.delete_channel(self.id, reason)

property readonly is_private: bool

Is this a private thread?

property readonly guild: models.Guild

The guild this channel belongs to.

property readonly parent_channel: Union[naff.models.discord.channel.GuildText, GuildForum]

The channel this thread is a child of.

property readonly parent_message: Optional[Message]

The message this thread is a child of.

property readonly mention: str

Returns a string that would mention this thread.

property readonly permission_overwrites: List[PermissionOverwrite]

The permission overwrites for this channel.

async method fetch_members(self)

Get the members that have access to this thread.

Source code in naff/models/discord/channel.py
async def fetch_members(self) -> List["models.ThreadMember"]:
    """Get the members that have access to this thread."""
    members_data = await self._client.http.list_thread_members(self.id)
    return models.ThreadMember.from_list(members_data, self._client)

async method add_member(self, member)

Add a member to this thread.

Parameters:

Name Type Description Default
member Union[models.Member, int, str, SnowflakeObject, SupportsInt]

The member to add

required
Source code in naff/models/discord/channel.py
async def add_member(self, member: Union["models.Member", Snowflake_Type]) -> None:
    """
    Add a member to this thread.

    Args:
        member: The member to add

    """
    await self._client.http.add_thread_member(self.id, to_snowflake(member))

async method remove_member(self, member)

Remove a member from this thread.

Parameters:

Name Type Description Default
member Union[models.Member, int, str, SnowflakeObject, SupportsInt]

The member to remove

required
Source code in naff/models/discord/channel.py
async def remove_member(self, member: Union["models.Member", Snowflake_Type]) -> None:
    """
    Remove a member from this thread.

    Args:
        member: The member to remove

    """
    await self._client.http.remove_thread_member(self.id, to_snowflake(member))

async method join(self)

Join this thread.

Source code in naff/models/discord/channel.py
async def join(self) -> None:
    """Join this thread."""
    await self._client.http.join_thread(self.id)

async method leave(self)

Leave this thread.

Source code in naff/models/discord/channel.py
async def leave(self) -> None:
    """Leave this thread."""
    await self._client.http.leave_thread(self.id)

async method archive(self, locked, reason)

Helper method to archive this thread.

Parameters:

Name Type Description Default
locked bool

whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it

False
reason Union[str, naff.client.const.Missing]

The reason for this archive

Missing

Returns:

Type Description
TYPE_THREAD_CHANNEL

The archived thread channel object.

Source code in naff/models/discord/channel.py
async def archive(self, locked: bool = False, reason: Absent[str] = MISSING) -> "TYPE_THREAD_CHANNEL":
    """
    Helper method to archive this thread.

    Args:
        locked: whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
        reason: The reason for this archive

    Returns:
        The archived thread channel object.

    """
    return await super().edit(locked=locked, archived=True, reason=reason)

attrs class GuildNewsThread (ThreadChannel)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

Source code in naff/models/discord/channel.py
@define()
class GuildNewsThread(ThreadChannel):
    async def edit(
        self,
        name: Absent[str] = MISSING,
        archived: Absent[bool] = MISSING,
        auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
        locked: Absent[bool] = MISSING,
        rate_limit_per_user: Absent[int] = MISSING,
        reason: Absent[str] = MISSING,
        **kwargs,
    ) -> "GuildNewsThread":
        """
        Edit this thread.

        Args:
            name: 1-100 character channel name
            archived: whether the thread is archived
            auto_archive_duration: duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080
            locked: whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
            rate_limit_per_user: amount of seconds a user has to wait before sending another message (0-21600)
            reason: The reason for this change

        Returns:
            The edited thread channel object.

        """
        return await super().edit(
            name=name,
            archived=archived,
            auto_archive_duration=auto_archive_duration,
            locked=locked,
            rate_limit_per_user=rate_limit_per_user,
            reason=reason,
            **kwargs,
        )

async inherited method send(self, content, embeds, embed, components, stickers, allowed_mentions, reply_to, files, file, tts, suppress_embeds, flags, delete_after, **kwargs)

Send a message.

Parameters:

Name Type Description Default
content Optional[str]

Message text content.

None
embeds Union[List[Union[Embed, dict]], Embed, dict]

Embedded rich content (up to 6000 characters).

None
embed Union[Embed, dict]

Embedded rich content (up to 6000 characters).

None
components Union[List[List[Union[BaseComponent, dict]]], List[Union[BaseComponent, dict]], BaseComponent, dict]

The components to include with the message.

None
stickers Union[List[Union[Sticker, Snowflake_Type]], Sticker, Snowflake_Type]

IDs of up to 3 stickers in the server to send in the message.

None
allowed_mentions Union[AllowedMentions, dict]

Allowed mentions for the message.

None
reply_to Union[MessageReference, Message, dict, Snowflake_Type]

Message to reference, must be from the same channel.

None
files Union[UPLOADABLE_TYPE, List[UPLOADABLE_TYPE]]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
file Optional[UPLOADABLE_TYPE]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
tts bool

Should this message use Text To Speech.

False
suppress_embeds bool

Should embeds be suppressed on this send

False
flags Union[int, MessageFlags]

Message flags to apply.

None
delete_after Optional[float]

Delete message after this many seconds.

None

Returns:

Type Description
Message

New message object that was sent.

Source code in naff/models/discord/channel.py
async def send(
    self,
    content: Optional[str] = None,
    embeds: Optional[Union[List[Union["Embed", dict]], Union["Embed", dict]]] = None,
    embed: Optional[Union["Embed", dict]] = None,
    components: Optional[
        Union[List[List[Union["BaseComponent", dict]]], List[Union["BaseComponent", dict]], "BaseComponent", dict]
    ] = None,
    stickers: Optional[Union[List[Union["Sticker", "Snowflake_Type"]], "Sticker", "Snowflake_Type"]] = None,
    allowed_mentions: Optional[Union["AllowedMentions", dict]] = None,
    reply_to: Optional[Union["MessageReference", "Message", dict, "Snowflake_Type"]] = None,
    files: Optional[Union["UPLOADABLE_TYPE", List["UPLOADABLE_TYPE"]]] = None,
    file: Optional["UPLOADABLE_TYPE"] = None,
    tts: bool = False,
    suppress_embeds: bool = False,
    flags: Optional[Union[int, "MessageFlags"]] = None,
    delete_after: Optional[float] = None,
    **kwargs,
) -> "Message":
    """
    Send a message.

    Args:
        content: Message text content.
        embeds: Embedded rich content (up to 6000 characters).
        embed: Embedded rich content (up to 6000 characters).
        components: The components to include with the message.
        stickers: IDs of up to 3 stickers in the server to send in the message.
        allowed_mentions: Allowed mentions for the message.
        reply_to: Message to reference, must be from the same channel.
        files: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        file: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        tts: Should this message use Text To Speech.
        suppress_embeds: Should embeds be suppressed on this send
        flags: Message flags to apply.
        delete_after: Delete message after this many seconds.

    Returns:
        New message object that was sent.

    """
    if not content and not (embeds or embed) and not (files or file) and not stickers:
        raise errors.EmptyMessageException(
            "You cannot send a message without any content, embeds, files, or stickers"
        )

    if suppress_embeds:
        if isinstance(flags, int):
            flags = MessageFlags(flags)
        flags = flags | MessageFlags.SUPPRESS_EMBEDS

    message_payload = models.discord.message.process_message_payload(
        content=content,
        embeds=embeds or embed,
        components=components,
        stickers=stickers,
        allowed_mentions=allowed_mentions,
        reply_to=reply_to,
        tts=tts,
        flags=flags,
        **kwargs,
    )

    message_data = await self._send_http_request(message_payload, files=files or file)
    if message_data:
        message = self._client.cache.place_message_data(message_data)
        if delete_after:
            await message.delete(delay=delete_after)
        return message

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

async inherited method fetch_message(self, message_id)

Fetch a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
Optional[models.Message]

The message object fetched. If the message is not found, returns None.

Source code in naff/models/discord/channel.py
async def fetch_message(self, message_id: Snowflake_Type) -> Optional["models.Message"]:
    """
    Fetch a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched. If the message is not found, returns None.

    """
    try:
        return await self._client.cache.fetch_message(self.id, message_id)
    except NotFound:
        return None

inherited method get_message(self, message_id)

Get a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
models.Message

The message object fetched.

Source code in naff/models/discord/channel.py
def get_message(self, message_id: Snowflake_Type) -> "models.Message":
    """
    Get a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched.

    """
    message_id = to_snowflake(message_id)
    message: "models.Message" = self._client.cache.get_message(self.id, message_id)
    return message

inherited method history(self, limit, before, after, around)

Get an async iterator for the history of this channel.

Parameters:

Name Type Description Default
limit

The maximum number of messages to return (set to 0 for no limit)

100
before Union[int, str, SnowflakeObject, SupportsInt]

get messages before this message ID

None
after Union[int, str, SnowflakeObject, SupportsInt]

get messages after this message ID

None
around Union[int, str, SnowflakeObject, SupportsInt]

get messages "around" this message ID

None
Example Usage:

1
2
3
4
5
async for message in channel.history(limit=0):
    if message.author.id == 174918559539920897:
        print("Found author's message")
        # ...
        break
or
1
2
3
history = channel.history(limit=250)
# Flatten the async iterator into a list
messages = await history.flatten()

Returns:

Type Description
ChannelHistory

ChannelHistory (AsyncIterator)

Source code in naff/models/discord/channel.py
def history(
    self,
    limit=100,
    before: Snowflake_Type = None,
    after: Snowflake_Type = None,
    around: Snowflake_Type = None,
) -> ChannelHistory:
    """
    Get an async iterator for the history of this channel.

    Args:
        limit: The maximum number of messages to return (set to 0 for no limit)
        before: get messages before this message ID
        after: get messages after this message ID
        around: get messages "around" this message ID

    ??? Hint "Example Usage:"
        ```python
        async for message in channel.history(limit=0):
            if message.author.id == 174918559539920897:
                print("Found author's message")
                # ...
                break
        ```
        or
        ```python
        history = channel.history(limit=250)
        # Flatten the async iterator into a list
        messages = await history.flatten()
        ```

    Returns:
        ChannelHistory (AsyncIterator)

    """
    return ChannelHistory(self, limit, before, after, around)

async inherited method fetch_messages(self, limit, around, before, after)

Fetch multiple messages from the channel.

Parameters:

Name Type Description Default
limit int

Max number of messages to return, default 50, max 100

50
around Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages around

Missing
before Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages before

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages after

Missing

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_messages(
    self,
    limit: int = 50,
    around: Snowflake_Type = MISSING,
    before: Snowflake_Type = MISSING,
    after: Snowflake_Type = MISSING,
) -> List["models.Message"]:
    """
    Fetch multiple messages from the channel.

    Args:
        limit: Max number of messages to return, default `50`, max `100`
        around: Message to get messages around
        before: Message to get messages before
        after: Message to get messages after

    Returns:
        A list of messages fetched.

    """
    if limit > 100:
        raise ValueError("You cannot fetch more than 100 messages at once.")

    if around:
        around = to_snowflake(around)
    elif before:
        before = to_snowflake(before)
    elif after:
        after = to_snowflake(after)

    messages_data = await self._client.http.get_channel_messages(self.id, limit, around, before, after)
    for m in messages_data:
        m["guild_id"] = self._guild_id

    return [self._client.cache.place_message_data(m) for m in messages_data]

async inherited method fetch_pinned_messages(self)

Fetch pinned messages from the channel.

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_pinned_messages(self) -> List["models.Message"]:
    """
    Fetch pinned messages from the channel.

    Returns:
        A list of messages fetched.

    """
    messages_data = await self._client.http.get_pinned_messages(self.id)
    return [self._client.cache.place_message_data(message_data) for message_data in messages_data]

async inherited method delete_messages(self, messages, reason)

Bulk delete messages from channel.

Parameters:

Name Type Description Default
messages List[Union[int, str, SnowflakeObject, SupportsInt, models.Message]]

List of messages or message IDs to delete.

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this action. Used for audit logs.

Missing
Source code in naff/models/discord/channel.py
async def delete_messages(
    self, messages: List[Union[Snowflake_Type, "models.Message"]], reason: Absent[Optional[str]] = MISSING
) -> None:
    """
    Bulk delete messages from channel.

    Args:
        messages: List of messages or message IDs to delete.
        reason: The reason for this action. Used for audit logs.

    """
    message_ids = [to_snowflake(message) for message in messages]
    # TODO Add check for min/max and duplicates.

    if len(message_ids) == 1:
        # bulk delete messages will throw a http error if only 1 message is passed
        await self.delete_message(message_ids[0], reason)
    else:
        await self._client.http.bulk_delete_messages(self.id, message_ids, reason)

async inherited method delete_message(self, message, reason)

Delete a single message from a channel.

Parameters:

Name Type Description Default
message Union[int, str, SnowflakeObject, SupportsInt, models.Message]

The message to delete

required
reason str

The reason for this action

None
Source code in naff/models/discord/channel.py
async def delete_message(self, message: Union[Snowflake_Type, "models.Message"], reason: str = None) -> None:
    """
    Delete a single message from a channel.

    Args:
        message: The message to delete
        reason: The reason for this action

    """
    message = to_snowflake(message)
    await self._client.http.delete_message(self.id, message, reason=reason)

async inherited method purge(self, deletion_limit, search_limit, predicate, avoid_loading_msg, before, after, around, reason)

Bulk delete messages within a channel. If a predicate is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the deletion_limit.

Example Usage:
1
2
3
# this will delete the last 20 messages sent by a user with the given ID
deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
await channel.send(f"{deleted} messages deleted")

Parameters:

Name Type Description Default
deletion_limit int

The target amount of messages to delete

50
search_limit int

How many messages to search through

100
predicate Callable[[models.Message], bool]

A function that returns True or False, and takes a message as an argument

Missing
avoid_loading_msg bool

Should the bot attempt to avoid deleting its own loading messages (recommended enabled)

True
before Union[int, str, SnowflakeObject, SupportsInt]

Search messages before this ID

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Search messages after this ID

Missing
around Union[int, str, SnowflakeObject, SupportsInt]

Search messages around this ID

Missing
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this deletion

Missing

Returns:

Type Description
int

The total amount of messages deleted

Source code in naff/models/discord/channel.py
async def purge(
    self,
    deletion_limit: int = 50,
    search_limit: int = 100,
    predicate: Callable[["models.Message"], bool] = MISSING,
    avoid_loading_msg: bool = True,
    before: Optional[Snowflake_Type] = MISSING,
    after: Optional[Snowflake_Type] = MISSING,
    around: Optional[Snowflake_Type] = MISSING,
    reason: Absent[Optional[str]] = MISSING,
) -> int:
    """
    Bulk delete messages within a channel. If a `predicate` is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the `deletion_limit`.

    ??? Hint "Example Usage:"
        ```python
        # this will delete the last 20 messages sent by a user with the given ID
        deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
        await channel.send(f"{deleted} messages deleted")
        ```

    Args:
        deletion_limit: The target amount of messages to delete
        search_limit: How many messages to search through
        predicate: A function that returns True or False, and takes a message as an argument
        avoid_loading_msg: Should the bot attempt to avoid deleting its own loading messages (recommended enabled)
        before: Search messages before this ID
        after: Search messages after this ID
        around: Search messages around this ID
        reason: The reason for this deletion

    Returns:
        The total amount of messages deleted

    """
    if not predicate:

        def predicate(m) -> bool:
            return True  # noqa

    to_delete = []

    # 1209600 14 days ago in seconds, 1420070400000 is used to convert to snowflake
    fourteen_days_ago = int((time.time() - 1209600) * 1000.0 - DISCORD_EPOCH) << 22
    async for message in self.history(limit=search_limit, before=before, after=after, around=around):
        if deletion_limit != 0 and len(to_delete) == deletion_limit:
            break

        if not predicate(message):
            # fails predicate
            continue

        if avoid_loading_msg:
            if message._author_id == self._client.user.id and MessageFlags.LOADING in message.flags:
                continue

        if message.id < fourteen_days_ago:
            # message is too old to be purged
            continue

        to_delete.append(message.id)

    count = len(to_delete)
    while len(to_delete):
        iteration = [to_delete.pop() for i in range(min(100, len(to_delete)))]
        await self.delete_messages(iteration, reason=reason)
    return count

async inherited method trigger_typing(self)

Trigger a typing animation in this channel.

Source code in naff/models/discord/channel.py
async def trigger_typing(self) -> None:
    """Trigger a typing animation in this channel."""
    await self._client.http.trigger_typing_indicator(self.id)

inherited property readonly typing: Typing

A context manager to send a typing state to a given channel as long as long as the wrapped operation takes.

async inherited method create_webhook(self, name, avatar)

Create a webhook in this channel.

Parameters:

Name Type Description Default
name str

The name of the webhook

required
avatar Union[naff.models.discord.file.File, io.IOBase, BinaryIO, pathlib.Path, str, naff.client.const.Missing]

An optional default avatar image to use

Missing

Returns:

Type Description
models.Webhook

The created webhook object

Exceptions:

Type Description
ValueError

If you try to name the webhook "Clyde"

Source code in naff/models/discord/channel.py
async def create_webhook(self, name: str, avatar: Absent[UPLOADABLE_TYPE] = MISSING) -> "models.Webhook":
    """
    Create a webhook in this channel.

    Args:
        name: The name of the webhook
        avatar: An optional default avatar image to use

    Returns:
        The created webhook object

    Raises:
        ValueError: If you try to name the webhook "Clyde"

    """
    return await models.Webhook.create(self._client, self, name, avatar)  # type: ignore

async inherited method delete_webhook(self, webhook)

Delete a given webhook in this channel.

Parameters:

Name Type Description Default
webhook models.Webhook

The webhook to delete

required
Source code in naff/models/discord/channel.py
async def delete_webhook(self, webhook: "models.Webhook") -> None:
    """
    Delete a given webhook in this channel.

    Args:
        webhook: The webhook to delete

    """
    return await webhook.delete()

async inherited method fetch_webhooks(self)

Fetches all the webhooks for this channel.

Returns:

Type Description
List[models.Webhook]

List of webhook objects

Source code in naff/models/discord/channel.py
async def fetch_webhooks(self) -> List["models.Webhook"]:
    """
    Fetches all the webhooks for this channel.

    Returns:
        List of webhook objects

    """
    resp = await self._client.http.get_channel_webhooks(self.id)
    return [models.Webhook.from_dict(d, self._client) for d in resp]

async inherited method delete(self, reason)

Delete this channel.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for deleting this channel

Missing
Source code in naff/models/discord/channel.py
async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Delete this channel.

    Args:
        reason: The reason for deleting this channel

    """
    await self._client.http.delete_channel(self.id, reason)

inherited property readonly is_private: bool

Is this a private thread?

inherited property readonly guild: models.Guild

The guild this channel belongs to.

inherited property readonly parent_channel: Union[naff.models.discord.channel.GuildText, GuildForum]

The channel this thread is a child of.

inherited property readonly parent_message: Optional[Message]

The message this thread is a child of.

inherited property readonly mention: str

Returns a string that would mention this thread.

inherited property readonly permission_overwrites: List[PermissionOverwrite]

The permission overwrites for this channel.

async inherited method fetch_members(self)

Get the members that have access to this thread.

Source code in naff/models/discord/channel.py
async def fetch_members(self) -> List["models.ThreadMember"]:
    """Get the members that have access to this thread."""
    members_data = await self._client.http.list_thread_members(self.id)
    return models.ThreadMember.from_list(members_data, self._client)

async inherited method add_member(self, member)

Add a member to this thread.

Parameters:

Name Type Description Default
member Union[models.Member, int, str, SnowflakeObject, SupportsInt]

The member to add

required
Source code in naff/models/discord/channel.py
async def add_member(self, member: Union["models.Member", Snowflake_Type]) -> None:
    """
    Add a member to this thread.

    Args:
        member: The member to add

    """
    await self._client.http.add_thread_member(self.id, to_snowflake(member))

async inherited method remove_member(self, member)

Remove a member from this thread.

Parameters:

Name Type Description Default
member Union[models.Member, int, str, SnowflakeObject, SupportsInt]

The member to remove

required
Source code in naff/models/discord/channel.py
async def remove_member(self, member: Union["models.Member", Snowflake_Type]) -> None:
    """
    Remove a member from this thread.

    Args:
        member: The member to remove

    """
    await self._client.http.remove_thread_member(self.id, to_snowflake(member))

async inherited method join(self)

Join this thread.

Source code in naff/models/discord/channel.py
async def join(self) -> None:
    """Join this thread."""
    await self._client.http.join_thread(self.id)

async inherited method leave(self)

Leave this thread.

Source code in naff/models/discord/channel.py
async def leave(self) -> None:
    """Leave this thread."""
    await self._client.http.leave_thread(self.id)

async inherited method archive(self, locked, reason)

Helper method to archive this thread.

Parameters:

Name Type Description Default
locked bool

whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it

False
reason Union[str, naff.client.const.Missing]

The reason for this archive

Missing

Returns:

Type Description
TYPE_THREAD_CHANNEL

The archived thread channel object.

Source code in naff/models/discord/channel.py
async def archive(self, locked: bool = False, reason: Absent[str] = MISSING) -> "TYPE_THREAD_CHANNEL":
    """
    Helper method to archive this thread.

    Args:
        locked: whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
        reason: The reason for this archive

    Returns:
        The archived thread channel object.

    """
    return await super().edit(locked=locked, archived=True, reason=reason)

async method edit(self, name, archived, auto_archive_duration, locked, rate_limit_per_user, reason, **kwargs)

Edit this thread.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

1-100 character channel name

Missing
archived Union[bool, naff.client.const.Missing]

whether the thread is archived

Missing
auto_archive_duration Union[naff.models.discord.enums.AutoArchiveDuration, naff.client.const.Missing]

duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080

Missing
locked Union[bool, naff.client.const.Missing]

whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it

Missing
rate_limit_per_user Union[int, naff.client.const.Missing]

amount of seconds a user has to wait before sending another message (0-21600)

Missing
reason Union[str, naff.client.const.Missing]

The reason for this change

Missing

Returns:

Type Description
GuildNewsThread

The edited thread channel object.

Source code in naff/models/discord/channel.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    archived: Absent[bool] = MISSING,
    auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
    locked: Absent[bool] = MISSING,
    rate_limit_per_user: Absent[int] = MISSING,
    reason: Absent[str] = MISSING,
    **kwargs,
) -> "GuildNewsThread":
    """
    Edit this thread.

    Args:
        name: 1-100 character channel name
        archived: whether the thread is archived
        auto_archive_duration: duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080
        locked: whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
        rate_limit_per_user: amount of seconds a user has to wait before sending another message (0-21600)
        reason: The reason for this change

    Returns:
        The edited thread channel object.

    """
    return await super().edit(
        name=name,
        archived=archived,
        auto_archive_duration=auto_archive_duration,
        locked=locked,
        rate_limit_per_user=rate_limit_per_user,
        reason=reason,
        **kwargs,
    )

attrs class GuildPublicThread (ThreadChannel)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

Source code in naff/models/discord/channel.py
@define()
class GuildPublicThread(ThreadChannel):

    _applied_tags: List[Snowflake_Type] = field(factory=list)

    async def edit(
        self,
        name: Absent[str] = MISSING,
        archived: Absent[bool] = MISSING,
        auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
        applied_tags: Absent[List[Union[Snowflake_Type, ThreadTag]]] = MISSING,
        locked: Absent[bool] = MISSING,
        rate_limit_per_user: Absent[int] = MISSING,
        flags: Absent[Union[int, ChannelFlags]] = MISSING,
        reason: Absent[str] = MISSING,
        **kwargs,
    ) -> "GuildPublicThread":
        """
        Edit this thread.

        Args:
            name: 1-100 character channel name
            archived: whether the thread is archived
            applied_tags: list of tags to apply to a forum post (!!! This is for forum threads only)
            auto_archive_duration: duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080
            locked: whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
            rate_limit_per_user: amount of seconds a user has to wait before sending another message (0-21600)
            flags: channel flags for forum threads
            reason: The reason for this change

        Returns:
            The edited thread channel object.
        """
        if applied_tags != MISSING:
            applied_tags = [str(tag.id) if isinstance(tag, ThreadTag) else str(tag) for tag in applied_tags]

        return await super().edit(
            name=name,
            archived=archived,
            auto_archive_duration=auto_archive_duration,
            applied_tags=applied_tags,
            locked=locked,
            rate_limit_per_user=rate_limit_per_user,
            reason=reason,
            flags=flags,
            **kwargs,
        )

    @property
    def applied_tags(self) -> list[ThreadTag]:
        """
        The tags applied to this thread.

        Note:
            This is only on forum threads.

        """
        if not isinstance(self.parent_channel, GuildForum):
            raise AttributeError("This is only available on forum threads.")
        return [tag for tag in self.parent_channel.available_tags if str(tag.id) in self._applied_tags]

    @property
    def initial_post(self) -> Optional["Message"]:
        """
        The initial message posted by the OP.

        Note:
            This is only on forum threads.

        """
        if not isinstance(self.parent_channel, GuildForum):
            raise AttributeError("This is only available on forum threads.")
        return self.get_message(self.id)

async inherited method send(self, content, embeds, embed, components, stickers, allowed_mentions, reply_to, files, file, tts, suppress_embeds, flags, delete_after, **kwargs)

Send a message.

Parameters:

Name Type Description Default
content Optional[str]

Message text content.

None
embeds Union[List[Union[Embed, dict]], Embed, dict]

Embedded rich content (up to 6000 characters).

None
embed Union[Embed, dict]

Embedded rich content (up to 6000 characters).

None
components Union[List[List[Union[BaseComponent, dict]]], List[Union[BaseComponent, dict]], BaseComponent, dict]

The components to include with the message.

None
stickers Union[List[Union[Sticker, Snowflake_Type]], Sticker, Snowflake_Type]

IDs of up to 3 stickers in the server to send in the message.

None
allowed_mentions Union[AllowedMentions, dict]

Allowed mentions for the message.

None
reply_to Union[MessageReference, Message, dict, Snowflake_Type]

Message to reference, must be from the same channel.

None
files Union[UPLOADABLE_TYPE, List[UPLOADABLE_TYPE]]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
file Optional[UPLOADABLE_TYPE]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
tts bool

Should this message use Text To Speech.

False
suppress_embeds bool

Should embeds be suppressed on this send

False
flags Union[int, MessageFlags]

Message flags to apply.

None
delete_after Optional[float]

Delete message after this many seconds.

None

Returns:

Type Description
Message

New message object that was sent.

Source code in naff/models/discord/channel.py
async def send(
    self,
    content: Optional[str] = None,
    embeds: Optional[Union[List[Union["Embed", dict]], Union["Embed", dict]]] = None,
    embed: Optional[Union["Embed", dict]] = None,
    components: Optional[
        Union[List[List[Union["BaseComponent", dict]]], List[Union["BaseComponent", dict]], "BaseComponent", dict]
    ] = None,
    stickers: Optional[Union[List[Union["Sticker", "Snowflake_Type"]], "Sticker", "Snowflake_Type"]] = None,
    allowed_mentions: Optional[Union["AllowedMentions", dict]] = None,
    reply_to: Optional[Union["MessageReference", "Message", dict, "Snowflake_Type"]] = None,
    files: Optional[Union["UPLOADABLE_TYPE", List["UPLOADABLE_TYPE"]]] = None,
    file: Optional["UPLOADABLE_TYPE"] = None,
    tts: bool = False,
    suppress_embeds: bool = False,
    flags: Optional[Union[int, "MessageFlags"]] = None,
    delete_after: Optional[float] = None,
    **kwargs,
) -> "Message":
    """
    Send a message.

    Args:
        content: Message text content.
        embeds: Embedded rich content (up to 6000 characters).
        embed: Embedded rich content (up to 6000 characters).
        components: The components to include with the message.
        stickers: IDs of up to 3 stickers in the server to send in the message.
        allowed_mentions: Allowed mentions for the message.
        reply_to: Message to reference, must be from the same channel.
        files: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        file: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        tts: Should this message use Text To Speech.
        suppress_embeds: Should embeds be suppressed on this send
        flags: Message flags to apply.
        delete_after: Delete message after this many seconds.

    Returns:
        New message object that was sent.

    """
    if not content and not (embeds or embed) and not (files or file) and not stickers:
        raise errors.EmptyMessageException(
            "You cannot send a message without any content, embeds, files, or stickers"
        )

    if suppress_embeds:
        if isinstance(flags, int):
            flags = MessageFlags(flags)
        flags = flags | MessageFlags.SUPPRESS_EMBEDS

    message_payload = models.discord.message.process_message_payload(
        content=content,
        embeds=embeds or embed,
        components=components,
        stickers=stickers,
        allowed_mentions=allowed_mentions,
        reply_to=reply_to,
        tts=tts,
        flags=flags,
        **kwargs,
    )

    message_data = await self._send_http_request(message_payload, files=files or file)
    if message_data:
        message = self._client.cache.place_message_data(message_data)
        if delete_after:
            await message.delete(delay=delete_after)
        return message

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

async inherited method fetch_message(self, message_id)

Fetch a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
Optional[models.Message]

The message object fetched. If the message is not found, returns None.

Source code in naff/models/discord/channel.py
async def fetch_message(self, message_id: Snowflake_Type) -> Optional["models.Message"]:
    """
    Fetch a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched. If the message is not found, returns None.

    """
    try:
        return await self._client.cache.fetch_message(self.id, message_id)
    except NotFound:
        return None

inherited method get_message(self, message_id)

Get a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
models.Message

The message object fetched.

Source code in naff/models/discord/channel.py
def get_message(self, message_id: Snowflake_Type) -> "models.Message":
    """
    Get a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched.

    """
    message_id = to_snowflake(message_id)
    message: "models.Message" = self._client.cache.get_message(self.id, message_id)
    return message

inherited method history(self, limit, before, after, around)

Get an async iterator for the history of this channel.

Parameters:

Name Type Description Default
limit

The maximum number of messages to return (set to 0 for no limit)

100
before Union[int, str, SnowflakeObject, SupportsInt]

get messages before this message ID

None
after Union[int, str, SnowflakeObject, SupportsInt]

get messages after this message ID

None
around Union[int, str, SnowflakeObject, SupportsInt]

get messages "around" this message ID

None
Example Usage:

1
2
3
4
5
async for message in channel.history(limit=0):
    if message.author.id == 174918559539920897:
        print("Found author's message")
        # ...
        break
or
1
2
3
history = channel.history(limit=250)
# Flatten the async iterator into a list
messages = await history.flatten()

Returns:

Type Description
ChannelHistory

ChannelHistory (AsyncIterator)

Source code in naff/models/discord/channel.py
def history(
    self,
    limit=100,
    before: Snowflake_Type = None,
    after: Snowflake_Type = None,
    around: Snowflake_Type = None,
) -> ChannelHistory:
    """
    Get an async iterator for the history of this channel.

    Args:
        limit: The maximum number of messages to return (set to 0 for no limit)
        before: get messages before this message ID
        after: get messages after this message ID
        around: get messages "around" this message ID

    ??? Hint "Example Usage:"
        ```python
        async for message in channel.history(limit=0):
            if message.author.id == 174918559539920897:
                print("Found author's message")
                # ...
                break
        ```
        or
        ```python
        history = channel.history(limit=250)
        # Flatten the async iterator into a list
        messages = await history.flatten()
        ```

    Returns:
        ChannelHistory (AsyncIterator)

    """
    return ChannelHistory(self, limit, before, after, around)

async inherited method fetch_messages(self, limit, around, before, after)

Fetch multiple messages from the channel.

Parameters:

Name Type Description Default
limit int

Max number of messages to return, default 50, max 100

50
around Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages around

Missing
before Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages before

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages after

Missing

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_messages(
    self,
    limit: int = 50,
    around: Snowflake_Type = MISSING,
    before: Snowflake_Type = MISSING,
    after: Snowflake_Type = MISSING,
) -> List["models.Message"]:
    """
    Fetch multiple messages from the channel.

    Args:
        limit: Max number of messages to return, default `50`, max `100`
        around: Message to get messages around
        before: Message to get messages before
        after: Message to get messages after

    Returns:
        A list of messages fetched.

    """
    if limit > 100:
        raise ValueError("You cannot fetch more than 100 messages at once.")

    if around:
        around = to_snowflake(around)
    elif before:
        before = to_snowflake(before)
    elif after:
        after = to_snowflake(after)

    messages_data = await self._client.http.get_channel_messages(self.id, limit, around, before, after)
    for m in messages_data:
        m["guild_id"] = self._guild_id

    return [self._client.cache.place_message_data(m) for m in messages_data]

async inherited method fetch_pinned_messages(self)

Fetch pinned messages from the channel.

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_pinned_messages(self) -> List["models.Message"]:
    """
    Fetch pinned messages from the channel.

    Returns:
        A list of messages fetched.

    """
    messages_data = await self._client.http.get_pinned_messages(self.id)
    return [self._client.cache.place_message_data(message_data) for message_data in messages_data]

async inherited method delete_messages(self, messages, reason)

Bulk delete messages from channel.

Parameters:

Name Type Description Default
messages List[Union[int, str, SnowflakeObject, SupportsInt, models.Message]]

List of messages or message IDs to delete.

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this action. Used for audit logs.

Missing
Source code in naff/models/discord/channel.py
async def delete_messages(
    self, messages: List[Union[Snowflake_Type, "models.Message"]], reason: Absent[Optional[str]] = MISSING
) -> None:
    """
    Bulk delete messages from channel.

    Args:
        messages: List of messages or message IDs to delete.
        reason: The reason for this action. Used for audit logs.

    """
    message_ids = [to_snowflake(message) for message in messages]
    # TODO Add check for min/max and duplicates.

    if len(message_ids) == 1:
        # bulk delete messages will throw a http error if only 1 message is passed
        await self.delete_message(message_ids[0], reason)
    else:
        await self._client.http.bulk_delete_messages(self.id, message_ids, reason)

async inherited method delete_message(self, message, reason)

Delete a single message from a channel.

Parameters:

Name Type Description Default
message Union[int, str, SnowflakeObject, SupportsInt, models.Message]

The message to delete

required
reason str

The reason for this action

None
Source code in naff/models/discord/channel.py
async def delete_message(self, message: Union[Snowflake_Type, "models.Message"], reason: str = None) -> None:
    """
    Delete a single message from a channel.

    Args:
        message: The message to delete
        reason: The reason for this action

    """
    message = to_snowflake(message)
    await self._client.http.delete_message(self.id, message, reason=reason)

async inherited method purge(self, deletion_limit, search_limit, predicate, avoid_loading_msg, before, after, around, reason)

Bulk delete messages within a channel. If a predicate is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the deletion_limit.

Example Usage:
1
2
3
# this will delete the last 20 messages sent by a user with the given ID
deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
await channel.send(f"{deleted} messages deleted")

Parameters:

Name Type Description Default
deletion_limit int

The target amount of messages to delete

50
search_limit int

How many messages to search through

100
predicate Callable[[models.Message], bool]

A function that returns True or False, and takes a message as an argument

Missing
avoid_loading_msg bool

Should the bot attempt to avoid deleting its own loading messages (recommended enabled)

True
before Union[int, str, SnowflakeObject, SupportsInt]

Search messages before this ID

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Search messages after this ID

Missing
around Union[int, str, SnowflakeObject, SupportsInt]

Search messages around this ID

Missing
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this deletion

Missing

Returns:

Type Description
int

The total amount of messages deleted

Source code in naff/models/discord/channel.py
async def purge(
    self,
    deletion_limit: int = 50,
    search_limit: int = 100,
    predicate: Callable[["models.Message"], bool] = MISSING,
    avoid_loading_msg: bool = True,
    before: Optional[Snowflake_Type] = MISSING,
    after: Optional[Snowflake_Type] = MISSING,
    around: Optional[Snowflake_Type] = MISSING,
    reason: Absent[Optional[str]] = MISSING,
) -> int:
    """
    Bulk delete messages within a channel. If a `predicate` is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the `deletion_limit`.

    ??? Hint "Example Usage:"
        ```python
        # this will delete the last 20 messages sent by a user with the given ID
        deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
        await channel.send(f"{deleted} messages deleted")
        ```

    Args:
        deletion_limit: The target amount of messages to delete
        search_limit: How many messages to search through
        predicate: A function that returns True or False, and takes a message as an argument
        avoid_loading_msg: Should the bot attempt to avoid deleting its own loading messages (recommended enabled)
        before: Search messages before this ID
        after: Search messages after this ID
        around: Search messages around this ID
        reason: The reason for this deletion

    Returns:
        The total amount of messages deleted

    """
    if not predicate:

        def predicate(m) -> bool:
            return True  # noqa

    to_delete = []

    # 1209600 14 days ago in seconds, 1420070400000 is used to convert to snowflake
    fourteen_days_ago = int((time.time() - 1209600) * 1000.0 - DISCORD_EPOCH) << 22
    async for message in self.history(limit=search_limit, before=before, after=after, around=around):
        if deletion_limit != 0 and len(to_delete) == deletion_limit:
            break

        if not predicate(message):
            # fails predicate
            continue

        if avoid_loading_msg:
            if message._author_id == self._client.user.id and MessageFlags.LOADING in message.flags:
                continue

        if message.id < fourteen_days_ago:
            # message is too old to be purged
            continue

        to_delete.append(message.id)

    count = len(to_delete)
    while len(to_delete):
        iteration = [to_delete.pop() for i in range(min(100, len(to_delete)))]
        await self.delete_messages(iteration, reason=reason)
    return count

async inherited method trigger_typing(self)

Trigger a typing animation in this channel.

Source code in naff/models/discord/channel.py
async def trigger_typing(self) -> None:
    """Trigger a typing animation in this channel."""
    await self._client.http.trigger_typing_indicator(self.id)

inherited property readonly typing: Typing

A context manager to send a typing state to a given channel as long as long as the wrapped operation takes.

async inherited method create_webhook(self, name, avatar)

Create a webhook in this channel.

Parameters:

Name Type Description Default
name str

The name of the webhook

required
avatar Union[naff.models.discord.file.File, io.IOBase, BinaryIO, pathlib.Path, str, naff.client.const.Missing]

An optional default avatar image to use

Missing

Returns:

Type Description
models.Webhook

The created webhook object

Exceptions:

Type Description
ValueError

If you try to name the webhook "Clyde"

Source code in naff/models/discord/channel.py
async def create_webhook(self, name: str, avatar: Absent[UPLOADABLE_TYPE] = MISSING) -> "models.Webhook":
    """
    Create a webhook in this channel.

    Args:
        name: The name of the webhook
        avatar: An optional default avatar image to use

    Returns:
        The created webhook object

    Raises:
        ValueError: If you try to name the webhook "Clyde"

    """
    return await models.Webhook.create(self._client, self, name, avatar)  # type: ignore

async inherited method delete_webhook(self, webhook)

Delete a given webhook in this channel.

Parameters:

Name Type Description Default
webhook models.Webhook

The webhook to delete

required
Source code in naff/models/discord/channel.py
async def delete_webhook(self, webhook: "models.Webhook") -> None:
    """
    Delete a given webhook in this channel.

    Args:
        webhook: The webhook to delete

    """
    return await webhook.delete()

async inherited method fetch_webhooks(self)

Fetches all the webhooks for this channel.

Returns:

Type Description
List[models.Webhook]

List of webhook objects

Source code in naff/models/discord/channel.py
async def fetch_webhooks(self) -> List["models.Webhook"]:
    """
    Fetches all the webhooks for this channel.

    Returns:
        List of webhook objects

    """
    resp = await self._client.http.get_channel_webhooks(self.id)
    return [models.Webhook.from_dict(d, self._client) for d in resp]

async inherited method delete(self, reason)

Delete this channel.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for deleting this channel

Missing
Source code in naff/models/discord/channel.py
async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Delete this channel.

    Args:
        reason: The reason for deleting this channel

    """
    await self._client.http.delete_channel(self.id, reason)

inherited property readonly is_private: bool

Is this a private thread?

inherited property readonly guild: models.Guild

The guild this channel belongs to.

inherited property readonly parent_channel: Union[naff.models.discord.channel.GuildText, GuildForum]

The channel this thread is a child of.

inherited property readonly parent_message: Optional[Message]

The message this thread is a child of.

inherited property readonly mention: str

Returns a string that would mention this thread.

inherited property readonly permission_overwrites: List[PermissionOverwrite]

The permission overwrites for this channel.

async inherited method fetch_members(self)

Get the members that have access to this thread.

Source code in naff/models/discord/channel.py
async def fetch_members(self) -> List["models.ThreadMember"]:
    """Get the members that have access to this thread."""
    members_data = await self._client.http.list_thread_members(self.id)
    return models.ThreadMember.from_list(members_data, self._client)

async inherited method add_member(self, member)

Add a member to this thread.

Parameters:

Name Type Description Default
member Union[models.Member, int, str, SnowflakeObject, SupportsInt]

The member to add

required
Source code in naff/models/discord/channel.py
async def add_member(self, member: Union["models.Member", Snowflake_Type]) -> None:
    """
    Add a member to this thread.

    Args:
        member: The member to add

    """
    await self._client.http.add_thread_member(self.id, to_snowflake(member))

async inherited method remove_member(self, member)

Remove a member from this thread.

Parameters:

Name Type Description Default
member Union[models.Member, int, str, SnowflakeObject, SupportsInt]

The member to remove

required
Source code in naff/models/discord/channel.py
async def remove_member(self, member: Union["models.Member", Snowflake_Type]) -> None:
    """
    Remove a member from this thread.

    Args:
        member: The member to remove

    """
    await self._client.http.remove_thread_member(self.id, to_snowflake(member))

async inherited method join(self)

Join this thread.

Source code in naff/models/discord/channel.py
async def join(self) -> None:
    """Join this thread."""
    await self._client.http.join_thread(self.id)

async inherited method leave(self)

Leave this thread.

Source code in naff/models/discord/channel.py
async def leave(self) -> None:
    """Leave this thread."""
    await self._client.http.leave_thread(self.id)

async inherited method archive(self, locked, reason)

Helper method to archive this thread.

Parameters:

Name Type Description Default
locked bool

whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it

False
reason Union[str, naff.client.const.Missing]

The reason for this archive

Missing

Returns:

Type Description
TYPE_THREAD_CHANNEL

The archived thread channel object.

Source code in naff/models/discord/channel.py
async def archive(self, locked: bool = False, reason: Absent[str] = MISSING) -> "TYPE_THREAD_CHANNEL":
    """
    Helper method to archive this thread.

    Args:
        locked: whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
        reason: The reason for this archive

    Returns:
        The archived thread channel object.

    """
    return await super().edit(locked=locked, archived=True, reason=reason)

async method edit(self, name, archived, auto_archive_duration, applied_tags, locked, rate_limit_per_user, flags, reason, **kwargs)

Edit this thread.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

1-100 character channel name

Missing
archived Union[bool, naff.client.const.Missing]

whether the thread is archived

Missing
applied_tags Union[List[Union[int, str, SnowflakeObject, SupportsInt, naff.models.discord.thread.ThreadTag]], naff.client.const.Missing]

list of tags to apply to a forum post (!!! This is for forum threads only)

Missing
auto_archive_duration Union[naff.models.discord.enums.AutoArchiveDuration, naff.client.const.Missing]

duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080

Missing
locked Union[bool, naff.client.const.Missing]

whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it

Missing
rate_limit_per_user Union[int, naff.client.const.Missing]

amount of seconds a user has to wait before sending another message (0-21600)

Missing
flags Union[int, naff.models.discord.enums.ChannelFlags, naff.client.const.Missing]

channel flags for forum threads

Missing
reason Union[str, naff.client.const.Missing]

The reason for this change

Missing

Returns:

Type Description
GuildPublicThread

The edited thread channel object.

Source code in naff/models/discord/channel.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    archived: Absent[bool] = MISSING,
    auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
    applied_tags: Absent[List[Union[Snowflake_Type, ThreadTag]]] = MISSING,
    locked: Absent[bool] = MISSING,
    rate_limit_per_user: Absent[int] = MISSING,
    flags: Absent[Union[int, ChannelFlags]] = MISSING,
    reason: Absent[str] = MISSING,
    **kwargs,
) -> "GuildPublicThread":
    """
    Edit this thread.

    Args:
        name: 1-100 character channel name
        archived: whether the thread is archived
        applied_tags: list of tags to apply to a forum post (!!! This is for forum threads only)
        auto_archive_duration: duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080
        locked: whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
        rate_limit_per_user: amount of seconds a user has to wait before sending another message (0-21600)
        flags: channel flags for forum threads
        reason: The reason for this change

    Returns:
        The edited thread channel object.
    """
    if applied_tags != MISSING:
        applied_tags = [str(tag.id) if isinstance(tag, ThreadTag) else str(tag) for tag in applied_tags]

    return await super().edit(
        name=name,
        archived=archived,
        auto_archive_duration=auto_archive_duration,
        applied_tags=applied_tags,
        locked=locked,
        rate_limit_per_user=rate_limit_per_user,
        reason=reason,
        flags=flags,
        **kwargs,
    )

property readonly applied_tags: list

The tags applied to this thread.

Note

This is only on forum threads.

property readonly initial_post: Optional[Message]

The initial message posted by the OP.

Note

This is only on forum threads.

attrs class GuildPrivateThread (ThreadChannel)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

invitable bool

Whether non-moderators can add other non-moderators to a thread

Source code in naff/models/discord/channel.py
@define()
class GuildPrivateThread(ThreadChannel):
    invitable: bool = field(default=False)
    """Whether non-moderators can add other non-moderators to a thread"""

    async def edit(
        self,
        name: Absent[str] = MISSING,
        archived: Absent[bool] = MISSING,
        auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
        locked: Absent[bool] = MISSING,
        rate_limit_per_user: Absent[int] = MISSING,
        invitable: Absent[bool] = MISSING,
        reason: Absent[str] = MISSING,
        **kwargs,
    ) -> "GuildPrivateThread":
        """
        Edit this thread.

        Args:
            name: 1-100 character channel name
            archived: whether the thread is archived
            auto_archive_duration: duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080
            locked: whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
            rate_limit_per_user: amount of seconds a user has to wait before sending another message (0-21600)
            invitable: whether non-moderators can add other non-moderators to a thread; only available on private threads
            reason: The reason for this change

        Returns:
            The edited thread channel object.

        """
        return await super().edit(
            name=name,
            archived=archived,
            auto_archive_duration=auto_archive_duration,
            locked=locked,
            rate_limit_per_user=rate_limit_per_user,
            invitable=invitable,
            reason=reason,
            **kwargs,
        )

async inherited method send(self, content, embeds, embed, components, stickers, allowed_mentions, reply_to, files, file, tts, suppress_embeds, flags, delete_after, **kwargs)

Send a message.

Parameters:

Name Type Description Default
content Optional[str]

Message text content.

None
embeds Union[List[Union[Embed, dict]], Embed, dict]

Embedded rich content (up to 6000 characters).

None
embed Union[Embed, dict]

Embedded rich content (up to 6000 characters).

None
components Union[List[List[Union[BaseComponent, dict]]], List[Union[BaseComponent, dict]], BaseComponent, dict]

The components to include with the message.

None
stickers Union[List[Union[Sticker, Snowflake_Type]], Sticker, Snowflake_Type]

IDs of up to 3 stickers in the server to send in the message.

None
allowed_mentions Union[AllowedMentions, dict]

Allowed mentions for the message.

None
reply_to Union[MessageReference, Message, dict, Snowflake_Type]

Message to reference, must be from the same channel.

None
files Union[UPLOADABLE_TYPE, List[UPLOADABLE_TYPE]]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
file Optional[UPLOADABLE_TYPE]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
tts bool

Should this message use Text To Speech.

False
suppress_embeds bool

Should embeds be suppressed on this send

False
flags Union[int, MessageFlags]

Message flags to apply.

None
delete_after Optional[float]

Delete message after this many seconds.

None

Returns:

Type Description
Message

New message object that was sent.

Source code in naff/models/discord/channel.py
async def send(
    self,
    content: Optional[str] = None,
    embeds: Optional[Union[List[Union["Embed", dict]], Union["Embed", dict]]] = None,
    embed: Optional[Union["Embed", dict]] = None,
    components: Optional[
        Union[List[List[Union["BaseComponent", dict]]], List[Union["BaseComponent", dict]], "BaseComponent", dict]
    ] = None,
    stickers: Optional[Union[List[Union["Sticker", "Snowflake_Type"]], "Sticker", "Snowflake_Type"]] = None,
    allowed_mentions: Optional[Union["AllowedMentions", dict]] = None,
    reply_to: Optional[Union["MessageReference", "Message", dict, "Snowflake_Type"]] = None,
    files: Optional[Union["UPLOADABLE_TYPE", List["UPLOADABLE_TYPE"]]] = None,
    file: Optional["UPLOADABLE_TYPE"] = None,
    tts: bool = False,
    suppress_embeds: bool = False,
    flags: Optional[Union[int, "MessageFlags"]] = None,
    delete_after: Optional[float] = None,
    **kwargs,
) -> "Message":
    """
    Send a message.

    Args:
        content: Message text content.
        embeds: Embedded rich content (up to 6000 characters).
        embed: Embedded rich content (up to 6000 characters).
        components: The components to include with the message.
        stickers: IDs of up to 3 stickers in the server to send in the message.
        allowed_mentions: Allowed mentions for the message.
        reply_to: Message to reference, must be from the same channel.
        files: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        file: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        tts: Should this message use Text To Speech.
        suppress_embeds: Should embeds be suppressed on this send
        flags: Message flags to apply.
        delete_after: Delete message after this many seconds.

    Returns:
        New message object that was sent.

    """
    if not content and not (embeds or embed) and not (files or file) and not stickers:
        raise errors.EmptyMessageException(
            "You cannot send a message without any content, embeds, files, or stickers"
        )

    if suppress_embeds:
        if isinstance(flags, int):
            flags = MessageFlags(flags)
        flags = flags | MessageFlags.SUPPRESS_EMBEDS

    message_payload = models.discord.message.process_message_payload(
        content=content,
        embeds=embeds or embed,
        components=components,
        stickers=stickers,
        allowed_mentions=allowed_mentions,
        reply_to=reply_to,
        tts=tts,
        flags=flags,
        **kwargs,
    )

    message_data = await self._send_http_request(message_payload, files=files or file)
    if message_data:
        message = self._client.cache.place_message_data(message_data)
        if delete_after:
            await message.delete(delay=delete_after)
        return message

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

async inherited method fetch_message(self, message_id)

Fetch a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
Optional[models.Message]

The message object fetched. If the message is not found, returns None.

Source code in naff/models/discord/channel.py
async def fetch_message(self, message_id: Snowflake_Type) -> Optional["models.Message"]:
    """
    Fetch a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched. If the message is not found, returns None.

    """
    try:
        return await self._client.cache.fetch_message(self.id, message_id)
    except NotFound:
        return None

inherited method get_message(self, message_id)

Get a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
models.Message

The message object fetched.

Source code in naff/models/discord/channel.py
def get_message(self, message_id: Snowflake_Type) -> "models.Message":
    """
    Get a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched.

    """
    message_id = to_snowflake(message_id)
    message: "models.Message" = self._client.cache.get_message(self.id, message_id)
    return message

inherited method history(self, limit, before, after, around)

Get an async iterator for the history of this channel.

Parameters:

Name Type Description Default
limit

The maximum number of messages to return (set to 0 for no limit)

100
before Union[int, str, SnowflakeObject, SupportsInt]

get messages before this message ID

None
after Union[int, str, SnowflakeObject, SupportsInt]

get messages after this message ID

None
around Union[int, str, SnowflakeObject, SupportsInt]

get messages "around" this message ID

None
Example Usage:

1
2
3
4
5
async for message in channel.history(limit=0):
    if message.author.id == 174918559539920897:
        print("Found author's message")
        # ...
        break
or
1
2
3
history = channel.history(limit=250)
# Flatten the async iterator into a list
messages = await history.flatten()

Returns:

Type Description
ChannelHistory

ChannelHistory (AsyncIterator)

Source code in naff/models/discord/channel.py
def history(
    self,
    limit=100,
    before: Snowflake_Type = None,
    after: Snowflake_Type = None,
    around: Snowflake_Type = None,
) -> ChannelHistory:
    """
    Get an async iterator for the history of this channel.

    Args:
        limit: The maximum number of messages to return (set to 0 for no limit)
        before: get messages before this message ID
        after: get messages after this message ID
        around: get messages "around" this message ID

    ??? Hint "Example Usage:"
        ```python
        async for message in channel.history(limit=0):
            if message.author.id == 174918559539920897:
                print("Found author's message")
                # ...
                break
        ```
        or
        ```python
        history = channel.history(limit=250)
        # Flatten the async iterator into a list
        messages = await history.flatten()
        ```

    Returns:
        ChannelHistory (AsyncIterator)

    """
    return ChannelHistory(self, limit, before, after, around)

async inherited method fetch_messages(self, limit, around, before, after)

Fetch multiple messages from the channel.

Parameters:

Name Type Description Default
limit int

Max number of messages to return, default 50, max 100

50
around Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages around

Missing
before Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages before

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages after

Missing

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_messages(
    self,
    limit: int = 50,
    around: Snowflake_Type = MISSING,
    before: Snowflake_Type = MISSING,
    after: Snowflake_Type = MISSING,
) -> List["models.Message"]:
    """
    Fetch multiple messages from the channel.

    Args:
        limit: Max number of messages to return, default `50`, max `100`
        around: Message to get messages around
        before: Message to get messages before
        after: Message to get messages after

    Returns:
        A list of messages fetched.

    """
    if limit > 100:
        raise ValueError("You cannot fetch more than 100 messages at once.")

    if around:
        around = to_snowflake(around)
    elif before:
        before = to_snowflake(before)
    elif after:
        after = to_snowflake(after)

    messages_data = await self._client.http.get_channel_messages(self.id, limit, around, before, after)
    for m in messages_data:
        m["guild_id"] = self._guild_id

    return [self._client.cache.place_message_data(m) for m in messages_data]

async inherited method fetch_pinned_messages(self)

Fetch pinned messages from the channel.

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_pinned_messages(self) -> List["models.Message"]:
    """
    Fetch pinned messages from the channel.

    Returns:
        A list of messages fetched.

    """
    messages_data = await self._client.http.get_pinned_messages(self.id)
    return [self._client.cache.place_message_data(message_data) for message_data in messages_data]

async inherited method delete_messages(self, messages, reason)

Bulk delete messages from channel.

Parameters:

Name Type Description Default
messages List[Union[int, str, SnowflakeObject, SupportsInt, models.Message]]

List of messages or message IDs to delete.

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this action. Used for audit logs.

Missing
Source code in naff/models/discord/channel.py
async def delete_messages(
    self, messages: List[Union[Snowflake_Type, "models.Message"]], reason: Absent[Optional[str]] = MISSING
) -> None:
    """
    Bulk delete messages from channel.

    Args:
        messages: List of messages or message IDs to delete.
        reason: The reason for this action. Used for audit logs.

    """
    message_ids = [to_snowflake(message) for message in messages]
    # TODO Add check for min/max and duplicates.

    if len(message_ids) == 1:
        # bulk delete messages will throw a http error if only 1 message is passed
        await self.delete_message(message_ids[0], reason)
    else:
        await self._client.http.bulk_delete_messages(self.id, message_ids, reason)

async inherited method delete_message(self, message, reason)

Delete a single message from a channel.

Parameters:

Name Type Description Default
message Union[int, str, SnowflakeObject, SupportsInt, models.Message]

The message to delete

required
reason str

The reason for this action

None
Source code in naff/models/discord/channel.py
async def delete_message(self, message: Union[Snowflake_Type, "models.Message"], reason: str = None) -> None:
    """
    Delete a single message from a channel.

    Args:
        message: The message to delete
        reason: The reason for this action

    """
    message = to_snowflake(message)
    await self._client.http.delete_message(self.id, message, reason=reason)

async inherited method purge(self, deletion_limit, search_limit, predicate, avoid_loading_msg, before, after, around, reason)

Bulk delete messages within a channel. If a predicate is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the deletion_limit.

Example Usage:
1
2
3
# this will delete the last 20 messages sent by a user with the given ID
deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
await channel.send(f"{deleted} messages deleted")

Parameters:

Name Type Description Default
deletion_limit int

The target amount of messages to delete

50
search_limit int

How many messages to search through

100
predicate Callable[[models.Message], bool]

A function that returns True or False, and takes a message as an argument

Missing
avoid_loading_msg bool

Should the bot attempt to avoid deleting its own loading messages (recommended enabled)

True
before Union[int, str, SnowflakeObject, SupportsInt]

Search messages before this ID

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Search messages after this ID

Missing
around Union[int, str, SnowflakeObject, SupportsInt]

Search messages around this ID

Missing
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this deletion

Missing

Returns:

Type Description
int

The total amount of messages deleted

Source code in naff/models/discord/channel.py
async def purge(
    self,
    deletion_limit: int = 50,
    search_limit: int = 100,
    predicate: Callable[["models.Message"], bool] = MISSING,
    avoid_loading_msg: bool = True,
    before: Optional[Snowflake_Type] = MISSING,
    after: Optional[Snowflake_Type] = MISSING,
    around: Optional[Snowflake_Type] = MISSING,
    reason: Absent[Optional[str]] = MISSING,
) -> int:
    """
    Bulk delete messages within a channel. If a `predicate` is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the `deletion_limit`.

    ??? Hint "Example Usage:"
        ```python
        # this will delete the last 20 messages sent by a user with the given ID
        deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
        await channel.send(f"{deleted} messages deleted")
        ```

    Args:
        deletion_limit: The target amount of messages to delete
        search_limit: How many messages to search through
        predicate: A function that returns True or False, and takes a message as an argument
        avoid_loading_msg: Should the bot attempt to avoid deleting its own loading messages (recommended enabled)
        before: Search messages before this ID
        after: Search messages after this ID
        around: Search messages around this ID
        reason: The reason for this deletion

    Returns:
        The total amount of messages deleted

    """
    if not predicate:

        def predicate(m) -> bool:
            return True  # noqa

    to_delete = []

    # 1209600 14 days ago in seconds, 1420070400000 is used to convert to snowflake
    fourteen_days_ago = int((time.time() - 1209600) * 1000.0 - DISCORD_EPOCH) << 22
    async for message in self.history(limit=search_limit, before=before, after=after, around=around):
        if deletion_limit != 0 and len(to_delete) == deletion_limit:
            break

        if not predicate(message):
            # fails predicate
            continue

        if avoid_loading_msg:
            if message._author_id == self._client.user.id and MessageFlags.LOADING in message.flags:
                continue

        if message.id < fourteen_days_ago:
            # message is too old to be purged
            continue

        to_delete.append(message.id)

    count = len(to_delete)
    while len(to_delete):
        iteration = [to_delete.pop() for i in range(min(100, len(to_delete)))]
        await self.delete_messages(iteration, reason=reason)
    return count

async inherited method trigger_typing(self)

Trigger a typing animation in this channel.

Source code in naff/models/discord/channel.py
async def trigger_typing(self) -> None:
    """Trigger a typing animation in this channel."""
    await self._client.http.trigger_typing_indicator(self.id)

inherited property readonly typing: Typing

A context manager to send a typing state to a given channel as long as long as the wrapped operation takes.

async inherited method create_webhook(self, name, avatar)

Create a webhook in this channel.

Parameters:

Name Type Description Default
name str

The name of the webhook

required
avatar Union[naff.models.discord.file.File, io.IOBase, BinaryIO, pathlib.Path, str, naff.client.const.Missing]

An optional default avatar image to use

Missing

Returns:

Type Description
models.Webhook

The created webhook object

Exceptions:

Type Description
ValueError

If you try to name the webhook "Clyde"

Source code in naff/models/discord/channel.py
async def create_webhook(self, name: str, avatar: Absent[UPLOADABLE_TYPE] = MISSING) -> "models.Webhook":
    """
    Create a webhook in this channel.

    Args:
        name: The name of the webhook
        avatar: An optional default avatar image to use

    Returns:
        The created webhook object

    Raises:
        ValueError: If you try to name the webhook "Clyde"

    """
    return await models.Webhook.create(self._client, self, name, avatar)  # type: ignore

async inherited method delete_webhook(self, webhook)

Delete a given webhook in this channel.

Parameters:

Name Type Description Default
webhook models.Webhook

The webhook to delete

required
Source code in naff/models/discord/channel.py
async def delete_webhook(self, webhook: "models.Webhook") -> None:
    """
    Delete a given webhook in this channel.

    Args:
        webhook: The webhook to delete

    """
    return await webhook.delete()

async inherited method fetch_webhooks(self)

Fetches all the webhooks for this channel.

Returns:

Type Description
List[models.Webhook]

List of webhook objects

Source code in naff/models/discord/channel.py
async def fetch_webhooks(self) -> List["models.Webhook"]:
    """
    Fetches all the webhooks for this channel.

    Returns:
        List of webhook objects

    """
    resp = await self._client.http.get_channel_webhooks(self.id)
    return [models.Webhook.from_dict(d, self._client) for d in resp]

async inherited method delete(self, reason)

Delete this channel.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for deleting this channel

Missing
Source code in naff/models/discord/channel.py
async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Delete this channel.

    Args:
        reason: The reason for deleting this channel

    """
    await self._client.http.delete_channel(self.id, reason)

inherited property readonly is_private: bool

Is this a private thread?

inherited property readonly guild: models.Guild

The guild this channel belongs to.

inherited property readonly parent_channel: Union[naff.models.discord.channel.GuildText, GuildForum]

The channel this thread is a child of.

inherited property readonly parent_message: Optional[Message]

The message this thread is a child of.

inherited property readonly mention: str

Returns a string that would mention this thread.

inherited property readonly permission_overwrites: List[PermissionOverwrite]

The permission overwrites for this channel.

async inherited method fetch_members(self)

Get the members that have access to this thread.

Source code in naff/models/discord/channel.py
async def fetch_members(self) -> List["models.ThreadMember"]:
    """Get the members that have access to this thread."""
    members_data = await self._client.http.list_thread_members(self.id)
    return models.ThreadMember.from_list(members_data, self._client)

async inherited method add_member(self, member)

Add a member to this thread.

Parameters:

Name Type Description Default
member Union[models.Member, int, str, SnowflakeObject, SupportsInt]

The member to add

required
Source code in naff/models/discord/channel.py
async def add_member(self, member: Union["models.Member", Snowflake_Type]) -> None:
    """
    Add a member to this thread.

    Args:
        member: The member to add

    """
    await self._client.http.add_thread_member(self.id, to_snowflake(member))

async inherited method remove_member(self, member)

Remove a member from this thread.

Parameters:

Name Type Description Default
member Union[models.Member, int, str, SnowflakeObject, SupportsInt]

The member to remove

required
Source code in naff/models/discord/channel.py
async def remove_member(self, member: Union["models.Member", Snowflake_Type]) -> None:
    """
    Remove a member from this thread.

    Args:
        member: The member to remove

    """
    await self._client.http.remove_thread_member(self.id, to_snowflake(member))

async inherited method join(self)

Join this thread.

Source code in naff/models/discord/channel.py
async def join(self) -> None:
    """Join this thread."""
    await self._client.http.join_thread(self.id)

async inherited method leave(self)

Leave this thread.

Source code in naff/models/discord/channel.py
async def leave(self) -> None:
    """Leave this thread."""
    await self._client.http.leave_thread(self.id)

async inherited method archive(self, locked, reason)

Helper method to archive this thread.

Parameters:

Name Type Description Default
locked bool

whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it

False
reason Union[str, naff.client.const.Missing]

The reason for this archive

Missing

Returns:

Type Description
TYPE_THREAD_CHANNEL

The archived thread channel object.

Source code in naff/models/discord/channel.py
async def archive(self, locked: bool = False, reason: Absent[str] = MISSING) -> "TYPE_THREAD_CHANNEL":
    """
    Helper method to archive this thread.

    Args:
        locked: whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
        reason: The reason for this archive

    Returns:
        The archived thread channel object.

    """
    return await super().edit(locked=locked, archived=True, reason=reason)

async method edit(self, name, archived, auto_archive_duration, locked, rate_limit_per_user, invitable, reason, **kwargs)

Edit this thread.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

1-100 character channel name

Missing
archived Union[bool, naff.client.const.Missing]

whether the thread is archived

Missing
auto_archive_duration Union[naff.models.discord.enums.AutoArchiveDuration, naff.client.const.Missing]

duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080

Missing
locked Union[bool, naff.client.const.Missing]

whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it

Missing
rate_limit_per_user Union[int, naff.client.const.Missing]

amount of seconds a user has to wait before sending another message (0-21600)

Missing
invitable Union[bool, naff.client.const.Missing]

whether non-moderators can add other non-moderators to a thread; only available on private threads

Missing
reason Union[str, naff.client.const.Missing]

The reason for this change

Missing

Returns:

Type Description
GuildPrivateThread

The edited thread channel object.

Source code in naff/models/discord/channel.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    archived: Absent[bool] = MISSING,
    auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
    locked: Absent[bool] = MISSING,
    rate_limit_per_user: Absent[int] = MISSING,
    invitable: Absent[bool] = MISSING,
    reason: Absent[str] = MISSING,
    **kwargs,
) -> "GuildPrivateThread":
    """
    Edit this thread.

    Args:
        name: 1-100 character channel name
        archived: whether the thread is archived
        auto_archive_duration: duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080
        locked: whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
        rate_limit_per_user: amount of seconds a user has to wait before sending another message (0-21600)
        invitable: whether non-moderators can add other non-moderators to a thread; only available on private threads
        reason: The reason for this change

    Returns:
        The edited thread channel object.

    """
    return await super().edit(
        name=name,
        archived=archived,
        auto_archive_duration=auto_archive_duration,
        locked=locked,
        rate_limit_per_user=rate_limit_per_user,
        invitable=invitable,
        reason=reason,
        **kwargs,
    )

attrs class VoiceChannel (GuildChannel)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

bitrate int

The bitrate (in bits) of the voice channel

user_limit int

The user limit of the voice channel

rtc_region str

Voice region id for the voice channel, automatic when set to None

video_quality_mode Union[naff.models.discord.enums.VideoQualityModes, int]

The camera video quality mode of the voice channel, 1 when not present

Source code in naff/models/discord/channel.py
@define(slots=False)
class VoiceChannel(GuildChannel):  # May not be needed, can be directly just GuildVoice.
    bitrate: int = field()
    """The bitrate (in bits) of the voice channel"""
    user_limit: int = field()
    """The user limit of the voice channel"""
    rtc_region: str = field(default="auto")
    """Voice region id for the voice channel, automatic when set to None"""
    video_quality_mode: Union[VideoQualityModes, int] = field(default=VideoQualityModes.AUTO)
    """The camera video quality mode of the voice channel, 1 when not present"""
    _voice_member_ids: list[Snowflake_Type] = field(factory=list)

    async def edit(
        self,
        name: Absent[str] = MISSING,
        position: Absent[int] = MISSING,
        permission_overwrites: Absent[
            Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
        ] = MISSING,
        parent_id: Absent[Snowflake_Type] = MISSING,
        bitrate: Absent[int] = MISSING,
        user_limit: Absent[int] = MISSING,
        rtc_region: Absent[str] = MISSING,
        video_quality_mode: Absent[VideoQualityModes] = MISSING,
        reason: Absent[str] = MISSING,
        **kwargs,
    ) -> Union["GuildVoice", "GuildStageVoice"]:
        """
        Edit guild voice channel.

        Args:
            name: 1-100 character channel name
            position: the position of the channel in the left-hand listing
            permission_overwrites: a list of `PermissionOverwrite` to apply to the channel
            parent_id: the parent category `Snowflake_Type` for the channel
            bitrate: the bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)
            user_limit: the user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit
            rtc_region: channel voice region id, automatic when not set
            video_quality_mode: the camera video quality mode of the voice channel
            reason: optional reason for audit logs

        Returns:
            The edited voice channel object.

        """
        return await super().edit(
            name=name,
            position=position,
            permission_overwrites=permission_overwrites,
            parent_id=parent_id,
            bitrate=bitrate,
            user_limit=user_limit,
            rtc_region=rtc_region,
            video_quality_mode=video_quality_mode,
            reason=reason,
            **kwargs,
        )

    @property
    def members(self) -> List["models.Member"]:
        """Returns a list of members that have access to this voice channel"""
        return [m for m in self.guild.members if Permissions.CONNECT in m.channel_permissions(self)]  # type: ignore

    @property
    def voice_members(self) -> List["models.Member"]:
        """Returns a list of members that are currently in the channel. Note: This will not be accurate if the bot was offline while users joined the channel"""
        return [self._client.cache.get_member(self._guild_id, member_id) for member_id in self._voice_member_ids]

    @property
    def voice_state(self) -> Optional["ActiveVoiceState"]:
        """Returns the voice state of the bot in this channel if it is connected"""
        return self._client.get_bot_voice_state(self._guild_id)

    async def connect(self, muted: bool = False, deafened: bool = False) -> "ActiveVoiceState":
        """
        Connect the bot to this voice channel, or move the bot to this voice channel if it is already connected in another voice channel.

        Args:
            muted: Whether the bot should be muted when connected.
            deafened: Whether the bot should be deafened when connected.

        Returns:
            The new active voice state on successfully connection.

        """
        if not self.voice_state:
            return await self._client.connect_to_vc(self._guild_id, self.id, muted, deafened)
        await self.voice_state.move(self.id)
        return self.voice_state

    async def disconnect(self) -> None:
        """
        Disconnect from the currently connected connected voice state.

        Raises:
            VoiceNotConnected if the bot is not connected to a voice channel
        """
        if self.voice_state:
            return await self.voice_state.disconnect()
        else:
            raise VoiceNotConnected

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

inherited property readonly mention: str

Returns a string that would mention the channel.

async inherited method delete(self, reason)

Delete this channel.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for deleting this channel

Missing
Source code in naff/models/discord/channel.py
async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Delete this channel.

    Args:
        reason: The reason for deleting this channel

    """
    await self._client.http.delete_channel(self.id, reason)

inherited property readonly guild: models.Guild

The guild this channel belongs to.

inherited property readonly category: Optional[GuildCategory]

The parent category of this channel.

inherited property readonly gui_position: int

The position of this channel in the Discord interface.

inherited method permissions_for(self, instance)

Calculates permissions for an instance

Parameters:

Name Type Description Default
instance Union[int, str, SnowflakeObject, SupportsInt]

Member or Role instance (or its ID)

required

Returns:

Type Description
Permissions

Permissions data

Exceptions:

Type Description
ValueError

If could not find any member or role by given ID

RuntimeError

If given instance is from another guild

Source code in naff/models/discord/channel.py
def permissions_for(self, instance: Snowflake_Type) -> Permissions:
    """
    Calculates permissions for an instance

    Args:
        instance: Member or Role instance (or its ID)

    Returns:
        Permissions data

    Raises:
        ValueError: If could not find any member or role by given ID
        RuntimeError: If given instance is from another guild

    """
    if (is_member := isinstance(instance, models.Member)) or isinstance(instance, models.Role):
        if instance._guild_id != self._guild_id:
            raise RuntimeError("Unable to calculate permissions for the instance from different guild")

        if is_member:
            return instance.channel_permissions(self)

        else:
            permissions = instance.permissions

            for overwrite in self.permission_overwrites:
                if overwrite.id == instance.id:
                    permissions &= ~overwrite.deny
                    permissions |= overwrite.allow
                    break

            return permissions

    else:
        instance = to_snowflake(instance)
        guild = self.guild
        instance = guild.get_member(instance) or guild.get_role(instance)

        if not instance:
            raise ValueError("Unable to find any member or role by given instance ID")

        return self.permissions_for(instance)

async inherited method add_permission(self, target, type, allow, deny, reason)

Add a permission to this channel.

Parameters:

Name Type Description Default
target Union[PermissionOverwrite, models.Role, models.User, models.Member, Snowflake_Type]

The updated PermissionOverwrite object, or the Role or User object/id to update

required
type Optional[OverwriteTypes]

The type of permission overwrite. Only applicable if target is an id

None
allow Union[List[Permissions], int]

List of permissions to allow. Only applicable if target is not an PermissionOverwrite object

None
deny Union[List[Permissions], int]

List of permissions to deny. Only applicable if target is not an PermissionOverwrite object

None
reason Optional[str]

The reason for this change

None

Exceptions:

Type Description
ValueError

Invalid target for permission

Source code in naff/models/discord/channel.py
async def add_permission(
    self,
    target: Union["PermissionOverwrite", "models.Role", "models.User", "models.Member", "Snowflake_Type"],
    type: Optional["OverwriteTypes"] = None,
    allow: Optional[List["Permissions"] | int] = None,
    deny: Optional[List["Permissions"] | int] = None,
    reason: Optional[str] = None,
) -> None:
    """
    Add a permission to this channel.

    Args:
        target: The updated PermissionOverwrite object, or the Role or User object/id to update
        type: The type of permission overwrite. Only applicable if target is an id
        allow: List of permissions to allow. Only applicable if target is not an PermissionOverwrite object
        deny: List of permissions to deny. Only applicable if target is not an PermissionOverwrite object
        reason: The reason for this change

    Raises:
        ValueError: Invalid target for permission

    """
    allow = allow or []
    deny = deny or []
    if not isinstance(target, PermissionOverwrite):
        if isinstance(target, (models.User, models.Member)):
            target = target.id
            type = OverwriteTypes.MEMBER
        elif isinstance(target, models.Role):
            target = target.id
            type = OverwriteTypes.ROLE
        elif type and isinstance(target, Snowflake_Type):
            target = to_snowflake(target)
        else:
            raise ValueError("Invalid target and/or type for permission")
        overwrite = PermissionOverwrite(id=target, type=type, allow=Permissions.NONE, deny=Permissions.NONE)
        if isinstance(allow, int):
            overwrite.allow |= allow
        else:
            for perm in allow:
                overwrite.allow |= perm
        if isinstance(deny, int):
            overwrite.deny |= deny
        else:
            for perm in deny:
                overwrite.deny |= perm
    else:
        overwrite = target

    if exists := get(self.permission_overwrites, id=overwrite.id, type=overwrite.type):
        exists.deny = (exists.deny | overwrite.deny) & ~overwrite.allow
        exists.allow = (exists.allow | overwrite.allow) & ~overwrite.deny
        await self.edit_permission(exists, reason)
    else:
        permission_overwrites = self.permission_overwrites
        permission_overwrites.append(overwrite)
        await self.edit(permission_overwrites=permission_overwrites)

async inherited method edit_permission(self, overwrite, reason)

Edit the permissions for this channel.

Parameters:

Name Type Description Default
overwrite PermissionOverwrite

The permission overwrite to apply

required
reason Optional[str]

The reason for this change

None
Source code in naff/models/discord/channel.py
async def edit_permission(self, overwrite: PermissionOverwrite, reason: Optional[str] = None) -> None:
    """
    Edit the permissions for this channel.

    Args:
        overwrite: The permission overwrite to apply
        reason: The reason for this change
    """
    await self._client.http.edit_channel_permission(
        self.id, overwrite.id, overwrite.allow, overwrite.deny, overwrite.type, reason
    )

async inherited method delete_permission(self, target, reason)

Delete a permission overwrite for this channel.

Parameters:

Name Type Description Default
target Union[PermissionOverwrite, models.Role, models.User]

The permission overwrite to delete

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this change

Missing
Source code in naff/models/discord/channel.py
async def delete_permission(
    self,
    target: Union["PermissionOverwrite", "models.Role", "models.User"],
    reason: Absent[Optional[str]] = MISSING,
) -> None:
    """
    Delete a permission overwrite for this channel.

    Args:
        target: The permission overwrite to delete
        reason: The reason for this change

    """
    target = to_snowflake(target)
    await self._client.http.delete_channel_permission(self.id, target, reason)

async inherited method set_permission(self, target, *, add_reactions, administrator, attach_files, ban_members, change_nickname, connect, create_instant_invite, deafen_members, embed_links, kick_members, manage_channels, manage_emojis_and_stickers, manage_events, manage_guild, manage_messages, manage_nicknames, manage_roles, manage_threads, manage_webhooks, mention_everyone, moderate_members, move_members, mute_members, priority_speaker, read_message_history, request_to_speak, send_messages, send_messages_in_threads, send_tts_messages, speak, start_embedded_activities, stream, use_application_commands, use_external_emojis, use_external_stickers, use_private_threads, use_public_threads, use_vad, view_audit_log, view_channel, view_guild_insights, reason)

Set the Permission Overwrites for a given target.

Parameters:

Name Type Description Default
target Union[models.Role, models.Member, models.User]

The target to set permission overwrites for

required
add_reactions bool | None

Allows for the addition of reactions to messages

None
administrator bool | None

Allows all permissions and bypasses channel permission overwrites

None
attach_files bool | None

Allows for uploading images and files

None
ban_members bool | None

Allows banning members

None
change_nickname bool | None

Allows for modification of own nickname

None
connect bool | None

Allows for joining of a voice channel

None
create_instant_invite bool | None

Allows creation of instant invites

None
deafen_members bool | None

Allows for deafening of members in a voice channel

None
embed_links bool | None

Links sent by users with this permission will be auto-embedded

None
kick_members bool | None

Allows kicking members

None
manage_channels bool | None

Allows management and editing of channels

None
manage_emojis_and_stickers bool | None

Allows management and editing of emojis and stickers

None
manage_events bool | None

Allows for creating, editing, and deleting scheduled events

None
manage_guild bool | None

Allows management and editing of the guild

None
manage_messages bool | None

Allows for deletion of other users messages

None
manage_nicknames bool | None

Allows for modification of other users nicknames

None
manage_roles bool | None

Allows management and editing of roles

None
manage_threads bool | None

Allows for deleting and archiving threads, and viewing all private threads

None
manage_webhooks bool | None

Allows management and editing of webhooks

None
mention_everyone bool | None

Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all online users in a channel

None
moderate_members bool | None

Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels

None
move_members bool | None

Allows for moving of members between voice channels

None
mute_members bool | None

Allows for muting members in a voice channel

None
priority_speaker bool | None

Allows for using priority speaker in a voice channel

None
read_message_history bool | None

Allows for reading of message history

None
request_to_speak bool | None

Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)

None
send_messages bool | None

Allows for sending messages in a channel (does not allow sending messages in threads)

None
send_messages_in_threads bool | None

Allows for sending messages in threads

None
send_tts_messages bool | None

Allows for sending of /tts messages

None
speak bool | None

Allows for speaking in a voice channel

None
start_embedded_activities bool | None

Allows for using Activities (applications with the EMBEDDED flag) in a voice channel

None
stream bool | None

Allows the user to go live

None
use_application_commands bool | None

Allows members to use application commands, including slash commands and context menu commands

None
use_external_emojis bool | None

Allows the usage of custom emojis from other servers

None
use_external_stickers bool | None

Allows the usage of custom stickers from other servers

None
use_private_threads bool | None

Allows for creating private threads

None
use_public_threads bool | None

Allows for creating public and announcement threads

None
use_vad bool | None

Allows for using voice-activity-detection in a voice channel

None
view_audit_log bool | None

Allows for viewing of audit logs

None
view_channel bool | None

Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels

None
view_guild_insights bool | None

Allows for viewing guild insights

None
reason str

The reason for creating this overwrite

None
Source code in naff/models/discord/channel.py
async def set_permission(
    self,
    target: Union["models.Role", "models.Member", "models.User"],
    *,
    add_reactions: bool | None = None,
    administrator: bool | None = None,
    attach_files: bool | None = None,
    ban_members: bool | None = None,
    change_nickname: bool | None = None,
    connect: bool | None = None,
    create_instant_invite: bool | None = None,
    deafen_members: bool | None = None,
    embed_links: bool | None = None,
    kick_members: bool | None = None,
    manage_channels: bool | None = None,
    manage_emojis_and_stickers: bool | None = None,
    manage_events: bool | None = None,
    manage_guild: bool | None = None,
    manage_messages: bool | None = None,
    manage_nicknames: bool | None = None,
    manage_roles: bool | None = None,
    manage_threads: bool | None = None,
    manage_webhooks: bool | None = None,
    mention_everyone: bool | None = None,
    moderate_members: bool | None = None,
    move_members: bool | None = None,
    mute_members: bool | None = None,
    priority_speaker: bool | None = None,
    read_message_history: bool | None = None,
    request_to_speak: bool | None = None,
    send_messages: bool | None = None,
    send_messages_in_threads: bool | None = None,
    send_tts_messages: bool | None = None,
    speak: bool | None = None,
    start_embedded_activities: bool | None = None,
    stream: bool | None = None,
    use_application_commands: bool | None = None,
    use_external_emojis: bool | None = None,
    use_external_stickers: bool | None = None,
    use_private_threads: bool | None = None,
    use_public_threads: bool | None = None,
    use_vad: bool | None = None,
    view_audit_log: bool | None = None,
    view_channel: bool | None = None,
    view_guild_insights: bool | None = None,
    reason: str = None,
) -> None:
    """
    Set the Permission Overwrites for a given target.

    Args:
        target: The target to set permission overwrites for
        add_reactions: Allows for the addition of reactions to messages
        administrator: Allows all permissions and bypasses channel permission overwrites
        attach_files: Allows for uploading images and files
        ban_members: Allows banning members
        change_nickname: Allows for modification of own nickname
        connect: Allows for joining of a voice channel
        create_instant_invite: Allows creation of instant invites
        deafen_members: Allows for deafening of members in a voice channel
        embed_links: Links sent by users with this permission will be auto-embedded
        kick_members: Allows kicking members
        manage_channels: Allows management and editing of channels
        manage_emojis_and_stickers: Allows management and editing of emojis and stickers
        manage_events: Allows for creating, editing, and deleting scheduled events
        manage_guild: Allows management and editing of the guild
        manage_messages: Allows for deletion of other users messages
        manage_nicknames: Allows for modification of other users nicknames
        manage_roles: Allows management and editing of roles
        manage_threads: Allows for deleting and archiving threads, and viewing all private threads
        manage_webhooks: Allows management and editing of webhooks
        mention_everyone: Allows for using the `@everyone` tag to notify all users in a channel, and the `@here` tag to notify all online users in a channel
        moderate_members: Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels
        move_members: Allows for moving of members between voice channels
        mute_members: Allows for muting members in a voice channel
        priority_speaker: Allows for using priority speaker in a voice channel
        read_message_history: Allows for reading of message history
        request_to_speak: Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)
        send_messages:  Allows for sending messages in a channel (does not allow sending messages in threads)
        send_messages_in_threads: Allows for sending messages in threads
        send_tts_messages:  Allows for sending of `/tts` messages
        speak: Allows for speaking in a voice channel
        start_embedded_activities: Allows for using Activities (applications with the `EMBEDDED` flag) in a voice channel
        stream: Allows the user to go live
        use_application_commands: Allows members to use application commands, including slash commands and context menu commands
        use_external_emojis: Allows the usage of custom emojis from other servers
        use_external_stickers: Allows the usage of custom stickers from other servers
        use_private_threads: Allows for creating private threads
        use_public_threads:  Allows for creating public and announcement threads
        use_vad: Allows for using voice-activity-detection in a voice channel
        view_audit_log: Allows for viewing of audit logs
        view_channel: Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels
        view_guild_insights: Allows for viewing guild insights
        reason: The reason for creating this overwrite
    """
    overwrite = PermissionOverwrite.for_target(target)

    allow: Permissions = Permissions.NONE
    deny: Permissions = Permissions.NONE

    for name, val in locals().items():
        if isinstance(val, bool):
            if val:
                allow |= getattr(Permissions, name.upper())
            else:
                deny |= getattr(Permissions, name.upper())

    overwrite.add_allows(allow)
    overwrite.add_denies(deny)

    await self.edit_permission(overwrite, reason)

inherited property readonly bots: List[models.Member]

Returns a list of bots that can see this channel.

inherited property readonly humans: List[models.Member]

Returns a list of humans that can see this channel.

async inherited method clone(self, name, reason)

Clone this channel and create a new one.

Parameters:

Name Type Description Default
name Optional[str]

The name of the new channel. Defaults to the current name

None
reason Union[str, NoneType, naff.client.const.Missing]

The reason for creating this channel

Missing

Returns:

Type Description
TYPE_GUILD_CHANNEL

The newly created channel.

Source code in naff/models/discord/channel.py
async def clone(self, name: Optional[str] = None, reason: Absent[Optional[str]] = MISSING) -> "TYPE_GUILD_CHANNEL":
    """
    Clone this channel and create a new one.

    Args:
        name: The name of the new channel. Defaults to the current name
        reason: The reason for creating this channel

    Returns:
        The newly created channel.

    """
    return await self.guild.create_channel(
        channel_type=self.type,
        name=name if name else self.name,
        topic=getattr(self, "topic", MISSING),
        position=self.position,
        permission_overwrites=self.permission_overwrites,
        category=self.category,
        nsfw=self.nsfw,
        bitrate=getattr(self, "bitrate", 64000),
        user_limit=getattr(self, "user_limit", 0),
        rate_limit_per_user=getattr(self, "rate_limit_per_user", 0),
        reason=reason,
    )

async method edit(self, name, position, permission_overwrites, parent_id, bitrate, user_limit, rtc_region, video_quality_mode, reason, **kwargs)

Edit guild voice channel.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

1-100 character channel name

Missing
position Union[int, naff.client.const.Missing]

the position of the channel in the left-hand listing

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

a list of PermissionOverwrite to apply to the channel

Missing
parent_id Union[int, str, SnowflakeObject, SupportsInt, naff.client.const.Missing]

the parent category Snowflake_Type for the channel

Missing
bitrate Union[int, naff.client.const.Missing]

the bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)

Missing
user_limit Union[int, naff.client.const.Missing]

the user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit

Missing
rtc_region Union[str, naff.client.const.Missing]

channel voice region id, automatic when not set

Missing
video_quality_mode Union[naff.models.discord.enums.VideoQualityModes, naff.client.const.Missing]

the camera video quality mode of the voice channel

Missing
reason Union[str, naff.client.const.Missing]

optional reason for audit logs

Missing

Returns:

Type Description
Union[GuildVoice, GuildStageVoice]

The edited voice channel object.

Source code in naff/models/discord/channel.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    position: Absent[int] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    parent_id: Absent[Snowflake_Type] = MISSING,
    bitrate: Absent[int] = MISSING,
    user_limit: Absent[int] = MISSING,
    rtc_region: Absent[str] = MISSING,
    video_quality_mode: Absent[VideoQualityModes] = MISSING,
    reason: Absent[str] = MISSING,
    **kwargs,
) -> Union["GuildVoice", "GuildStageVoice"]:
    """
    Edit guild voice channel.

    Args:
        name: 1-100 character channel name
        position: the position of the channel in the left-hand listing
        permission_overwrites: a list of `PermissionOverwrite` to apply to the channel
        parent_id: the parent category `Snowflake_Type` for the channel
        bitrate: the bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)
        user_limit: the user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit
        rtc_region: channel voice region id, automatic when not set
        video_quality_mode: the camera video quality mode of the voice channel
        reason: optional reason for audit logs

    Returns:
        The edited voice channel object.

    """
    return await super().edit(
        name=name,
        position=position,
        permission_overwrites=permission_overwrites,
        parent_id=parent_id,
        bitrate=bitrate,
        user_limit=user_limit,
        rtc_region=rtc_region,
        video_quality_mode=video_quality_mode,
        reason=reason,
        **kwargs,
    )

property readonly members: List[models.Member]

Returns a list of members that have access to this voice channel

property readonly voice_members: List[models.Member]

Returns a list of members that are currently in the channel. Note: This will not be accurate if the bot was offline while users joined the channel

property readonly voice_state: Optional[ActiveVoiceState]

Returns the voice state of the bot in this channel if it is connected

async method connect(self, muted, deafened)

Connect the bot to this voice channel, or move the bot to this voice channel if it is already connected in another voice channel.

Parameters:

Name Type Description Default
muted bool

Whether the bot should be muted when connected.

False
deafened bool

Whether the bot should be deafened when connected.

False

Returns:

Type Description
ActiveVoiceState

The new active voice state on successfully connection.

Source code in naff/models/discord/channel.py
async def connect(self, muted: bool = False, deafened: bool = False) -> "ActiveVoiceState":
    """
    Connect the bot to this voice channel, or move the bot to this voice channel if it is already connected in another voice channel.

    Args:
        muted: Whether the bot should be muted when connected.
        deafened: Whether the bot should be deafened when connected.

    Returns:
        The new active voice state on successfully connection.

    """
    if not self.voice_state:
        return await self._client.connect_to_vc(self._guild_id, self.id, muted, deafened)
    await self.voice_state.move(self.id)
    return self.voice_state

async method disconnect(self)

Disconnect from the currently connected connected voice state.

Source code in naff/models/discord/channel.py
async def disconnect(self) -> None:
    """
    Disconnect from the currently connected connected voice state.

    Raises:
        VoiceNotConnected if the bot is not connected to a voice channel
    """
    if self.voice_state:
        return await self.voice_state.disconnect()
    else:
        raise VoiceNotConnected

attrs class GuildVoice (VoiceChannel, InvitableMixin, MessageableMixin)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

Source code in naff/models/discord/channel.py
@define()
class GuildVoice(VoiceChannel, InvitableMixin, MessageableMixin):
    pass

async inherited method send(self, content, embeds, embed, components, stickers, allowed_mentions, reply_to, files, file, tts, suppress_embeds, flags, delete_after, **kwargs)

Send a message.

Parameters:

Name Type Description Default
content Optional[str]

Message text content.

None
embeds Union[List[Union[Embed, dict]], Embed, dict]

Embedded rich content (up to 6000 characters).

None
embed Union[Embed, dict]

Embedded rich content (up to 6000 characters).

None
components Union[List[List[Union[BaseComponent, dict]]], List[Union[BaseComponent, dict]], BaseComponent, dict]

The components to include with the message.

None
stickers Union[List[Union[Sticker, Snowflake_Type]], Sticker, Snowflake_Type]

IDs of up to 3 stickers in the server to send in the message.

None
allowed_mentions Union[AllowedMentions, dict]

Allowed mentions for the message.

None
reply_to Union[MessageReference, Message, dict, Snowflake_Type]

Message to reference, must be from the same channel.

None
files Union[UPLOADABLE_TYPE, List[UPLOADABLE_TYPE]]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
file Optional[UPLOADABLE_TYPE]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
tts bool

Should this message use Text To Speech.

False
suppress_embeds bool

Should embeds be suppressed on this send

False
flags Union[int, MessageFlags]

Message flags to apply.

None
delete_after Optional[float]

Delete message after this many seconds.

None

Returns:

Type Description
Message

New message object that was sent.

Source code in naff/models/discord/channel.py
async def send(
    self,
    content: Optional[str] = None,
    embeds: Optional[Union[List[Union["Embed", dict]], Union["Embed", dict]]] = None,
    embed: Optional[Union["Embed", dict]] = None,
    components: Optional[
        Union[List[List[Union["BaseComponent", dict]]], List[Union["BaseComponent", dict]], "BaseComponent", dict]
    ] = None,
    stickers: Optional[Union[List[Union["Sticker", "Snowflake_Type"]], "Sticker", "Snowflake_Type"]] = None,
    allowed_mentions: Optional[Union["AllowedMentions", dict]] = None,
    reply_to: Optional[Union["MessageReference", "Message", dict, "Snowflake_Type"]] = None,
    files: Optional[Union["UPLOADABLE_TYPE", List["UPLOADABLE_TYPE"]]] = None,
    file: Optional["UPLOADABLE_TYPE"] = None,
    tts: bool = False,
    suppress_embeds: bool = False,
    flags: Optional[Union[int, "MessageFlags"]] = None,
    delete_after: Optional[float] = None,
    **kwargs,
) -> "Message":
    """
    Send a message.

    Args:
        content: Message text content.
        embeds: Embedded rich content (up to 6000 characters).
        embed: Embedded rich content (up to 6000 characters).
        components: The components to include with the message.
        stickers: IDs of up to 3 stickers in the server to send in the message.
        allowed_mentions: Allowed mentions for the message.
        reply_to: Message to reference, must be from the same channel.
        files: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        file: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        tts: Should this message use Text To Speech.
        suppress_embeds: Should embeds be suppressed on this send
        flags: Message flags to apply.
        delete_after: Delete message after this many seconds.

    Returns:
        New message object that was sent.

    """
    if not content and not (embeds or embed) and not (files or file) and not stickers:
        raise errors.EmptyMessageException(
            "You cannot send a message without any content, embeds, files, or stickers"
        )

    if suppress_embeds:
        if isinstance(flags, int):
            flags = MessageFlags(flags)
        flags = flags | MessageFlags.SUPPRESS_EMBEDS

    message_payload = models.discord.message.process_message_payload(
        content=content,
        embeds=embeds or embed,
        components=components,
        stickers=stickers,
        allowed_mentions=allowed_mentions,
        reply_to=reply_to,
        tts=tts,
        flags=flags,
        **kwargs,
    )

    message_data = await self._send_http_request(message_payload, files=files or file)
    if message_data:
        message = self._client.cache.place_message_data(message_data)
        if delete_after:
            await message.delete(delay=delete_after)
        return message

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

async inherited method fetch_message(self, message_id)

Fetch a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
Optional[models.Message]

The message object fetched. If the message is not found, returns None.

Source code in naff/models/discord/channel.py
async def fetch_message(self, message_id: Snowflake_Type) -> Optional["models.Message"]:
    """
    Fetch a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched. If the message is not found, returns None.

    """
    try:
        return await self._client.cache.fetch_message(self.id, message_id)
    except NotFound:
        return None

inherited method get_message(self, message_id)

Get a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
models.Message

The message object fetched.

Source code in naff/models/discord/channel.py
def get_message(self, message_id: Snowflake_Type) -> "models.Message":
    """
    Get a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched.

    """
    message_id = to_snowflake(message_id)
    message: "models.Message" = self._client.cache.get_message(self.id, message_id)
    return message

inherited method history(self, limit, before, after, around)

Get an async iterator for the history of this channel.

Parameters:

Name Type Description Default
limit

The maximum number of messages to return (set to 0 for no limit)

100
before Union[int, str, SnowflakeObject, SupportsInt]

get messages before this message ID

None
after Union[int, str, SnowflakeObject, SupportsInt]

get messages after this message ID

None
around Union[int, str, SnowflakeObject, SupportsInt]

get messages "around" this message ID

None
Example Usage:

1
2
3
4
5
async for message in channel.history(limit=0):
    if message.author.id == 174918559539920897:
        print("Found author's message")
        # ...
        break
or
1
2
3
history = channel.history(limit=250)
# Flatten the async iterator into a list
messages = await history.flatten()

Returns:

Type Description
ChannelHistory

ChannelHistory (AsyncIterator)

Source code in naff/models/discord/channel.py
def history(
    self,
    limit=100,
    before: Snowflake_Type = None,
    after: Snowflake_Type = None,
    around: Snowflake_Type = None,
) -> ChannelHistory:
    """
    Get an async iterator for the history of this channel.

    Args:
        limit: The maximum number of messages to return (set to 0 for no limit)
        before: get messages before this message ID
        after: get messages after this message ID
        around: get messages "around" this message ID

    ??? Hint "Example Usage:"
        ```python
        async for message in channel.history(limit=0):
            if message.author.id == 174918559539920897:
                print("Found author's message")
                # ...
                break
        ```
        or
        ```python
        history = channel.history(limit=250)
        # Flatten the async iterator into a list
        messages = await history.flatten()
        ```

    Returns:
        ChannelHistory (AsyncIterator)

    """
    return ChannelHistory(self, limit, before, after, around)

async inherited method fetch_messages(self, limit, around, before, after)

Fetch multiple messages from the channel.

Parameters:

Name Type Description Default
limit int

Max number of messages to return, default 50, max 100

50
around Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages around

Missing
before Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages before

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages after

Missing

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_messages(
    self,
    limit: int = 50,
    around: Snowflake_Type = MISSING,
    before: Snowflake_Type = MISSING,
    after: Snowflake_Type = MISSING,
) -> List["models.Message"]:
    """
    Fetch multiple messages from the channel.

    Args:
        limit: Max number of messages to return, default `50`, max `100`
        around: Message to get messages around
        before: Message to get messages before
        after: Message to get messages after

    Returns:
        A list of messages fetched.

    """
    if limit > 100:
        raise ValueError("You cannot fetch more than 100 messages at once.")

    if around:
        around = to_snowflake(around)
    elif before:
        before = to_snowflake(before)
    elif after:
        after = to_snowflake(after)

    messages_data = await self._client.http.get_channel_messages(self.id, limit, around, before, after)
    for m in messages_data:
        m["guild_id"] = self._guild_id

    return [self._client.cache.place_message_data(m) for m in messages_data]

async inherited method fetch_pinned_messages(self)

Fetch pinned messages from the channel.

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_pinned_messages(self) -> List["models.Message"]:
    """
    Fetch pinned messages from the channel.

    Returns:
        A list of messages fetched.

    """
    messages_data = await self._client.http.get_pinned_messages(self.id)
    return [self._client.cache.place_message_data(message_data) for message_data in messages_data]

async inherited method delete_messages(self, messages, reason)

Bulk delete messages from channel.

Parameters:

Name Type Description Default
messages List[Union[int, str, SnowflakeObject, SupportsInt, models.Message]]

List of messages or message IDs to delete.

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this action. Used for audit logs.

Missing
Source code in naff/models/discord/channel.py
async def delete_messages(
    self, messages: List[Union[Snowflake_Type, "models.Message"]], reason: Absent[Optional[str]] = MISSING
) -> None:
    """
    Bulk delete messages from channel.

    Args:
        messages: List of messages or message IDs to delete.
        reason: The reason for this action. Used for audit logs.

    """
    message_ids = [to_snowflake(message) for message in messages]
    # TODO Add check for min/max and duplicates.

    if len(message_ids) == 1:
        # bulk delete messages will throw a http error if only 1 message is passed
        await self.delete_message(message_ids[0], reason)
    else:
        await self._client.http.bulk_delete_messages(self.id, message_ids, reason)

async inherited method delete_message(self, message, reason)

Delete a single message from a channel.

Parameters:

Name Type Description Default
message Union[int, str, SnowflakeObject, SupportsInt, models.Message]

The message to delete

required
reason str

The reason for this action

None
Source code in naff/models/discord/channel.py
async def delete_message(self, message: Union[Snowflake_Type, "models.Message"], reason: str = None) -> None:
    """
    Delete a single message from a channel.

    Args:
        message: The message to delete
        reason: The reason for this action

    """
    message = to_snowflake(message)
    await self._client.http.delete_message(self.id, message, reason=reason)

async inherited method purge(self, deletion_limit, search_limit, predicate, avoid_loading_msg, before, after, around, reason)

Bulk delete messages within a channel. If a predicate is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the deletion_limit.

Example Usage:
1
2
3
# this will delete the last 20 messages sent by a user with the given ID
deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
await channel.send(f"{deleted} messages deleted")

Parameters:

Name Type Description Default
deletion_limit int

The target amount of messages to delete

50
search_limit int

How many messages to search through

100
predicate Callable[[models.Message], bool]

A function that returns True or False, and takes a message as an argument

Missing
avoid_loading_msg bool

Should the bot attempt to avoid deleting its own loading messages (recommended enabled)

True
before Union[int, str, SnowflakeObject, SupportsInt]

Search messages before this ID

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Search messages after this ID

Missing
around Union[int, str, SnowflakeObject, SupportsInt]

Search messages around this ID

Missing
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this deletion

Missing

Returns:

Type Description
int

The total amount of messages deleted

Source code in naff/models/discord/channel.py
async def purge(
    self,
    deletion_limit: int = 50,
    search_limit: int = 100,
    predicate: Callable[["models.Message"], bool] = MISSING,
    avoid_loading_msg: bool = True,
    before: Optional[Snowflake_Type] = MISSING,
    after: Optional[Snowflake_Type] = MISSING,
    around: Optional[Snowflake_Type] = MISSING,
    reason: Absent[Optional[str]] = MISSING,
) -> int:
    """
    Bulk delete messages within a channel. If a `predicate` is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the `deletion_limit`.

    ??? Hint "Example Usage:"
        ```python
        # this will delete the last 20 messages sent by a user with the given ID
        deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
        await channel.send(f"{deleted} messages deleted")
        ```

    Args:
        deletion_limit: The target amount of messages to delete
        search_limit: How many messages to search through
        predicate: A function that returns True or False, and takes a message as an argument
        avoid_loading_msg: Should the bot attempt to avoid deleting its own loading messages (recommended enabled)
        before: Search messages before this ID
        after: Search messages after this ID
        around: Search messages around this ID
        reason: The reason for this deletion

    Returns:
        The total amount of messages deleted

    """
    if not predicate:

        def predicate(m) -> bool:
            return True  # noqa

    to_delete = []

    # 1209600 14 days ago in seconds, 1420070400000 is used to convert to snowflake
    fourteen_days_ago = int((time.time() - 1209600) * 1000.0 - DISCORD_EPOCH) << 22
    async for message in self.history(limit=search_limit, before=before, after=after, around=around):
        if deletion_limit != 0 and len(to_delete) == deletion_limit:
            break

        if not predicate(message):
            # fails predicate
            continue

        if avoid_loading_msg:
            if message._author_id == self._client.user.id and MessageFlags.LOADING in message.flags:
                continue

        if message.id < fourteen_days_ago:
            # message is too old to be purged
            continue

        to_delete.append(message.id)

    count = len(to_delete)
    while len(to_delete):
        iteration = [to_delete.pop() for i in range(min(100, len(to_delete)))]
        await self.delete_messages(iteration, reason=reason)
    return count

async inherited method trigger_typing(self)

Trigger a typing animation in this channel.

Source code in naff/models/discord/channel.py
async def trigger_typing(self) -> None:
    """Trigger a typing animation in this channel."""
    await self._client.http.trigger_typing_indicator(self.id)

inherited property readonly typing: Typing

A context manager to send a typing state to a given channel as long as long as the wrapped operation takes.

async inherited method create_invite(self, max_age, max_uses, temporary, unique, target_type, target_user, target_application, reason)

Creates a new channel invite.

Parameters:

Name Type Description Default
max_age int

Max age of invite in seconds, default 86400 (24 hours).

86400
max_uses int

Max uses of invite, default 0.

0
temporary bool

Grants temporary membership, default False.

False
unique bool

Invite is unique, default false.

False
target_type Optional[naff.models.discord.enums.InviteTargetTypes]

Target type for streams and embedded applications.

None
target_user Union[int, str, SnowflakeObject, SupportsInt, models.User]

Target User ID for Stream target type.

None
target_application Union[int, str, SnowflakeObject, SupportsInt, models.Application]

Target Application ID for Embedded App target type.

None
reason Optional[str]

The reason for creating this invite.

None

Returns:

Type Description
models.Invite

Newly created Invite object.

Source code in naff/models/discord/channel.py
async def create_invite(
    self,
    max_age: int = 86400,
    max_uses: int = 0,
    temporary: bool = False,
    unique: bool = False,
    target_type: Optional[InviteTargetTypes] = None,
    target_user: Optional[Union[Snowflake_Type, "models.User"]] = None,
    target_application: Optional[Union[Snowflake_Type, "models.Application"]] = None,
    reason: Optional[str] = None,
) -> "models.Invite":
    """
    Creates a new channel invite.

    Args:
        max_age: Max age of invite in seconds, default 86400 (24 hours).
        max_uses: Max uses of invite, default 0.
        temporary: Grants temporary membership, default False.
        unique: Invite is unique, default false.
        target_type: Target type for streams and embedded applications.
        target_user: Target User ID for Stream target type.
        target_application: Target Application ID for Embedded App target type.
        reason: The reason for creating this invite.

    Returns:
        Newly created Invite object.

    """
    if target_type:
        if target_type == InviteTargetTypes.STREAM and not target_user:
            raise ValueError("Stream target must include target user id.")
        elif target_type == InviteTargetTypes.EMBEDDED_APPLICATION and not target_application:
            raise ValueError("Embedded Application target must include target application id.")

    if target_user and target_application:
        raise ValueError("Invite target must be either User or Embedded Application, not both.")
    elif target_user:
        target_user = to_snowflake(target_user)
        target_type = InviteTargetTypes.STREAM
    elif target_application:
        target_application = to_snowflake(target_application)
        target_type = InviteTargetTypes.EMBEDDED_APPLICATION

    invite_data = await self._client.http.create_channel_invite(
        self.id, max_age, max_uses, temporary, unique, target_type, target_user, target_application, reason
    )
    return models.Invite.from_dict(invite_data, self._client)

async inherited method fetch_invites(self)

Fetches all invites (with invite metadata) for the channel.

Returns:

Type Description
List[models.Invite]

List of Invite objects.

Source code in naff/models/discord/channel.py
async def fetch_invites(self) -> List["models.Invite"]:
    """
    Fetches all invites (with invite metadata) for the channel.

    Returns:
        List of Invite objects.

    """
    invites_data = await self._client.http.get_channel_invites(self.id)
    return models.Invite.from_list(invites_data, self._client)

inherited property readonly mention: str

Returns a string that would mention the channel.

async inherited method delete(self, reason)

Delete this channel.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for deleting this channel

Missing
Source code in naff/models/discord/channel.py
async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Delete this channel.

    Args:
        reason: The reason for deleting this channel

    """
    await self._client.http.delete_channel(self.id, reason)

inherited property readonly guild: models.Guild

The guild this channel belongs to.

inherited property readonly category: Optional[GuildCategory]

The parent category of this channel.

inherited property readonly gui_position: int

The position of this channel in the Discord interface.

inherited method permissions_for(self, instance)

Calculates permissions for an instance

Parameters:

Name Type Description Default
instance Union[int, str, SnowflakeObject, SupportsInt]

Member or Role instance (or its ID)

required

Returns:

Type Description
Permissions

Permissions data

Exceptions:

Type Description
ValueError

If could not find any member or role by given ID

RuntimeError

If given instance is from another guild

Source code in naff/models/discord/channel.py
def permissions_for(self, instance: Snowflake_Type) -> Permissions:
    """
    Calculates permissions for an instance

    Args:
        instance: Member or Role instance (or its ID)

    Returns:
        Permissions data

    Raises:
        ValueError: If could not find any member or role by given ID
        RuntimeError: If given instance is from another guild

    """
    if (is_member := isinstance(instance, models.Member)) or isinstance(instance, models.Role):
        if instance._guild_id != self._guild_id:
            raise RuntimeError("Unable to calculate permissions for the instance from different guild")

        if is_member:
            return instance.channel_permissions(self)

        else:
            permissions = instance.permissions

            for overwrite in self.permission_overwrites:
                if overwrite.id == instance.id:
                    permissions &= ~overwrite.deny
                    permissions |= overwrite.allow
                    break

            return permissions

    else:
        instance = to_snowflake(instance)
        guild = self.guild
        instance = guild.get_member(instance) or guild.get_role(instance)

        if not instance:
            raise ValueError("Unable to find any member or role by given instance ID")

        return self.permissions_for(instance)

async inherited method add_permission(self, target, type, allow, deny, reason)

Add a permission to this channel.

Parameters:

Name Type Description Default
target Union[PermissionOverwrite, models.Role, models.User, models.Member, Snowflake_Type]

The updated PermissionOverwrite object, or the Role or User object/id to update

required
type Optional[OverwriteTypes]

The type of permission overwrite. Only applicable if target is an id

None
allow Union[List[Permissions], int]

List of permissions to allow. Only applicable if target is not an PermissionOverwrite object

None
deny Union[List[Permissions], int]

List of permissions to deny. Only applicable if target is not an PermissionOverwrite object

None
reason Optional[str]

The reason for this change

None

Exceptions:

Type Description
ValueError

Invalid target for permission

Source code in naff/models/discord/channel.py
async def add_permission(
    self,
    target: Union["PermissionOverwrite", "models.Role", "models.User", "models.Member", "Snowflake_Type"],
    type: Optional["OverwriteTypes"] = None,
    allow: Optional[List["Permissions"] | int] = None,
    deny: Optional[List["Permissions"] | int] = None,
    reason: Optional[str] = None,
) -> None:
    """
    Add a permission to this channel.

    Args:
        target: The updated PermissionOverwrite object, or the Role or User object/id to update
        type: The type of permission overwrite. Only applicable if target is an id
        allow: List of permissions to allow. Only applicable if target is not an PermissionOverwrite object
        deny: List of permissions to deny. Only applicable if target is not an PermissionOverwrite object
        reason: The reason for this change

    Raises:
        ValueError: Invalid target for permission

    """
    allow = allow or []
    deny = deny or []
    if not isinstance(target, PermissionOverwrite):
        if isinstance(target, (models.User, models.Member)):
            target = target.id
            type = OverwriteTypes.MEMBER
        elif isinstance(target, models.Role):
            target = target.id
            type = OverwriteTypes.ROLE
        elif type and isinstance(target, Snowflake_Type):
            target = to_snowflake(target)
        else:
            raise ValueError("Invalid target and/or type for permission")
        overwrite = PermissionOverwrite(id=target, type=type, allow=Permissions.NONE, deny=Permissions.NONE)
        if isinstance(allow, int):
            overwrite.allow |= allow
        else:
            for perm in allow:
                overwrite.allow |= perm
        if isinstance(deny, int):
            overwrite.deny |= deny
        else:
            for perm in deny:
                overwrite.deny |= perm
    else:
        overwrite = target

    if exists := get(self.permission_overwrites, id=overwrite.id, type=overwrite.type):
        exists.deny = (exists.deny | overwrite.deny) & ~overwrite.allow
        exists.allow = (exists.allow | overwrite.allow) & ~overwrite.deny
        await self.edit_permission(exists, reason)
    else:
        permission_overwrites = self.permission_overwrites
        permission_overwrites.append(overwrite)
        await self.edit(permission_overwrites=permission_overwrites)

async inherited method edit_permission(self, overwrite, reason)

Edit the permissions for this channel.

Parameters:

Name Type Description Default
overwrite PermissionOverwrite

The permission overwrite to apply

required
reason Optional[str]

The reason for this change

None
Source code in naff/models/discord/channel.py
async def edit_permission(self, overwrite: PermissionOverwrite, reason: Optional[str] = None) -> None:
    """
    Edit the permissions for this channel.

    Args:
        overwrite: The permission overwrite to apply
        reason: The reason for this change
    """
    await self._client.http.edit_channel_permission(
        self.id, overwrite.id, overwrite.allow, overwrite.deny, overwrite.type, reason
    )

async inherited method delete_permission(self, target, reason)

Delete a permission overwrite for this channel.

Parameters:

Name Type Description Default
target Union[PermissionOverwrite, models.Role, models.User]

The permission overwrite to delete

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this change

Missing
Source code in naff/models/discord/channel.py
async def delete_permission(
    self,
    target: Union["PermissionOverwrite", "models.Role", "models.User"],
    reason: Absent[Optional[str]] = MISSING,
) -> None:
    """
    Delete a permission overwrite for this channel.

    Args:
        target: The permission overwrite to delete
        reason: The reason for this change

    """
    target = to_snowflake(target)
    await self._client.http.delete_channel_permission(self.id, target, reason)

async inherited method set_permission(self, target, *, add_reactions, administrator, attach_files, ban_members, change_nickname, connect, create_instant_invite, deafen_members, embed_links, kick_members, manage_channels, manage_emojis_and_stickers, manage_events, manage_guild, manage_messages, manage_nicknames, manage_roles, manage_threads, manage_webhooks, mention_everyone, moderate_members, move_members, mute_members, priority_speaker, read_message_history, request_to_speak, send_messages, send_messages_in_threads, send_tts_messages, speak, start_embedded_activities, stream, use_application_commands, use_external_emojis, use_external_stickers, use_private_threads, use_public_threads, use_vad, view_audit_log, view_channel, view_guild_insights, reason)

Set the Permission Overwrites for a given target.

Parameters:

Name Type Description Default
target Union[models.Role, models.Member, models.User]

The target to set permission overwrites for

required
add_reactions bool | None

Allows for the addition of reactions to messages

None
administrator bool | None

Allows all permissions and bypasses channel permission overwrites

None
attach_files bool | None

Allows for uploading images and files

None
ban_members bool | None

Allows banning members

None
change_nickname bool | None

Allows for modification of own nickname

None
connect bool | None

Allows for joining of a voice channel

None
create_instant_invite bool | None

Allows creation of instant invites

None
deafen_members bool | None

Allows for deafening of members in a voice channel

None
embed_links bool | None

Links sent by users with this permission will be auto-embedded

None
kick_members bool | None

Allows kicking members

None
manage_channels bool | None

Allows management and editing of channels

None
manage_emojis_and_stickers bool | None

Allows management and editing of emojis and stickers

None
manage_events bool | None

Allows for creating, editing, and deleting scheduled events

None
manage_guild bool | None

Allows management and editing of the guild

None
manage_messages bool | None

Allows for deletion of other users messages

None
manage_nicknames bool | None

Allows for modification of other users nicknames

None
manage_roles bool | None

Allows management and editing of roles

None
manage_threads bool | None

Allows for deleting and archiving threads, and viewing all private threads

None
manage_webhooks bool | None

Allows management and editing of webhooks

None
mention_everyone bool | None

Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all online users in a channel

None
moderate_members bool | None

Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels

None
move_members bool | None

Allows for moving of members between voice channels

None
mute_members bool | None

Allows for muting members in a voice channel

None
priority_speaker bool | None

Allows for using priority speaker in a voice channel

None
read_message_history bool | None

Allows for reading of message history

None
request_to_speak bool | None

Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)

None
send_messages bool | None

Allows for sending messages in a channel (does not allow sending messages in threads)

None
send_messages_in_threads bool | None

Allows for sending messages in threads

None
send_tts_messages bool | None

Allows for sending of /tts messages

None
speak bool | None

Allows for speaking in a voice channel

None
start_embedded_activities bool | None

Allows for using Activities (applications with the EMBEDDED flag) in a voice channel

None
stream bool | None

Allows the user to go live

None
use_application_commands bool | None

Allows members to use application commands, including slash commands and context menu commands

None
use_external_emojis bool | None

Allows the usage of custom emojis from other servers

None
use_external_stickers bool | None

Allows the usage of custom stickers from other servers

None
use_private_threads bool | None

Allows for creating private threads

None
use_public_threads bool | None

Allows for creating public and announcement threads

None
use_vad bool | None

Allows for using voice-activity-detection in a voice channel

None
view_audit_log bool | None

Allows for viewing of audit logs

None
view_channel bool | None

Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels

None
view_guild_insights bool | None

Allows for viewing guild insights

None
reason str

The reason for creating this overwrite

None
Source code in naff/models/discord/channel.py
async def set_permission(
    self,
    target: Union["models.Role", "models.Member", "models.User"],
    *,
    add_reactions: bool | None = None,
    administrator: bool | None = None,
    attach_files: bool | None = None,
    ban_members: bool | None = None,
    change_nickname: bool | None = None,
    connect: bool | None = None,
    create_instant_invite: bool | None = None,
    deafen_members: bool | None = None,
    embed_links: bool | None = None,
    kick_members: bool | None = None,
    manage_channels: bool | None = None,
    manage_emojis_and_stickers: bool | None = None,
    manage_events: bool | None = None,
    manage_guild: bool | None = None,
    manage_messages: bool | None = None,
    manage_nicknames: bool | None = None,
    manage_roles: bool | None = None,
    manage_threads: bool | None = None,
    manage_webhooks: bool | None = None,
    mention_everyone: bool | None = None,
    moderate_members: bool | None = None,
    move_members: bool | None = None,
    mute_members: bool | None = None,
    priority_speaker: bool | None = None,
    read_message_history: bool | None = None,
    request_to_speak: bool | None = None,
    send_messages: bool | None = None,
    send_messages_in_threads: bool | None = None,
    send_tts_messages: bool | None = None,
    speak: bool | None = None,
    start_embedded_activities: bool | None = None,
    stream: bool | None = None,
    use_application_commands: bool | None = None,
    use_external_emojis: bool | None = None,
    use_external_stickers: bool | None = None,
    use_private_threads: bool | None = None,
    use_public_threads: bool | None = None,
    use_vad: bool | None = None,
    view_audit_log: bool | None = None,
    view_channel: bool | None = None,
    view_guild_insights: bool | None = None,
    reason: str = None,
) -> None:
    """
    Set the Permission Overwrites for a given target.

    Args:
        target: The target to set permission overwrites for
        add_reactions: Allows for the addition of reactions to messages
        administrator: Allows all permissions and bypasses channel permission overwrites
        attach_files: Allows for uploading images and files
        ban_members: Allows banning members
        change_nickname: Allows for modification of own nickname
        connect: Allows for joining of a voice channel
        create_instant_invite: Allows creation of instant invites
        deafen_members: Allows for deafening of members in a voice channel
        embed_links: Links sent by users with this permission will be auto-embedded
        kick_members: Allows kicking members
        manage_channels: Allows management and editing of channels
        manage_emojis_and_stickers: Allows management and editing of emojis and stickers
        manage_events: Allows for creating, editing, and deleting scheduled events
        manage_guild: Allows management and editing of the guild
        manage_messages: Allows for deletion of other users messages
        manage_nicknames: Allows for modification of other users nicknames
        manage_roles: Allows management and editing of roles
        manage_threads: Allows for deleting and archiving threads, and viewing all private threads
        manage_webhooks: Allows management and editing of webhooks
        mention_everyone: Allows for using the `@everyone` tag to notify all users in a channel, and the `@here` tag to notify all online users in a channel
        moderate_members: Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels
        move_members: Allows for moving of members between voice channels
        mute_members: Allows for muting members in a voice channel
        priority_speaker: Allows for using priority speaker in a voice channel
        read_message_history: Allows for reading of message history
        request_to_speak: Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)
        send_messages:  Allows for sending messages in a channel (does not allow sending messages in threads)
        send_messages_in_threads: Allows for sending messages in threads
        send_tts_messages:  Allows for sending of `/tts` messages
        speak: Allows for speaking in a voice channel
        start_embedded_activities: Allows for using Activities (applications with the `EMBEDDED` flag) in a voice channel
        stream: Allows the user to go live
        use_application_commands: Allows members to use application commands, including slash commands and context menu commands
        use_external_emojis: Allows the usage of custom emojis from other servers
        use_external_stickers: Allows the usage of custom stickers from other servers
        use_private_threads: Allows for creating private threads
        use_public_threads:  Allows for creating public and announcement threads
        use_vad: Allows for using voice-activity-detection in a voice channel
        view_audit_log: Allows for viewing of audit logs
        view_channel: Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels
        view_guild_insights: Allows for viewing guild insights
        reason: The reason for creating this overwrite
    """
    overwrite = PermissionOverwrite.for_target(target)

    allow: Permissions = Permissions.NONE
    deny: Permissions = Permissions.NONE

    for name, val in locals().items():
        if isinstance(val, bool):
            if val:
                allow |= getattr(Permissions, name.upper())
            else:
                deny |= getattr(Permissions, name.upper())

    overwrite.add_allows(allow)
    overwrite.add_denies(deny)

    await self.edit_permission(overwrite, reason)

inherited property readonly bots: List[models.Member]

Returns a list of bots that can see this channel.

inherited property readonly humans: List[models.Member]

Returns a list of humans that can see this channel.

async inherited method clone(self, name, reason)

Clone this channel and create a new one.

Parameters:

Name Type Description Default
name Optional[str]

The name of the new channel. Defaults to the current name

None
reason Union[str, NoneType, naff.client.const.Missing]

The reason for creating this channel

Missing

Returns:

Type Description
TYPE_GUILD_CHANNEL

The newly created channel.

Source code in naff/models/discord/channel.py
async def clone(self, name: Optional[str] = None, reason: Absent[Optional[str]] = MISSING) -> "TYPE_GUILD_CHANNEL":
    """
    Clone this channel and create a new one.

    Args:
        name: The name of the new channel. Defaults to the current name
        reason: The reason for creating this channel

    Returns:
        The newly created channel.

    """
    return await self.guild.create_channel(
        channel_type=self.type,
        name=name if name else self.name,
        topic=getattr(self, "topic", MISSING),
        position=self.position,
        permission_overwrites=self.permission_overwrites,
        category=self.category,
        nsfw=self.nsfw,
        bitrate=getattr(self, "bitrate", 64000),
        user_limit=getattr(self, "user_limit", 0),
        rate_limit_per_user=getattr(self, "rate_limit_per_user", 0),
        reason=reason,
    )

async inherited method edit(self, name, position, permission_overwrites, parent_id, bitrate, user_limit, rtc_region, video_quality_mode, reason, **kwargs)

Edit guild voice channel.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

1-100 character channel name

Missing
position Union[int, naff.client.const.Missing]

the position of the channel in the left-hand listing

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

a list of PermissionOverwrite to apply to the channel

Missing
parent_id Union[int, str, SnowflakeObject, SupportsInt, naff.client.const.Missing]

the parent category Snowflake_Type for the channel

Missing
bitrate Union[int, naff.client.const.Missing]

the bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)

Missing
user_limit Union[int, naff.client.const.Missing]

the user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit

Missing
rtc_region Union[str, naff.client.const.Missing]

channel voice region id, automatic when not set

Missing
video_quality_mode Union[naff.models.discord.enums.VideoQualityModes, naff.client.const.Missing]

the camera video quality mode of the voice channel

Missing
reason Union[str, naff.client.const.Missing]

optional reason for audit logs

Missing

Returns:

Type Description
Union[GuildVoice, GuildStageVoice]

The edited voice channel object.

Source code in naff/models/discord/channel.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    position: Absent[int] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    parent_id: Absent[Snowflake_Type] = MISSING,
    bitrate: Absent[int] = MISSING,
    user_limit: Absent[int] = MISSING,
    rtc_region: Absent[str] = MISSING,
    video_quality_mode: Absent[VideoQualityModes] = MISSING,
    reason: Absent[str] = MISSING,
    **kwargs,
) -> Union["GuildVoice", "GuildStageVoice"]:
    """
    Edit guild voice channel.

    Args:
        name: 1-100 character channel name
        position: the position of the channel in the left-hand listing
        permission_overwrites: a list of `PermissionOverwrite` to apply to the channel
        parent_id: the parent category `Snowflake_Type` for the channel
        bitrate: the bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)
        user_limit: the user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit
        rtc_region: channel voice region id, automatic when not set
        video_quality_mode: the camera video quality mode of the voice channel
        reason: optional reason for audit logs

    Returns:
        The edited voice channel object.

    """
    return await super().edit(
        name=name,
        position=position,
        permission_overwrites=permission_overwrites,
        parent_id=parent_id,
        bitrate=bitrate,
        user_limit=user_limit,
        rtc_region=rtc_region,
        video_quality_mode=video_quality_mode,
        reason=reason,
        **kwargs,
    )

inherited property readonly members: List[models.Member]

Returns a list of members that have access to this voice channel

inherited property readonly voice_members: List[models.Member]

Returns a list of members that are currently in the channel. Note: This will not be accurate if the bot was offline while users joined the channel

inherited property readonly voice_state: Optional[ActiveVoiceState]

Returns the voice state of the bot in this channel if it is connected

async inherited method connect(self, muted, deafened)

Connect the bot to this voice channel, or move the bot to this voice channel if it is already connected in another voice channel.

Parameters:

Name Type Description Default
muted bool

Whether the bot should be muted when connected.

False
deafened bool

Whether the bot should be deafened when connected.

False

Returns:

Type Description
ActiveVoiceState

The new active voice state on successfully connection.

Source code in naff/models/discord/channel.py
async def connect(self, muted: bool = False, deafened: bool = False) -> "ActiveVoiceState":
    """
    Connect the bot to this voice channel, or move the bot to this voice channel if it is already connected in another voice channel.

    Args:
        muted: Whether the bot should be muted when connected.
        deafened: Whether the bot should be deafened when connected.

    Returns:
        The new active voice state on successfully connection.

    """
    if not self.voice_state:
        return await self._client.connect_to_vc(self._guild_id, self.id, muted, deafened)
    await self.voice_state.move(self.id)
    return self.voice_state

async inherited method disconnect(self)

Disconnect from the currently connected connected voice state.

Source code in naff/models/discord/channel.py
async def disconnect(self) -> None:
    """
    Disconnect from the currently connected connected voice state.

    Raises:
        VoiceNotConnected if the bot is not connected to a voice channel
    """
    if self.voice_state:
        return await self.voice_state.disconnect()
    else:
        raise VoiceNotConnected

attrs class GuildStageVoice (GuildVoice)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

stage_instance models.StageInstance

The stage instance that this voice channel belongs to

Source code in naff/models/discord/channel.py
@define()
class GuildStageVoice(GuildVoice):
    stage_instance: "models.StageInstance" = field(default=MISSING)
    """The stage instance that this voice channel belongs to"""

    # todo: Listeners and speakers properties (needs voice state caching)

    async def fetch_stage_instance(self) -> "models.StageInstance":
        """
        Fetches the stage instance associated with this channel.

        Returns:
            The stage instance associated with this channel. If no stage is live, will return None.

        """
        self.stage_instance = models.StageInstance.from_dict(
            await self._client.http.get_stage_instance(self.id), self._client
        )
        return self.stage_instance

    async def create_stage_instance(
        self,
        topic: str,
        privacy_level: StagePrivacyLevel = StagePrivacyLevel.GUILD_ONLY,
        reason: Absent[Optional[str]] = MISSING,
    ) -> "models.StageInstance":
        """
        Create a stage instance in this channel.

        Args:
            topic: The topic of the stage (1-120 characters)
            privacy_level: The privacy level of the stage
            reason: The reason for creating this instance

        Returns:
            The created stage instance object.

        """
        self.stage_instance = models.StageInstance.from_dict(
            await self._client.http.create_stage_instance(self.id, topic, privacy_level, reason), self._client
        )
        return self.stage_instance

    async def close_stage(self, reason: Absent[Optional[str]] = MISSING) -> None:
        """
        Closes the live stage instance.

        Args:
            reason: The reason for closing the stage

        """
        if not self.stage_instance:
            # we dont know of an active stage instance, so lets check for one
            if not await self.get_stage_instance():
                raise ValueError("No stage instance found")

        await self.stage_instance.delete(reason=reason)

async inherited method send(self, content, embeds, embed, components, stickers, allowed_mentions, reply_to, files, file, tts, suppress_embeds, flags, delete_after, **kwargs)

Send a message.

Parameters:

Name Type Description Default
content Optional[str]

Message text content.

None
embeds Union[List[Union[Embed, dict]], Embed, dict]

Embedded rich content (up to 6000 characters).

None
embed Union[Embed, dict]

Embedded rich content (up to 6000 characters).

None
components Union[List[List[Union[BaseComponent, dict]]], List[Union[BaseComponent, dict]], BaseComponent, dict]

The components to include with the message.

None
stickers Union[List[Union[Sticker, Snowflake_Type]], Sticker, Snowflake_Type]

IDs of up to 3 stickers in the server to send in the message.

None
allowed_mentions Union[AllowedMentions, dict]

Allowed mentions for the message.

None
reply_to Union[MessageReference, Message, dict, Snowflake_Type]

Message to reference, must be from the same channel.

None
files Union[UPLOADABLE_TYPE, List[UPLOADABLE_TYPE]]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
file Optional[UPLOADABLE_TYPE]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
tts bool

Should this message use Text To Speech.

False
suppress_embeds bool

Should embeds be suppressed on this send

False
flags Union[int, MessageFlags]

Message flags to apply.

None
delete_after Optional[float]

Delete message after this many seconds.

None

Returns:

Type Description
Message

New message object that was sent.

Source code in naff/models/discord/channel.py
async def send(
    self,
    content: Optional[str] = None,
    embeds: Optional[Union[List[Union["Embed", dict]], Union["Embed", dict]]] = None,
    embed: Optional[Union["Embed", dict]] = None,
    components: Optional[
        Union[List[List[Union["BaseComponent", dict]]], List[Union["BaseComponent", dict]], "BaseComponent", dict]
    ] = None,
    stickers: Optional[Union[List[Union["Sticker", "Snowflake_Type"]], "Sticker", "Snowflake_Type"]] = None,
    allowed_mentions: Optional[Union["AllowedMentions", dict]] = None,
    reply_to: Optional[Union["MessageReference", "Message", dict, "Snowflake_Type"]] = None,
    files: Optional[Union["UPLOADABLE_TYPE", List["UPLOADABLE_TYPE"]]] = None,
    file: Optional["UPLOADABLE_TYPE"] = None,
    tts: bool = False,
    suppress_embeds: bool = False,
    flags: Optional[Union[int, "MessageFlags"]] = None,
    delete_after: Optional[float] = None,
    **kwargs,
) -> "Message":
    """
    Send a message.

    Args:
        content: Message text content.
        embeds: Embedded rich content (up to 6000 characters).
        embed: Embedded rich content (up to 6000 characters).
        components: The components to include with the message.
        stickers: IDs of up to 3 stickers in the server to send in the message.
        allowed_mentions: Allowed mentions for the message.
        reply_to: Message to reference, must be from the same channel.
        files: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        file: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        tts: Should this message use Text To Speech.
        suppress_embeds: Should embeds be suppressed on this send
        flags: Message flags to apply.
        delete_after: Delete message after this many seconds.

    Returns:
        New message object that was sent.

    """
    if not content and not (embeds or embed) and not (files or file) and not stickers:
        raise errors.EmptyMessageException(
            "You cannot send a message without any content, embeds, files, or stickers"
        )

    if suppress_embeds:
        if isinstance(flags, int):
            flags = MessageFlags(flags)
        flags = flags | MessageFlags.SUPPRESS_EMBEDS

    message_payload = models.discord.message.process_message_payload(
        content=content,
        embeds=embeds or embed,
        components=components,
        stickers=stickers,
        allowed_mentions=allowed_mentions,
        reply_to=reply_to,
        tts=tts,
        flags=flags,
        **kwargs,
    )

    message_data = await self._send_http_request(message_payload, files=files or file)
    if message_data:
        message = self._client.cache.place_message_data(message_data)
        if delete_after:
            await message.delete(delay=delete_after)
        return message

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

async inherited method fetch_message(self, message_id)

Fetch a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
Optional[models.Message]

The message object fetched. If the message is not found, returns None.

Source code in naff/models/discord/channel.py
async def fetch_message(self, message_id: Snowflake_Type) -> Optional["models.Message"]:
    """
    Fetch a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched. If the message is not found, returns None.

    """
    try:
        return await self._client.cache.fetch_message(self.id, message_id)
    except NotFound:
        return None

inherited method get_message(self, message_id)

Get a message from the channel.

Parameters:

Name Type Description Default
message_id Union[int, str, SnowflakeObject, SupportsInt]

ID of message to retrieve.

required

Returns:

Type Description
models.Message

The message object fetched.

Source code in naff/models/discord/channel.py
def get_message(self, message_id: Snowflake_Type) -> "models.Message":
    """
    Get a message from the channel.

    Args:
        message_id: ID of message to retrieve.

    Returns:
        The message object fetched.

    """
    message_id = to_snowflake(message_id)
    message: "models.Message" = self._client.cache.get_message(self.id, message_id)
    return message

inherited method history(self, limit, before, after, around)

Get an async iterator for the history of this channel.

Parameters:

Name Type Description Default
limit

The maximum number of messages to return (set to 0 for no limit)

100
before Union[int, str, SnowflakeObject, SupportsInt]

get messages before this message ID

None
after Union[int, str, SnowflakeObject, SupportsInt]

get messages after this message ID

None
around Union[int, str, SnowflakeObject, SupportsInt]

get messages "around" this message ID

None
Example Usage:

1
2
3
4
5
async for message in channel.history(limit=0):
    if message.author.id == 174918559539920897:
        print("Found author's message")
        # ...
        break
or
1
2
3
history = channel.history(limit=250)
# Flatten the async iterator into a list
messages = await history.flatten()

Returns:

Type Description
ChannelHistory

ChannelHistory (AsyncIterator)

Source code in naff/models/discord/channel.py
def history(
    self,
    limit=100,
    before: Snowflake_Type = None,
    after: Snowflake_Type = None,
    around: Snowflake_Type = None,
) -> ChannelHistory:
    """
    Get an async iterator for the history of this channel.

    Args:
        limit: The maximum number of messages to return (set to 0 for no limit)
        before: get messages before this message ID
        after: get messages after this message ID
        around: get messages "around" this message ID

    ??? Hint "Example Usage:"
        ```python
        async for message in channel.history(limit=0):
            if message.author.id == 174918559539920897:
                print("Found author's message")
                # ...
                break
        ```
        or
        ```python
        history = channel.history(limit=250)
        # Flatten the async iterator into a list
        messages = await history.flatten()
        ```

    Returns:
        ChannelHistory (AsyncIterator)

    """
    return ChannelHistory(self, limit, before, after, around)

async inherited method fetch_messages(self, limit, around, before, after)

Fetch multiple messages from the channel.

Parameters:

Name Type Description Default
limit int

Max number of messages to return, default 50, max 100

50
around Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages around

Missing
before Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages before

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Message to get messages after

Missing

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_messages(
    self,
    limit: int = 50,
    around: Snowflake_Type = MISSING,
    before: Snowflake_Type = MISSING,
    after: Snowflake_Type = MISSING,
) -> List["models.Message"]:
    """
    Fetch multiple messages from the channel.

    Args:
        limit: Max number of messages to return, default `50`, max `100`
        around: Message to get messages around
        before: Message to get messages before
        after: Message to get messages after

    Returns:
        A list of messages fetched.

    """
    if limit > 100:
        raise ValueError("You cannot fetch more than 100 messages at once.")

    if around:
        around = to_snowflake(around)
    elif before:
        before = to_snowflake(before)
    elif after:
        after = to_snowflake(after)

    messages_data = await self._client.http.get_channel_messages(self.id, limit, around, before, after)
    for m in messages_data:
        m["guild_id"] = self._guild_id

    return [self._client.cache.place_message_data(m) for m in messages_data]

async inherited method fetch_pinned_messages(self)

Fetch pinned messages from the channel.

Returns:

Type Description
List[models.Message]

A list of messages fetched.

Source code in naff/models/discord/channel.py
async def fetch_pinned_messages(self) -> List["models.Message"]:
    """
    Fetch pinned messages from the channel.

    Returns:
        A list of messages fetched.

    """
    messages_data = await self._client.http.get_pinned_messages(self.id)
    return [self._client.cache.place_message_data(message_data) for message_data in messages_data]

async inherited method delete_messages(self, messages, reason)

Bulk delete messages from channel.

Parameters:

Name Type Description Default
messages List[Union[int, str, SnowflakeObject, SupportsInt, models.Message]]

List of messages or message IDs to delete.

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this action. Used for audit logs.

Missing
Source code in naff/models/discord/channel.py
async def delete_messages(
    self, messages: List[Union[Snowflake_Type, "models.Message"]], reason: Absent[Optional[str]] = MISSING
) -> None:
    """
    Bulk delete messages from channel.

    Args:
        messages: List of messages or message IDs to delete.
        reason: The reason for this action. Used for audit logs.

    """
    message_ids = [to_snowflake(message) for message in messages]
    # TODO Add check for min/max and duplicates.

    if len(message_ids) == 1:
        # bulk delete messages will throw a http error if only 1 message is passed
        await self.delete_message(message_ids[0], reason)
    else:
        await self._client.http.bulk_delete_messages(self.id, message_ids, reason)

async inherited method delete_message(self, message, reason)

Delete a single message from a channel.

Parameters:

Name Type Description Default
message Union[int, str, SnowflakeObject, SupportsInt, models.Message]

The message to delete

required
reason str

The reason for this action

None
Source code in naff/models/discord/channel.py
async def delete_message(self, message: Union[Snowflake_Type, "models.Message"], reason: str = None) -> None:
    """
    Delete a single message from a channel.

    Args:
        message: The message to delete
        reason: The reason for this action

    """
    message = to_snowflake(message)
    await self._client.http.delete_message(self.id, message, reason=reason)

async inherited method purge(self, deletion_limit, search_limit, predicate, avoid_loading_msg, before, after, around, reason)

Bulk delete messages within a channel. If a predicate is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the deletion_limit.

Example Usage:
1
2
3
# this will delete the last 20 messages sent by a user with the given ID
deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
await channel.send(f"{deleted} messages deleted")

Parameters:

Name Type Description Default
deletion_limit int

The target amount of messages to delete

50
search_limit int

How many messages to search through

100
predicate Callable[[models.Message], bool]

A function that returns True or False, and takes a message as an argument

Missing
avoid_loading_msg bool

Should the bot attempt to avoid deleting its own loading messages (recommended enabled)

True
before Union[int, str, SnowflakeObject, SupportsInt]

Search messages before this ID

Missing
after Union[int, str, SnowflakeObject, SupportsInt]

Search messages after this ID

Missing
around Union[int, str, SnowflakeObject, SupportsInt]

Search messages around this ID

Missing
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this deletion

Missing

Returns:

Type Description
int

The total amount of messages deleted

Source code in naff/models/discord/channel.py
async def purge(
    self,
    deletion_limit: int = 50,
    search_limit: int = 100,
    predicate: Callable[["models.Message"], bool] = MISSING,
    avoid_loading_msg: bool = True,
    before: Optional[Snowflake_Type] = MISSING,
    after: Optional[Snowflake_Type] = MISSING,
    around: Optional[Snowflake_Type] = MISSING,
    reason: Absent[Optional[str]] = MISSING,
) -> int:
    """
    Bulk delete messages within a channel. If a `predicate` is provided, it will be used to determine which messages to delete, otherwise all messages will be deleted within the `deletion_limit`.

    ??? Hint "Example Usage:"
        ```python
        # this will delete the last 20 messages sent by a user with the given ID
        deleted = await channel.purge(deletion_limit=20, predicate=lambda m: m.author.id == 174918559539920897)
        await channel.send(f"{deleted} messages deleted")
        ```

    Args:
        deletion_limit: The target amount of messages to delete
        search_limit: How many messages to search through
        predicate: A function that returns True or False, and takes a message as an argument
        avoid_loading_msg: Should the bot attempt to avoid deleting its own loading messages (recommended enabled)
        before: Search messages before this ID
        after: Search messages after this ID
        around: Search messages around this ID
        reason: The reason for this deletion

    Returns:
        The total amount of messages deleted

    """
    if not predicate:

        def predicate(m) -> bool:
            return True  # noqa

    to_delete = []

    # 1209600 14 days ago in seconds, 1420070400000 is used to convert to snowflake
    fourteen_days_ago = int((time.time() - 1209600) * 1000.0 - DISCORD_EPOCH) << 22
    async for message in self.history(limit=search_limit, before=before, after=after, around=around):
        if deletion_limit != 0 and len(to_delete) == deletion_limit:
            break

        if not predicate(message):
            # fails predicate
            continue

        if avoid_loading_msg:
            if message._author_id == self._client.user.id and MessageFlags.LOADING in message.flags:
                continue

        if message.id < fourteen_days_ago:
            # message is too old to be purged
            continue

        to_delete.append(message.id)

    count = len(to_delete)
    while len(to_delete):
        iteration = [to_delete.pop() for i in range(min(100, len(to_delete)))]
        await self.delete_messages(iteration, reason=reason)
    return count

async inherited method trigger_typing(self)

Trigger a typing animation in this channel.

Source code in naff/models/discord/channel.py
async def trigger_typing(self) -> None:
    """Trigger a typing animation in this channel."""
    await self._client.http.trigger_typing_indicator(self.id)

inherited property readonly typing: Typing

A context manager to send a typing state to a given channel as long as long as the wrapped operation takes.

async inherited method create_invite(self, max_age, max_uses, temporary, unique, target_type, target_user, target_application, reason)

Creates a new channel invite.

Parameters:

Name Type Description Default
max_age int

Max age of invite in seconds, default 86400 (24 hours).

86400
max_uses int

Max uses of invite, default 0.

0
temporary bool

Grants temporary membership, default False.

False
unique bool

Invite is unique, default false.

False
target_type Optional[naff.models.discord.enums.InviteTargetTypes]

Target type for streams and embedded applications.

None
target_user Union[int, str, SnowflakeObject, SupportsInt, models.User]

Target User ID for Stream target type.

None
target_application Union[int, str, SnowflakeObject, SupportsInt, models.Application]

Target Application ID for Embedded App target type.

None
reason Optional[str]

The reason for creating this invite.

None

Returns:

Type Description
models.Invite

Newly created Invite object.

Source code in naff/models/discord/channel.py
async def create_invite(
    self,
    max_age: int = 86400,
    max_uses: int = 0,
    temporary: bool = False,
    unique: bool = False,
    target_type: Optional[InviteTargetTypes] = None,
    target_user: Optional[Union[Snowflake_Type, "models.User"]] = None,
    target_application: Optional[Union[Snowflake_Type, "models.Application"]] = None,
    reason: Optional[str] = None,
) -> "models.Invite":
    """
    Creates a new channel invite.

    Args:
        max_age: Max age of invite in seconds, default 86400 (24 hours).
        max_uses: Max uses of invite, default 0.
        temporary: Grants temporary membership, default False.
        unique: Invite is unique, default false.
        target_type: Target type for streams and embedded applications.
        target_user: Target User ID for Stream target type.
        target_application: Target Application ID for Embedded App target type.
        reason: The reason for creating this invite.

    Returns:
        Newly created Invite object.

    """
    if target_type:
        if target_type == InviteTargetTypes.STREAM and not target_user:
            raise ValueError("Stream target must include target user id.")
        elif target_type == InviteTargetTypes.EMBEDDED_APPLICATION and not target_application:
            raise ValueError("Embedded Application target must include target application id.")

    if target_user and target_application:
        raise ValueError("Invite target must be either User or Embedded Application, not both.")
    elif target_user:
        target_user = to_snowflake(target_user)
        target_type = InviteTargetTypes.STREAM
    elif target_application:
        target_application = to_snowflake(target_application)
        target_type = InviteTargetTypes.EMBEDDED_APPLICATION

    invite_data = await self._client.http.create_channel_invite(
        self.id, max_age, max_uses, temporary, unique, target_type, target_user, target_application, reason
    )
    return models.Invite.from_dict(invite_data, self._client)

async inherited method fetch_invites(self)

Fetches all invites (with invite metadata) for the channel.

Returns:

Type Description
List[models.Invite]

List of Invite objects.

Source code in naff/models/discord/channel.py
async def fetch_invites(self) -> List["models.Invite"]:
    """
    Fetches all invites (with invite metadata) for the channel.

    Returns:
        List of Invite objects.

    """
    invites_data = await self._client.http.get_channel_invites(self.id)
    return models.Invite.from_list(invites_data, self._client)

inherited property readonly mention: str

Returns a string that would mention the channel.

async inherited method delete(self, reason)

Delete this channel.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for deleting this channel

Missing
Source code in naff/models/discord/channel.py
async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Delete this channel.

    Args:
        reason: The reason for deleting this channel

    """
    await self._client.http.delete_channel(self.id, reason)

inherited property readonly guild: models.Guild

The guild this channel belongs to.

inherited property readonly category: Optional[GuildCategory]

The parent category of this channel.

inherited property readonly gui_position: int

The position of this channel in the Discord interface.

inherited method permissions_for(self, instance)

Calculates permissions for an instance

Parameters:

Name Type Description Default
instance Union[int, str, SnowflakeObject, SupportsInt]

Member or Role instance (or its ID)

required

Returns:

Type Description
Permissions

Permissions data

Exceptions:

Type Description
ValueError

If could not find any member or role by given ID

RuntimeError

If given instance is from another guild

Source code in naff/models/discord/channel.py
def permissions_for(self, instance: Snowflake_Type) -> Permissions:
    """
    Calculates permissions for an instance

    Args:
        instance: Member or Role instance (or its ID)

    Returns:
        Permissions data

    Raises:
        ValueError: If could not find any member or role by given ID
        RuntimeError: If given instance is from another guild

    """
    if (is_member := isinstance(instance, models.Member)) or isinstance(instance, models.Role):
        if instance._guild_id != self._guild_id:
            raise RuntimeError("Unable to calculate permissions for the instance from different guild")

        if is_member:
            return instance.channel_permissions(self)

        else:
            permissions = instance.permissions

            for overwrite in self.permission_overwrites:
                if overwrite.id == instance.id:
                    permissions &= ~overwrite.deny
                    permissions |= overwrite.allow
                    break

            return permissions

    else:
        instance = to_snowflake(instance)
        guild = self.guild
        instance = guild.get_member(instance) or guild.get_role(instance)

        if not instance:
            raise ValueError("Unable to find any member or role by given instance ID")

        return self.permissions_for(instance)

async inherited method add_permission(self, target, type, allow, deny, reason)

Add a permission to this channel.

Parameters:

Name Type Description Default
target Union[PermissionOverwrite, models.Role, models.User, models.Member, Snowflake_Type]

The updated PermissionOverwrite object, or the Role or User object/id to update

required
type Optional[OverwriteTypes]

The type of permission overwrite. Only applicable if target is an id

None
allow Union[List[Permissions], int]

List of permissions to allow. Only applicable if target is not an PermissionOverwrite object

None
deny Union[List[Permissions], int]

List of permissions to deny. Only applicable if target is not an PermissionOverwrite object

None
reason Optional[str]

The reason for this change

None

Exceptions:

Type Description
ValueError

Invalid target for permission

Source code in naff/models/discord/channel.py
async def add_permission(
    self,
    target: Union["PermissionOverwrite", "models.Role", "models.User", "models.Member", "Snowflake_Type"],
    type: Optional["OverwriteTypes"] = None,
    allow: Optional[List["Permissions"] | int] = None,
    deny: Optional[List["Permissions"] | int] = None,
    reason: Optional[str] = None,
) -> None:
    """
    Add a permission to this channel.

    Args:
        target: The updated PermissionOverwrite object, or the Role or User object/id to update
        type: The type of permission overwrite. Only applicable if target is an id
        allow: List of permissions to allow. Only applicable if target is not an PermissionOverwrite object
        deny: List of permissions to deny. Only applicable if target is not an PermissionOverwrite object
        reason: The reason for this change

    Raises:
        ValueError: Invalid target for permission

    """
    allow = allow or []
    deny = deny or []
    if not isinstance(target, PermissionOverwrite):
        if isinstance(target, (models.User, models.Member)):
            target = target.id
            type = OverwriteTypes.MEMBER
        elif isinstance(target, models.Role):
            target = target.id
            type = OverwriteTypes.ROLE
        elif type and isinstance(target, Snowflake_Type):
            target = to_snowflake(target)
        else:
            raise ValueError("Invalid target and/or type for permission")
        overwrite = PermissionOverwrite(id=target, type=type, allow=Permissions.NONE, deny=Permissions.NONE)
        if isinstance(allow, int):
            overwrite.allow |= allow
        else:
            for perm in allow:
                overwrite.allow |= perm
        if isinstance(deny, int):
            overwrite.deny |= deny
        else:
            for perm in deny:
                overwrite.deny |= perm
    else:
        overwrite = target

    if exists := get(self.permission_overwrites, id=overwrite.id, type=overwrite.type):
        exists.deny = (exists.deny | overwrite.deny) & ~overwrite.allow
        exists.allow = (exists.allow | overwrite.allow) & ~overwrite.deny
        await self.edit_permission(exists, reason)
    else:
        permission_overwrites = self.permission_overwrites
        permission_overwrites.append(overwrite)
        await self.edit(permission_overwrites=permission_overwrites)

async inherited method edit_permission(self, overwrite, reason)

Edit the permissions for this channel.

Parameters:

Name Type Description Default
overwrite PermissionOverwrite

The permission overwrite to apply

required
reason Optional[str]

The reason for this change

None
Source code in naff/models/discord/channel.py
async def edit_permission(self, overwrite: PermissionOverwrite, reason: Optional[str] = None) -> None:
    """
    Edit the permissions for this channel.

    Args:
        overwrite: The permission overwrite to apply
        reason: The reason for this change
    """
    await self._client.http.edit_channel_permission(
        self.id, overwrite.id, overwrite.allow, overwrite.deny, overwrite.type, reason
    )

async inherited method delete_permission(self, target, reason)

Delete a permission overwrite for this channel.

Parameters:

Name Type Description Default
target Union[PermissionOverwrite, models.Role, models.User]

The permission overwrite to delete

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this change

Missing
Source code in naff/models/discord/channel.py
async def delete_permission(
    self,
    target: Union["PermissionOverwrite", "models.Role", "models.User"],
    reason: Absent[Optional[str]] = MISSING,
) -> None:
    """
    Delete a permission overwrite for this channel.

    Args:
        target: The permission overwrite to delete
        reason: The reason for this change

    """
    target = to_snowflake(target)
    await self._client.http.delete_channel_permission(self.id, target, reason)

async inherited method set_permission(self, target, *, add_reactions, administrator, attach_files, ban_members, change_nickname, connect, create_instant_invite, deafen_members, embed_links, kick_members, manage_channels, manage_emojis_and_stickers, manage_events, manage_guild, manage_messages, manage_nicknames, manage_roles, manage_threads, manage_webhooks, mention_everyone, moderate_members, move_members, mute_members, priority_speaker, read_message_history, request_to_speak, send_messages, send_messages_in_threads, send_tts_messages, speak, start_embedded_activities, stream, use_application_commands, use_external_emojis, use_external_stickers, use_private_threads, use_public_threads, use_vad, view_audit_log, view_channel, view_guild_insights, reason)

Set the Permission Overwrites for a given target.

Parameters:

Name Type Description Default
target Union[models.Role, models.Member, models.User]

The target to set permission overwrites for

required
add_reactions bool | None

Allows for the addition of reactions to messages

None
administrator bool | None

Allows all permissions and bypasses channel permission overwrites

None
attach_files bool | None

Allows for uploading images and files

None
ban_members bool | None

Allows banning members

None
change_nickname bool | None

Allows for modification of own nickname

None
connect bool | None

Allows for joining of a voice channel

None
create_instant_invite bool | None

Allows creation of instant invites

None
deafen_members bool | None

Allows for deafening of members in a voice channel

None
embed_links bool | None

Links sent by users with this permission will be auto-embedded

None
kick_members bool | None

Allows kicking members

None
manage_channels bool | None

Allows management and editing of channels

None
manage_emojis_and_stickers bool | None

Allows management and editing of emojis and stickers

None
manage_events bool | None

Allows for creating, editing, and deleting scheduled events

None
manage_guild bool | None

Allows management and editing of the guild

None
manage_messages bool | None

Allows for deletion of other users messages

None
manage_nicknames bool | None

Allows for modification of other users nicknames

None
manage_roles bool | None

Allows management and editing of roles

None
manage_threads bool | None

Allows for deleting and archiving threads, and viewing all private threads

None
manage_webhooks bool | None

Allows management and editing of webhooks

None
mention_everyone bool | None

Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all online users in a channel

None
moderate_members bool | None

Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels

None
move_members bool | None

Allows for moving of members between voice channels

None
mute_members bool | None

Allows for muting members in a voice channel

None
priority_speaker bool | None

Allows for using priority speaker in a voice channel

None
read_message_history bool | None

Allows for reading of message history

None
request_to_speak bool | None

Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)

None
send_messages bool | None

Allows for sending messages in a channel (does not allow sending messages in threads)

None
send_messages_in_threads bool | None

Allows for sending messages in threads

None
send_tts_messages bool | None

Allows for sending of /tts messages

None
speak bool | None

Allows for speaking in a voice channel

None
start_embedded_activities bool | None

Allows for using Activities (applications with the EMBEDDED flag) in a voice channel

None
stream bool | None

Allows the user to go live

None
use_application_commands bool | None

Allows members to use application commands, including slash commands and context menu commands

None
use_external_emojis bool | None

Allows the usage of custom emojis from other servers

None
use_external_stickers bool | None

Allows the usage of custom stickers from other servers

None
use_private_threads bool | None

Allows for creating private threads

None
use_public_threads bool | None

Allows for creating public and announcement threads

None
use_vad bool | None

Allows for using voice-activity-detection in a voice channel

None
view_audit_log bool | None

Allows for viewing of audit logs

None
view_channel bool | None

Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels

None
view_guild_insights bool | None

Allows for viewing guild insights

None
reason str

The reason for creating this overwrite

None
Source code in naff/models/discord/channel.py
async def set_permission(
    self,
    target: Union["models.Role", "models.Member", "models.User"],
    *,
    add_reactions: bool | None = None,
    administrator: bool | None = None,
    attach_files: bool | None = None,
    ban_members: bool | None = None,
    change_nickname: bool | None = None,
    connect: bool | None = None,
    create_instant_invite: bool | None = None,
    deafen_members: bool | None = None,
    embed_links: bool | None = None,
    kick_members: bool | None = None,
    manage_channels: bool | None = None,
    manage_emojis_and_stickers: bool | None = None,
    manage_events: bool | None = None,
    manage_guild: bool | None = None,
    manage_messages: bool | None = None,
    manage_nicknames: bool | None = None,
    manage_roles: bool | None = None,
    manage_threads: bool | None = None,
    manage_webhooks: bool | None = None,
    mention_everyone: bool | None = None,
    moderate_members: bool | None = None,
    move_members: bool | None = None,
    mute_members: bool | None = None,
    priority_speaker: bool | None = None,
    read_message_history: bool | None = None,
    request_to_speak: bool | None = None,
    send_messages: bool | None = None,
    send_messages_in_threads: bool | None = None,
    send_tts_messages: bool | None = None,
    speak: bool | None = None,
    start_embedded_activities: bool | None = None,
    stream: bool | None = None,
    use_application_commands: bool | None = None,
    use_external_emojis: bool | None = None,
    use_external_stickers: bool | None = None,
    use_private_threads: bool | None = None,
    use_public_threads: bool | None = None,
    use_vad: bool | None = None,
    view_audit_log: bool | None = None,
    view_channel: bool | None = None,
    view_guild_insights: bool | None = None,
    reason: str = None,
) -> None:
    """
    Set the Permission Overwrites for a given target.

    Args:
        target: The target to set permission overwrites for
        add_reactions: Allows for the addition of reactions to messages
        administrator: Allows all permissions and bypasses channel permission overwrites
        attach_files: Allows for uploading images and files
        ban_members: Allows banning members
        change_nickname: Allows for modification of own nickname
        connect: Allows for joining of a voice channel
        create_instant_invite: Allows creation of instant invites
        deafen_members: Allows for deafening of members in a voice channel
        embed_links: Links sent by users with this permission will be auto-embedded
        kick_members: Allows kicking members
        manage_channels: Allows management and editing of channels
        manage_emojis_and_stickers: Allows management and editing of emojis and stickers
        manage_events: Allows for creating, editing, and deleting scheduled events
        manage_guild: Allows management and editing of the guild
        manage_messages: Allows for deletion of other users messages
        manage_nicknames: Allows for modification of other users nicknames
        manage_roles: Allows management and editing of roles
        manage_threads: Allows for deleting and archiving threads, and viewing all private threads
        manage_webhooks: Allows management and editing of webhooks
        mention_everyone: Allows for using the `@everyone` tag to notify all users in a channel, and the `@here` tag to notify all online users in a channel
        moderate_members: Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels
        move_members: Allows for moving of members between voice channels
        mute_members: Allows for muting members in a voice channel
        priority_speaker: Allows for using priority speaker in a voice channel
        read_message_history: Allows for reading of message history
        request_to_speak: Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)
        send_messages:  Allows for sending messages in a channel (does not allow sending messages in threads)
        send_messages_in_threads: Allows for sending messages in threads
        send_tts_messages:  Allows for sending of `/tts` messages
        speak: Allows for speaking in a voice channel
        start_embedded_activities: Allows for using Activities (applications with the `EMBEDDED` flag) in a voice channel
        stream: Allows the user to go live
        use_application_commands: Allows members to use application commands, including slash commands and context menu commands
        use_external_emojis: Allows the usage of custom emojis from other servers
        use_external_stickers: Allows the usage of custom stickers from other servers
        use_private_threads: Allows for creating private threads
        use_public_threads:  Allows for creating public and announcement threads
        use_vad: Allows for using voice-activity-detection in a voice channel
        view_audit_log: Allows for viewing of audit logs
        view_channel: Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels
        view_guild_insights: Allows for viewing guild insights
        reason: The reason for creating this overwrite
    """
    overwrite = PermissionOverwrite.for_target(target)

    allow: Permissions = Permissions.NONE
    deny: Permissions = Permissions.NONE

    for name, val in locals().items():
        if isinstance(val, bool):
            if val:
                allow |= getattr(Permissions, name.upper())
            else:
                deny |= getattr(Permissions, name.upper())

    overwrite.add_allows(allow)
    overwrite.add_denies(deny)

    await self.edit_permission(overwrite, reason)

inherited property readonly bots: List[models.Member]

Returns a list of bots that can see this channel.

inherited property readonly humans: List[models.Member]

Returns a list of humans that can see this channel.

async inherited method clone(self, name, reason)

Clone this channel and create a new one.

Parameters:

Name Type Description Default
name Optional[str]

The name of the new channel. Defaults to the current name

None
reason Union[str, NoneType, naff.client.const.Missing]

The reason for creating this channel

Missing

Returns:

Type Description
TYPE_GUILD_CHANNEL

The newly created channel.

Source code in naff/models/discord/channel.py
async def clone(self, name: Optional[str] = None, reason: Absent[Optional[str]] = MISSING) -> "TYPE_GUILD_CHANNEL":
    """
    Clone this channel and create a new one.

    Args:
        name: The name of the new channel. Defaults to the current name
        reason: The reason for creating this channel

    Returns:
        The newly created channel.

    """
    return await self.guild.create_channel(
        channel_type=self.type,
        name=name if name else self.name,
        topic=getattr(self, "topic", MISSING),
        position=self.position,
        permission_overwrites=self.permission_overwrites,
        category=self.category,
        nsfw=self.nsfw,
        bitrate=getattr(self, "bitrate", 64000),
        user_limit=getattr(self, "user_limit", 0),
        rate_limit_per_user=getattr(self, "rate_limit_per_user", 0),
        reason=reason,
    )

async inherited method edit(self, name, position, permission_overwrites, parent_id, bitrate, user_limit, rtc_region, video_quality_mode, reason, **kwargs)

Edit guild voice channel.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

1-100 character channel name

Missing
position Union[int, naff.client.const.Missing]

the position of the channel in the left-hand listing

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

a list of PermissionOverwrite to apply to the channel

Missing
parent_id Union[int, str, SnowflakeObject, SupportsInt, naff.client.const.Missing]

the parent category Snowflake_Type for the channel

Missing
bitrate Union[int, naff.client.const.Missing]

the bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)

Missing
user_limit Union[int, naff.client.const.Missing]

the user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit

Missing
rtc_region Union[str, naff.client.const.Missing]

channel voice region id, automatic when not set

Missing
video_quality_mode Union[naff.models.discord.enums.VideoQualityModes, naff.client.const.Missing]

the camera video quality mode of the voice channel

Missing
reason Union[str, naff.client.const.Missing]

optional reason for audit logs

Missing

Returns:

Type Description
Union[GuildVoice, GuildStageVoice]

The edited voice channel object.

Source code in naff/models/discord/channel.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    position: Absent[int] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    parent_id: Absent[Snowflake_Type] = MISSING,
    bitrate: Absent[int] = MISSING,
    user_limit: Absent[int] = MISSING,
    rtc_region: Absent[str] = MISSING,
    video_quality_mode: Absent[VideoQualityModes] = MISSING,
    reason: Absent[str] = MISSING,
    **kwargs,
) -> Union["GuildVoice", "GuildStageVoice"]:
    """
    Edit guild voice channel.

    Args:
        name: 1-100 character channel name
        position: the position of the channel in the left-hand listing
        permission_overwrites: a list of `PermissionOverwrite` to apply to the channel
        parent_id: the parent category `Snowflake_Type` for the channel
        bitrate: the bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)
        user_limit: the user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit
        rtc_region: channel voice region id, automatic when not set
        video_quality_mode: the camera video quality mode of the voice channel
        reason: optional reason for audit logs

    Returns:
        The edited voice channel object.

    """
    return await super().edit(
        name=name,
        position=position,
        permission_overwrites=permission_overwrites,
        parent_id=parent_id,
        bitrate=bitrate,
        user_limit=user_limit,
        rtc_region=rtc_region,
        video_quality_mode=video_quality_mode,
        reason=reason,
        **kwargs,
    )

inherited property readonly members: List[models.Member]

Returns a list of members that have access to this voice channel

inherited property readonly voice_members: List[models.Member]

Returns a list of members that are currently in the channel. Note: This will not be accurate if the bot was offline while users joined the channel

inherited property readonly voice_state: Optional[ActiveVoiceState]

Returns the voice state of the bot in this channel if it is connected

async inherited method connect(self, muted, deafened)

Connect the bot to this voice channel, or move the bot to this voice channel if it is already connected in another voice channel.

Parameters:

Name Type Description Default
muted bool

Whether the bot should be muted when connected.

False
deafened bool

Whether the bot should be deafened when connected.

False

Returns:

Type Description
ActiveVoiceState

The new active voice state on successfully connection.

Source code in naff/models/discord/channel.py
async def connect(self, muted: bool = False, deafened: bool = False) -> "ActiveVoiceState":
    """
    Connect the bot to this voice channel, or move the bot to this voice channel if it is already connected in another voice channel.

    Args:
        muted: Whether the bot should be muted when connected.
        deafened: Whether the bot should be deafened when connected.

    Returns:
        The new active voice state on successfully connection.

    """
    if not self.voice_state:
        return await self._client.connect_to_vc(self._guild_id, self.id, muted, deafened)
    await self.voice_state.move(self.id)
    return self.voice_state

async inherited method disconnect(self)

Disconnect from the currently connected connected voice state.

Source code in naff/models/discord/channel.py
async def disconnect(self) -> None:
    """
    Disconnect from the currently connected connected voice state.

    Raises:
        VoiceNotConnected if the bot is not connected to a voice channel
    """
    if self.voice_state:
        return await self.voice_state.disconnect()
    else:
        raise VoiceNotConnected

async method fetch_stage_instance(self)

Fetches the stage instance associated with this channel.

Returns:

Type Description
models.StageInstance

The stage instance associated with this channel. If no stage is live, will return None.

Source code in naff/models/discord/channel.py
async def fetch_stage_instance(self) -> "models.StageInstance":
    """
    Fetches the stage instance associated with this channel.

    Returns:
        The stage instance associated with this channel. If no stage is live, will return None.

    """
    self.stage_instance = models.StageInstance.from_dict(
        await self._client.http.get_stage_instance(self.id), self._client
    )
    return self.stage_instance

async method create_stage_instance(self, topic, privacy_level, reason)

Create a stage instance in this channel.

Parameters:

Name Type Description Default
topic str

The topic of the stage (1-120 characters)

required
privacy_level StagePrivacyLevel

The privacy level of the stage

<StagePrivacyLevel.GUILD_ONLY: 2>
reason Union[str, NoneType, naff.client.const.Missing]

The reason for creating this instance

Missing

Returns:

Type Description
models.StageInstance

The created stage instance object.

Source code in naff/models/discord/channel.py
async def create_stage_instance(
    self,
    topic: str,
    privacy_level: StagePrivacyLevel = StagePrivacyLevel.GUILD_ONLY,
    reason: Absent[Optional[str]] = MISSING,
) -> "models.StageInstance":
    """
    Create a stage instance in this channel.

    Args:
        topic: The topic of the stage (1-120 characters)
        privacy_level: The privacy level of the stage
        reason: The reason for creating this instance

    Returns:
        The created stage instance object.

    """
    self.stage_instance = models.StageInstance.from_dict(
        await self._client.http.create_stage_instance(self.id, topic, privacy_level, reason), self._client
    )
    return self.stage_instance

async method close_stage(self, reason)

Closes the live stage instance.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for closing the stage

Missing
Source code in naff/models/discord/channel.py
async def close_stage(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Closes the live stage instance.

    Args:
        reason: The reason for closing the stage

    """
    if not self.stage_instance:
        # we dont know of an active stage instance, so lets check for one
        if not await self.get_stage_instance():
            raise ValueError("No stage instance found")

    await self.stage_instance.delete(reason=reason)

attrs class GuildForum (GuildChannel)

Attr attributes:

Name Type Description
id int

Discord unique snowflake ID

available_tags List[naff.models.discord.thread.ThreadTag]

A list of tags available to assign to threads

Source code in naff/models/discord/channel.py
@define()
class GuildForum(GuildChannel):
    available_tags: List[ThreadTag] = field(factory=list)
    """A list of tags available to assign to threads"""
    last_message_id: Optional[Snowflake_Type] = field(default=None)
    # TODO: Implement "template" once the API supports them

    @classmethod
    def _process_dict(cls, data: Dict[str, Any], client: "Client") -> Dict[str, Any]:
        data = super()._process_dict(data, client)
        data["available_tags"] = [
            ThreadTag.from_dict(tag_data | {"parent_channel_id": data["id"]}, client)
            for tag_data in data.get("available_tags", [])
        ]
        return data

    async def create_post(
        self,
        name: str,
        content: str | None,
        applied_tags: Optional[List[Union["Snowflake_Type", "ThreadTag"]]] = MISSING,
        *,
        auto_archive_duration: AutoArchiveDuration = AutoArchiveDuration.ONE_DAY,
        rate_limit_per_user: Absent[int] = MISSING,
        embeds: Optional[Union[List[Union["Embed", dict]], Union["Embed", dict]]] = None,
        embed: Optional[Union["Embed", dict]] = None,
        components: Optional[
            Union[List[List[Union["BaseComponent", dict]]], List[Union["BaseComponent", dict]], "BaseComponent", dict]
        ] = None,
        stickers: Optional[Union[List[Union["Sticker", "Snowflake_Type"]], "Sticker", "Snowflake_Type"]] = None,
        allowed_mentions: Optional[Union["AllowedMentions", dict]] = None,
        files: Optional[Union["UPLOADABLE_TYPE", List["UPLOADABLE_TYPE"]]] = None,
        file: Optional["UPLOADABLE_TYPE"] = None,
        tts: bool = False,
        reason: Absent[str] = MISSING,
    ) -> "GuildPublicThread":
        """
        Create a post within this channel.

        Args:
            name: The name of the post
            content: The text content of this post
            applied_tags: A list of tag ids or tag objects to apply to this post
            auto_archive_duration: Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.
            rate_limit_per_user: The time users must wait between sending messages
            embeds: Embedded rich content (up to 6000 characters).
            embed: Embedded rich content (up to 6000 characters).
            components: The components to include with the message.
            stickers: IDs of up to 3 stickers in the server to send in the message.
            allowed_mentions: Allowed mentions for the message.
            files: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
            file: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
            tts: Should this message use Text To Speech.
            flags: Message flags to apply.
            reason: The reason for creating this post

        Returns:
            A GuildPublicThread object representing the created post.
        """
        if applied_tags != MISSING:
            applied_tags = [str(tag.id) if isinstance(tag, ThreadTag) else str(tag) for tag in applied_tags]

        message_payload = models.discord.message.process_message_payload(
            content=content,
            embeds=embeds or embed,
            components=components,
            stickers=stickers,
            allowed_mentions=allowed_mentions,
            tts=tts,
        )

        data = await self._client.http.create_forum_thread(
            self.id,
            name,
            auto_archive_duration,
            message_payload,
            applied_tags,
            rate_limit_per_user,
            files=files or file,
            reason=reason,
        )
        return self._client.cache.place_channel_data(data)

    async def create_tag(self, name: str, emoji: Union["models.PartialEmoji", dict, str]) -> "ThreadTag":
        """
        Create a tag for this forum.

        Args:
            name: The name of the tag
            emoji: The emoji to use for the tag

        Note:
            If the emoji is a custom emoji, it must be from the same guild as the channel.

        Returns:
            The created tag object.

        """
        if isinstance(emoji, str):
            emoji = PartialEmoji.from_str(emoji)
        elif isinstance(emoji, dict):
            emoji = PartialEmoji.from_dict(emoji)

        if emoji.id:
            data = await self._client.http.create_tag(self.id, name, emoji_id=emoji.id)
        else:
            data = await self._client.http.create_tag(self.id, name, emoji_name=emoji.name)

        channel_data = self._client.cache.place_channel_data(data)
        return [tag for tag in channel_data.available_tags if tag.name == name][0]

    async def edit_tag(
        self,
        tag_id: "Snowflake_Type",
        *,
        name: str | None = None,
        emoji: Union["models.PartialEmoji", dict, str, None] = None,
    ) -> "ThreadTag":
        """
        Edit a tag for this forum.

        Args:
            tag_id: The id of the tag to edit
            name: The name for this tag
            emoji: The emoji for this tag
        """
        if isinstance(emoji, str):
            emoji = PartialEmoji.from_str(emoji)
        elif isinstance(emoji, dict):
            emoji = PartialEmoji.from_dict(emoji)

        if emoji.id:
            data = await self._client.http.edit_tag(self.id, tag_id, name, emoji_id=emoji.id)
        else:
            data = await self._client.http.edit_tag(self.id, tag_id, name, emoji_name=emoji.name)

        channel_data = self._client.cache.place_channel_data(data)
        return [tag for tag in channel_data.available_tags if tag.name == name][0]

    async def delete_tag(self, tag_id: "Snowflake_Type") -> None:
        """
        Delete a tag for this forum.

        Args:
            tag_id: The ID of the tag to delete
        """
        data = await self._client.http.delete_tag(self.id, tag_id)
        self._client.cache.place_channel_data(data)

inherited method update_from_dict(self, data)

Updates object attribute(s) with new json data received from discord api.

Parameters:

Name Type Description Default
data

The json data received from discord api.

required

Returns:

Type Description
~T

The updated object class instance.

Source code in naff/models/discord/channel.py
def update_from_dict(self, data) -> T:
    data = self._process_dict(data, self._client)
    for key, value in self._filter_kwargs(data, self._get_keys()).items():
        # todo improve
        setattr(self, key, value)

    return self

inherited property readonly created_at: models.Timestamp

Returns a timestamp representing the date-time this discord object was created.

:Returns:

inherited method to_dict(self)

Exports object into dictionary representation, ready to be sent to discord api.

Returns:

Type Description
Dict[str, Any]

The exported dictionary.

Source code in naff/models/discord/channel.py
def to_dict(self) -> Dict[str, Any]:
    """
    Exports object into dictionary representation, ready to be sent to discord api.

    Returns:
        The exported dictionary.

    """
    self._check_object()
    return serializer.to_dict(self)

inherited property readonly mention: str

Returns a string that would mention the channel.

async inherited method edit(self, name, icon, type, position, topic, nsfw, rate_limit_per_user, bitrate, user_limit, permission_overwrites, parent_id, rtc_region, video_quality_mode, default_auto_archive_duration, archived, auto_archive_duration, locked, invitable, reason, **kwargs)

Edits the channel.

Parameters:

Name Type Description Default
name Union[str, naff.client.const.Missing]

1-100 character channel name

Missing
icon Union[naff.models.discord.file.File, io.IOBase, BinaryIO, pathlib.Path, str, naff.client.const.Missing]

DM Group icon

Missing
type Union[naff.models.discord.enums.ChannelTypes, naff.client.const.Missing]

The type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature

Missing
position Union[int, naff.client.const.Missing]

The position of the channel in the left-hand listing

Missing
topic Union[str, naff.client.const.Missing]

0-1024 character channel topic

Missing
nsfw Union[bool, naff.client.const.Missing]

Whether the channel is nsfw

Missing
rate_limit_per_user Union[int, naff.client.const.Missing]

Amount of seconds a user has to wait before sending another message (0-21600)

Missing
bitrate Union[int, naff.client.const.Missing]

The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)

Missing
user_limit Union[int, naff.client.const.Missing]

The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit

Missing
permission_overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]], naff.client.const.Missing]

Channel or category-specific permissions

Missing
parent_id Union[int, str, SnowflakeObject, SupportsInt, naff.client.const.Missing]

The id of the new parent category for a channel

Missing
rtc_region Union[models.VoiceRegion, str, naff.client.const.Missing]

Channel voice region id, automatic when set to None.

Missing
video_quality_mode Union[naff.models.discord.enums.VideoQualityModes, naff.client.const.Missing]

The camera video quality mode of the voice channel

Missing
default_auto_archive_duration Union[naff.models.discord.enums.AutoArchiveDuration, naff.client.const.Missing]

The default duration that the clients use (not the API) for newly created threads in the channel, in minutes, to automatically archive the thread after recent activity

Missing
archived Union[bool, naff.client.const.Missing]

Whether the thread is archived

Missing
auto_archive_duration Union[naff.models.discord.enums.AutoArchiveDuration, naff.client.const.Missing]

Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080

Missing
locked Union[bool, naff.client.const.Missing]

Whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it

Missing
invitable Union[bool, naff.client.const.Missing]

Whether non-moderators can add other non-moderators to a thread; only available on private threads

Missing
reason Union[str, naff.client.const.Missing]

The reason for editing the channel

Missing

Returns:

Type Description
TYPE_ALL_CHANNEL

The edited channel. May be a new object if the channel type changes.

Source code in naff/models/discord/channel.py
async def edit(
    self,
    name: Absent[str] = MISSING,
    icon: Absent[UPLOADABLE_TYPE] = MISSING,
    type: Absent[ChannelTypes] = MISSING,
    position: Absent[int] = MISSING,
    topic: Absent[str] = MISSING,
    nsfw: Absent[bool] = MISSING,
    rate_limit_per_user: Absent[int] = MISSING,
    bitrate: Absent[int] = MISSING,
    user_limit: Absent[int] = MISSING,
    permission_overwrites: Absent[
        Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
    ] = MISSING,
    parent_id: Absent[Snowflake_Type] = MISSING,
    rtc_region: Absent[Union["models.VoiceRegion", str]] = MISSING,
    video_quality_mode: Absent[VideoQualityModes] = MISSING,
    default_auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
    archived: Absent[bool] = MISSING,
    auto_archive_duration: Absent[AutoArchiveDuration] = MISSING,
    locked: Absent[bool] = MISSING,
    invitable: Absent[bool] = MISSING,
    reason: Absent[str] = MISSING,
    **kwargs,
) -> "TYPE_ALL_CHANNEL":
    """
    Edits the channel.

    Args:
        name: 1-100 character channel name
        icon: DM Group icon
        type: The type of channel; only conversion between text and news is supported and only in guilds with the "NEWS" feature
        position: The position of the channel in the left-hand listing
        topic: 0-1024 character channel topic
        nsfw: Whether the channel is nsfw
        rate_limit_per_user: Amount of seconds a user has to wait before sending another message (0-21600)
        bitrate: The bitrate (in bits) of the voice channel; 8000 to 96000 (128000 for VIP servers)
        user_limit: The user limit of the voice channel; 0 refers to no limit, 1 to 99 refers to a user limit
        permission_overwrites: Channel or category-specific permissions
        parent_id: The id of the new parent category for a channel
        rtc_region: Channel voice region id, automatic when set to None.
        video_quality_mode: The camera video quality mode of the voice channel
        default_auto_archive_duration: The default duration that the clients use (not the API) for newly created threads in the channel, in minutes, to automatically archive the thread after recent activity
        archived: Whether the thread is archived
        auto_archive_duration: Duration in minutes to automatically archive the thread after recent activity, can be set to: 60, 1440, 4320, 10080
        locked: Whether the thread is locked; when a thread is locked, only users with MANAGE_THREADS can unarchive it
        invitable: Whether non-moderators can add other non-moderators to a thread; only available on private threads
        reason: The reason for editing the channel

    Returns:
        The edited channel. May be a new object if the channel type changes.

    """
    payload = {
        "name": name,
        "icon": to_image_data(icon),
        "type": type,
        "position": position,
        "topic": topic,
        "nsfw": nsfw,
        "rate_limit_per_user": rate_limit_per_user,
        "bitrate": bitrate,
        "user_limit": user_limit,
        "permission_overwrites": process_permission_overwrites(permission_overwrites),
        "parent_id": to_optional_snowflake(parent_id),
        "rtc_region": rtc_region.id if isinstance(rtc_region, models.VoiceRegion) else rtc_region,
        "video_quality_mode": video_quality_mode,
        "default_auto_archive_duration": default_auto_archive_duration,
        "archived": archived,
        "auto_archive_duration": auto_archive_duration,
        "locked": locked,
        "invitable": invitable,
        **kwargs,
    }
    channel_data = await self._client.http.modify_channel(self.id, payload, reason)
    if not channel_data:
        raise TooManyChanges(
            "You have changed this channel too frequently, you need to wait a while before trying again."
        ) from None

    return self._client.cache.place_channel_data(channel_data)

async inherited method delete(self, reason)

Delete this channel.

Parameters:

Name Type Description Default
reason Union[str, NoneType, naff.client.const.Missing]

The reason for deleting this channel

Missing
Source code in naff/models/discord/channel.py
async def delete(self, reason: Absent[Optional[str]] = MISSING) -> None:
    """
    Delete this channel.

    Args:
        reason: The reason for deleting this channel

    """
    await self._client.http.delete_channel(self.id, reason)

inherited property readonly guild: models.Guild

The guild this channel belongs to.

inherited property readonly category: Optional[GuildCategory]

The parent category of this channel.

inherited property readonly gui_position: int

The position of this channel in the Discord interface.

inherited method permissions_for(self, instance)

Calculates permissions for an instance

Parameters:

Name Type Description Default
instance Union[int, str, SnowflakeObject, SupportsInt]

Member or Role instance (or its ID)

required

Returns:

Type Description
Permissions

Permissions data

Exceptions:

Type Description
ValueError

If could not find any member or role by given ID

RuntimeError

If given instance is from another guild

Source code in naff/models/discord/channel.py
def permissions_for(self, instance: Snowflake_Type) -> Permissions:
    """
    Calculates permissions for an instance

    Args:
        instance: Member or Role instance (or its ID)

    Returns:
        Permissions data

    Raises:
        ValueError: If could not find any member or role by given ID
        RuntimeError: If given instance is from another guild

    """
    if (is_member := isinstance(instance, models.Member)) or isinstance(instance, models.Role):
        if instance._guild_id != self._guild_id:
            raise RuntimeError("Unable to calculate permissions for the instance from different guild")

        if is_member:
            return instance.channel_permissions(self)

        else:
            permissions = instance.permissions

            for overwrite in self.permission_overwrites:
                if overwrite.id == instance.id:
                    permissions &= ~overwrite.deny
                    permissions |= overwrite.allow
                    break

            return permissions

    else:
        instance = to_snowflake(instance)
        guild = self.guild
        instance = guild.get_member(instance) or guild.get_role(instance)

        if not instance:
            raise ValueError("Unable to find any member or role by given instance ID")

        return self.permissions_for(instance)

async inherited method add_permission(self, target, type, allow, deny, reason)

Add a permission to this channel.

Parameters:

Name Type Description Default
target Union[PermissionOverwrite, models.Role, models.User, models.Member, Snowflake_Type]

The updated PermissionOverwrite object, or the Role or User object/id to update

required
type Optional[OverwriteTypes]

The type of permission overwrite. Only applicable if target is an id

None
allow Union[List[Permissions], int]

List of permissions to allow. Only applicable if target is not an PermissionOverwrite object

None
deny Union[List[Permissions], int]

List of permissions to deny. Only applicable if target is not an PermissionOverwrite object

None
reason Optional[str]

The reason for this change

None

Exceptions:

Type Description
ValueError

Invalid target for permission

Source code in naff/models/discord/channel.py
async def add_permission(
    self,
    target: Union["PermissionOverwrite", "models.Role", "models.User", "models.Member", "Snowflake_Type"],
    type: Optional["OverwriteTypes"] = None,
    allow: Optional[List["Permissions"] | int] = None,
    deny: Optional[List["Permissions"] | int] = None,
    reason: Optional[str] = None,
) -> None:
    """
    Add a permission to this channel.

    Args:
        target: The updated PermissionOverwrite object, or the Role or User object/id to update
        type: The type of permission overwrite. Only applicable if target is an id
        allow: List of permissions to allow. Only applicable if target is not an PermissionOverwrite object
        deny: List of permissions to deny. Only applicable if target is not an PermissionOverwrite object
        reason: The reason for this change

    Raises:
        ValueError: Invalid target for permission

    """
    allow = allow or []
    deny = deny or []
    if not isinstance(target, PermissionOverwrite):
        if isinstance(target, (models.User, models.Member)):
            target = target.id
            type = OverwriteTypes.MEMBER
        elif isinstance(target, models.Role):
            target = target.id
            type = OverwriteTypes.ROLE
        elif type and isinstance(target, Snowflake_Type):
            target = to_snowflake(target)
        else:
            raise ValueError("Invalid target and/or type for permission")
        overwrite = PermissionOverwrite(id=target, type=type, allow=Permissions.NONE, deny=Permissions.NONE)
        if isinstance(allow, int):
            overwrite.allow |= allow
        else:
            for perm in allow:
                overwrite.allow |= perm
        if isinstance(deny, int):
            overwrite.deny |= deny
        else:
            for perm in deny:
                overwrite.deny |= perm
    else:
        overwrite = target

    if exists := get(self.permission_overwrites, id=overwrite.id, type=overwrite.type):
        exists.deny = (exists.deny | overwrite.deny) & ~overwrite.allow
        exists.allow = (exists.allow | overwrite.allow) & ~overwrite.deny
        await self.edit_permission(exists, reason)
    else:
        permission_overwrites = self.permission_overwrites
        permission_overwrites.append(overwrite)
        await self.edit(permission_overwrites=permission_overwrites)

async inherited method edit_permission(self, overwrite, reason)

Edit the permissions for this channel.

Parameters:

Name Type Description Default
overwrite PermissionOverwrite

The permission overwrite to apply

required
reason Optional[str]

The reason for this change

None
Source code in naff/models/discord/channel.py
async def edit_permission(self, overwrite: PermissionOverwrite, reason: Optional[str] = None) -> None:
    """
    Edit the permissions for this channel.

    Args:
        overwrite: The permission overwrite to apply
        reason: The reason for this change
    """
    await self._client.http.edit_channel_permission(
        self.id, overwrite.id, overwrite.allow, overwrite.deny, overwrite.type, reason
    )

async inherited method delete_permission(self, target, reason)

Delete a permission overwrite for this channel.

Parameters:

Name Type Description Default
target Union[PermissionOverwrite, models.Role, models.User]

The permission overwrite to delete

required
reason Union[str, NoneType, naff.client.const.Missing]

The reason for this change

Missing
Source code in naff/models/discord/channel.py
async def delete_permission(
    self,
    target: Union["PermissionOverwrite", "models.Role", "models.User"],
    reason: Absent[Optional[str]] = MISSING,
) -> None:
    """
    Delete a permission overwrite for this channel.

    Args:
        target: The permission overwrite to delete
        reason: The reason for this change

    """
    target = to_snowflake(target)
    await self._client.http.delete_channel_permission(self.id, target, reason)

async inherited method set_permission(self, target, *, add_reactions, administrator, attach_files, ban_members, change_nickname, connect, create_instant_invite, deafen_members, embed_links, kick_members, manage_channels, manage_emojis_and_stickers, manage_events, manage_guild, manage_messages, manage_nicknames, manage_roles, manage_threads, manage_webhooks, mention_everyone, moderate_members, move_members, mute_members, priority_speaker, read_message_history, request_to_speak, send_messages, send_messages_in_threads, send_tts_messages, speak, start_embedded_activities, stream, use_application_commands, use_external_emojis, use_external_stickers, use_private_threads, use_public_threads, use_vad, view_audit_log, view_channel, view_guild_insights, reason)

Set the Permission Overwrites for a given target.

Parameters:

Name Type Description Default
target Union[models.Role, models.Member, models.User]

The target to set permission overwrites for

required
add_reactions bool | None

Allows for the addition of reactions to messages

None
administrator bool | None

Allows all permissions and bypasses channel permission overwrites

None
attach_files bool | None

Allows for uploading images and files

None
ban_members bool | None

Allows banning members

None
change_nickname bool | None

Allows for modification of own nickname

None
connect bool | None

Allows for joining of a voice channel

None
create_instant_invite bool | None

Allows creation of instant invites

None
deafen_members bool | None

Allows for deafening of members in a voice channel

None
embed_links bool | None

Links sent by users with this permission will be auto-embedded

None
kick_members bool | None

Allows kicking members

None
manage_channels bool | None

Allows management and editing of channels

None
manage_emojis_and_stickers bool | None

Allows management and editing of emojis and stickers

None
manage_events bool | None

Allows for creating, editing, and deleting scheduled events

None
manage_guild bool | None

Allows management and editing of the guild

None
manage_messages bool | None

Allows for deletion of other users messages

None
manage_nicknames bool | None

Allows for modification of other users nicknames

None
manage_roles bool | None

Allows management and editing of roles

None
manage_threads bool | None

Allows for deleting and archiving threads, and viewing all private threads

None
manage_webhooks bool | None

Allows management and editing of webhooks

None
mention_everyone bool | None

Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all online users in a channel

None
moderate_members bool | None

Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels

None
move_members bool | None

Allows for moving of members between voice channels

None
mute_members bool | None

Allows for muting members in a voice channel

None
priority_speaker bool | None

Allows for using priority speaker in a voice channel

None
read_message_history bool | None

Allows for reading of message history

None
request_to_speak bool | None

Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)

None
send_messages bool | None

Allows for sending messages in a channel (does not allow sending messages in threads)

None
send_messages_in_threads bool | None

Allows for sending messages in threads

None
send_tts_messages bool | None

Allows for sending of /tts messages

None
speak bool | None

Allows for speaking in a voice channel

None
start_embedded_activities bool | None

Allows for using Activities (applications with the EMBEDDED flag) in a voice channel

None
stream bool | None

Allows the user to go live

None
use_application_commands bool | None

Allows members to use application commands, including slash commands and context menu commands

None
use_external_emojis bool | None

Allows the usage of custom emojis from other servers

None
use_external_stickers bool | None

Allows the usage of custom stickers from other servers

None
use_private_threads bool | None

Allows for creating private threads

None
use_public_threads bool | None

Allows for creating public and announcement threads

None
use_vad bool | None

Allows for using voice-activity-detection in a voice channel

None
view_audit_log bool | None

Allows for viewing of audit logs

None
view_channel bool | None

Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels

None
view_guild_insights bool | None

Allows for viewing guild insights

None
reason str

The reason for creating this overwrite

None
Source code in naff/models/discord/channel.py
async def set_permission(
    self,
    target: Union["models.Role", "models.Member", "models.User"],
    *,
    add_reactions: bool | None = None,
    administrator: bool | None = None,
    attach_files: bool | None = None,
    ban_members: bool | None = None,
    change_nickname: bool | None = None,
    connect: bool | None = None,
    create_instant_invite: bool | None = None,
    deafen_members: bool | None = None,
    embed_links: bool | None = None,
    kick_members: bool | None = None,
    manage_channels: bool | None = None,
    manage_emojis_and_stickers: bool | None = None,
    manage_events: bool | None = None,
    manage_guild: bool | None = None,
    manage_messages: bool | None = None,
    manage_nicknames: bool | None = None,
    manage_roles: bool | None = None,
    manage_threads: bool | None = None,
    manage_webhooks: bool | None = None,
    mention_everyone: bool | None = None,
    moderate_members: bool | None = None,
    move_members: bool | None = None,
    mute_members: bool | None = None,
    priority_speaker: bool | None = None,
    read_message_history: bool | None = None,
    request_to_speak: bool | None = None,
    send_messages: bool | None = None,
    send_messages_in_threads: bool | None = None,
    send_tts_messages: bool | None = None,
    speak: bool | None = None,
    start_embedded_activities: bool | None = None,
    stream: bool | None = None,
    use_application_commands: bool | None = None,
    use_external_emojis: bool | None = None,
    use_external_stickers: bool | None = None,
    use_private_threads: bool | None = None,
    use_public_threads: bool | None = None,
    use_vad: bool | None = None,
    view_audit_log: bool | None = None,
    view_channel: bool | None = None,
    view_guild_insights: bool | None = None,
    reason: str = None,
) -> None:
    """
    Set the Permission Overwrites for a given target.

    Args:
        target: The target to set permission overwrites for
        add_reactions: Allows for the addition of reactions to messages
        administrator: Allows all permissions and bypasses channel permission overwrites
        attach_files: Allows for uploading images and files
        ban_members: Allows banning members
        change_nickname: Allows for modification of own nickname
        connect: Allows for joining of a voice channel
        create_instant_invite: Allows creation of instant invites
        deafen_members: Allows for deafening of members in a voice channel
        embed_links: Links sent by users with this permission will be auto-embedded
        kick_members: Allows kicking members
        manage_channels: Allows management and editing of channels
        manage_emojis_and_stickers: Allows management and editing of emojis and stickers
        manage_events: Allows for creating, editing, and deleting scheduled events
        manage_guild: Allows management and editing of the guild
        manage_messages: Allows for deletion of other users messages
        manage_nicknames: Allows for modification of other users nicknames
        manage_roles: Allows management and editing of roles
        manage_threads: Allows for deleting and archiving threads, and viewing all private threads
        manage_webhooks: Allows management and editing of webhooks
        mention_everyone: Allows for using the `@everyone` tag to notify all users in a channel, and the `@here` tag to notify all online users in a channel
        moderate_members: Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels
        move_members: Allows for moving of members between voice channels
        mute_members: Allows for muting members in a voice channel
        priority_speaker: Allows for using priority speaker in a voice channel
        read_message_history: Allows for reading of message history
        request_to_speak: Allows for requesting to speak in stage channels. (This permission is under active development and may be changed or removed.)
        send_messages:  Allows for sending messages in a channel (does not allow sending messages in threads)
        send_messages_in_threads: Allows for sending messages in threads
        send_tts_messages:  Allows for sending of `/tts` messages
        speak: Allows for speaking in a voice channel
        start_embedded_activities: Allows for using Activities (applications with the `EMBEDDED` flag) in a voice channel
        stream: Allows the user to go live
        use_application_commands: Allows members to use application commands, including slash commands and context menu commands
        use_external_emojis: Allows the usage of custom emojis from other servers
        use_external_stickers: Allows the usage of custom stickers from other servers
        use_private_threads: Allows for creating private threads
        use_public_threads:  Allows for creating public and announcement threads
        use_vad: Allows for using voice-activity-detection in a voice channel
        view_audit_log: Allows for viewing of audit logs
        view_channel: Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels
        view_guild_insights: Allows for viewing guild insights
        reason: The reason for creating this overwrite
    """
    overwrite = PermissionOverwrite.for_target(target)

    allow: Permissions = Permissions.NONE
    deny: Permissions = Permissions.NONE

    for name, val in locals().items():
        if isinstance(val, bool):
            if val:
                allow |= getattr(Permissions, name.upper())
            else:
                deny |= getattr(Permissions, name.upper())

    overwrite.add_allows(allow)
    overwrite.add_denies(deny)

    await self.edit_permission(overwrite, reason)

inherited property readonly members: List[models.Member]

Returns a list of members that can see this channel.

inherited property readonly bots: List[models.Member]

Returns a list of bots that can see this channel.

inherited property readonly humans: List[models.Member]

Returns a list of humans that can see this channel.

async inherited method clone(self, name, reason)

Clone this channel and create a new one.

Parameters:

Name Type Description Default
name Optional[str]

The name of the new channel. Defaults to the current name

None
reason Union[str, NoneType, naff.client.const.Missing]

The reason for creating this channel

Missing

Returns:

Type Description
TYPE_GUILD_CHANNEL

The newly created channel.

Source code in naff/models/discord/channel.py
async def clone(self, name: Optional[str] = None, reason: Absent[Optional[str]] = MISSING) -> "TYPE_GUILD_CHANNEL":
    """
    Clone this channel and create a new one.

    Args:
        name: The name of the new channel. Defaults to the current name
        reason: The reason for creating this channel

    Returns:
        The newly created channel.

    """
    return await self.guild.create_channel(
        channel_type=self.type,
        name=name if name else self.name,
        topic=getattr(self, "topic", MISSING),
        position=self.position,
        permission_overwrites=self.permission_overwrites,
        category=self.category,
        nsfw=self.nsfw,
        bitrate=getattr(self, "bitrate", 64000),
        user_limit=getattr(self, "user_limit", 0),
        rate_limit_per_user=getattr(self, "rate_limit_per_user", 0),
        reason=reason,
    )

async method create_post(self, name, content, applied_tags, *, auto_archive_duration, rate_limit_per_user, embeds, embed, components, stickers, allowed_mentions, files, file, tts, reason)

Create a post within this channel.

Parameters:

Name Type Description Default
name str

The name of the post

required
content str | None

The text content of this post

required
applied_tags Optional[List[Union[Snowflake_Type, ThreadTag]]]

A list of tag ids or tag objects to apply to this post

Missing
auto_archive_duration AutoArchiveDuration

Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.

<AutoArchiveDuration.ONE_DAY: 1440>
rate_limit_per_user Union[int, naff.client.const.Missing]

The time users must wait between sending messages

Missing
embeds Union[List[Union[Embed, dict]], Embed, dict]

Embedded rich content (up to 6000 characters).

None
embed Union[Embed, dict]

Embedded rich content (up to 6000 characters).

None
components Union[List[List[Union[BaseComponent, dict]]], List[Union[BaseComponent, dict]], BaseComponent, dict]

The components to include with the message.

None
stickers Union[List[Union[Sticker, Snowflake_Type]], Sticker, Snowflake_Type]

IDs of up to 3 stickers in the server to send in the message.

None
allowed_mentions Union[AllowedMentions, dict]

Allowed mentions for the message.

None
files Union[UPLOADABLE_TYPE, List[UPLOADABLE_TYPE]]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
file Optional[UPLOADABLE_TYPE]

Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.

None
tts bool

Should this message use Text To Speech.

False
flags

Message flags to apply.

required
reason Union[str, naff.client.const.Missing]

The reason for creating this post

Missing

Returns:

Type Description
GuildPublicThread

A GuildPublicThread object representing the created post.

Source code in naff/models/discord/channel.py
async def create_post(
    self,
    name: str,
    content: str | None,
    applied_tags: Optional[List[Union["Snowflake_Type", "ThreadTag"]]] = MISSING,
    *,
    auto_archive_duration: AutoArchiveDuration = AutoArchiveDuration.ONE_DAY,
    rate_limit_per_user: Absent[int] = MISSING,
    embeds: Optional[Union[List[Union["Embed", dict]], Union["Embed", dict]]] = None,
    embed: Optional[Union["Embed", dict]] = None,
    components: Optional[
        Union[List[List[Union["BaseComponent", dict]]], List[Union["BaseComponent", dict]], "BaseComponent", dict]
    ] = None,
    stickers: Optional[Union[List[Union["Sticker", "Snowflake_Type"]], "Sticker", "Snowflake_Type"]] = None,
    allowed_mentions: Optional[Union["AllowedMentions", dict]] = None,
    files: Optional[Union["UPLOADABLE_TYPE", List["UPLOADABLE_TYPE"]]] = None,
    file: Optional["UPLOADABLE_TYPE"] = None,
    tts: bool = False,
    reason: Absent[str] = MISSING,
) -> "GuildPublicThread":
    """
    Create a post within this channel.

    Args:
        name: The name of the post
        content: The text content of this post
        applied_tags: A list of tag ids or tag objects to apply to this post
        auto_archive_duration: Time before the thread will be automatically archived. Note 3 day and 7 day archive durations require the server to be boosted.
        rate_limit_per_user: The time users must wait between sending messages
        embeds: Embedded rich content (up to 6000 characters).
        embed: Embedded rich content (up to 6000 characters).
        components: The components to include with the message.
        stickers: IDs of up to 3 stickers in the server to send in the message.
        allowed_mentions: Allowed mentions for the message.
        files: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        file: Files to send, the path, bytes or File() instance, defaults to None. You may have up to 10 files.
        tts: Should this message use Text To Speech.
        flags: Message flags to apply.
        reason: The reason for creating this post

    Returns:
        A GuildPublicThread object representing the created post.
    """
    if applied_tags != MISSING:
        applied_tags = [str(tag.id) if isinstance(tag, ThreadTag) else str(tag) for tag in applied_tags]

    message_payload = models.discord.message.process_message_payload(
        content=content,
        embeds=embeds or embed,
        components=components,
        stickers=stickers,
        allowed_mentions=allowed_mentions,
        tts=tts,
    )

    data = await self._client.http.create_forum_thread(
        self.id,
        name,
        auto_archive_duration,
        message_payload,
        applied_tags,
        rate_limit_per_user,
        files=files or file,
        reason=reason,
    )
    return self._client.cache.place_channel_data(data)

async method create_tag(self, name, emoji)

Create a tag for this forum.

Parameters:

Name Type Description Default
name str

The name of the tag

required
emoji Union[models.PartialEmoji, dict, str]

The emoji to use for the tag

required

Note

If the emoji is a custom emoji, it must be from the same guild as the channel.

Returns:

Type Description
ThreadTag

The created tag object.

Source code in naff/models/discord/channel.py
async def create_tag(self, name: str, emoji: Union["models.PartialEmoji", dict, str]) -> "ThreadTag":
    """
    Create a tag for this forum.

    Args:
        name: The name of the tag
        emoji: The emoji to use for the tag

    Note:
        If the emoji is a custom emoji, it must be from the same guild as the channel.

    Returns:
        The created tag object.

    """
    if isinstance(emoji, str):
        emoji = PartialEmoji.from_str(emoji)
    elif isinstance(emoji, dict):
        emoji = PartialEmoji.from_dict(emoji)

    if emoji.id:
        data = await self._client.http.create_tag(self.id, name, emoji_id=emoji.id)
    else:
        data = await self._client.http.create_tag(self.id, name, emoji_name=emoji.name)

    channel_data = self._client.cache.place_channel_data(data)
    return [tag for tag in channel_data.available_tags if tag.name == name][0]

async method edit_tag(self, tag_id, *, name, emoji)

Edit a tag for this forum.

Parameters:

Name Type Description Default
tag_id Snowflake_Type

The id of the tag to edit

required
name str | None

The name for this tag

None
emoji Union[models.PartialEmoji, dict, str]

The emoji for this tag

None
Source code in naff/models/discord/channel.py
async def edit_tag(
    self,
    tag_id: "Snowflake_Type",
    *,
    name: str | None = None,
    emoji: Union["models.PartialEmoji", dict, str, None] = None,
) -> "ThreadTag":
    """
    Edit a tag for this forum.

    Args:
        tag_id: The id of the tag to edit
        name: The name for this tag
        emoji: The emoji for this tag
    """
    if isinstance(emoji, str):
        emoji = PartialEmoji.from_str(emoji)
    elif isinstance(emoji, dict):
        emoji = PartialEmoji.from_dict(emoji)

    if emoji.id:
        data = await self._client.http.edit_tag(self.id, tag_id, name, emoji_id=emoji.id)
    else:
        data = await self._client.http.edit_tag(self.id, tag_id, name, emoji_name=emoji.name)

    channel_data = self._client.cache.place_channel_data(data)
    return [tag for tag in channel_data.available_tags if tag.name == name][0]

async method delete_tag(self, tag_id)

Delete a tag for this forum.

Parameters:

Name Type Description Default
tag_id Snowflake_Type

The ID of the tag to delete

required
Source code in naff/models/discord/channel.py
async def delete_tag(self, tag_id: "Snowflake_Type") -> None:
    """
    Delete a tag for this forum.

    Args:
        tag_id: The ID of the tag to delete
    """
    data = await self._client.http.delete_tag(self.id, tag_id)
    self._client.cache.place_channel_data(data)

function process_permission_overwrites(overwrites)

Processes a permission overwrite lists into format for sending to discord.

Parameters:

Name Type Description Default
overwrites Union[dict, naff.models.discord.channel.PermissionOverwrite, List[Union[dict, naff.models.discord.channel.PermissionOverwrite]]]

The permission overwrites to process

required

Returns:

Type Description
List[dict]

The processed permission overwrites

Source code in naff/models/discord/channel.py
def process_permission_overwrites(
    overwrites: Union[dict, PermissionOverwrite, List[Union[dict, PermissionOverwrite]]]
) -> List[dict]:
    """
    Processes a permission overwrite lists into format for sending to discord.

    Args:
        overwrites: The permission overwrites to process

    Returns:
        The processed permission overwrites

    """
    if not overwrites:
        return overwrites

    if isinstance(overwrites, dict):
        return [overwrites]

    if isinstance(overwrites, list):
        return list(map(to_dict, overwrites))

    if isinstance(overwrites, PermissionOverwrite):
        return [overwrites.to_dict()]

    raise ValueError(f"Invalid overwrites: {overwrites}")