Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9a7f49e
fix: :bug: Fix `AttributeError` when accessing `AuditLogEntry.changes…
Paillat-dev Aug 28, 2025
6085463
feat: :sparkles: Implement and document `AuditLogDiff.communication_d…
Paillat-dev Aug 28, 2025
69c81c3
feat: Add support for user.primary_guild (#2876)
Lulalaby Aug 28, 2025
921260d
docs: :memo: Fix docstring of `Nameplate` (#2884)
Paillat-dev Aug 28, 2025
5f5b0fd
feat: Message pin updates (#2872)
NeloBlivion Aug 28, 2025
dd6688d
fix: fix typing for PermissionOverwrite.update (#2878)
JL710 Aug 30, 2025
90ba570
feat: add ThreadAutoArchiveDuration enum (#2826)
BOXERRMD Aug 30, 2025
b0e0840
feat: adding missing parameters and attribute documentation (#2772)
Lumabots Aug 30, 2025
a1e8949
feat: :sparkles: Soundboard (#2623)
Paillat-dev Aug 30, 2025
2abb5dd
feat: :recycle: Better nameplates assets api (#2890)
Paillat-dev Aug 30, 2025
cf7dc16
fix: handling of Optional[...] in command option type resolution (#2852)
Lumabots Aug 30, 2025
f6f6f4e
fix: change badge property to cached_property (#2891)
Lulalaby Aug 30, 2025
c7fdd01
docs: document version addition for asset properties
Lulalaby Aug 30, 2025
329ae2f
fix: datetime type for create_scheduled_event (#2879)
JL710 Aug 30, 2025
5051530
docs: 📝 Fixes (#2892)
Paillat-dev Aug 30, 2025
a69e354
fix: improve handling of types in option input_type validation (#2893)
Lumabots Aug 30, 2025
78ae3d4
fix: lala (#2896)
Lumabots Aug 31, 2025
b907c05
chore: update badges
Lulalaby Aug 31, 2025
cbe39f7
Update supported versions in SECURITY.md
Lulalaby Aug 31, 2025
22461a2
fix: usage of SlashCommandOptionType since its a subclass of tuple (#…
Lulalaby Sep 1, 2025
cf0e203
feat: Implement with_response For Interaction Callbacks (#2711)
Icebluewolf Sep 3, 2025
062d571
feat: ✨ Add support for new member fields for bots (#2910)
Soheab Sep 10, 2025
a13260c
fix: typehint issue (#2917)
Lumabots Sep 15, 2025
b9dead9
fix: Remove Extra Bytes Added By Discord Before OPUS Decoding (#2925)
Icebluewolf Sep 15, 2025
796465c
:rotating_light: :art: Format code and fix linter warnings
Paillat-dev Oct 9, 2025
419a24e
:bug: Fix imports
Paillat-dev Oct 9, 2025
f51992e
:fire: Remove deprecated attributes on CategoryChannel
Paillat-dev Oct 9, 2025
158a1fc
Update examples/soundboard.py
Paillat-dev Oct 9, 2025
d517720
Update discord/soundboard.py
Paillat-dev Oct 9, 2025
0c5a3c7
Update discord/raw_models.py
Paillat-dev Oct 9, 2025
56831c9
Update discord/components.py
Paillat-dev Oct 9, 2025
0267f6f
Update discord/components.py
Paillat-dev Oct 9, 2025
4deddb5
Update discord/channel.py
Paillat-dev Oct 9, 2025
2ef0974
Update discord/ext/commands/core.py
Paillat-dev Oct 9, 2025
e6f1e4d
:goal_net: Add error handling for missing emojis.json file in utils.py
Paillat-dev Oct 9, 2025
94a8eae
Merge branch 'master' into merge-upstream
Paillat-dev Oct 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
| Version | Supported |
| ------- | ------------------ |
| 2.x | :white_check_mark: |
| <2.0.0 | :x: |
| <2.6.1 | :x: |

## Reporting a Vulnerability

Expand Down
81 changes: 80 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,46 @@ possible (see our [Version Guarantees] for more info).

These changes are available on the `master` branch, but have not yet been released.

### Added

- Implemented `with_response` for interaction callbacks, adding
`Interaction.callback.is_loading()` and `Interaction.callback.is_ephemeral()`.
([#2711](https://github.com/Pycord-Development/pycord/pull/2711))
- Added `RawMessageUpdateEvent.new_message` - message update events now contain full
message objects ([#2780](https://github.com/Pycord-Development/pycord/pull/2780))
- Added support for setting guild-specific `avatar`, `banner`, and `bio` for the bot
user through `Member.edit`.
([#2908](https://github.com/Pycord-Development/pycord/pull/2908))
- Added support for select default values.
([#2899](https://github.com/Pycord-Development/pycord/pull/2899))
- Adds a new generic parameter to selects to type `ui.Select.values` return type.
- Adds `SelectDefaultValue` object to create select default values.
- Adds `SelectDefaultValueType` enum.
- Adds pre-typed and pre-constructed with select_type `ui.Select` aliases for the
different select types: `ui.StringSelect`, `ui.UserSelect`, `ui.RoleSelect`,
`ui.MentionableSelect`, and `ui.ChannelSelect`.

### Changed

### Fixed

- Manage silence for new SSRC with existing user_id.
([#2808](https://github.com/Pycord-Development/pycord/pull/2808))
- Unbound `raw` reference in `parse_message_update` causing errors on message updates.
([#2905](https://github.com/Pycord-Development/pycord/pull/2905))
- `view=None` in various methods causing an AttributeError.
([#2915](https://github.com/Pycord-Development/pycord/pull/2915))
- `View.message` being `None` when it had not been interacted with yet.
([#2916](https://github.com/Pycord-Development/pycord/pull/2916))
- Fixed a crash when processing message edit events while message cache was disabled.
([#2924](https://github.com/Pycord-Development/pycord/pull/2924))
- Fixed OPUS Decode Error when recording audio.
([#2925](https://github.com/Pycord-Development/pycord/pull/2925))

### Removed

## [2.7.0rc1] - 2025-08-30

⚠️ **This version removes support for Python 3.8.** ⚠️

### Added
Expand Down Expand Up @@ -47,6 +87,15 @@ These changes are available on the `master` branch, but have not yet been releas
([#2659](https://github.com/Pycord-Development/pycord/pull/2659))
- Added `VoiceMessage` subclass of `File` to allow voice messages to be sent.
([#2579](https://github.com/Pycord-Development/pycord/pull/2579))
- Added the following soundboard-related features:
- Manage guild soundboard sounds with `Guild.fetch_sounds()`, `Guild.create_sound()`,
`SoundboardSound.edit()`, and `SoundboardSound.delete()`.
- Access Discord default sounds with `Client.fetch_default_sounds()`.
- Play sounds in voice channels with `VoiceChannel.send_soundboard_sound()`.
- New `on_voice_channel_effect_send` event for sound and emoji effects.
- Soundboard limits based on guild premium tier (8-48 slots) in
`Guild.soundboard_limit`.
([#2623](https://github.com/Pycord-Development/pycord/pull/2623))
- Added new `Subscription` object and related methods/events.
([#2564](https://github.com/Pycord-Development/pycord/pull/2564))
- Added `Message.forward_to`, `Message.snapshots`, and other related attributes.
Expand All @@ -57,6 +106,8 @@ These changes are available on the `master` branch, but have not yet been releas
([#2714](https://github.com/Pycord-Development/pycord/pull/2714))
- Added the ability to pass a `datetime.time` object to `format_dt`.
([#2747](https://github.com/Pycord-Development/pycord/pull/2747))
- Added various missing channel parameters and allow `default_reaction_emoji` to be
`None`. ([#2772](https://github.com/Pycord-Development/pycord/pull/2772))
- Added support for type hinting slash command options with `typing.Annotated`.
([#2782](https://github.com/Pycord-Development/pycord/pull/2782))
- Added conversion to `Member` in `MentionableConverter`.
Expand All @@ -67,8 +118,18 @@ These changes are available on the `master` branch, but have not yet been releas
([#2817](https://github.com/Pycord-Development/pycord/pull/2817))
- Added role gradients support with `Role.colours` and the `RoleColours` class.
([#2818](https://github.com/Pycord-Development/pycord/pull/2818))
- Added `ThreadArchiveDuration` enum to improve clarity of thread archive durations.
([#2826](https://github.com/Pycord-Development/pycord/pull/2826))
- Added `Interaction.attachment_size_limit`.
([#2854](https://github.com/Pycord-Development/pycord/pull/2854))
- Added support for selects and text displays in modals.
([#2858](https://github.com/Pycord-Development/pycord/pull/2858))
- Added `AuditLogDiff.communication_disabled_until`.
([#2883](https://github.com/Pycord-Development/pycord/pull/2883))
- Added `discord.User.primary_guild` and the `PrimaryGuild` class.
([#2876](https://github.com/Pycord-Development/pycord/pull/2876))
- Added `get_component` to `Message`, `Section`, `Container` and `ActionRow`.
([#2849](https://github.com/Pycord-Development/pycord/pull/2849))

### Fixed

Expand Down Expand Up @@ -140,6 +201,15 @@ These changes are available on the `master` branch, but have not yet been releas
([#2843](https://github.com/Pycord-Development/pycord/pull/2843))
- Fixed `TypeError` when using `@option` with certain annotations and along with
`channel_types`. ([#2835](https://github.com/Pycord-Development/pycord/pull/2835))
- Fixed `TypeError` when using `Optional[...]` or `... | None` in command option type.
([#2852](https://github.com/Pycord-Development/pycord/pull/2852))
- Fixed type-hinting for `PermissionOverwrite.update`.
([#2878](https://github.com/Pycord-Development/pycord/pull/2878))
- Fixed `AttributeError` when accessing `AuditLogEntry.changes` more than once.
([#2882])(https://github.com/Pycord-Development/pycord/pull/2882))
- Fixed type hint for argument `start_time` and `end_time` of
`Guild.create_scheduled_event`
([#2879](https://github.com/Pycord-Development/pycord/pull/2879))

### Changed

Expand All @@ -161,6 +231,8 @@ These changes are available on the `master` branch, but have not yet been releas
([#2797](https://github.com/Pycord-Development/pycord/pull/2797))
- Upgraded voice websocket version to v8.
([#2812](https://github.com/Pycord-Development/pycord/pull/2812))
- `Messageable.pins()` now returns a `MessagePinIterator` and has new arguments.
([#2872](https://github.com/Pycord-Development/pycord/pull/2872))

### Deprecated

Expand All @@ -170,6 +242,11 @@ These changes are available on the `master` branch, but have not yet been releas
([#2501](https://github.com/Pycord-Development/pycord/pull/2501))
- Deprecated `Interaction.cached_channel` in favor of `Interaction.channel`.
([#2658](https://github.com/Pycord-Development/pycord/pull/2658))
- Deprecated `is_nsfw` for categories since it was never supported by the API.
([#2772](https://github.com/Pycord-Development/pycord/pull/2772))
- Deprecated `Messageable.pins()` returning a list of `Message`; it should be used as an
iterator of `MessagePin` instead.
([#2872](https://github.com/Pycord-Development/pycord/pull/2872))

### Removed

Expand Down Expand Up @@ -1079,7 +1156,9 @@ These changes are available on the `master` branch, but have not yet been releas
- Fix py3.10 UnionType checks issue.
([#1240](https://github.com/Pycord-Development/pycord/pull/1240))

[unreleased]: https://github.com/Pycord-Development/pycord/compare/v2.6.0...HEAD
[unreleased]: https://github.com/Pycord-Development/pycord/compare/v2.7.0rc1...HEAD
[2.7.0rc1]: https://github.com/Pycord-Development/pycord/compare/v2.6.0...v2.7.0rc1
[2.6.1]: https://github.com/Pycord-Development/pycord/compare/v2.6.0...v2.6.1
[2.6.0]: https://github.com/Pycord-Development/pycord/compare/v2.5.0...v2.6.0
[2.5.0]: https://github.com/Pycord-Development/pycord/compare/v2.4.1...v2.5.0
[2.4.1]: https://github.com/Pycord-Development/pycord/compare/v2.4.0...v2.4.1
Expand Down
5 changes: 3 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ Pycord is a modern, easy to use, feature-rich, and async ready API wrapper for D
.. image:: https://img.shields.io/github/v/release/Pycord-Development/pycord?include_prereleases&label=Latest%20Release&logo=github&sort=semver&style=for-the-badge&logoColor=white
:target: https://github.com/Pycord-Development/pycord/releases
:alt: Latest release

.. image:: https://img.shields.io/discord/881207955029110855?label=discord&style=for-the-badge&logo=discord&color=5865F2&logoColor=white
:target: https://pycord.dev/discord
:alt: Discord server invite

.. image:: https://img.shields.io/github/sponsors/Pycord-Development?style=for-the-badge
:target: https://github.com/sponsors/Pycord-Development
:alt: GitHub Sponsors
.. image:: https://badges.crowdin.net/badge/dark/crowdin-on-light.png
:target: https://translations.pycord.dev/documentation/?utm_source=badge&utm_medium=referral&utm_campaign=badge-add-on
:alt: Crowdin | Agile localization for tech companies
Expand Down
1 change: 1 addition & 0 deletions discord/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
from .role import *
from .scheduled_events import *
from .shard import *
from .soundboard import *
from .stage_instance import *
from .sticker import *
from .team import *
Expand Down
68 changes: 50 additions & 18 deletions discord/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
from .file import File, VoiceMessage
from .flags import ChannelFlags, MessageFlags
from .invite import Invite
from .iterators import HistoryIterator
from .iterators import HistoryIterator, MessagePinIterator
from .mentions import AllowedMentions
from .partial_emoji import PartialEmoji, _EmojiTag
from .permissions import PermissionOverwrite, Permissions
Expand Down Expand Up @@ -1679,32 +1679,64 @@ async def fetch_message(self, id: int, /) -> Message:
data = await self._state.http.get_message(channel.id, id)
return self._state.create_message(channel=channel, data=data)

async def pins(self) -> list[Message]:
"""|coro|
def pins(
self,
*,
limit: int | None = 50,
before: SnowflakeTime | None = None,
) -> MessagePinIterator:
"""Returns a :class:`~discord.MessagePinIterator` that enables receiving the destination's pinned messages.

Retrieves all messages that are currently pinned in the channel.
You must have :attr:`~discord.Permissions.read_message_history` permissions to use this.

.. note::
.. warning::

Due to a limitation with the Discord API, the :class:`.Message`
objects returned by this method do not contain complete
:attr:`.Message.reactions` data.
Starting from version 3.0, `await channel.pins()` will no longer return a list of :class:`Message`. See examples below for new usage instead.

Returns
-------
List[:class:`~discord.Message`]
The messages that are currently pinned.
Parameters
----------
limit: Optional[:class:`int`]
The number of pinned messages to retrieve.
If ``None``, retrieves every pinned message in the channel.
before: Optional[Union[:class:`~discord.abc.Snowflake`, :class:`datetime.datetime`]]
Retrieve messages pinned before this datetime.
If a datetime is provided, it is recommended to use a UTC aware datetime.
If the datetime is naive, it is assumed to be local time.

Yields
------
:class:`~discord.MessagePin`
The pinned message.

Raises
------
~discord.Forbidden
You do not have permissions to get pinned messages.
~discord.HTTPException
Retrieving the pinned messages failed.
"""
The request to get pinned messages failed.

channel = await self._get_channel()
state = self._state
data = await state.http.pins_from(channel.id)
return [state.create_message(channel=channel, data=m) for m in data]
Examples
--------

Usage ::

counter = 0
async for pin in channel.pins(limit=250):
if pin.message.author == client.user:
counter += 1

Flattening into a list: ::

pins = await channel.pins(limit=None).flatten()
# pins is now a list of MessagePin...

All parameters are optional.
"""
return MessagePinIterator(
self,
limit=limit,
before=before,
)

def can_send(self, *objects) -> bool:
"""Returns a :class:`bool` indicating whether you have the permissions to send the object(s).
Expand Down
45 changes: 45 additions & 0 deletions discord/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
if TYPE_CHECKING:
ValidStaticFormatTypes = Literal["webp", "jpeg", "jpg", "png"]
ValidAssetFormatTypes = Literal["webp", "jpeg", "jpg", "png", "gif"]
from .state import ConnectionState


VALID_STATIC_FORMATS = frozenset({"jpeg", "jpg", "webp", "png"})
VALID_ASSET_FORMATS = VALID_STATIC_FORMATS | {"gif"}
Expand Down Expand Up @@ -204,6 +206,31 @@ def _from_avatar_decoration(cls, state, user_id: int, avatar_decoration: str) ->
animated=animated,
)

@classmethod
def _from_user_primary_guild_tag(cls, state: ConnectionState, identity_guild_id: int, badge_id: str) -> Asset:
"""Creates an Asset for a user's primary guild (tag) badge.

Parameters
----------
state: ConnectionState
The connection state.
identity_guild_id: int
The ID of the guild.
badge_id: str
The badge hash/id.

Returns
-------
:class:`Asset`
The primary guild badge asset.
"""
return cls(
state,
url=f"{Asset.BASE}/guild-tag-badges/{identity_guild_id}/{badge_id}.png?size=256",
key=badge_id,
animated=False,
)

@classmethod
def _from_guild_avatar(cls, state, guild_id: int, member_id: int, avatar: str) -> Asset:
animated = avatar.startswith("a_")
Expand Down Expand Up @@ -244,6 +271,16 @@ def _from_cover_image(cls, state, object_id: int, cover_image_hash: str) -> Asse
animated=False,
)

@classmethod
def _from_collectible(cls, state: ConnectionState, asset: str, animated: bool = False) -> Asset:
name = "static.png" if not animated else "asset.webm"
return cls(
state,
url=f"{cls.BASE}/assets/collectibles/{asset}{name}",
key=asset,
animated=animated,
)

@classmethod
def _from_guild_image(cls, state, guild_id: int, image: str, path: str) -> Asset:
animated = False
Expand Down Expand Up @@ -299,6 +336,14 @@ def _from_scheduled_event_image(cls, state, event_id: int, cover_hash: str) -> A
animated=False,
)

@classmethod
def _from_soundboard_sound(cls, state, sound_id: int) -> Asset:
return cls(
state,
url=f"{cls.BASE}/soundboard-sounds/{sound_id}",
key=str(sound_id),
)

def __str__(self) -> str:
return self._url

Expand Down
10 changes: 8 additions & 2 deletions discord/audit_logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

from __future__ import annotations

import datetime
from functools import cached_property
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Generator, TypeVar

Expand All @@ -46,8 +47,6 @@


if TYPE_CHECKING:
import datetime

from . import abc
from .emoji import GuildEmoji
from .guild import Guild
Expand Down Expand Up @@ -197,6 +196,12 @@ def _transform_trigger_metadata(
return AutoModTriggerMetadata.from_dict(data)


def _transform_communication_disabled_until(entry: AuditLogEntry, data: str) -> datetime.datetime | None:
if data:
return datetime.datetime.fromisoformat(data)
return None


class AuditLogDiff:
def __len__(self) -> int:
return len(self.__dict__)
Expand Down Expand Up @@ -269,6 +274,7 @@ class AuditLogChanges:
"trigger_metadata": (None, _transform_trigger_metadata),
"exempt_roles": (None, _transform_roles),
"exempt_channels": (None, _transform_channels),
"communication_disabled_until": (None, _transform_communication_disabled_until),
}

def __init__(
Expand Down
Loading