Browse Source

Create temporary DMChannels from message create events

This allows for DMChannels to work without falling back to the
Object error case since there is enough information to build a pseudo
DMChannel object.

This is a breaking change since it changes the type of
DMChannel.recipient to Optional[User] for when this faux object is
created.
pull/6713/head
Rapptz 4 years ago
parent
commit
7bdaa793f6
  1. 21
      discord/channel.py
  2. 6
      discord/state.py

21
discord/channel.py

@ -1195,8 +1195,10 @@ class DMChannel(discord.abc.Messageable, Hashable):
Attributes Attributes
---------- ----------
recipient: :class:`User` recipient: Optional[:class:`User`]
The user you are participating with in the direct message channel. The user you are participating with in the direct message channel.
If this channel is received through the gateway, the recipient information
may not be always available.
me: :class:`ClientUser` me: :class:`ClientUser`
The user presenting yourself. The user presenting yourself.
id: :class:`int` id: :class:`int`
@ -1215,11 +1217,26 @@ class DMChannel(discord.abc.Messageable, Hashable):
return self return self
def __str__(self): def __str__(self):
return f'Direct Message with {self.recipient}' if self.recipient:
return f'Direct Message with {self.recipient}'
return 'Direct Message with Unknown User'
def __repr__(self): def __repr__(self):
return f'<DMChannel id={self.id} recipient={self.recipient!r}>' return f'<DMChannel id={self.id} recipient={self.recipient!r}>'
@classmethod
def _from_message(cls, state, channel_id, payload):
# The MESSAGE_CREATE payload no longer gives bots
# an appropriate CHANNEL_CREATE.
# However, it has enough data for us to pretend since
# bots can no longer be in a group DM.
self = cls.__new__(cls)
self._state = state
self.id = channel_id
self.recipient = None
self.me = state.user
return self
@property @property
def type(self): def type(self):
""":class:`ChannelType`: The channel's Discord type.""" """:class:`ChannelType`: The channel's Discord type."""

6
discord/state.py

@ -338,10 +338,10 @@ class ConnectionState:
if len(self._private_channels) > 128: if len(self._private_channels) > 128:
_, to_remove = self._private_channels.popitem(last=False) _, to_remove = self._private_channels.popitem(last=False)
if isinstance(to_remove, DMChannel): if isinstance(to_remove, DMChannel) and to_remove.recipient:
self._private_channels_by_user.pop(to_remove.recipient.id, None) self._private_channels_by_user.pop(to_remove.recipient.id, None)
if isinstance(channel, DMChannel): if isinstance(channel, DMChannel) and channel.recipient:
self._private_channels_by_user[channel.recipient.id] = channel self._private_channels_by_user[channel.recipient.id] = channel
def add_dm_channel(self, data): def add_dm_channel(self, data):
@ -371,7 +371,7 @@ class ConnectionState:
try: try:
guild = self._get_guild(int(data['guild_id'])) guild = self._get_guild(int(data['guild_id']))
except KeyError: except KeyError:
channel = self.get_channel(channel_id) channel = DMChannel._from_message(self, channel_id, data)
guild = None guild = None
else: else:
channel = guild and guild.get_channel(channel_id) channel = guild and guild.get_channel(channel_id)

Loading…
Cancel
Save