Browse Source

Merge remote-tracking branch 'bijij/feature/guild_onboarding' into feature/guild/onboarding

pull/10226/head
Soheab_ 7 days ago
parent
commit
ab07076b95
  1. 1
      discord/__init__.py
  2. 21
      discord/audit_logs.py
  3. 25
      discord/enums.py
  4. 67
      discord/guild.py
  5. 37
      discord/http.py
  6. 430
      discord/onboarding.py
  7. 2
      discord/reaction.py
  8. 2
      discord/state.py
  9. 29
      discord/types/audit_log.py
  10. 29
      discord/types/onboarding.py
  11. 2
      discord/webhook/async_.py
  12. 298
      docs/api.rst

1
discord/__init__.py

@ -73,6 +73,7 @@ from .poll import *
from .soundboard import *
from .subscription import *
from .presences import *
from .onboarding import *
class VersionInfo(NamedTuple):

21
discord/audit_logs.py

@ -44,6 +44,7 @@ from .sticker import GuildSticker
from .threads import Thread
from .integrations import PartialIntegration
from .channel import ForumChannel, StageChannel, ForumTag
from .onboarding import OnboardingPrompt, OnboardingPromptOption
__all__ = (
'AuditLogDiff',
@ -73,6 +74,7 @@ if TYPE_CHECKING:
from .types.snowflake import Snowflake
from .types.command import ApplicationCommandPermissions
from .types.automod import AutoModerationAction
from .types.onboarding import Prompt as PromptPayload, PromptOption as PromptOptionPayload
from .user import User
from .app_commands import AppCommand
from .webhook import Webhook
@ -246,6 +248,16 @@ def _transform_default_emoji(entry: AuditLogEntry, data: str) -> PartialEmoji:
return PartialEmoji(name=data)
def _transform_onboarding_prompts(entry: AuditLogEntry, data: List[PromptPayload]) -> List[OnboardingPrompt]:
return [OnboardingPrompt(data=prompt, state=entry._state, guild=entry.guild) for prompt in data]
def _transform_onboarding_prompt_options(
entry: AuditLogEntry, data: List[PromptOptionPayload]
) -> List[OnboardingPromptOption]:
return [OnboardingPromptOption(data=option, state=entry._state, guild=entry.guild) for option in data]
E = TypeVar('E', bound=enums.Enum)
@ -268,13 +280,15 @@ def _flag_transformer(cls: Type[F]) -> Callable[[AuditLogEntry, Union[int, str]]
def _transform_type(
entry: AuditLogEntry, data: Union[int, str]
) -> Union[enums.ChannelType, enums.StickerType, enums.WebhookType, str]:
) -> Union[enums.ChannelType, enums.StickerType, enums.WebhookType, str, enums.OnboardingPromptType]:
if entry.action.name.startswith('sticker_'):
return enums.try_enum(enums.StickerType, data)
elif entry.action.name.startswith('integration_'):
return data # type: ignore # integration type is str
elif entry.action.name.startswith('webhook_'):
return enums.try_enum(enums.WebhookType, data)
elif entry.action.name.startswith('onboarding_question_'):
return enums.try_enum(enums.OnboardingPromptType, data)
else:
return enums.try_enum(enums.ChannelType, data)
@ -353,7 +367,10 @@ class AuditLogChanges:
'flags': (None, _transform_overloaded_flags),
'default_reaction_emoji': (None, _transform_default_reaction),
'emoji_name': ('emoji', _transform_default_emoji),
'user_id': ('user', _transform_member_id)
'user_id': ('user', _transform_member_id),
'options': (None, _transform_onboarding_prompt_options),
'prompts': (None, _transform_onboarding_prompts),
'default_channel_ids': ('default_channels', _transform_channels_or_threads),
}
# fmt: on

25
discord/enums.py

@ -77,6 +77,8 @@ __all__ = (
'VoiceChannelEffectAnimationType',
'SubscriptionStatus',
'MessageReferenceType',
'OnboardingPromptType',
'OnboardingMode',
)
@ -399,6 +401,11 @@ class AuditLogAction(Enum):
automod_timeout_member = 145
creator_monetization_request_created = 150
creator_monetization_terms_accepted = 151
onboarding_question_create = 163
onboarding_question_update = 164
onboarding_update = 167
server_guide_create = 190
server_guide_update = 191
# fmt: on
@property
@ -464,6 +471,10 @@ class AuditLogAction(Enum):
AuditLogAction.soundboard_sound_create: AuditLogActionCategory.create,
AuditLogAction.soundboard_sound_update: AuditLogActionCategory.update,
AuditLogAction.soundboard_sound_delete: AuditLogActionCategory.delete,
AuditLogAction.onboarding_question_create: AuditLogActionCategory.create,
AuditLogAction.onboarding_question_update: AuditLogActionCategory.update,
AuditLogAction.onboarding_update: AuditLogActionCategory.update,
}
# fmt: on
return lookup[self]
@ -509,6 +520,10 @@ class AuditLogAction(Enum):
return 'user'
elif v < 152:
return 'creator_monetization'
elif v < 165:
return 'onboarding_question'
elif v < 168:
return 'onboarding'
class UserFlags(Enum):
@ -864,6 +879,16 @@ class SubscriptionStatus(Enum):
inactive = 2
class OnboardingPromptType(Enum):
multiple_choice = 0
dropdown = 1
class OnboardingMode(Enum):
default = 0
advanced = 1
def create_unknown_value(cls: Type[E], val: Any) -> E:
value_cls = cls._enum_value_cls_ # type: ignore # This is narrowed below
name = f'unknown_{val}'

67
discord/guild.py

@ -76,6 +76,7 @@ from .enums import (
AutoModRuleEventType,
ForumOrderType,
ForumLayoutType,
OnboardingMode,
)
from .mixins import Hashable
from .user import User
@ -91,6 +92,7 @@ from .sticker import GuildSticker
from .file import File
from .audit_logs import AuditLogEntry
from .object import OLDEST_OBJECT, Object
from .onboarding import Onboarding, PartialOnboardingPrompt
from .welcome_screen import WelcomeScreen, WelcomeChannel
from .automod import AutoModRule, AutoModTrigger, AutoModRuleAction
from .partial_emoji import _EmojiTag, PartialEmoji
@ -4823,3 +4825,68 @@ class Guild(Hashable):
data = await self._state.http.create_soundboard_sound(self.id, reason=reason, **payload)
return SoundboardSound(guild=self, state=self._state, data=data)
async def onboarding(self) -> Onboarding:
"""|coro|
Fetches the onboarding configuration for this guild.
.. versionadded:: 2.4
Returns
--------
:class:`Onboarding`
The onboarding configuration that was fetched.
"""
data = await self._state.http.get_guild_onboarding(self.id)
return Onboarding(data=data, guild=self, state=self._state)
async def edit_onboarding(
self,
*,
prompts: List[PartialOnboardingPrompt] = MISSING,
default_channels: List[Snowflake] = MISSING,
enabled: bool = MISSING,
mode: OnboardingMode = MISSING,
reason: str = MISSING,
) -> Onboarding:
"""|coro|
Edits the onboarding configuration for this guild.
.. versionadded:: 2.4
Parameters
-----------
prompts: List[:class:`PartialOnboardingPrompt`]
The prompts that will be shown to new members.
default_channels: List[:class:`abc.Snowflake`]
The channels that will be used as the default channels for new members.
enabled: :class:`bool`
Whether the onboarding configuration is enabled.
mode: :class:`OnboardingMode`
The mode that will be used for the onboarding configuration.
reason: :class:`str`
The reason for editing the onboarding configuration. Shows up on the audit log.
Raises
-------
Forbidden
You do not have permissions to edit the onboarding configuration.
HTTPException
Editing the onboarding configuration failed.
Returns
--------
:class:`Onboarding`
The new onboarding configuration.
"""
data = await self._state.http.edit_guild_onboarding(
self.id,
prompts=[p.to_dict(id=i) for i, p in enumerate(prompts)] if prompts is not MISSING else None,
default_channel_ids=[c.id for c in default_channels] if default_channels is not MISSING else None,
enabled=enabled if enabled is not MISSING else None,
mode=mode.value if mode is not MISSING else None,
reason=reason if reason is not MISSING else None,
)
return Onboarding(data=data, guild=self, state=self._state)

37
discord/http.py

@ -81,6 +81,7 @@ if TYPE_CHECKING:
invite,
member,
message,
onboarding,
template,
role,
user,
@ -2541,6 +2542,42 @@ class HTTPClient:
),
)
# Guild Onboarding
def get_guild_onboarding(self, guild_id: Snowflake) -> Response[onboarding.Onboarding]:
return self.request(Route('GET', '/guilds/{guild_id}/onboarding', guild_id=guild_id))
def edit_guild_onboarding(
self,
guild_id: Snowflake,
*,
prompts: Optional[List[onboarding.Prompt]] = None,
default_channel_ids: Optional[List[Snowflake]] = None,
enabled: Optional[bool] = None,
mode: Optional[onboarding.OnboardingMode] = None,
reason: Optional[str],
) -> Response[onboarding.Onboarding]:
payload = {}
if prompts is not None:
payload['prompts'] = prompts
if default_channel_ids is not None:
payload['default_channel_ids'] = default_channel_ids
if enabled is not None:
payload['enabled'] = enabled
if mode is not None:
payload['mode'] = mode
return self.request(
Route('PUT', f'/guilds/{guild_id}/onboarding', guild_id=guild_id),
json=payload,
reason=reason,
)
# Soundboard
def get_soundboard_default_sounds(self) -> Response[List[soundboard.SoundboardDefaultSound]]:

430
discord/onboarding.py

@ -22,238 +22,326 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
from __future__ import annotations
from typing import TYPE_CHECKING, Dict, List, Union
import os
from typing import TYPE_CHECKING, Iterable, Optional, Set, List, Union
from discord.utils import MISSING
from . import utils
from .mixins import Hashable
from .object import Object
from .role import Role
from .enums import OnboardingPromptType, try_enum
from .partial_emoji import PartialEmoji
from .utils import SequenceProxy
from .enums import OnboardingMode, OnboardingPromptType, try_enum
from .utils import cached_slot_property, MISSING
__all__ = (
'Onboarding',
'PartialOnboardingPrompt',
'OnboardingPrompt',
'OnboardingPromptOption',
'PartialOnboardingPromptOption',
)
if TYPE_CHECKING:
from .abc import GuildChannel, PartialMessageable
from .abc import GuildChannel
from .emoji import Emoji
from .guild import Guild
from .partial_emoji import PartialEmoji
from .role import Role
from .threads import Thread
from .types.onboarding import (
Prompt as PromptPayload,
PromptOption as PromptOptionPayload,
Onboarding as OnboardingPayload,
OnboardingPrompt as OnboardingPromptPayload,
OnboardingPromptOption as OnboardingPromptOptionPayload,
)
from .state import ConnectionState
class OnboardingPromptOption(Hashable):
"""Represents a guild's onboarding prompt's option.
.. container:: operations
.. describe:: x == y
Checks if two guilds are equal.
class PartialOnboardingPromptOption:
"""Represents a partial onboarding prompt option, these are used in the creation
of an :class:`OnboardingPrompt` via :meth:`Guild.edit_onboarding`.
.. describe:: x != y
.. versionadded:: 2.4
Checks if two guilds are not equal.
.. describe:: hash(x)
Returns the guild's hash.
.. describe:: str(x)
Attributes
-----------
title: :class:`str`
The title of this prompt option.
description: Optional[:class:`str`]
The description of this prompt option.
emoji: Optional[Union[:class:`Emoji`, :class:`PartialEmoji`, :class:`str`]]
The emoji tied to this option. May be a custom emoji, or a unicode emoji.
channel_ids: Set[:class:`int`]
The IDs of the channels that will be made visible if this option is selected.
role_ids: Set[:class:`int`]
The IDs of the roles given to the user if this option is selected.
"""
Returns the guild's name.
__slots__ = (
'title',
'emoji',
'description',
'channel_ids',
'role_ids',
)
.. versionadded:: 2.2
def __init__(
self,
title: str,
emoji: Union[Emoji, PartialEmoji, str],
description: Optional[str] = None,
channel_ids: Iterable[int] = MISSING,
role_ids: Iterable[int] = MISSING,
) -> None:
self.title: str = title
self.description: Optional[str] = description
self.emoji: Union[PartialEmoji, Emoji, str] = emoji
self.channel_ids: Set[int] = set(channel_ids or [])
self.role_ids: Set[int] = set(role_ids or [])
def to_dict(self, *, id: int = MISSING) -> PromptOptionPayload:
if isinstance(self.emoji, str):
emoji_payload = {"emoji_name": self.emoji}
else:
emoji_payload = {
"emoji_id": self.emoji.id,
"emoji_name": self.emoji.name,
"emoji_animated": self.emoji.animated,
}
return {
'id': id or os.urandom(16).hex(),
'title': self.title,
'description': self.description,
'channel_ids': list(self.channel_ids),
'role_ids': list(self.role_ids),
**emoji_payload,
} # type: ignore
class OnboardingPromptOption(PartialOnboardingPromptOption, Hashable):
"""Represents an onboarding prompt option.
.. versionadded:: 2.4
Attributes
-----------
id: :class:`int`
The ID of the option.
The ID of this prompt option.
guild: :class:`Guild`
The guild the onboarding prompt option is related to.
title: :class:`str`
The title of the option.
description: :class:`str`
The description of the option.
emoji: :class:`PartialEmoji`
The emoji of the option.
The title of this prompt option.
description: Optional[:class:`str`]
The description of this prompt option.
emoji: Optional[Union[:class:`Emoji`, :class:`PartialEmoji`, :class:`str`]]
The emoji tied to this option. May be a custom emoji, or a unicode emoji.
channel_ids: Set[:class:`int`]
The IDs of the channels that will be made visible if this option is selected.
role_ids: Set[:class:`int`]
The IDs of the roles given to the user if this option is selected.
"""
__slots__ = ('id', 'title', 'description', 'emoji', '_channels', '_roles', '_onboarding')
def __init__(self, *, onboarding: Onboarding, data: OnboardingPromptOptionPayload) -> None:
self._onboarding: Onboarding = onboarding
self._channels: Dict[int, Union[GuildChannel, Thread, PartialMessageable, Object]] = {}
self._roles: Dict[int, Union[Role, Object]] = {}
self._from_data(data)
def _from_data(self, data: OnboardingPromptOptionPayload) -> None:
guild = self._onboarding._guild
state = guild._state
__slots__ = (
'_state',
'_cs_channels',
'_cs_roles',
'guild',
'id',
)
def __init__(self, *, data: PromptOptionPayload, state: ConnectionState, guild: Guild) -> None:
self._state: ConnectionState = state
self.guild: Guild = guild
self.id: int = int(data['id'])
self.title: str = data['title']
self.description: str = data['description']
emoji = PartialEmoji.from_dict(data['emoji'])
emoji._state = state
self.emoji: PartialEmoji = emoji
channel_ids = data.get('channel_ids', [])
for channel_id in channel_ids:
channel = guild.get_channel_or_thread(int(channel_id)) or state.get_channel(int(channel_id))
self._channels[int(channel_id)] = channel or Object(id=channel_id) # type: ignore # can't be PrivateChannel
role_ids = data.get('role_ids', [])
for role_id in role_ids:
role = guild.get_role(int(role_id))
self._roles[int(role_id)] = role or Object(id=role_id, type=Role)
super().__init__(
title=data['title'],
description=data['description'],
emoji=self._state.get_emoji_from_partial_payload(data['emoji']),
channel_ids=[int(id) for id in data['channel_ids']],
role_ids=[int(id) for id in data['role_ids']],
)
def __repr__(self) -> str:
return f'<OnboardingPromptOption id={self.id} title={self.title!r} description={self.description!r} emoji={self.emoji!r}>'
@property
def channels(self) -> SequenceProxy[Union[GuildChannel, Thread, PartialMessageable, Object]]:
"""List[:class:`Union[GuildChannel, Thread, PartialMessageable, Object]`]: A list of channels that are opted into when this option is selected."""
return SequenceProxy(self._channels.values())
@property
def roles(self) -> SequenceProxy[Union[Role, Object]]:
"""List[:class:`Union[Role, Object]`]: A list of roles that are assigned when this option is selected."""
return SequenceProxy(self._roles.values())
class OnboardingPrompt(Hashable):
"""Represents a guild's onboarding prompt.
.. container:: operations
.. describe:: x == y
return f'<OnboardingPromptOption id={self.id} title={self.title}>'
Checks if two guilds are equal.
@cached_slot_property('_cs_channels')
def channels(self) -> List[Union[GuildChannel, Thread]]:
"""List[Union[:class:`abc.GuildChannel`, :class:`Thread`]]: The list of channels which will be made visible if this option is selected."""
it = filter(None, map(self.guild._resolve_channel, self.channel_ids))
return utils._unique(it)
.. describe:: x != y
@cached_slot_property('_cs_roles')
def roles(self) -> List[Role]:
"""List[:class:`Role`]: The list of roles given to the user if this option is selected."""
it = filter(None, map(self.guild.get_role, self.role_ids))
return utils._unique(it)
Checks if two guilds are not equal.
def to_dict(self) -> PromptOptionPayload:
return super().to_dict(id=self.id)
.. describe:: hash(x)
Returns the guild's hash.
class PartialOnboardingPrompt:
"""Represents a partial onboarding prompt, these are used in the creation
of an :class:`Onboarding` via :meth:`Guild.edit_onboarding`.
.. describe:: str(x)
.. versionadded:: 2.4
Returns the guild's name.
Attributes
-----------
type: :class:`OnboardingPromptType`
The type of this prompt.
title: :class:`str`
The title of this prompt.
options: List[:class:`PartialOnboardingPromptOption`]
The options of this prompt.
single_select: :class:`bool`
Whether this prompt is single select.
required: :class:`bool`
Whether this prompt is required.
in_onboarding: :class:`bool`
Whether this prompt is in the onboarding flow.
"""
.. versionadded:: 2.2
__slots__ = (
'type',
'title',
'options',
'single_select',
'required',
'in_onboarding',
)
def __init__(
self,
*,
type: OnboardingPromptType,
title: str,
options: List[PartialOnboardingPromptOption],
single_select: bool = True,
required: bool = True,
in_onboarding: bool = True,
) -> None:
self.type: OnboardingPromptType = try_enum(OnboardingPromptType, type)
self.title: str = title
self.options: List[PartialOnboardingPromptOption] = options
self.single_select: bool = single_select
self.required: bool = required
self.in_onboarding: bool = in_onboarding
def to_dict(self, *, id: int) -> PromptPayload:
return {
'id': id,
'type': self.type.value,
'title': self.title,
'options': [option.to_dict() for option in self.options],
'single_select': self.single_select,
'required': self.required,
'in_onboarding': self.in_onboarding,
}
class OnboardingPrompt(PartialOnboardingPrompt, Hashable):
"""Represents an onboarding prompt.
.. versionadded:: 2.4
Attributes
-----------
id: :class:`int`
The ID of the prompt.
The ID of this prompt.
guild: :class:`Guild`
The guild the onboarding prompt is related to.
type: :class:`OnboardingPromptType`
The type of onboarding prompt.
title: :class:`str`
The title of the prompt.
The title of this prompt.
options: List[:class:`OnboardingPromptOption`]
The list of options the user can select from.
single_select: :class:`bool`
Whether only one option can be selected at a time.
Whether only one option can be selected.
required: :class:`bool`
Whether the prompt is required in the onboarding flow.
Whether this prompt is required to complete the onboarding flow.
in_onboarding: :class:`bool`
Whether the prompt is in the onboarding flow.
Whether this prompt is part of the onboarding flow.
"""
__slots__ = ('id', 'title', 'single_select', 'required', 'in_onboarding', '_oboarding', '_options', '_type')
def __init__(self, *, onboarding: Onboarding, data: OnboardingPromptPayload) -> None:
self._oboarding: Onboarding = onboarding
self._from_data(data)
options: List[OnboardingPromptOption]
__slots__ = (
'_state',
'guild',
'id',
'title',
'options',
'single_select',
'required',
'in_onboarding',
'type',
)
def _from_data(self, data: OnboardingPromptPayload) -> None:
def __init__(self, *, data: PromptPayload, state: ConnectionState, guild: Guild):
self._state: ConnectionState = state
self.guild: Guild = guild
self.id: int = int(data['id'])
self.title: str = data['title']
self.single_select: bool = data['single_select']
self.required: bool = data['required']
self._type: OnboardingPromptType = try_enum(OnboardingPromptType, data['type'])
self.in_onboarding: bool = data['in_onboarding']
self._options: List[OnboardingPromptOption] = [
OnboardingPromptOption(onboarding=self._oboarding, data=option) for option in data['options']
]
super().__init__(
type=try_enum(OnboardingPromptType, data['type']),
title=data['title'],
options=[OnboardingPromptOption(data=option_data, state=state, guild=guild) for option_data in data['options']],
single_select=data['single_select'],
required=data['required'],
in_onboarding=data['in_onboarding'],
)
def __repr__(self) -> str:
return f'<OnboardingPrompt id={self.id} title={self.title!r} single_select={self.single_select} required={self.required} in_onboarding={self.in_onboarding} type={self.type!r}>'
@property
def type(self) -> OnboardingPromptType:
"""Optional[:class:`OnboardingPromptType`]: The type of the prompt."""
return self._type
@property
def options(self) -> SequenceProxy[OnboardingPromptOption]:
"""List[:class:`OnboardingPromptOption`]: The options available to the prompt."""
return SequenceProxy(self._options)
return f'<OnboardingPrompt id={self.id} title={self.title}, type={self.type}>'
class Onboarding:
"""Represents a guild's onboarding.
.. container:: operations
"""Represents a guild's onboarding configuration.
.. describe:: x == y
Checks if two guilds are equal.
.. describe:: x != y
Checks if two guilds are not equal.
.. describe:: hash(x)
Returns the guild's hash.
.. describe:: str(x)
Returns the guild's name.
.. versionadded:: 2.2
.. versionadded:: 2.4
Attributes
-----------
enabled: :class:`bool`
Whether guild onboarding is enabled.
guild: :class:`Guild`
The guild the onboarding configuration is for.
prompts: List[:class:`OnboardingPrompt`]
The list of prompts shown during the onboarding and customize community flows.
default_channel_ids: Set[:class:`int`]
The IDs of the channels exposed to a new user by default.
enabled: :class:`bool`:
Whether onboarding is enabled in this guild.
mode: :class:`OnboardingMode`
The mode of onboarding for this guild.
"""
__slots__ = ('enabled', '_guild', '_default_channel_ids', '_default_channels', '_prompts', '_guild_id')
def __init__(self, *, guild: Guild, data: OnboardingPayload) -> None:
self._guild = guild
self._default_channels: Dict[int, Union[GuildChannel, Thread, PartialMessageable, Object]] = {}
self._from_data(data)
def _from_data(self, data: OnboardingPayload) -> None:
guild = self._guild
state = guild._state
__slots__ = (
'_state',
'_cs_default_channels',
'guild',
'prompts',
'default_channel_ids',
'enabled',
'mode',
)
def __init__(self, *, data: OnboardingPayload, guild: Guild, state: ConnectionState) -> None:
self._state: ConnectionState = state
self.guild: Guild = guild
self.default_channel_ids: Set[int] = {int(channel_id) for channel_id in data['default_channel_ids']}
self.prompts: List[OnboardingPrompt] = [
OnboardingPrompt(data=prompt_data, state=state, guild=guild) for prompt_data in data['prompts']
]
self.enabled: bool = data['enabled']
self._guild_id: int = int(data['guild_id'])
prompts = data.get('prompts', [])
self._prompts: List[OnboardingPrompt] = [OnboardingPrompt(onboarding=self, data=prompt) for prompt in prompts]
default_channel_ids = data.get('default_channel_ids', [])
for channel_id in default_channel_ids:
channel = guild.get_channel_or_thread(int(channel_id)) or state.get_channel(int(channel_id))
self._default_channels[int(channel_id)] = channel or Object(id=channel_id) # type: ignore # can't be a private channel
self.mode: OnboardingMode = try_enum(OnboardingMode, data.get('mode', 0))
def __repr__(self) -> str:
return f'<Onboarding enabled={self.enabled}>'
@property
def default_channels(self) -> SequenceProxy[Union[GuildChannel, Thread, PartialMessageable, Object]]:
"""List[Union[:class:`GuildChannel`, :class:`Thread`, :class:`Object`]: The channels that new members get opted into automatically."""
return SequenceProxy(self._default_channels.values())
return f'<Onboarding guild={self.guild!r} enabled={self.enabled}>'
@property
def prompts(self) -> SequenceProxy[OnboardingPrompt]:
"""List[:class:`GuildOnboardingPrompt`]: The prompts shown during onboarding and in costomize community."""
return SequenceProxy(self._prompts)
@cached_slot_property('_cs_default_channels')
def default_channels(self) -> List[Union[GuildChannel, Thread]]:
"""List[Union[:class:`abc.GuildChannel`, :class:`Thread`]]: The list of channels exposed to a new user by default."""
it = filter(None, map(self.guild._resolve_channel, self.default_channel_ids))
return utils._unique(it)

2
discord/reaction.py

@ -102,7 +102,7 @@ class Reaction:
def __init__(self, *, message: Message, data: ReactionPayload, emoji: Optional[Union[PartialEmoji, Emoji, str]] = None):
self.message: Message = message
self.emoji: Union[PartialEmoji, Emoji, str] = emoji or message._state.get_reaction_emoji(data['emoji'])
self.emoji: Union[PartialEmoji, Emoji, str] = emoji or message._state.get_emoji_from_partial_payload(data['emoji'])
self.count: int = data.get('count', 1)
self.me: bool = data['me']
details = data.get('count_details', {})

2
discord/state.py

@ -1786,7 +1786,7 @@ class ConnectionState(Generic[ClientT]):
return channel.guild.get_member(user_id)
return self.get_user(user_id)
def get_reaction_emoji(self, data: PartialEmojiPayload) -> Union[Emoji, PartialEmoji, str]:
def get_emoji_from_partial_payload(self, data: PartialEmojiPayload) -> Union[Emoji, PartialEmoji, str]:
emoji_id = utils._get_as_snowflake(data, 'id')
if not emoji_id:

29
discord/types/audit_log.py

@ -38,6 +38,7 @@ from .channel import ChannelType, DefaultReaction, PrivacyLevel, VideoQualityMod
from .threads import Thread
from .command import ApplicationCommand, ApplicationCommandPermissions
from .automod import AutoModerationTriggerMetadata
from .onboarding import PromptOption, Prompt
AuditLogEvent = Literal[
1,
@ -99,6 +100,9 @@ AuditLogEvent = Literal[
145,
150,
151,
163,
164,
167,
]
@ -116,6 +120,7 @@ class _AuditLogChange_Str(TypedDict):
'tags',
'unicode_emoji',
'emoji_name',
'title',
]
new_value: str
old_value: str
@ -163,6 +168,10 @@ class _AuditLogChange_Bool(TypedDict):
'available',
'archived',
'locked',
'enabled',
'single_select',
'required',
'in_onboarding',
]
new_value: bool
old_value: bool
@ -273,8 +282,8 @@ class _AuditLogChange_AppCommandPermissions(TypedDict):
old_value: ApplicationCommandPermissions
class _AuditLogChange_AppliedTags(TypedDict):
key: Literal['applied_tags']
class _AuditLogChange_SnowflakeList(TypedDict):
key: Literal['applied_tags', 'default_channel_ids']
new_value: List[Snowflake]
old_value: List[Snowflake]
@ -297,6 +306,18 @@ class _AuditLogChange_TriggerMetadata(TypedDict):
old_value: Optional[AutoModerationTriggerMetadata]
class _AuditLogChange_Prompts(TypedDict):
key: Literal['prompts']
new_value: List[Prompt]
old_value: List[Prompt]
class _AuditLogChange_Options(TypedDict):
key: Literal['options']
new_value: List[PromptOption]
old_value: List[PromptOption]
AuditLogChange = Union[
_AuditLogChange_Str,
_AuditLogChange_AssetHash,
@ -317,10 +338,12 @@ AuditLogChange = Union[
_AuditLogChange_Status,
_AuditLogChange_EntityType,
_AuditLogChange_AppCommandPermissions,
_AuditLogChange_AppliedTags,
_AuditLogChange_SnowflakeList,
_AuditLogChange_AvailableTags,
_AuditLogChange_DefaultReactionEmoji,
_AuditLogChange_TriggerMetadata,
_AuditLogChange_Prompts,
_AuditLogChange_Options,
]

29
discord/types/onboarding.py

@ -24,37 +24,38 @@ DEALINGS IN THE SOFTWARE.
from __future__ import annotations
from typing import List, Literal, TypedDict, TYPE_CHECKING
from .snowflake import Snowflake
from typing import Literal, Optional, TypedDict
if TYPE_CHECKING:
from .emoji import PartialEmoji
from .emoji import PartialEmoji
from .snowflake import Snowflake
OnboardingPromptType = Literal[0, 1]
PromptType = Literal[0, 1]
OnboardingMode = Literal[0, 1]
class OnboardingPromptOption(TypedDict):
class PromptOption(TypedDict):
id: Snowflake
channel_ids: List[Snowflake]
role_ids: List[Snowflake]
channel_ids: list[Snowflake]
role_ids: list[Snowflake]
emoji: PartialEmoji
title: str
description: str
description: Optional[str]
class OnboardingPrompt(TypedDict):
class Prompt(TypedDict):
id: Snowflake
options: List[OnboardingPromptOption]
options: list[PromptOption]
title: str
single_select: bool
required: bool
in_onboarding: bool
type: OnboardingPromptType
type: PromptType
class Onboarding(TypedDict):
guild_id: Snowflake
prompts: List[OnboardingPrompt]
default_channel_ids: List[Snowflake]
prompts: list[Prompt]
default_channel_ids: list[Snowflake]
enabled: bool
mode: OnboardingMode

2
discord/webhook/async_.py

@ -755,7 +755,7 @@ class _WebhookState:
def get_reaction_emoji(self, data: PartialEmojiPayload) -> Union[PartialEmoji, Emoji, str]:
if self._parent is not None:
return self._parent.get_reaction_emoji(data)
return self._parent.get_emoji_from_partial_payload(data)
emoji_id = utils._get_as_snowflake(data, 'id')

298
docs/api.rst

@ -3097,6 +3097,48 @@ of :class:`enum.Enum`.
.. versionadded:: 2.5
.. attribute:: onboarding_question_create
A guild onboarding prompt was created.
Possible attributes for :class:`AuditLogDiff`:
- :attr:`~AuditLogDiff.type`
- :attr:`~AuditLogDiff.title`
- :attr:`~AuditLogDiff.options`
- :attr:`~AuditLogDiff.single_select`
- :attr:`~AuditLogDiff.required`
- :attr:`~AuditLogDiff.in_onboarding`
.. versionadded:: 2.4
.. attribute:: onboarding_question_update
A guild onboarding prompt was updated.
Possible attributes for :class:`AuditLogDiff`:
- :attr:`~AuditLogDiff.type`
- :attr:`~AuditLogDiff.title`
- :attr:`~AuditLogDiff.options`
- :attr:`~AuditLogDiff.single_select`
- :attr:`~AuditLogDiff.required`
- :attr:`~AuditLogDiff.in_onboarding`
.. versionadded:: 2.4
.. attribute:: onboarding_update
The guild's onboarding configuration was updated.
Possible attributes for :class:`AuditLogDiff`:
- :attr:`~AuditLogDiff.enabled`
- :attr:`~AuditLogDiff.default_channels`
- :attr:`~AuditLogDiff.prompts`
.. versionadded:: 2.4
.. class:: AuditLogActionCategory
Represents the category that the :class:`AuditLogAction` belongs to.
@ -3770,110 +3812,34 @@ of :class:`enum.Enum`.
The entitlement owner is a user.
.. class:: PollLayoutType
.. class:: OnboardingPromptType
Represents how a poll answers are shown.
Represents the type of onboarding prompt.
.. versionadded:: 2.4
.. attribute:: default
The default layout.
.. attribute:: multiple_choice
.. class:: InviteType
Prompt options are multiple choice.
Represents the type of an invite.
.. attribute:: dropdown
.. versionadded:: 2.4
.. attribute:: guild
Prompt options are displayed as a drop-down.
The invite is a guild invite.
.. class:: OnboardingMode
.. attribute:: group_dm
The invite is a group DM invite.
.. attribute:: friend
The invite is a friend invite.
.. class:: ReactionType
Represents the type of a reaction.
Represents the onboarding constriant mode.
.. versionadded:: 2.4
.. attribute:: normal
A normal reaction.
.. attribute:: burst
A burst reaction, also known as a "super reaction".
.. class:: VoiceChannelEffectAnimationType
Represents the animation type of a voice channel effect.
.. versionadded:: 2.5
.. attribute:: premium
A fun animation, sent by a Nitro subscriber.
.. attribute:: basic
The standard animation.
.. class:: SubscriptionStatus
Represents the status of an subscription.
.. versionadded:: 2.5
.. attribute:: active
The subscription is active.
.. attribute:: ending
The subscription is active but will not renew.
.. attribute:: inactive
The subscription is inactive and not being charged.
.. class:: MessageReferenceType
Represents the type of a message reference.
.. versionadded:: 2.5
.. attribute:: default
A standard reference used by message replies (:attr:`MessageType.reply`),
crossposted messaged created by a followed channel integration, and messages of type:
- :attr:`MessageType.pins_add`
- :attr:`MessageType.channel_follow_add`
- :attr:`MessageType.thread_created`
- :attr:`MessageType.thread_starter_message`
- :attr:`MessageType.poll_result`
- :attr:`MessageType.context_menu_command`
Only default channels count towards onboarding constraints.
.. attribute:: forward
.. attribute:: advanced
A forwarded message.
.. attribute:: reply
Default channels and questions count towards onboarding constraints.
An alias for :attr:`.default`.
.. _discord-api-audit-logs:
@ -4121,9 +4087,9 @@ AuditLogDiff
.. attribute:: type
The type of channel, sticker, webhook or integration.
The type of channel, sticker, webhook, integration or onboarding prompt.
:type: Union[:class:`ChannelType`, :class:`StickerType`, :class:`WebhookType`, :class:`str`]
:type: Union[:class:`ChannelType`, :class:`StickerType`, :class:`WebhookType`, :class:`str`, :class:`OnboardingPromptType`]
.. attribute:: topic
@ -4478,7 +4444,7 @@ AuditLogDiff
.. attribute:: enabled
Whether the automod rule is active or not.
Whether guild onboarding or the automod rule is active or not.
:type: :class:`bool`
@ -4608,6 +4574,118 @@ AuditLogDiff
:type: :class:`float`
.. attribute:: options
The onboarding prompt options associated with this onboarding prompt.
See also :attr:`OnboardingPrompt.options`
:type: List[:class:`OnboardingPromptOption`]
.. attribute:: default_channels
The default channels associated with the onboarding in this guild.
See also :attr:`Onboarding.default_channels`
:type: List[:class:`abc.GuildChannel`, :class:`Object`]
.. attribute:: prompts
The onboarding prompts associated with the onboarding in this guild.
See also :attr:`Onboarding.prompts`
:type: List[:class:`OnboardingPrompt`]
.. attribute:: title
The title of the onboarding prompt.
See also :attr:`OnboardingPrompt.title`
:type: :class:`str`
.. attribute:: single_select
Whether only one prompt option can be selected.
See also :attr:`OnboardingPrompt.single_select`
:type: :class:`bool`
.. attribute:: required
Whether the onboarding prompt is required to complete the onboarding.
See also :attr:`OnboardingPrompt.required`
:type: :class:`bool`
.. attribute:: in_onboarding
Whether this prompt is currently part of the onboarding flow.
See also :attr:`OnboardingPrompt.in_onboarding`
:type: :class:`bool`
.. attribute:: options
The onboarding prompt options associated with this onboarding prompt.
See also :attr:`OnboardingPrompt.options`
:type: List[:class:`OnboardingPromptOption`]
.. attribute:: default_channels
The default channels associated with the onboarding in this guild.
See also :attr:`Onboarding.default_channels`
:type: List[:class:`abc.GuildChannel`, :class:`Object`]
.. attribute:: prompts
The onboarding prompts associated with the onboarding in this guild.
See also :attr:`Onboarding.prompts`
:type: List[:class:`OnboardingPrompt`]
.. attribute:: title
The title of the onboarding prompt.
See also :attr:`OnboardingPrompt.title`
:type: :class:`str`
.. attribute:: single_select
Whether only one prompt option can be selected.
See also :attr:`OnboardingPrompt.single_select`
:type: :class:`bool`
.. attribute:: required
Whether the onboarding prompt is required to complete the onboarding.
See also :attr:`OnboardingPrompt.required`
:type: :class:`bool`
.. attribute:: in_onboarding
Whether this prompt is currently part of the onboarding flow.
See also :attr:`OnboardingPrompt.in_onboarding`
:type: :class:`bool`
.. this is currently missing the following keys: reason and application_id
I'm not sure how to port these
@ -5231,6 +5309,46 @@ GuildSticker
.. autoclass:: GuildSticker()
:members:
Onboarding
~~~~~~~~~~~
.. attributetable:: Onboarding
.. autoclass:: Onboarding()
:members:
PartialOnboardingPrompt
~~~~~~~~~~~~~~~~~~~~~~~~
.. attributetable:: PartialOnboardingPrompt
.. autoclass:: PartialOnboardingPrompt
:members:
OnboardingPrompt
~~~~~~~~~~~~~~~~~
.. attributetable:: OnboardingPrompt
.. autoclass:: OnboardingPrompt()
:members:
PartialOnboardingPromptOption
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. attributetable:: PartialOnboardingPromptOption
.. autoclass:: PartialOnboardingPromptOption
:members:
OnboardingPromptOption
~~~~~~~~~~~~~~~~~~~~~~~
.. attributetable:: OnboardingPromptOption
.. autoclass:: OnboardingPromptOption()
:members:
BaseSoundboardSound
~~~~~~~~~~~~~~~~~~~~~~~

Loading…
Cancel
Save