Skip to content
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ These changes are available on the `master` branch, but have not yet been releas
([#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))

### Changed

Expand Down
32 changes: 0 additions & 32 deletions discord/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -1020,38 +1020,6 @@ def guild_voice_state(
def edit_profile(self, payload: dict[str, Any]) -> Response[user.User]:
return self.request(Route("PATCH", "/users/@me"), json=payload)

def change_my_nickname(
self,
guild_id: Snowflake,
nickname: str,
*,
reason: str | None = None,
) -> Response[member.Nickname]:
r = Route("PATCH", "/guilds/{guild_id}/members/@me", guild_id=guild_id)
payload = {
"nick": nickname,
}
return self.request(r, json=payload, reason=reason)

def change_nickname(
self,
guild_id: Snowflake,
user_id: Snowflake,
nickname: str,
*,
reason: str | None = None,
) -> Response[member.Member]:
r = Route(
"PATCH",
"/guilds/{guild_id}/members/{user_id}",
guild_id=guild_id,
user_id=user_id,
)
payload = {
"nick": nickname,
}
return self.request(r, json=payload, reason=reason)

def edit_my_voice_state(
self, guild_id: Snowflake, payload: dict[str, Any]
) -> Response[None]:
Expand Down
64 changes: 62 additions & 2 deletions discord/member.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
from .asset import Asset
from .colour import Colour
from .enums import Status, try_enum
from .errors import InvalidArgument
from .flags import MemberFlags
from .object import Object
from .permissions import Permissions
Expand Down Expand Up @@ -769,6 +770,9 @@ async def edit(
reason: str | None = None,
communication_disabled_until: datetime.datetime | None = MISSING,
bypass_verification: bool | None = MISSING,
banner: bytes | None = MISSING,
avatar: bytes | None = MISSING,
bio: str | None = MISSING,
) -> Member | None:
"""|coro|

Expand Down Expand Up @@ -804,6 +808,14 @@ async def edit(

- Client has ALL THREE of :attr:`Permissions.moderate_members`, :attr:`Permissions.kick_members`, and :attr:`Permissions.ban_members`

.. note::

The following parameters are only available when editing the bot's own member:

- ``avatar``
- ``banner``
- ``bio``

All parameters are optional.

.. versionchanged:: 1.1
Expand Down Expand Up @@ -841,6 +853,26 @@ async def edit(
Indicates if the member should bypass the guild's verification requirements.

.. versionadded:: 2.6
banner: Optional[:class:`bytes`]
A :term:`py:bytes-like object` representing the banner.
Could be ``None`` to denote removal of the banner.

This is only available when editing the bot's own member (i.e. :attr:`Guild.me`).

.. versionadded:: 2.7
avatar: Optional[:class:`bytes`]
A :term:`py:bytes-like object` representing the avatar.
Could be ``None`` to denote removal of the avatar.

This is only available when editing the bot's own member (i.e. :attr:`Guild.me`).

.. versionadded:: 2.7
bio: Optional[:class:`str`]
The new bio for the member. Could be ``None`` to denote removal of the bio.

This is only available when editing the bot's own member (i.e. :attr:`Guild.me`).

.. versionadded:: 2.7

Returns
-------
Expand All @@ -854,16 +886,19 @@ async def edit(
You do not have the proper permissions to the action requested.
HTTPException
The operation failed.
InvalidArgument
You tried to edit the avatar, banner, or bio of a member that is not the bot.
"""
http = self._state.http
guild_id = self.guild.id
me = self._state.self_id == self.id
payload: dict[str, Any] = {}
bot_payload: dict[str, Any] = {}

if nick is not MISSING:
nick = nick or ""
if me:
await http.change_my_nickname(guild_id, nick, reason=reason)
bot_payload["nick"] = nick
else:
payload["nick"] = nick

Expand Down Expand Up @@ -910,9 +945,34 @@ async def edit(
flags.bypasses_verification = bypass_verification
payload["flags"] = flags.value

if avatar is not MISSING:
if avatar is None:
bot_payload["avatar"] = None
else:
bot_payload["avatar"] = utils._bytes_to_base64_data(avatar)

if banner is not MISSING:
if banner is None:
bot_payload["banner"] = None
else:
bot_payload["banner"] = utils._bytes_to_base64_data(banner)

if bio is not MISSING:
bot_payload["bio"] = bio or ""

if bot_payload and not me:
raise InvalidArgument(
"Can only edit avatar, banner, or bio for the bot's member."
)

if payload:
data = await http.edit_member(guild_id, self.id, reason=reason, **payload)
return Member(data=data, guild=self.guild, state=self._state)
elif bot_payload:
data = await http.edit_member(guild_id, "@me", reason=reason, **bot_payload)
else:
return None

return Member(data=data, guild=self.guild, state=self._state)

async def timeout(
self, until: datetime.datetime | None, *, reason: str | None = None
Expand Down
Loading