21 Commits

Author SHA1 Message Date
5a51f9dd23 Fix typings in raw_models.py 2021-09-01 22:30:05 +02:00
c34612dd71 Merge branch '2.0' into pr7268
# Conflicts:
#	discord/raw_models.py
2021-09-01 22:27:34 +02:00
6f5614373a Merge pull request #15 from WhoTheOOF/patch-3
Add original dark blurple
2021-09-01 04:40:12 +02:00
2e12746c70 Merge pull request #11 from TheMoksej/patch-2
versionadded needs to be added here
2021-09-01 04:38:26 +02:00
5ef72e4f70 Merge pull request #20 from paris-ci/special_methods
Special methods
2021-09-01 04:27:33 +02:00
7e18d30820 Merge pull request #17 from Astrea49/2.0
Prefer `static_format` over `format` with static assets
2021-09-01 04:26:31 +02:00
923a6a885d Merge pull request #13 from paris-ci/rework_set_in_embeds
Make `Embed.image` and `Embed.thumbnail` full-featured properties
2021-09-01 04:24:57 +02:00
b28893aa36 Merge pull request #40 from Gnome-py/required-intents
Remove intents.default and make intents a required parameter
2021-09-01 04:21:37 +02:00
6e41bd2219 Remove intents.default and make intents a required parameter 2021-08-31 20:53:54 +01:00
64ee792391 Add int() support to Hashable, making it available across the board for AuditLogEntry, *Channel, Guild, Object, Message, ... 2021-08-29 01:21:20 +02:00
22de755059 Add int() and str() support to Message 2021-08-29 01:09:05 +02:00
fa7f8efc8e Add int() support to Guild 2021-08-29 01:07:26 +02:00
9d1df65af3 Add int() support to Role 2021-08-29 01:06:18 +02:00
3ce86f6cde Add int() support to Emoji 2021-08-29 01:05:28 +02:00
31e3e99c2b Add __int__ special method to User and Member 2021-08-29 00:59:29 +02:00
cc90d312f5 Add original dark blurple
This adds the old discord dark blurple color as a classmethod for embeds and whatever.
2021-08-28 17:26:46 -05:00
75f052b8c9 Prefer static_format over format with static assets 2021-08-28 18:24:05 -04:00
c8cdb275c5 Fix set_* function name 2021-08-28 23:29:49 +02:00
406f0ffe04 Make Embed.image and Embed.thumbnail full-featured properties
This avoids the need for set_* methods.
2021-08-28 23:14:26 +02:00
a4acbd2e08 versionadded needs to be added here 2021-08-28 22:10:58 +02:00
e4750c7105 Add raw thread delete event 2021-07-23 10:13:02 +02:00
48 changed files with 316 additions and 223 deletions

View File

@ -313,10 +313,11 @@ class Asset(AssetMixin):
if self._animated:
if format not in VALID_ASSET_FORMATS:
raise InvalidArgument(f'format must be one of {VALID_ASSET_FORMATS}')
else:
url = url.with_path(f'{path}.{format}')
elif static_format is MISSING:
if format not in VALID_STATIC_FORMATS:
raise InvalidArgument(f'format must be one of {VALID_STATIC_FORMATS}')
url = url.with_path(f'{path}.{format}')
url = url.with_path(f'{path}.{format}')
if static_format is not MISSING and not self._animated:
if static_format not in VALID_STATIC_FORMATS:

View File

@ -330,6 +330,10 @@ class AuditLogEntry(Hashable):
Returns the entry's hash.
.. describe:: int(x)
Returns the entry's ID.
.. versionchanged:: 1.7
Audit log entries are now comparable and hashable.

View File

@ -45,7 +45,7 @@ import datetime
import discord.abc
from .permissions import PermissionOverwrite, Permissions
from .enums import ChannelType, StagePrivacyLevel, try_enum, VoiceRegion, VideoQualityMode, PartyType
from .enums import ChannelType, StagePrivacyLevel, try_enum, VoiceRegion, VideoQualityMode
from .mixins import Hashable
from .object import Object
from . import utils
@ -115,6 +115,10 @@ class TextChannel(discord.abc.Messageable, discord.abc.GuildChannel, Hashable):
Returns the channel's name.
.. describe:: int(x)
Returns the channel's ID.
Attributes
-----------
name: :class:`str`
@ -1037,38 +1041,6 @@ class VoiceChannel(VocalGuildChannel):
# the payload will always be the proper channel payload
return self.__class__(state=self._state, guild=self.guild, data=payload) # type: ignore
async def create_party(self, application_id: PartyType, max_age: int = 86400 , max_uses: int = 0):
"""|coro|
Creates a party in this voice channel.
.. versionadded:: 2.0
Parameters
----------
application_id : :class:`PartyType`
The id of the application the party belongs to. currently any of
``PartyType.youtube``, ``PartyType.poker``, ``PartyType.betrayal``, ``PartyType.fishing``, ``PartyType.chess``.
max_age : :class:`int`, optional
Duration in seconds after which the invite expires, by default 1 day.
max_uses : :class:`int`, optional
maximum number of times this invite can be used, by default unlimited.
Raises
-------
Forbidden
You do not have permissions to create a party.
HTTPException
Party creation failed.
Returns
--------
:class:`Party`
The created party.
"""
return Party(await self._state.http.create_party(self.id, application_id.value, max_age=max_age, max_uses=max_uses))
class StageChannel(VocalGuildChannel):
"""Represents a Discord guild stage channel.
@ -1366,6 +1338,10 @@ class CategoryChannel(discord.abc.GuildChannel, Hashable):
Returns the category's name.
.. describe:: int(x)
Returns the category's ID.
Attributes
-----------
name: :class:`str`
@ -1588,6 +1564,10 @@ class StoreChannel(discord.abc.GuildChannel, Hashable):
Returns the channel's name.
.. describe:: int(x)
Returns the channel's ID.
Attributes
-----------
name: :class:`str`
@ -1760,6 +1740,10 @@ class DMChannel(discord.abc.Messageable, Hashable):
Returns a string representation of the channel
.. describe:: int(x)
Returns the channel's ID.
Attributes
----------
recipient: Optional[:class:`User`]
@ -1886,6 +1870,10 @@ class GroupChannel(discord.abc.Messageable, Hashable):
Returns a string representation of the channel
.. describe:: int(x)
Returns the channel's ID.
Attributes
----------
recipients: List[:class:`User`]
@ -2032,6 +2020,10 @@ class PartialMessageable(discord.abc.Messageable, Hashable):
Returns the partial messageable's hash.
.. describe:: int(x)
Returns the messageable's ID.
Attributes
-----------
id: :class:`int`
@ -2070,76 +2062,6 @@ class PartialMessageable(discord.abc.Messageable, Hashable):
return PartialMessage(channel=self, id=message_id)
class Party:
"""Represents a party in a voice channel.
.. container:: operations
.. describe:: x == y
Checks if two party are equal.
.. describe:: x != y
Checks if two party are not equal.
.. describe:: hash(x)
Returns the party hash.
.. describe:: str(x)
Returns the party URL.
Attributes
-----------
code: :class:`str`
The URL fragment used for the party.
uses: :class:`int`
How many times the invite has been used.
max_uses: :class:`int`
How many times the invite can be used.
A value of ``0`` indicates that it has unlimited uses.
max_age: :class:`int`
How long before the party expires in seconds.
A value of ``0`` indicates that it doesn't expire.
temporary: :class:`bool`
Indicates that the invite grants temporary membership.
If ``True``, members who joined via this invite will be kicked upon disconnect.
created_at: :class:`datetime.datetime`
An aware UTC datetime object denoting the time the invite was created.
Note
----
Parties are still in BETA so there are some limitations.
Currently this BETA feature is only supported on web and updated PC app versions of Discord and is not supported on mobile.
First someone has to to click the blue link itself and not the join button, then everyone else can click the join button normally.
"""
__slots__ = ('code', 'uses', 'max_uses', 'max_age', 'temporary', 'created_at')
def __init__(self, data):
self.code: str = data['code']
self.uses: Optional[int] = data.get('uses')
self.max_uses: Optional[int] = data.get('max_uses')
self.max_age: Optional[int] = data.get('max_age')
self.temporary: Optional[bool] = data.get('temporary')
self.created_at: Optional[datetime.datetime] = utils.parse_time(data.get('created_at'))
# TODO: add more fields here such as guild. raw data: https://mystb.in/AdvertisersExperiencesMothers.json
def __repr__(self):
return f'<Party code={self.code}>'
def __str__(self):
return f'https://discord.gg/{self.code}'
def __hash__(self) -> int:
return hash(self.code)
def __eq__(self, other):
return isinstance(other, Party) and self.code == other.code
def _guild_channel_factory(channel_type: int):
value = try_enum(ChannelType, channel_type)

View File

@ -142,7 +142,6 @@ class Client:
intents: :class:`Intents`
The intents that you want to enable for the session. This is a way of
disabling and enabling certain gateway events from triggering and being sent.
If not given, defaults to a regularly constructed :class:`Intents` class.
.. versionadded:: 1.5
member_cache_flags: :class:`MemberCacheFlags`
@ -203,9 +202,12 @@ class Client:
def __init__(
self,
*,
intents: Intents,
loop: Optional[asyncio.AbstractEventLoop] = None,
**options: Any,
):
options["intents"] = intents
# self.ws is set in the connect method
self.ws: DiscordWebSocket = None # type: ignore
self.loop: asyncio.AbstractEventLoop = asyncio.get_event_loop() if loop is None else loop

View File

@ -324,6 +324,15 @@ class Colour:
.. versionadded:: 2.0
"""
return cls(0xFEE75C)
@classmethod
def dark_blurple(cls: Type[CT]) -> CT:
"""A factory method that returns a :class:`Colour` with a value of ``0x4E5D94``.
This is the original Dark Blurple branding.
.. versionadded:: 2.0
"""
return cls(0x4E5D94)
Color = Colour

View File

@ -72,30 +72,36 @@ if TYPE_CHECKING:
T = TypeVar('T')
MaybeEmpty = Union[T, _EmptyEmbed]
class _EmbedFooterProxy(Protocol):
text: MaybeEmpty[str]
icon_url: MaybeEmpty[str]
class _EmbedFieldProxy(Protocol):
name: MaybeEmpty[str]
value: MaybeEmpty[str]
inline: bool
class _EmbedMediaProxy(Protocol):
url: MaybeEmpty[str]
proxy_url: MaybeEmpty[str]
height: MaybeEmpty[int]
width: MaybeEmpty[int]
class _EmbedVideoProxy(Protocol):
url: MaybeEmpty[str]
height: MaybeEmpty[int]
width: MaybeEmpty[int]
class _EmbedProviderProxy(Protocol):
name: MaybeEmpty[str]
url: MaybeEmpty[str]
class _EmbedAuthorProxy(Protocol):
name: MaybeEmpty[str]
url: MaybeEmpty[str]
@ -175,15 +181,15 @@ class Embed:
Empty: Final = EmptyEmbed
def __init__(
self,
*,
colour: Union[int, Colour, _EmptyEmbed] = EmptyEmbed,
color: Union[int, Colour, _EmptyEmbed] = EmptyEmbed,
title: MaybeEmpty[Any] = EmptyEmbed,
type: EmbedType = 'rich',
url: MaybeEmpty[Any] = EmptyEmbed,
description: MaybeEmpty[Any] = EmptyEmbed,
timestamp: datetime.datetime = None,
self,
*,
colour: Union[int, Colour, _EmptyEmbed] = EmptyEmbed,
color: Union[int, Colour, _EmptyEmbed] = EmptyEmbed,
title: MaybeEmpty[Any] = EmptyEmbed,
type: EmbedType = 'rich',
url: MaybeEmpty[Any] = EmptyEmbed,
description: MaybeEmpty[Any] = EmptyEmbed,
timestamp: datetime.datetime = None,
):
self.colour = colour if colour is not EmptyEmbed else color
@ -366,7 +372,7 @@ class Embed:
self._footer['icon_url'] = str(icon_url)
return self
def remove_footer(self: E) -> E:
"""Clears embed's footer information.
@ -381,7 +387,7 @@ class Embed:
pass
return self
@property
def image(self) -> _EmbedMediaProxy:
"""Returns an ``EmbedProxy`` denoting the image contents.
@ -397,6 +403,19 @@ class Embed:
"""
return EmbedProxy(getattr(self, '_image', {})) # type: ignore
@image.setter
def image(self: E, *, url: Any):
self._image = {
'url': str(url),
}
@image.deleter
def image(self: E):
try:
del self._image
except AttributeError:
pass
def set_image(self: E, *, url: MaybeEmpty[Any]) -> E:
"""Sets the image for the embed content.
@ -413,14 +432,9 @@ class Embed:
"""
if url is EmptyEmbed:
try:
del self._image
except AttributeError:
pass
del self.image
else:
self._image = {
'url': str(url),
}
self.image = url
return self
@ -439,7 +453,25 @@ class Embed:
"""
return EmbedProxy(getattr(self, '_thumbnail', {})) # type: ignore
def set_thumbnail(self: E, *, url: MaybeEmpty[Any]) -> E:
@thumbnail.setter
def thumbnail(self: E, *, url: Any):
"""Sets the thumbnail for the embed content.
"""
self._thumbnail = {
'url': str(url),
}
return
@thumbnail.deleter
def thumbnail(self):
try:
del self.thumbnail
except AttributeError:
pass
def set_thumbnail(self: E, *, url: MaybeEmpty[Any]):
"""Sets the thumbnail for the embed content.
This function returns the class instance to allow for fluent-style
@ -453,16 +485,10 @@ class Embed:
url: :class:`str`
The source URL for the thumbnail. Only HTTP(S) is supported.
"""
if url is EmptyEmbed:
try:
del self._thumbnail
except AttributeError:
pass
del self.thumbnail
else:
self._thumbnail = {
'url': str(url),
}
self.thumbnail = url
return self

View File

@ -72,6 +72,10 @@ class Emoji(_EmojiTag, AssetMixin):
Returns the emoji rendered for discord.
.. describe:: int(x)
Returns the emoji ID.
Attributes
-----------
name: :class:`str`
@ -137,6 +141,9 @@ class Emoji(_EmojiTag, AssetMixin):
return f'<a:{self.name}:{self.id}>'
return f'<:{self.name}:{self.id}>'
def __int__(self) -> int:
return self.id
def __repr__(self) -> str:
return f'<Emoji id={self.id} name={self.name!r} animated={self.animated} managed={self.managed}>'

View File

@ -30,7 +30,6 @@ __all__ = (
'Enum',
'ChannelType',
'MessageType',
'PartyType',
'VoiceRegion',
'SpeakingState',
'VerificationLevel',
@ -215,14 +214,6 @@ class MessageType(Enum):
guild_invite_reminder = 22
class PartyType(Enum):
youtube = 755600276941176913
poker = 755827207812677713
betrayal = 773336526917861400
fishing = 814288819477020702
chess = 832012774040141894
class VoiceRegion(Enum):
us_west = 'us-west'
us_east = 'us-east'

View File

@ -120,8 +120,8 @@ class _DefaultRepr:
_default = _DefaultRepr()
class BotBase(GroupMixin):
def __init__(self, command_prefix, help_command=_default, description=None, **options):
super().__init__(**options)
def __init__(self, command_prefix, help_command=_default, description=None, *, intents: discord.Intents, **options):
super().__init__(**options, intents=intents)
self.command_prefix = command_prefix
self.extra_events: Dict[str, List[CoroFunc]] = {}
self.__cogs: Dict[str, Cog] = {}

View File

@ -480,16 +480,6 @@ class Intents(BaseFlags):
self.value = self.DEFAULT_VALUE
return self
@classmethod
def default(cls: Type[Intents]) -> Intents:
"""A factory method that creates a :class:`Intents` with everything enabled
except :attr:`presences` and :attr:`members`.
"""
self = cls.all()
self.presences = False
self.members = False
return self
@flag_value
def guilds(self):
""":class:`bool`: Whether guild related events are enabled.

View File

@ -140,6 +140,10 @@ class Guild(Hashable):
Returns the guild's name.
.. describe:: int(x)
Returns the guild's ID.
Attributes
----------
name: :class:`str`
@ -738,12 +742,16 @@ class Guild(Hashable):
@property
def humans(self) -> List[Member]:
"""List[:class:`Member`]: A list of human members that belong to this guild."""
"""List[:class:`Member`]: A list of human members that belong to this guild.
.. versionadded:: 2.0 """
return [member for member in self.members if not member.bot]
@property
def bots(self) -> List[Member]:
"""List[:class:`Member`]: A list of bots that belong to this guild."""
"""List[:class:`Member`]: A list of bots that belong to this guild.
.. versionadded:: 2.0 """
return [member for member in self.members if member.bot]
def get_member(self, user_id: int, /) -> Optional[Member]:

View File

@ -880,24 +880,6 @@ class HTTPClient:
) -> Response[None]:
return self.request(Route('DELETE', '/channels/{channel_id}', channel_id=channel_id), reason=reason)
def create_party(
self,
channel_id: Snowflake,
application_id: Snowflake,
max_age: int,
max_uses: int,
) -> Response[channel.Party]:
payload = {
'max_age': max_age,
'max_uses': max_uses,
'target_application_id': application_id,
'target_type': 2,
'temporary': False,
'validate': None
}
return self.request(Route("POST", "/channels/{channel_id}/invites", channel_id=channel_id), json=payload)
# Thread management
def start_thread_with_message(

View File

@ -230,6 +230,7 @@ class Invite(Hashable):
Returns the invite URL.
The following table illustrates what methods will obtain the attributes:
+------------------------------------+------------------------------------------------------------+
@ -433,6 +434,9 @@ class Invite(Hashable):
def __str__(self) -> str:
return self.url
def __int__(self) -> int:
return 0 # To keep the object compatible with the hashable abc.
def __repr__(self) -> str:
return (
f'<Invite code={self.code!r} guild={self.guild!r} '

View File

@ -226,6 +226,10 @@ class Member(discord.abc.Messageable, _UserTag):
Returns the member's name with the discriminator.
.. describe:: int(x)
Returns the user's ID.
Attributes
----------
joined_at: Optional[:class:`datetime.datetime`]
@ -300,6 +304,9 @@ class Member(discord.abc.Messageable, _UserTag):
def __str__(self) -> str:
return str(self._user)
def __int__(self) -> int:
return self.id
def __repr__(self) -> str:
return (
f'<Member id={self._user.id} name={self._user.name!r} discriminator={self._user.discriminator!r}'

View File

@ -125,6 +125,10 @@ class Attachment(Hashable):
Returns the hash of the attachment.
.. describe:: int(x)
Returns the attachment's ID.
.. versionchanged:: 1.7
Attachment can now be casted to :class:`str` and is hashable.
@ -503,6 +507,14 @@ class Message(Hashable):
Returns the message's hash.
.. describe:: str(x)
Returns the message's content.
.. describe:: int(x)
Returns the message's ID.
Attributes
-----------
tts: :class:`bool`
@ -712,6 +724,10 @@ class Message(Hashable):
f'<{name} id={self.id} channel={self.channel!r} type={self.type!r} author={self.author!r} flags={self.flags!r}>'
)
def __str__(self) -> Optional[str]:
return self.content
def _try_patch(self, data, key, transform=None) -> None:
try:
value = data[key]
@ -1634,6 +1650,10 @@ class PartialMessage(Hashable):
Returns the partial message's hash.
.. describe:: int(x)
Returns the partial message's ID.
Attributes
-----------
channel: Union[:class:`TextChannel`, :class:`Thread`, :class:`DMChannel`]

View File

@ -43,5 +43,8 @@ class EqualityComparable:
class Hashable(EqualityComparable):
__slots__ = ()
def __int__(self) -> int:
return self.id
def __hash__(self) -> int:
return self.id >> 22

View File

@ -69,6 +69,10 @@ class Object(Hashable):
Returns the object's hash.
.. describe:: int(x)
Returns the object's ID.
Attributes
-----------
id: :class:`int`

View File

@ -39,8 +39,11 @@ if TYPE_CHECKING:
from .message import Message
from .partial_emoji import PartialEmoji
from .member import Member
from .threads import Thread
from .enums import ChannelType, try_enum
__all__ = (
'RawMessageDeleteEvent',
'RawBulkMessageDeleteEvent',
@ -49,6 +52,7 @@ __all__ = (
'RawReactionClearEvent',
'RawReactionClearEmojiEvent',
'RawIntegrationDeleteEvent',
'RawThreadDeleteEvent',
)
@ -276,3 +280,31 @@ class RawIntegrationDeleteEvent(_RawReprMixin):
self.application_id: Optional[int] = int(data['application_id'])
except KeyError:
self.application_id: Optional[int] = None
class RawThreadDeleteEvent(_RawReprMixin):
"""Represents the payload for a :func:`on_raw_thread_delete` event.
.. versionadded:: 2.0
Attributes
----------
thread_id: :class:`int`
The ID of the thread that was deleted.
thread_type: :class:`discord.ChannelType`
The channel type of the deleted thread.
guild_id: :class:`int`
The ID of the guild the thread was deleted in.
parent_id: :class:`int`
The ID of the channel the thread was belonged to.
thread: Optional[:class:`discord.Thread`]
The thread, if it could be found in the internal cache.
"""
__slots__ = ('thread_id', 'thread_type', 'parent_id', 'guild_id', 'thread')
def __init__(self, data) -> None:
self.thread_id: int = int(data['id'])
self.thread_type: ChannelType = try_enum(ChannelType, data['type'])
self.guild_id: int = int(data['guild_id'])
self.parent_id: int = int(data['parent_id'])
self.thread: Optional[Thread] = None

View File

@ -141,6 +141,14 @@ class Role(Hashable):
Returns the role's name.
.. describe:: str(x)
Returns the role's ID.
.. describe:: int(x)
Returns the role's ID.
Attributes
----------
id: :class:`int`
@ -195,6 +203,9 @@ class Role(Hashable):
def __str__(self) -> str:
return self.name
def __int__(self) -> int:
return self.id
def __repr__(self) -> str:
return f'<Role id={self.id} name={self.name!r}>'

View File

@ -61,6 +61,10 @@ class StageInstance(Hashable):
Returns the stage instance's hash.
.. describe:: int(x)
Returns the stage instance's ID.
Attributes
-----------
id: :class:`int`

View File

@ -152,6 +152,7 @@ class ConnectionState:
handlers: Dict[str, Callable],
hooks: Dict[str, Callable],
http: HTTPClient,
intents: Intents,
loop: asyncio.AbstractEventLoop,
**options: Any,
) -> None:
@ -194,12 +195,8 @@ class ConnectionState:
else:
status = str(status)
intents = options.get('intents', None)
if intents is not None:
if not isinstance(intents, Intents):
raise TypeError(f'intents parameter must be Intent not {type(intents)!r}')
else:
intents = Intents.default()
if not isinstance(intents, Intents):
raise TypeError(f'intents parameter must be Intent not {type(intents)!r}')
if not intents.guilds:
_log.warning('Guilds intent seems to be disabled. This may cause state related issues.')
@ -854,8 +851,10 @@ class ConnectionState:
_log.debug('THREAD_DELETE referencing an unknown guild ID: %s. Discarding', guild_id)
return
thread_id = int(data['id'])
thread = guild.get_thread(thread_id)
raw = RawThreadDeleteEvent(data)
raw.thread = thread = guild.get_thread(raw.thread_id)
self.dispatch('raw_thread_delete', raw)
if thread is not None:
guild._remove_thread(thread) # type: ignore
self.dispatch('thread_delete', thread)

View File

@ -67,6 +67,14 @@ class StickerPack(Hashable):
Returns the name of the sticker pack.
.. describe:: hash(x)
Returns the hash of the sticker pack.
.. describe:: int(x)
Returns the ID of the sticker pack.
.. describe:: x == y
Checks if the sticker pack is equal to another sticker pack.

View File

@ -74,6 +74,10 @@ class Thread(Messageable, Hashable):
Returns the thread's hash.
.. describe:: int(x)
Returns the thread's ID.
.. describe:: str(x)
Returns the thread's name.
@ -748,6 +752,10 @@ class ThreadMember(Hashable):
Returns the thread member's hash.
.. describe:: int(x)
Returns the thread member's ID.
.. describe:: str(x)
Returns the thread member's name.

View File

@ -155,10 +155,3 @@ class StageInstance(TypedDict):
topic: str
privacy_level: PrivacyLevel
discoverable_disabled: bool
class Party(TypedDict):
uses: int
max_uses: int
max_age: int
temporary: bool
created_at: str

View File

@ -96,6 +96,9 @@ class BaseUser(_UserTag):
def __str__(self) -> str:
return f'{self.name}#{self.discriminator}'
def __int__(self) -> int:
return self.id
def __eq__(self, other: Any) -> bool:
return isinstance(other, _UserTag) and other.id == self.id
@ -415,6 +418,10 @@ class User(BaseUser, discord.abc.Messageable):
Returns the user's name with discriminator.
.. describe:: int(x)
Returns the user's ID.
Attributes
-----------
name: :class:`str`

View File

@ -886,6 +886,10 @@ class Webhook(BaseWebhook):
Returns the webhooks's hash.
.. describe:: int(x)
Returns the webhooks's ID.
.. versionchanged:: 1.4
Webhooks are now comparable and hashable.

View File

@ -475,6 +475,10 @@ class SyncWebhook(BaseWebhook):
Returns the webhooks's hash.
.. describe:: int(x)
Returns the webhooks's ID.
.. versionchanged:: 1.4
Webhooks are now comparable and hashable.

View File

@ -718,7 +718,11 @@ to handle it, which defaults to print a traceback and ignoring the exception.
.. function:: on_thread_delete(thread)
Called whenever a thread is deleted.
Called whenever a thread is deleted. If the thread could
not be found in the internal cache this event will not be called.
Threads will not be in the cache if they are archived.
If you need this information use :func:`on_raw_thread_delete` instead.
Note that you can get the guild from :attr:`Thread.guild`.
@ -729,6 +733,18 @@ to handle it, which defaults to print a traceback and ignoring the exception.
:param thread: The thread that got deleted.
:type thread: :class:`Thread`
.. function:: on_raw_thread_delete(payload)
Called whenever a thread is deleted. Unlike :func:`on_thread_delete` this
is called regardless of the thread being in the internal thread cache or not.
This requires :attr:`Intents.guilds` to be enabled.
.. versionadded:: 2.0
:param payload: The raw event payload data.
:type payload: :class:`RawThreadDeleteEvent`
.. function:: on_thread_member_join(member)
on_thread_member_remove(member)
@ -3902,6 +3918,14 @@ RawIntegrationDeleteEvent
.. autoclass:: RawIntegrationDeleteEvent()
:members:
RawThreadDeleteEvent
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. attributetable:: RawThreadDeleteEvent
.. autoclass:: RawThreadDeleteEvent()
:members:
PartialWebhookGuild
~~~~~~~~~~~~~~~~~~~~

View File

@ -26,5 +26,5 @@ class MyClient(discord.Client):
async def before_my_task(self):
await self.wait_until_ready() # wait until the bot logs in
client = MyClient()
client = MyClient(intents=discord.Intents(guilds=True))
client.run('token')

View File

@ -22,5 +22,5 @@ class MyClient(discord.Client):
await asyncio.sleep(60) # task runs every 60 seconds
client = MyClient()
client = MyClient(intents=discord.Intents(guilds=True))
client.run('token')

View File

@ -9,10 +9,8 @@ module.
There are a number of utility commands being showcased here.'''
intents = discord.Intents.default()
intents.members = True
bot = commands.Bot(command_prefix='?', description=description, intents=intents)
intents = discord.Intents(guilds=True, messages=True, members=True)
bot = commands.Bot(command_prefix='t-', description=description, intents=intents)
@bot.event
async def on_ready():

View File

@ -123,8 +123,11 @@ class Music(commands.Cog):
elif ctx.voice_client.is_playing():
ctx.voice_client.stop()
bot = commands.Bot(command_prefix=commands.when_mentioned_or("!"),
description='Relatively simple music bot example')
bot = commands.Bot(
command_prefix=commands.when_mentioned_or("!"),
description='Relatively simple music bot example',
intents=discord.Intents(guilds=True, guild_messages=True, voice_states=True)
)
@bot.event
async def on_ready():

View File

@ -5,9 +5,8 @@ import typing
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True
intents = discord.Intents(guilds=True, messages=True, members=True)
bot = commands.Bot('!', intents=intents)

View File

@ -29,7 +29,7 @@ class MyBot(commands.Bot):
return await super().get_context(message, cls=cls)
bot = MyBot(command_prefix='!')
bot = MyBot(command_prefix='!', intents=discord.Intents(guilds=True, messages=True))
@bot.command()
async def guess(ctx, number: int):

View File

@ -17,5 +17,5 @@ class MyClient(discord.Client):
msg = f'{message.author} has deleted the message: {message.content}'
await message.channel.send(msg)
client = MyClient()
client = MyClient(intents=discord.Intents(guilds=True, messages=True))
client.run('token')

View File

@ -16,5 +16,5 @@ class MyClient(discord.Client):
msg = f'**{before.author}** edited their message:\n{before.content} -> {after.content}'
await before.channel.send(msg)
client = MyClient()
client = MyClient(intents=discord.Intents(guilds=True, messages=True))
client.run('token')

View File

@ -30,5 +30,5 @@ class MyClient(discord.Client):
else:
await message.channel.send(f'Oops. It is actually {answer}.')
client = MyClient()
client = MyClient(intents=discord.Intents(guilds=True, messages=True))
client.run('token')

View File

@ -14,8 +14,5 @@ class MyClient(discord.Client):
await guild.system_channel.send(to_send)
intents = discord.Intents.default()
intents.members = True
client = MyClient(intents=intents)
client = MyClient(intents=discord.Intents(guilds=True, members=True))
client.run('token')

View File

@ -78,8 +78,6 @@ class MyClient(discord.Client):
# If we want to do something in case of errors we'd do it here.
pass
intents = discord.Intents.default()
intents.members = True
intents = discord.Intents(guilds=True, members=True, guild_reactions=True)
client = MyClient(intents=intents)
client.run('token')

View File

@ -13,5 +13,5 @@ class MyClient(discord.Client):
if message.content.startswith('!hello'):
await message.reply('Hello!', mention_author=True)
client = MyClient()
client = MyClient(intents=discord.Intents(guilds=True, messages=True))
client.run('token')

View File

@ -3,7 +3,11 @@ import typing
import discord
from discord.ext import commands
bot = commands.Bot(command_prefix=commands.when_mentioned, description="Nothing to see here!")
bot = commands.Bot(
command_prefix=commands.when_mentioned,
description="Nothing to see here!",
intents=discord.Intents(guilds=True, messages=True)
)
# the `hidden` keyword argument hides it from the help command.
@bot.group(hidden=True)

View File

@ -5,7 +5,10 @@ import discord
class Bot(commands.Bot):
def __init__(self):
super().__init__(command_prefix=commands.when_mentioned_or('$'))
super().__init__(
command_prefix=commands.when_mentioned_or('$'),
intents=discord.Intents(guilds=True, messages=True)
)
async def on_ready(self):
print(f'Logged in as {self.user} (ID: {self.user.id})')

View File

@ -5,7 +5,10 @@ import discord
class CounterBot(commands.Bot):
def __init__(self):
super().__init__(command_prefix=commands.when_mentioned_or('$'))
super().__init__(
command_prefix=commands.when_mentioned_or('$'),
intents=discord.Intents(guilds=True, messages=True)
)
async def on_ready(self):
print(f'Logged in as {self.user} (ID: {self.user.id})')

View File

@ -1,5 +1,3 @@
import typing
import discord
from discord.ext import commands
@ -39,7 +37,10 @@ class DropdownView(discord.ui.View):
class Bot(commands.Bot):
def __init__(self):
super().__init__(command_prefix=commands.when_mentioned_or('$'))
super().__init__(
command_prefix=commands.when_mentioned_or('$'),
intents=discord.Intents(guilds=True, messages=True)
)
async def on_ready(self):
print(f'Logged in as {self.user} (ID: {self.user.id})')

View File

@ -4,7 +4,10 @@ import discord
class EphemeralCounterBot(commands.Bot):
def __init__(self):
super().__init__(command_prefix=commands.when_mentioned_or('$'))
super().__init__(
command_prefix=commands.when_mentioned_or('$'),
intents=discord.Intents(guilds=True, messages=True)
)
async def on_ready(self):
print(f'Logged in as {self.user} (ID: {self.user.id})')

View File

@ -5,7 +5,10 @@ from urllib.parse import quote_plus
class GoogleBot(commands.Bot):
def __init__(self):
super().__init__(command_prefix=commands.when_mentioned_or('$'))
super().__init__(
command_prefix=commands.when_mentioned_or('$'),
intents=discord.Intents(guilds=True, messages=True)
)
async def on_ready(self):
print(f'Logged in as {self.user} (ID: {self.user.id})')
@ -36,4 +39,4 @@ async def google(ctx: commands.Context, *, query: str):
await ctx.send(f'Google Result for: `{query}`', view=Google(query))
bot.run('token')
bot.run()

View File

@ -29,7 +29,11 @@ class PersistentView(discord.ui.View):
class PersistentViewBot(commands.Bot):
def __init__(self):
super().__init__(command_prefix=commands.when_mentioned_or('$'))
super().__init__(
command_prefix=commands.when_mentioned_or('$'),
intents=discord.Intents(guilds=True, messages=True)
)
self.persistent_views_added = False
async def on_ready(self):

View File

@ -120,7 +120,10 @@ class TicTacToe(discord.ui.View):
class TicTacToeBot(commands.Bot):
def __init__(self):
super().__init__(command_prefix=commands.when_mentioned_or('$'))
super().__init__(
command_prefix=commands.when_mentioned_or('$'),
intents=discord.Intents(guilds=True, messages=True)
)
async def on_ready(self):
print(f'Logged in as {self.user} (ID: {self.user.id})')