hikari.messages
Application and entities that are used to describe messages on Discord.
View Source
# -*- coding: utf-8 -*- # cython: language_level=3 # Copyright (c) 2020 Nekokatt # Copyright (c) 2021-present davfsa # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. """Application and entities that are used to describe messages on Discord.""" from __future__ import annotations __all__: typing.Sequence[str] = ( "MessageType", "MessageFlag", "MessageActivityType", "Attachment", "Reaction", "MessageActivity", "Mentions", "MessageInteraction", "MessageReference", "PartialMessage", "Message", "ActionRowComponent", "ButtonComponent", "ButtonStyle", "SelectMenuOption", "SelectMenuComponent", "InteractiveButtonTypes", "InteractiveButtonTypesT", "ComponentType", "PartialComponent", ) import typing import attr from hikari import files from hikari import guilds from hikari import snowflakes from hikari import traits from hikari import undefined from hikari import urls from hikari.internal import attr_extensions from hikari.internal import enums from hikari.internal import routes if typing.TYPE_CHECKING: import datetime from hikari import channels as channels_ from hikari import embeds as embeds_ from hikari import emojis as emojis_ from hikari import stickers as stickers_ from hikari import users as users_ from hikari.api import special_endpoints from hikari.interactions import base_interactions _T = typing.TypeVar("_T") @typing.final class MessageType(int, enums.Enum): """The type of a message.""" DEFAULT = 0 """A normal message.""" RECIPIENT_ADD = 1 """A message to denote a new recipient in a group.""" RECIPIENT_REMOVE = 2 """A message to denote that a recipient left the group.""" CALL = 3 """A message to denote a VoIP call.""" CHANNEL_NAME_CHANGE = 4 """A message to denote that the name of a channel changed.""" CHANNEL_ICON_CHANGE = 5 """A message to denote that the icon of a channel changed.""" CHANNEL_PINNED_MESSAGE = 6 """A message to denote that a message was pinned.""" GUILD_MEMBER_JOIN = 7 """A message to denote that a member joined the guild.""" USER_PREMIUM_GUILD_SUBSCRIPTION = 8 """A message to denote a Nitro subscription.""" USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1 = 9 """A message to denote a tier 1 Nitro subscription.""" USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2 = 10 """A message to denote a tier 2 Nitro subscription.""" USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3 = 11 """A message to denote a tier 3 Nitro subscription.""" CHANNEL_FOLLOW_ADD = 12 """Channel follow add.""" GUILD_DISCOVERY_DISQUALIFIED = 14 """A message to indicate that a guild has been disqualified from discovery.""" GUILD_DISCOVERY_REQUALIFIED = 15 """A message to indicate that a guild has re-qualified for discovery.""" GUILD_DISCOVERY_GRACE_PERIOD_INITIAL_WARNING = 16 """A message to indicate that the grace period before removal from discovery has started.""" GUILD_DISCOVERY_GRACE_PERIOD_FINAL_WARNING = 17 """A message to indicate the final warning before removal from discovery.""" REPLY = 19 """A message that replies to another message.""" CHAT_INPUT = 20 """A message sent to indicate a chat input application command has been executed.""" GUILD_INVITE_REMINDER = 22 """A message sent to remind to invite people to the guild.""" CONTEXT_MENU_COMMAND = 23 """A message sent to indicate a context menu has been executed.""" @typing.final class MessageFlag(enums.Flag): """Additional flags for message options.""" NONE = 0 """None""" CROSSPOSTED = 1 << 0 """This message has been published to subscribed channels via channel following.""" IS_CROSSPOST = 1 << 1 """This message originated from a message in another channel via channel following.""" SUPPRESS_EMBEDS = 1 << 2 """Any embeds on this message should be omitted when serializing the message.""" SOURCE_MESSAGE_DELETED = 1 << 3 """The message this crosspost originated from was deleted via channel following.""" URGENT = 1 << 4 """This message came from the urgent message system.""" EPHEMERAL = 1 << 6 """This message is only visible to the user that invoked the interaction.""" LOADING = 1 << 7 """This message symbolizes that the interaction is 'thinking'.""" @typing.final class MessageActivityType(int, enums.Enum): """The type of a rich presence message activity.""" NONE = 0 """No activity.""" JOIN = 1 """Join an activity.""" SPECTATE = 2 """Spectating something.""" LISTEN = 3 """Listening to something.""" JOIN_REQUEST = 5 """Request to join an activity.""" @attr_extensions.with_copy @attr.define(hash=True, kw_only=True, weakref_slot=False) class Attachment(snowflakes.Unique, files.WebResource): """Represents a file attached to a message. You can use this object in the same way as a `hikari.files.WebResource`, by passing it as an attached file when creating a message, etc. """ id: snowflakes.Snowflake = attr.field(hash=True, repr=True) """The ID of this entity.""" url: str = attr.field(hash=False, eq=False, repr=True) """The source URL of file.""" filename: str = attr.field(hash=False, eq=False, repr=True) """The name of the file.""" media_type: typing.Optional[str] = attr.field(hash=False, eq=False, repr=True) """The media type of the file.""" size: int = attr.field(hash=False, eq=False, repr=True) """The size of the file in bytes.""" proxy_url: str = attr.field(hash=False, eq=False, repr=False) """The proxied URL of file.""" height: typing.Optional[int] = attr.field(hash=False, eq=False, repr=False) """The height of the image (if the file is an image).""" width: typing.Optional[int] = attr.field(hash=False, eq=False, repr=False) """The width of the image (if the file is an image).""" is_ephemeral: bool = attr.field(hash=False, eq=False, repr=True) """Whether this attachment is ephemeral. This is a part of the ephemeral message response interactions feature and indicates that the attachment will be removed after a set period of time (but will exist as long as their relevant message exists). """ def __str__(self) -> str: return self.filename @attr_extensions.with_copy @attr.define(hash=True, kw_only=True, weakref_slot=False) class Reaction: """Represents a reaction in a message.""" count: int = attr.field(eq=False, hash=False, repr=True) """The number of times the emoji has been used to react.""" emoji: typing.Union[emojis_.UnicodeEmoji, emojis_.CustomEmoji] = attr.field(hash=True, repr=True) """The emoji used to react.""" is_me: bool = attr.field(eq=False, hash=False, repr=False) """Whether the current user reacted using this emoji.""" def __str__(self) -> str: return str(self.emoji) @attr_extensions.with_copy @attr.define(hash=False, kw_only=True, weakref_slot=False) class MessageActivity: """Represents the activity of a rich presence-enabled message.""" type: typing.Union[MessageActivityType, int] = attr.field(repr=True) """The type of message activity.""" party_id: typing.Optional[str] = attr.field(repr=True) """The party ID of the message activity.""" @attr_extensions.with_copy @attr.define(hash=False, kw_only=True, weakref_slot=False) class Mentions: """Description of mentions that exist in the message.""" # We refer back to the containing message so that we can provide info about # entities that were not notified, and provide access to cached roles # through this mechanism. _message: PartialMessage = attr.field(repr=False) users: undefined.UndefinedOr[typing.Mapping[snowflakes.Snowflake, users_.User]] = attr.field() """Users who were notified by their mention in the message.""" role_ids: undefined.UndefinedOr[typing.Sequence[snowflakes.Snowflake]] = attr.field() """IDs of roles that were notified by their mention in the message.""" channels: undefined.UndefinedOr[typing.Mapping[snowflakes.Snowflake, channels_.PartialChannel]] = attr.field() """Channel mentions that reference channels in the target crosspost's guild. If the message is not crossposted, this will always be empty. """ everyone: undefined.UndefinedOr[bool] = attr.field() """Whether the message notifies using `@everyone` or `@here`.""" @property def channels_ids(self) -> undefined.UndefinedOr[typing.Sequence[snowflakes.Snowflake]]: if self.channels is undefined.UNDEFINED: return undefined.UNDEFINED return list(self.channels.keys()) @property def user_ids(self) -> undefined.UndefinedOr[typing.Sequence[snowflakes.Snowflake]]: if self.users is undefined.UNDEFINED: return undefined.UNDEFINED return list(self.users.keys()) def get_members(self) -> undefined.UndefinedOr[typing.Mapping[snowflakes.Snowflake, guilds.Member]]: """Discover any cached members notified by this message. If this message was sent in a DM, this will always be empty. .. warning:: This will only return valid results on gateway events. For REST endpoints, this will potentially be empty. This is a limitation of Discord's API, as they do not consistently notify of the ID of the guild a message was sent in. .. note:: If you are using a stateless application such as a stateless bot or a REST-only client, this will always be empty. Furthermore, if you are running a stateful bot and have the GUILD_MEMBERS intent disabled, this will also be empty. Members that are not cached will not appear in this mapping. This means that there is a very small chance that some users provided in `notified_users` may not be present here. """ if self.users is undefined.UNDEFINED: return undefined.UNDEFINED if isinstance(self._message.app, traits.CacheAware) and self._message.guild_id is not None: app = self._message.app guild_id = self._message.guild_id return self._map_cache_maybe_discover( self.users, lambda user_id: app.cache.get_member(guild_id, user_id), ) return {} def get_roles(self) -> undefined.UndefinedOr[typing.Mapping[snowflakes.Snowflake, guilds.Role]]: """Attempt to look up the roles that are notified by this message. If this message was sent in a DM, this will always be empty. .. warning:: This will only return valid results on gateway events. For REST endpoints, this will potentially be empty. This is a limitation of Discord's API, as they do not consistently notify of the ID of the guild a message was sent in. .. note:: If you are using a stateless application such as a stateless bot or a REST-only client, this will always be empty. Furthermore, if you are running a stateful bot and have the GUILD intent disabled, this will also be empty. Roles that are not cached will not appear in this mapping. This means that there is a very small chance that some role IDs provided in `notifies_role_ids` may not be present here. This is a limitation of Discord, again. """ if self.role_ids is undefined.UNDEFINED: return undefined.UNDEFINED if isinstance(self._message.app, traits.CacheAware) and self._message.guild_id is not None: app = self._message.app return self._map_cache_maybe_discover( self.role_ids, app.cache.get_role, ) return {} @staticmethod def _map_cache_maybe_discover( ids: typing.Iterable[snowflakes.Snowflake], cache_call: typing.Callable[[snowflakes.Snowflake], typing.Optional[_T]], ) -> typing.Dict[snowflakes.Snowflake, _T]: results: typing.Dict[snowflakes.Snowflake, _T] = {} for id_ in ids: obj = cache_call(id_) if obj is not None: results[id_] = obj return results @attr_extensions.with_copy @attr.define(hash=False, kw_only=True, weakref_slot=False) class MessageReference: """Represents information about a referenced message. This will be included in crossposted messages, channel follow add message, pin add messages and replies. """ app: traits.RESTAware = attr.field( repr=False, eq=False, hash=False, metadata={attr_extensions.SKIP_DEEP_COPY: True} ) """The client application that models may use for procedures.""" id: typing.Optional[snowflakes.Snowflake] = attr.field(repr=True) """The ID of the original message. This will be `None` for channel follow add messages. This may point to a deleted message. """ channel_id: snowflakes.Snowflake = attr.field(repr=True) """The ID of the channel that the original message originated from.""" guild_id: typing.Optional[snowflakes.Snowflake] = attr.field(repr=True) """The ID of the guild that the message originated from. This will be `None` when the original message is not from a guild. """ @attr_extensions.with_copy @attr.define(hash=True, kw_only=True, weakref_slot=False) class MessageApplication(guilds.PartialApplication): """The representation of an application used in messages.""" cover_image_hash: typing.Optional[str] = attr.field(eq=False, hash=False, repr=False) """The CDN's hash of this application's default rich presence invite cover image.""" @property def cover_image_url(self) -> typing.Optional[files.URL]: """Rich presence cover image URL for this application, if set.""" return self.make_cover_image_url() def make_cover_image_url(self, *, ext: str = "png", size: int = 4096) -> typing.Optional[files.URL]: """Generate the rich presence cover image URL for this application, if set. Parameters ---------- ext : str The extension to use for this URL, defaults to `png`. Supports `png`, `jpeg`, `jpg` and `webp`. size : int The size to set for the URL, defaults to `4096`. Can be any power of two between 16 and 4096. Returns ------- typing.Optional[hikari.files.URL] The URL, or `None` if no cover image exists. Raises ------ ValueError If the size is not an integer power of 2 between 16 and 4096 (inclusive). """ if self.cover_image_hash is None: return None return routes.CDN_APPLICATION_COVER.compile_to_file( urls.CDN_URL, application_id=self.id, hash=self.cover_image_hash, size=size, file_format=ext, ) @attr_extensions.with_copy @attr.define(kw_only=True, repr=True, hash=True, weakref_slot=False) class MessageInteraction: """Representation of information provided for a message from an interaction.""" id: snowflakes.Snowflake = attr.field(hash=True, repr=True) """ID of the interaction this message was sent by.""" type: typing.Union[base_interactions.InteractionType, int] = attr.field(eq=False, repr=True) """The type of interaction this message was created by.""" name: str = attr.field(eq=False, repr=True) """Name of the application command the interaction is tied to.""" user: users_.User = attr.field(eq=False, repr=True) """Object of the user who invoked this interaction.""" @typing.final class ComponentType(int, enums.Enum): """Types of components found within Discord.""" ACTION_ROW = 1 """A non-interactive container component for other types of components. .. note:: As this is a container component it can never be contained within another component and therefore will always be top-level. .. note:: As of writing this can only contain one component type. """ BUTTON = 2 """A button component. .. note:: This cannot be top-level and must be within a container component such as `ComponentType.ACTION_ROW`. """ SELECT_MENU = 3 """A select menu component. .. note:: This cannot be top-level and must be within a container component such as `ComponentType.ACTION_ROW`. """ @typing.final class ButtonStyle(int, enums.Enum): """Enum of the available button styles. More information, such as how these look, can be found at <https://discord.com/developers/docs/interactions/message-components#buttons-button-styles> """ PRIMARY = 1 """A blurple "call to action" button.""" SECONDARY = 2 """A grey neutral button.""" SUCCESS = 3 """A green button.""" DANGER = 4 """A red button (usually indicates a destructive action).""" LINK = 5 """A grey button which navigates to a URL. .. warning:: Unlike the other button styles, clicking this one will not trigger an interaction and custom_id shouldn't be included for this style. """ InteractiveButtonTypesT = typing.Union[ typing.Literal[ButtonStyle.PRIMARY], typing.Literal[1], typing.Literal[ButtonStyle.SECONDARY], typing.Literal[2], typing.Literal[ButtonStyle.SUCCESS], typing.Literal[3], typing.Literal[ButtonStyle.DANGER], typing.Literal[4], ] """Type hints of the `ButtonStyle` values which are valid for interactive buttons. The following values are valid for this: * `ButtonStyle.PRIMARY`/`1` * `ButtonStyle.SECONDARY`/`2` * `ButtonStyle.SUCCESS`/`3` * `ButtonStyle.DANGER`/`4` """ InteractiveButtonTypes: typing.AbstractSet[InteractiveButtonTypesT] = frozenset( [ButtonStyle.PRIMARY, ButtonStyle.SECONDARY, ButtonStyle.SUCCESS, ButtonStyle.DANGER] ) """Set of the `ButtonType`s which are valid for interactive buttons. The following values are included in this: * `ButtonStyle.PRIMARY` * `ButtonStyle.SECONDARY` * `ButtonStyle.SUCCESS` * `ButtonStyle.DANGER` """ @attr.define(kw_only=True, weakref_slot=False) class PartialComponent: """Base class for all component entities.""" type: typing.Union[ComponentType, int] = attr.field() """The type of component this is.""" @attr.define(hash=True, kw_only=True, weakref_slot=False) class ButtonComponent(PartialComponent): """Represents a message button component. .. note:: This is an embedded component and will only ever be found within top-level container components such as `ActionRowComponent`. """ style: typing.Union[ButtonStyle, int] = attr.field(eq=False) """The button's style.""" label: typing.Optional[str] = attr.field(eq=False) """Text label which appears on the button.""" emoji: typing.Optional[emojis_.Emoji] = attr.field(eq=False) """Custom or unicode emoji which appears on the button.""" custom_id: typing.Optional[str] = attr.field(hash=True) """Developer defined identifier for this button (will be <= 100 characters). .. note:: This is required for the following button styles: * `ButtonStyle.PRIMARY` * `ButtonStyle.SECONDARY` * `ButtonStyle.SUCCESS` * `ButtonStyle.DANGER` """ url: typing.Optional[str] = attr.field(eq=False) """Url for `ButtonStyle.LINK` style buttons.""" is_disabled: bool = attr.field(eq=False) """Whether the button is disabled.""" @attr.define(kw_only=True, weakref_slot=False) class SelectMenuOption: """Represents an option for a `SelectMenuComponent`.""" label: str = attr.field() """User-facing name of the option, max 100 characters.""" value: str = attr.field() """Dev-defined value of the option, max 100 characters.""" description: typing.Optional[str] = attr.field() """Optional description of the option, max 100 characters.""" emoji: typing.Optional[emojis_.Emoji] = attr.field(eq=False) """Custom or unicode emoji which appears on the button.""" is_default: bool = attr.field() """Whether this option will be selected by default.""" @attr.define(hash=True, kw_only=True, weakref_slot=False) class SelectMenuComponent(PartialComponent): """Represents a message button component. .. note:: This is an embedded component and will only ever be found within top-level container components such as `ActionRowComponent`. """ custom_id: str = attr.field(hash=True) """Developer defined identifier for this menu (will be <= 100 characters).""" options: typing.Sequence[SelectMenuOption] = attr.field(eq=False) """Sequence of up to 25 of the options set for this menu.""" placeholder: typing.Optional[str] = attr.field(eq=False) """Custom placeholder text shown if nothing is selected, max 100 characters.""" min_values: int = attr.field(eq=False) """The minimum amount of options which must be chosen for this menu. This will be greater than or equal to 0 and will be less than or equal to `SelectMenuComponent.max_values`. """ max_values: int = attr.field(eq=False) """The minimum amount of options which can be chosen for this menu. This will be less than or equal to 25 and will be greater than or equal to `SelectMenuComponent.min_values`. """ is_disabled: bool = attr.field(eq=False) """Whether the select menu is disabled.""" @attr.define(weakref_slot=False) class ActionRowComponent(PartialComponent): """Represents a row of components attached to a message. .. note:: This is a top-level container component and will never be found within another component. """ components: typing.Sequence[PartialComponent] = attr.field() """Sequence of the components contained within this row.""" @typing.overload def __getitem__(self, index: int, /) -> PartialComponent: ... @typing.overload def __getitem__(self, slice_: slice, /) -> typing.Sequence[PartialComponent]: ... def __getitem__( self, index_or_slice: typing.Union[int, slice], / ) -> typing.Union[PartialComponent, typing.Sequence[PartialComponent]]: return self.components[index_or_slice] def __iter__(self) -> typing.Iterator[PartialComponent]: return iter(self.components) def __len__(self) -> int: return len(self.components) @attr_extensions.with_copy @attr.define(kw_only=True, repr=True, eq=False, weakref_slot=False) class PartialMessage(snowflakes.Unique): """A message representation containing partially populated information. This contains arbitrary fields that may be updated in a `MessageUpdateEvent`, but for all other purposes should be treated as being optionally specified. .. warning:: All fields on this model except `channel` and `id` may be set to `hikari.undefined.UNDEFINED` (a singleton) if we have not received information about their state from Discord alongside field nullability. """ app: traits.RESTAware = attr.field( repr=False, eq=False, hash=False, metadata={attr_extensions.SKIP_DEEP_COPY: True} ) """The client application that models may use for procedures.""" id: snowflakes.Snowflake = attr.field(hash=True, repr=True) """The ID of this entity.""" channel_id: snowflakes.Snowflake = attr.field(hash=False, eq=False, repr=True) """The ID of the channel that the message was sent in.""" guild_id: typing.Optional[snowflakes.Snowflake] = attr.field(hash=False, eq=False, repr=True) """The ID of the guild that the message was sent in or `None` for messages out of guilds. .. warning:: This will also be `None` for messages received from the REST API. This is a Discord limitation as stated here <https://github.com/discord/discord-api-docs/issues/912> """ author: undefined.UndefinedOr[users_.User] = attr.field(hash=False, eq=False, repr=True) """The author of this message. This will also be `hikari.undefined.UNDEFINED` in some cases such as when Discord updates a message with an embed URL preview or in messages fetched from the REST API. """ member: undefined.UndefinedNoneOr[guilds.Member] = attr.field(hash=False, eq=False, repr=False) """The member for the author who created the message. If the message is not in a guild, this will be `None`. This will also be `hikari.undefined.UNDEFINED` in some cases such as when Discord updates a message with an embed URL preview. .. warning:: This will also be `None` for messages received from the REST API. This is a Discord limitation as stated here <https://github.com/discord/discord-api-docs/issues/912> """ content: undefined.UndefinedNoneOr[str] = attr.field(hash=False, eq=False, repr=False) """The content of the message.""" timestamp: undefined.UndefinedOr[datetime.datetime] = attr.field(hash=False, eq=False, repr=False) """The timestamp that the message was sent at.""" edited_timestamp: undefined.UndefinedNoneOr[datetime.datetime] = attr.field(hash=False, eq=False, repr=False) """The timestamp that the message was last edited at. Will be `None` if the message wasn't ever edited, or `undefined` if the info is not available. """ is_tts: undefined.UndefinedOr[bool] = attr.field(hash=False, eq=False, repr=False) """Whether the message is a TTS message.""" mentions: Mentions = attr.field(hash=False, eq=False, repr=True) """Description of who is mentioned in a message. .. warning:: If the contents have not mutated and this is a message update event, some fields that are not affected may be empty instead. This is a Discord limitation. """ attachments: undefined.UndefinedOr[typing.Sequence[Attachment]] = attr.field(hash=False, eq=False, repr=False) """The message attachments.""" embeds: undefined.UndefinedOr[typing.Sequence[embeds_.Embed]] = attr.field(hash=False, eq=False, repr=False) """The message embeds.""" reactions: undefined.UndefinedOr[typing.Sequence[Reaction]] = attr.field(hash=False, eq=False, repr=False) """The message reactions.""" is_pinned: undefined.UndefinedOr[bool] = attr.field(hash=False, eq=False, repr=False) """Whether the message is pinned.""" webhook_id: undefined.UndefinedNoneOr[snowflakes.Snowflake] = attr.field(hash=False, eq=False, repr=False) """If the message was generated by a webhook, the webhook's ID.""" type: undefined.UndefinedOr[typing.Union[MessageType, int]] = attr.field(hash=False, eq=False, repr=False) """The message type.""" activity: undefined.UndefinedNoneOr[MessageActivity] = attr.field(hash=False, eq=False, repr=False) """The message activity. .. note:: This will only be provided for messages with rich-presence related chat embeds. """ application: undefined.UndefinedNoneOr[MessageApplication] = attr.field(hash=False, eq=False, repr=False) """The message application. .. note:: This will only be provided for messages with rich-presence related chat embeds. """ message_reference: undefined.UndefinedNoneOr[MessageReference] = attr.field(hash=False, eq=False, repr=False) """The message reference data.""" flags: undefined.UndefinedOr[MessageFlag] = attr.field(hash=False, eq=False, repr=False) """The message flags.""" stickers: undefined.UndefinedOr[typing.Sequence[stickers_.PartialSticker]] = attr.field( hash=False, eq=False, repr=False ) """The stickers sent with this message.""" nonce: undefined.UndefinedNoneOr[str] = attr.field(hash=False, eq=False, repr=False) """The message nonce. This is a string used for validating a message was sent. """ referenced_message: undefined.UndefinedNoneOr[Message] = attr.field(hash=False, eq=False, repr=False) """The message that was replied to. If `type` is `MessageType.REPLY` and `hikari.undefined.UNDEFINED`, Discord's backend didn't attempt to fetch the message, so the status is unknown. If `type` is `MessageType.REPLY` and `None`, the message was deleted. """ interaction: undefined.UndefinedNoneOr[MessageInteraction] = attr.field(hash=False, eq=False, repr=False) """Information about the interaction this message was created by.""" application_id: undefined.UndefinedNoneOr[snowflakes.Snowflake] = attr.field(hash=False, eq=False, repr=False) """ID of the application this message was sent by. .. note:: This will only be provided for interaction messages. """ components: undefined.UndefinedOr[typing.Sequence[PartialComponent]] = attr.field(hash=False, eq=False, repr=False) """Sequence of the components attached to this message.""" def make_link(self, guild: typing.Optional[snowflakes.SnowflakeishOr[guilds.PartialGuild]]) -> str: """Generate a jump link to this message. Other Parameters ---------------- guild : typing.Optional[hikari.snowflakes.SnowflakeishOr[hikari.guilds.PartialGuild]] Object or ID of the guild this message is in or `None` to generate a DM message link. This parameter is necessary since `PartialMessage.guild_id` isn't returned by the REST API regardless of whether the message is in a DM or not. Returns ------- str The jump link to the message. """ guild_id_str = "@me" if guild is None else str(int(guild)) return f"{urls.BASE_URL}/channels/{guild_id_str}/{self.channel_id}/{self.id}" async def fetch_channel(self) -> channels_.PartialChannel: """Fetch the channel this message was created in. Returns ------- hikari.channels.PartialChannel The object of the channel this message belongs to. Raises ------ hikari.errors.BadRequestError If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer. hikari.errors.ForbiddenError If you don't have access to the channel this message belongs to. hikari.errors.NotFoundError If the channel this message was created in does not exist. hikari.errors.UnauthorizedError If you are unauthorized to make the request (invalid/missing token). hikari.errors.RateLimitTooLongError Raised in the event that a rate limit occurs that is longer than `max_rate_limit` when making a request. hikari.errors.RateLimitedError Usually, Hikari will handle and retry on hitting rate-limits automatically. This includes most bucket-specific rate-limits and global rate-limits. In some rare edge cases, however, Discord implements other undocumented rules for rate-limiting, such as limits per attribute. These cannot be detected or handled normally by Hikari due to their undocumented nature, and will trigger this exception if they occur. hikari.errors.InternalServerError If an internal error occurs on Discord while handling the request. """ return await self.app.rest.fetch_channel(self.channel_id) async def edit( self, content: undefined.UndefinedOr[typing.Any] = undefined.UNDEFINED, *, attachment: undefined.UndefinedOr[files.Resourceish] = undefined.UNDEFINED, attachments: undefined.UndefinedOr[typing.Sequence[files.Resourceish]] = undefined.UNDEFINED, component: undefined.UndefinedNoneOr[special_endpoints.ComponentBuilder] = undefined.UNDEFINED, components: undefined.UndefinedNoneOr[ typing.Sequence[special_endpoints.ComponentBuilder] ] = undefined.UNDEFINED, embed: undefined.UndefinedNoneOr[embeds_.Embed] = undefined.UNDEFINED, embeds: undefined.UndefinedNoneOr[typing.Sequence[embeds_.Embed]] = undefined.UNDEFINED, replace_attachments: bool = False, mentions_everyone: undefined.UndefinedOr[bool] = undefined.UNDEFINED, mentions_reply: undefined.UndefinedOr[bool] = undefined.UNDEFINED, user_mentions: undefined.UndefinedOr[ typing.Union[snowflakes.SnowflakeishSequence[users_.PartialUser], bool] ] = undefined.UNDEFINED, role_mentions: undefined.UndefinedOr[ typing.Union[snowflakes.SnowflakeishSequence[guilds.PartialRole], bool] ] = undefined.UNDEFINED, flags: undefined.UndefinedOr[MessageFlag] = undefined.UNDEFINED, ) -> Message: """Edit an existing message in a given channel. .. note:: Mentioning everyone, roles, or users in message edits currently will not send a push notification showing a new mention to people on Discord. It will still highlight in their chat as if they were mentioned, however. .. warning:: If you specify a text `content`, `mentions_everyone`, `mentions_reply`, `user_mentions`, and `role_mentions` will default to `False` as the message will be re-parsed for mentions. This will also occur if only one of the four are specified This is a limitation of Discord's design. If in doubt, specify all four of them each time. .. warning:: If the message was not sent by your user, the only parameter you may provide to this call is the `flags` parameter. Anything else will result in a `hikari.errors.ForbiddenError` being raised. Parameters ---------- content : hikari.undefined.UndefinedOr[typing.Any] If provided, the message content to update with. If `hikari.undefined.UNDEFINED`, then the content will not be changed. If `None`, then the content will be removed. Any other value will be cast to a `str` before sending. If this is a `hikari.embeds.Embed` and neither the `embed` or `embeds` kwargs are provided or if this is a `hikari.files.Resourceish` and neither the `attachment` or `attachments` kwargs are provided, the values will be overwritten. This allows for simpler syntax when sending an embed or an attachment alone. Other Parameters ---------------- attachment : hikari.undefined.UndefinedOr[hikari.files.Resourceish] If provided, the attachment to set on the message. If `hikari.undefined.UNDEFINED`, the previous attachment, if present, is not changed. If this is `None`, then the attachment is removed, if present. Otherwise, the new attachment that was provided will be attached. attachments : hikari.undefined.UndefinedOr[typing.Sequence[hikari.files.Resourceish]] If provided, the attachments to set on the message. If `hikari.undefined.UNDEFINED`, the previous attachments, if present, are not changed. If this is `None`, then the attachments is removed, if present. Otherwise, the new attachments that were provided will be attached. component : hikari.undefined.UndefinedNoneOr[hikari.api.special_endpoints.ComponentBuilder] If provided, builder object of the component to set for this message. This component will replace any previously set components and passing `None` will remove all components. components : hikari.undefined.UndefinedNoneOr[typing.Sequence[hikari.api.special_endpoints.ComponentBuilder]] If provided, a sequence of the component builder objects set for this message. These components will replace any previously set components and passing `None` or an empty sequence will remove all components. embed : hikari.undefined.UndefinedNoneOr[hikari.embeds.Embed] If provided, the embed to set on the message. If `hikari.undefined.UNDEFINED`, the previous embed(s) are not changed. If this is `None` then any present embeds are removed. Otherwise, the new embed that was provided will be used as the replacement. embeds : hikari.undefined.UndefinedNoneOr[typing.Sequence[hikari.embeds.Embed]] If provided, the embeds to set on the message. If `hikari.undefined.UNDEFINED`, the previous embed(s) are not changed. If this is `None` then any present embeds are removed. Otherwise, the new embeds that were provided will be used as the replacement. replace_attachments: bool Whether to replace the attachments with the provided ones. Defaults to `False`. Note this will also overwrite the embed attachments. mentions_everyone : hikari.undefined.UndefinedOr[bool] Sanitation for `@everyone` mentions. If `hikari.undefined.UNDEFINED`, then the previous setting is not changed. If `True`, then `@everyone`/`@here` mentions in the message content will show up as mentioning everyone that can view the chat. mentions_reply : hikari.undefined.UndefinedOr[bool] If provided, whether to mention the author of the message that is being replied to. This will not do anything if this is not a reply message. user_mentions : hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.users.PartialUser], bool]] Sanitation for user mentions. If `hikari.undefined.UNDEFINED`, then the previous setting is not changed. If `True`, all valid user mentions will behave as mentions. If `False`, all valid user mentions will not behave as mentions. You may alternatively pass a collection of `hikari.snowflakes.Snowflake` user IDs, or `hikari.users.PartialUser`-derived objects. role_mentions : hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.guilds.PartialRole], bool]] Sanitation for role mentions. If `hikari.undefined.UNDEFINED`, then the previous setting is not changed. If `True`, all valid role mentions will behave as mentions. If `False`, all valid role mentions will not behave as mentions. You may alternatively pass a collection of `hikari.snowflakes.Snowflake` role IDs, or `hikari.guilds.PartialRole`-derived objects. flags : hikari.undefined.UndefinedOr[hikari.messages.MessageFlag] Optional flags to set on the message. If `hikari.undefined.UNDEFINED`, then nothing is changed. Note that some flags may not be able to be set. Currently the only flags that can be set are `NONE` and `SUPPRESS_EMBEDS`. If you have `MANAGE_MESSAGES` permissions, you can use this call to suppress embeds on another user's message. Returns ------- hikari.messages.Message The edited message. Raises ------ hikari.errors.BadRequestError This may be raised in several discrete situations, such as messages being empty with no embeds; messages with more than 2000 characters in them, embeds that exceed one of the many embed limits; invalid image URLs in embeds. hikari.errors.UnauthorizedError If you are unauthorized to make the request (invalid/missing token). hikari.errors.ForbiddenError If you lack permissions to send messages in the given channel; if you try to change the contents of another user's message; or if you try to edit the flags on another user's message without the permissions to manage messages. hikari.errors.NotFoundError If the channel or message is not found. hikari.errors.InternalServerError If an internal error occurs on Discord while handling the request. """ # noqa: E501 - Line too long return await self.app.rest.edit_message( message=self.id, channel=self.channel_id, content=content, attachment=attachment, attachments=attachments, component=component, components=components, embed=embed, embeds=embeds, replace_attachments=replace_attachments, mentions_everyone=mentions_everyone, mentions_reply=mentions_reply, user_mentions=user_mentions, role_mentions=role_mentions, flags=flags, ) async def respond( self, content: undefined.UndefinedOr[typing.Any] = undefined.UNDEFINED, *, attachment: undefined.UndefinedOr[files.Resourceish] = undefined.UNDEFINED, attachments: undefined.UndefinedOr[typing.Sequence[files.Resourceish]] = undefined.UNDEFINED, component: undefined.UndefinedOr[special_endpoints.ComponentBuilder] = undefined.UNDEFINED, components: undefined.UndefinedOr[typing.Sequence[special_endpoints.ComponentBuilder]] = undefined.UNDEFINED, embed: undefined.UndefinedOr[embeds_.Embed] = undefined.UNDEFINED, embeds: undefined.UndefinedOr[typing.Sequence[embeds_.Embed]] = undefined.UNDEFINED, tts: undefined.UndefinedOr[bool] = undefined.UNDEFINED, reply: typing.Union[ undefined.UndefinedType, snowflakes.SnowflakeishOr[PartialMessage], bool ] = undefined.UNDEFINED, mentions_everyone: undefined.UndefinedOr[bool] = undefined.UNDEFINED, mentions_reply: undefined.UndefinedOr[bool] = undefined.UNDEFINED, user_mentions: undefined.UndefinedOr[ typing.Union[snowflakes.SnowflakeishSequence[users_.PartialUser], bool] ] = undefined.UNDEFINED, role_mentions: undefined.UndefinedOr[ typing.Union[snowflakes.SnowflakeishSequence[guilds.PartialRole], bool] ] = undefined.UNDEFINED, ) -> Message: """Create a message in the channel this message belongs to. Parameters ---------- content : hikari.undefined.UndefinedOr[typing.Any] If provided, the message contents. If `hikari.undefined.UNDEFINED`, then nothing will be sent in the content. Any other value here will be cast to a `str`. If this is a `hikari.embeds.Embed` and no `embed` nor `embeds` kwarg is provided, then this will instead update the embed. This allows for simpler syntax when sending an embed alone. Likewise, if this is a `hikari.files.Resource`, then the content is instead treated as an attachment if no `attachment` and no `attachments` kwargs are provided. Other Parameters ---------------- attachment : hikari.undefined.UndefinedOr[hikari.files.Resourceish], If provided, the message attachment. This can be a resource, or string of a path on your computer or a URL. Attachments can be passed as many different things, to aid in convenience. - If a `pathlib.PurePath` or `str` to a valid URL, the resource at the given URL will be streamed to Discord when sending the message. Subclasses of `hikari.files.WebResource` such as `hikari.files.URL`, `hikari.messages.Attachment`, `hikari.emojis.Emoji`, `EmbedResource`, etc will also be uploaded this way. This will use bit-inception, so only a small percentage of the resource will remain in memory at any one time, thus aiding in scalability. - If a `hikari.files.Bytes` is passed, or a `str` that contains a valid data URI is passed, then this is uploaded with a randomized file name if not provided. - If a `hikari.files.File`, `pathlib.PurePath` or `str` that is an absolute or relative path to a file on your file system is passed, then this resource is uploaded as an attachment using non-blocking code internally and streamed using bit-inception where possible. This depends on the type of `concurrent.futures.Executor` that is being used for the application (default is a thread pool which supports this behaviour). attachments : hikari.undefined.UndefinedOr[typing.Sequence[hikari.files.Resourceish]], If provided, the message attachments. These can be resources, or strings consisting of paths on your computer or URLs. component : hikari.undefined.UndefinedOr[hikari.api.special_endpoints.ComponentBuilder] If provided, builder object of the component to include in this message. components : hikari.undefined.UndefinedOr[typing.Sequence[hikari.api.special_endpoints.ComponentBuilder]] If provided, a sequence of the component builder objects to include in this message. embed : hikari.undefined.UndefinedOr[hikari.embeds.Embed] If provided, the message embed. embeds : hikari.undefined.UndefinedOr[typing.Sequence[hikari.embeds.Embed]] If provided, the message embeds. tts : hikari.undefined.UndefinedOr[bool] If provided, whether the message will be TTS (Text To Speech). reply : typing.Union[hikari.undefined.UndefinedType, hikari.snowflakes.SnowflakeishOr[hikari.messages.PartialMessage], bool] If provided and `True`, reply to this message. If provided and not `bool`, the message to reply to. mentions_everyone : hikari.undefined.UndefinedOr[bool] If provided, whether the message should parse @everyone/@here mentions. mentions_reply : hikari.undefined.UndefinedOr[bool] If provided, whether to mention the author of the message that is being replied to. This will not do anything if not being used with `reply`. user_mentions : hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.users.PartialUser], bool]] If provided, and `True`, all mentions will be parsed. If provided, and `False`, no mentions will be parsed. Alternatively this may be a collection of `hikari.snowflakes.Snowflake`, or `hikari.users.PartialUser` derivatives to enforce mentioning specific users. role_mentions : hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.guilds.PartialRole], bool]] If provided, and `True`, all mentions will be parsed. If provided, and `False`, no mentions will be parsed. Alternatively this may be a collection of `hikari.snowflakes.Snowflake`, or `hikari.guilds.PartialRole` derivatives to enforce mentioning specific roles. Returns ------- hikari.messages.Message The created message. Raises ------ hikari.errors.BadRequestError This may be raised in several discrete situations, such as messages being empty with no attachments or embeds; messages with more than 2000 characters in them, embeds that exceed one of the many embed limits; too many attachments; attachments that are too large; invalid image URLs in embeds; `reply` not found or not in the same channel; too many components. hikari.errors.UnauthorizedError If you are unauthorized to make the request (invalid/missing token). hikari.errors.ForbiddenError If you lack permissions to send messages in the given channel. hikari.errors.NotFoundError If the channel is not found. hikari.errors.InternalServerError If an internal error occurs on Discord while handling the request. ValueError If more than 100 unique objects/entities are passed for `role_mentions` or `user_mentions`. TypeError If both `attachment` and `attachments` are specified. """ # noqa: E501 - Line too long if reply is True: reply = self elif reply is False: reply = undefined.UNDEFINED return await self.app.rest.create_message( channel=self.channel_id, content=content, attachment=attachment, attachments=attachments, component=component, components=components, embed=embed, embeds=embeds, tts=tts, reply=reply, mentions_everyone=mentions_everyone, user_mentions=user_mentions, role_mentions=role_mentions, mentions_reply=mentions_reply, ) async def delete(self) -> None: """Delete this message. Raises ------ hikari.errors.NotFoundError If the channel this message was created in is not found, or if the message has already been deleted. hikari.errors.ForbiddenError If you lack the permissions to delete the message. """ await self.app.rest.delete_message(self.channel_id, self.id) @typing.overload async def add_reaction( self, emoji: typing.Union[str, emojis_.Emoji], ) -> None: ... @typing.overload async def add_reaction( self, emoji: str, emoji_id: snowflakes.SnowflakeishOr[emojis_.CustomEmoji], ) -> None: ... async def add_reaction( self, emoji: typing.Union[str, emojis_.Emoji], emoji_id: undefined.UndefinedOr[snowflakes.SnowflakeishOr[emojis_.CustomEmoji]] = undefined.UNDEFINED, ) -> None: r"""Add a reaction to this message. Parameters ---------- emoji: typing.Union[str, hikari.emojis.Emoji] Object or name of the emoji to react with. Note that if the emoji is an `hikari.emojis.CustomEmoji` and is not from a guild the bot user is in, then this will fail. Other Parameters ---------------- emoji_id : hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]] ID of the custom emoji to react with. This should only be provided when a custom emoji's name is passed for `emoji`. Note that this will fail if the emoji is from a guild the bot isn't in. Examples -------- ```py # Using a unicode emoji. await message.add_reaction("👌") # Using a unicode emoji name. await message.add_reaction("\N{OK HAND SIGN}") # Using the name and id. await message.add_reaction("rooAYAYA", 705837374319493284) # Using an Emoji-derived object. await message.add_reaction(some_emoji_object) ``` Raises ------ hikari.errors.BadRequestError If the emoji is invalid, unknown, or formatted incorrectly. hikari.errors.ForbiddenError If this is the first reaction using this specific emoji on this message and you lack the `ADD_REACTIONS` permission. If you lack `READ_MESSAGE_HISTORY`, this may also raise this error. hikari.errors.NotFoundError If the channel or message is not found, or if the emoji is not found. This will also occur if you try to add an emoji from a guild you are not part of if no one else has previously reacted with the same emoji. """ await self.app.rest.add_reaction(channel=self.channel_id, message=self.id, emoji=emoji, emoji_id=emoji_id) @typing.overload async def remove_reaction( self, emoji: typing.Union[str, emojis_.Emoji], *, user: undefined.UndefinedOr[snowflakes.SnowflakeishOr[users_.PartialUser]] = undefined.UNDEFINED, ) -> None: ... @typing.overload async def remove_reaction( self, emoji: str, emoji_id: snowflakes.SnowflakeishOr[emojis_.CustomEmoji], *, user: undefined.UndefinedOr[snowflakes.SnowflakeishOr[users_.PartialUser]] = undefined.UNDEFINED, ) -> None: ... async def remove_reaction( self, emoji: typing.Union[str, emojis_.Emoji], emoji_id: undefined.UndefinedOr[snowflakes.SnowflakeishOr[emojis_.CustomEmoji]] = undefined.UNDEFINED, *, user: undefined.UndefinedOr[snowflakes.SnowflakeishOr[users_.PartialUser]] = undefined.UNDEFINED, ) -> None: r"""Remove a reaction from this message. Parameters ---------- emoji : typing.Union[str, hikari.emojis.Emoji] Object or name of the emoji to remove the reaction for. Other Parameters ---------------- emoji_id : hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]] ID of the custom emoji to remove the reaction for. This should only be provided when a custom emoji's name is passed for `emoji`. user : hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.users.PartialUser]] The user of the reaction to remove. If unspecified, then the bot's reaction is removed instead. Examples -------- ```py # Using a unicode emoji and removing the bot's reaction from this # reaction. await message.remove_reaction("\N{OK HAND SIGN}") # Using a custom emoji's name and ID to remove a specific user's # reaction from this reaction. await message.remove_reaction("a:Distraction", 745991233939439616, user=some_user) # Using a unicode emoji and removing a specific user from this # reaction. await message.remove_reaction("\N{OK HAND SIGN}", user=some_user) # Using the name and id. await message.add_reaction("rooAYAYA", 705837374319493284) # Using an Emoji object and removing a specific user from this # reaction. await message.remove_reaction(some_emoji_object, user=some_user) ``` Raises ------ hikari.errors.BadRequestError If the emoji is invalid, unknown, or formatted incorrectly. If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer. hikari.errors.ForbiddenError If this is the first reaction using this specific emoji on this message and you lack the `ADD_REACTIONS` permission. If you lack `READ_MESSAGE_HISTORY`, this may also raise this error. If you remove the reaction of another user without `MANAGE_MESSAGES`, this will be raised. hikari.errors.NotFoundError If the channel or message is not found, or if the emoji is not found. """ if user is undefined.UNDEFINED: await self.app.rest.delete_my_reaction( channel=self.channel_id, message=self.id, emoji=emoji, emoji_id=emoji_id ) else: await self.app.rest.delete_reaction( channel=self.channel_id, message=self.id, emoji=emoji, emoji_id=emoji_id, user=user ) @typing.overload async def remove_all_reactions(self) -> None: ... @typing.overload async def remove_all_reactions( self, emoji: typing.Union[str, emojis_.Emoji], ) -> None: ... @typing.overload async def remove_all_reactions( self, emoji: str, emoji_id: snowflakes.SnowflakeishOr[emojis_.CustomEmoji], ) -> None: ... async def remove_all_reactions( self, emoji: undefined.UndefinedOr[typing.Union[str, emojis_.Emoji]] = undefined.UNDEFINED, emoji_id: undefined.UndefinedOr[snowflakes.SnowflakeishOr[emojis_.CustomEmoji]] = undefined.UNDEFINED, ) -> None: r"""Remove all users' reactions for a specific emoji from the message. Other Parameters ---------------- emoji : hikari.undefined.UndefinedOr[typing.Union[str, hikari.emojis.Emoji]] Object or name of the emoji to get the reactions for. If not specified then all reactions are removed. emoji_id : hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]] ID of the custom emoji to react with. This should only be provided when a custom emoji's name is passed for `emoji`. Examples -------- ```py # Using a unicode emoji and removing all 👌 reacts from the message. # reaction. await message.remove_all_reactions("\N{OK HAND SIGN}") # Using the name and id. await message.add_reaction("rooAYAYA", 705837374319493284) # Removing all reactions entirely. await message.remove_all_reactions() ``` Raises ------ hikari.errors.ForbiddenError If you are missing the `MANAGE_MESSAGES` permission, or the permission to view the channel hikari.errors.NotFoundError If the channel or message is not found, or if the emoji is not found. hikari.errors.BadRequestError If the emoji is invalid, unknown, or formatted incorrectly. If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer. """ if emoji is undefined.UNDEFINED: await self.app.rest.delete_all_reactions(channel=self.channel_id, message=self.id) else: await self.app.rest.delete_all_reactions_for_emoji( channel=self.channel_id, message=self.id, emoji=emoji, emoji_id=emoji_id ) @attr.define(hash=True, kw_only=True, weakref_slot=False) class Message(PartialMessage): """Represents a message with all known details.""" author: users_.User = attr.field(hash=False, eq=False, repr=True) """The author of this message.""" member: typing.Optional[guilds.Member] = attr.field(hash=False, eq=False, repr=False) """The member properties for the message's author.""" content: typing.Optional[str] = attr.field(hash=False, eq=False, repr=False) """The content of the message.""" timestamp: datetime.datetime = attr.field(hash=False, eq=False, repr=False) """The timestamp that the message was sent at.""" edited_timestamp: typing.Optional[datetime.datetime] = attr.field(hash=False, eq=False, repr=False) """The timestamp that the message was last edited at. Will be `None` if it wasn't ever edited. """ is_tts: bool = attr.field(hash=False, eq=False, repr=False) """Whether the message is a TTS message.""" attachments: typing.Sequence[Attachment] = attr.field(hash=False, eq=False, repr=False) """The message attachments.""" embeds: typing.Sequence[embeds_.Embed] = attr.field(hash=False, eq=False, repr=False) """The message embeds.""" reactions: typing.Sequence[Reaction] = attr.field(hash=False, eq=False, repr=False) """The message reactions.""" is_pinned: bool = attr.field(hash=False, eq=False, repr=False) """Whether the message is pinned.""" webhook_id: typing.Optional[snowflakes.Snowflake] = attr.field(hash=False, eq=False, repr=False) """If the message was generated by a webhook, the webhook's id.""" type: typing.Union[MessageType, int] = attr.field(hash=False, eq=False, repr=False) """The message type.""" activity: typing.Optional[MessageActivity] = attr.field(hash=False, eq=False, repr=False) """The message activity. .. note:: This will only be provided for messages with rich-presence related chat embeds. """ application: typing.Optional[MessageApplication] = attr.field(hash=False, eq=False, repr=False) """The message application. .. note:: This will only be provided for messages with rich-presence related chat embeds. """ message_reference: typing.Optional[MessageReference] = attr.field(hash=False, eq=False, repr=False) """The message reference data.""" flags: MessageFlag = attr.field(hash=False, eq=False, repr=True) """The message flags.""" stickers: typing.Sequence[stickers_.PartialSticker] = attr.field(hash=False, eq=False, repr=False) """The stickers sent with this message.""" nonce: typing.Optional[str] = attr.field(hash=False, eq=False, repr=False) """The message nonce. This is a string used for validating a message was sent.""" referenced_message: typing.Optional[Message] = attr.field(hash=False, eq=False, repr=False) """The message that was replied to.""" interaction: typing.Optional[MessageInteraction] = attr.field(hash=False, eq=False, repr=False) """Information about the interaction this message was created by.""" application_id: typing.Optional[snowflakes.Snowflake] = attr.field(hash=False, eq=False, repr=False) """ID of the application this message was sent by. .. note:: This will only be provided for interaction messages. """ components: typing.Sequence[PartialComponent] = attr.field(hash=False, eq=False, repr=False) """Sequence of the components attached to this message."""
View Source
@attr.define(weakref_slot=False) class ActionRowComponent(PartialComponent): """Represents a row of components attached to a message. .. note:: This is a top-level container component and will never be found within another component. """ components: typing.Sequence[PartialComponent] = attr.field() """Sequence of the components contained within this row.""" @typing.overload def __getitem__(self, index: int, /) -> PartialComponent: ... @typing.overload def __getitem__(self, slice_: slice, /) -> typing.Sequence[PartialComponent]: ... def __getitem__( self, index_or_slice: typing.Union[int, slice], / ) -> typing.Union[PartialComponent, typing.Sequence[PartialComponent]]: return self.components[index_or_slice] def __iter__(self) -> typing.Iterator[PartialComponent]: return iter(self.components) def __len__(self) -> int: return len(self.components)
Represents a row of components attached to a message.
Note: This is a top-level container component and will never be found within another component.
Variables and properties
Sequence of the components contained within this row.
The type of component this is.
Methods
self,
components: Sequence[hikari.messages.PartialComponent],
*,
type: Union[hikari.messages.ComponentType, int]
):
View Source
def __init__(self, components, *, type): self.type = type self.components = components
Method generated by attrs for class ActionRowComponent.
View Source
@attr_extensions.with_copy @attr.define(hash=True, kw_only=True, weakref_slot=False) class Attachment(snowflakes.Unique, files.WebResource): """Represents a file attached to a message. You can use this object in the same way as a `hikari.files.WebResource`, by passing it as an attached file when creating a message, etc. """ id: snowflakes.Snowflake = attr.field(hash=True, repr=True) """The ID of this entity.""" url: str = attr.field(hash=False, eq=False, repr=True) """The source URL of file.""" filename: str = attr.field(hash=False, eq=False, repr=True) """The name of the file.""" media_type: typing.Optional[str] = attr.field(hash=False, eq=False, repr=True) """The media type of the file.""" size: int = attr.field(hash=False, eq=False, repr=True) """The size of the file in bytes.""" proxy_url: str = attr.field(hash=False, eq=False, repr=False) """The proxied URL of file.""" height: typing.Optional[int] = attr.field(hash=False, eq=False, repr=False) """The height of the image (if the file is an image).""" width: typing.Optional[int] = attr.field(hash=False, eq=False, repr=False) """The width of the image (if the file is an image).""" is_ephemeral: bool = attr.field(hash=False, eq=False, repr=True) """Whether this attachment is ephemeral. This is a part of the ephemeral message response interactions feature and indicates that the attachment will be removed after a set period of time (but will exist as long as their relevant message exists). """ def __str__(self) -> str: return self.filename
Represents a file attached to a message.
You can use this object in the same way as a hikari.files.WebResource
, by passing it as an attached file when creating a message, etc.
Variables and properties
When the object was created.
File extension, if there is one.
The name of the file.
The height of the image (if the file is an image).
The ID of this entity.
Whether this attachment is ephemeral.
This is a part of the ephemeral message response interactions feature and indicates that the attachment will be removed after a set period of time (but will exist as long as their relevant message exists).
The media type of the file.
The proxied URL of file.
The size of the file in bytes.
The source URL of file.
The width of the image (if the file is an image).
Methods
self,
*,
id: hikari.snowflakes.Snowflake,
url: str,
filename: str,
media_type: Optional[str],
size: int,
proxy_url: str,
height: Optional[int],
width: Optional[int],
is_ephemeral: bool
):
View Source
def __init__(self, *, id, url, filename, media_type, size, proxy_url, height, width, is_ephemeral): self.id = id self.url = url self.filename = filename self.media_type = media_type self.size = size self.proxy_url = proxy_url self.height = height self.width = width self.is_ephemeral = is_ephemeral
Method generated by attrs for class Attachment.
View Source
async def read( self, *, executor: typing.Optional[concurrent.futures.Executor] = None, ) -> bytes: """Read the entire resource at once into memory. ```py data = await resource.read(...) # ^-- This is a shortcut for the following --v async with resource.stream(...) as reader: data = await reader.read() ``` .. warning:: If you simply wish to re-upload this resource to Discord via any endpoint in Hikari, you should opt to just pass this resource object directly. This way, Hikari can perform byte inception, which significantly reduces the memory usage for your bot as it grows larger. Parameters ---------- executor : typing.Optional[concurrent.futures.Executor] The executor to run in for blocking operations. If `None`, then the default executor is used for the current event loop. Returns ------- bytes The entire resource. """ async with self.stream(executor=executor) as reader: return await reader.read()
Read the entire resource at once into memory.
data = await resource.read(...)
# ^-- This is a shortcut for the following --v
async with resource.stream(...) as reader:
data = await reader.read()
Warning: If you simply wish to re-upload this resource to Discord via any endpoint in Hikari, you should opt to just pass this resource object directly. This way, Hikari can perform byte inception, which significantly reduces the memory usage for your bot as it grows larger.
Parameters
- executor (typing.Optional[concurrent.futures.Executor]): The executor to run in for blocking operations. If
None
, then the default executor is used for the current event loop.
Returns
- bytes: The entire resource.
self,
*,
executor: Optional[concurrent.futures._base.Executor] = None,
head_only: bool = False
) -> hikari.files.AsyncReaderContextManager[hikari.files.WebReader]:
View Source
def stream( self, *, executor: typing.Optional[concurrent.futures.Executor] = None, head_only: bool = False, ) -> AsyncReaderContextManager[WebReader]: """Start streaming the content into memory by downloading it. You can use this to fetch the entire resource, parts of the resource, or just to view any metadata that may be provided. Parameters ---------- executor : typing.Optional[concurrent.futures.Executor] Not used. Provided only to match the underlying interface. head_only : bool Defaults to `False`. If `True`, then the implementation may only retrieve HEAD information if supported. This currently only has any effect for web requests. Examples -------- Downloading an entire resource at once into memory: ```py async with obj.stream() as stream: data = await stream.read() ``` Checking the metadata: ```py async with obj.stream() as stream: mimetype = stream.mimetype if mimetype is None: ... elif mimetype not in whitelisted_mimetypes: ... else: ... ``` Fetching the data-uri of a resource: ```py async with obj.stream() as stream: data_uri = await stream.data_uri() ``` Returns ------- AsyncReaderContextManager[WebReader] An async context manager that when entered, produces the data stream. Raises ------ hikari.errors.BadRequestError If a 400 is returned. hikari.errors.UnauthorizedError If a 401 is returned. hikari.errors.ForbiddenError If a 403 is returned. hikari.errors.NotFoundError If a 404 is returned. hikari.errors.ClientHTTPResponseError If any other 4xx is returned. hikari.errors.InternalServerError If any other 5xx is returned. hikari.errors.HTTPResponseError If any other unexpected response code is returned. """ return _WebReaderAsyncReaderContextManagerImpl(self, head_only)
Start streaming the content into memory by downloading it.
You can use this to fetch the entire resource, parts of the resource, or just to view any metadata that may be provided.
Parameters
- executor (typing.Optional[concurrent.futures.Executor]): Not used. Provided only to match the underlying interface.
- head_only (bool): Defaults to
False
. IfTrue
, then the implementation may only retrieve HEAD information if supported. This currently only has any effect for web requests.
Examples
Downloading an entire resource at once into memory:
async with obj.stream() as stream:
data = await stream.read()
Checking the metadata:
async with obj.stream() as stream:
mimetype = stream.mimetype
if mimetype is None:
...
elif mimetype not in whitelisted_mimetypes:
...
else:
...
Fetching the data-uri of a resource:
async with obj.stream() as stream:
data_uri = await stream.data_uri()
Returns
- AsyncReaderContextManager[WebReader]: An async context manager that when entered, produces the data stream.
Raises
- hikari.errors.BadRequestError: If a 400 is returned.
- hikari.errors.UnauthorizedError: If a 401 is returned.
- hikari.errors.ForbiddenError: If a 403 is returned.
- hikari.errors.NotFoundError: If a 404 is returned.
- hikari.errors.ClientHTTPResponseError: If any other 4xx is returned.
- hikari.errors.InternalServerError: If any other 5xx is returned.
- hikari.errors.HTTPResponseError: If any other unexpected response code is returned.
View Source
@attr.define(hash=True, kw_only=True, weakref_slot=False) class ButtonComponent(PartialComponent): """Represents a message button component. .. note:: This is an embedded component and will only ever be found within top-level container components such as `ActionRowComponent`. """ style: typing.Union[ButtonStyle, int] = attr.field(eq=False) """The button's style.""" label: typing.Optional[str] = attr.field(eq=False) """Text label which appears on the button.""" emoji: typing.Optional[emojis_.Emoji] = attr.field(eq=False) """Custom or unicode emoji which appears on the button.""" custom_id: typing.Optional[str] = attr.field(hash=True) """Developer defined identifier for this button (will be <= 100 characters). .. note:: This is required for the following button styles: * `ButtonStyle.PRIMARY` * `ButtonStyle.SECONDARY` * `ButtonStyle.SUCCESS` * `ButtonStyle.DANGER` """ url: typing.Optional[str] = attr.field(eq=False) """Url for `ButtonStyle.LINK` style buttons.""" is_disabled: bool = attr.field(eq=False) """Whether the button is disabled."""
Represents a message button component.
Note: This is an embedded component and will only ever be found within top-level container components such as ActionRowComponent
.
Variables and properties
Developer defined identifier for this button (will be <= 100 characters).
Note: This is required for the following button styles:
Custom or unicode emoji which appears on the button.
Whether the button is disabled.
Text label which appears on the button.
The button's style.
The type of component this is.
Url for ButtonStyle.LINK
style buttons.
Methods
self,
*,
type: Union[hikari.messages.ComponentType, int],
style: Union[hikari.messages.ButtonStyle, int],
label: Optional[str],
emoji: Optional[hikari.emojis.Emoji],
custom_id: Optional[str],
url: Optional[str],
is_disabled: bool
):
View Source
def __init__(self, *, type, style, label, emoji, custom_id, url, is_disabled): self.type = type self.style = style self.label = label self.emoji = emoji self.custom_id = custom_id self.url = url self.is_disabled = is_disabled
Method generated by attrs for class ButtonComponent.
View Source
@typing.final class ButtonStyle(int, enums.Enum): """Enum of the available button styles. More information, such as how these look, can be found at <https://discord.com/developers/docs/interactions/message-components#buttons-button-styles> """ PRIMARY = 1 """A blurple "call to action" button.""" SECONDARY = 2 """A grey neutral button.""" SUCCESS = 3 """A green button.""" DANGER = 4 """A red button (usually indicates a destructive action).""" LINK = 5 """A grey button which navigates to a URL. .. warning:: Unlike the other button styles, clicking this one will not trigger an interaction and custom_id shouldn't be included for this style. """
Enum of the available button styles.
More information, such as how these look, can be found at https://discord.com/developers/docs/interactions/message-components#buttons-button-styles
Variables and properties
A red button (usually indicates a destructive action).
A grey button which navigates to a URL.
Warning: Unlike the other button styles, clicking this one will not trigger an interaction and custom_id shouldn't be included for this style.
A blurple "call to action" button.
A grey neutral button.
A green button.
the denominator of a rational number in lowest terms
the imaginary part of a complex number
Return the name of the enum member as a str
.
the numerator of a rational number in lowest terms
the real part of a complex number
Return the value of the enum member.
Methods
View Source
def __call__(cls, value: typing.Any) -> typing.Any: """Cast a value to the enum, returning the raw value that was passed if value not found.""" try: return cls._value_to_member_map_[value] except KeyError: # If we can't find the value, just return what got casted in return value
Cast a value to the enum, returning the raw value that was passed if value not found.
Return integer ratio.
Return a pair of integers, whose ratio is exactly equal to the original int and with a positive denominator.
>>> (10).as_integer_ratio()
(10, 1)
>>> (-10).as_integer_ratio()
(-10, 1)
>>> (0).as_integer_ratio()
(0, 1)
Number of bits necessary to represent self in binary.
>>> bin(37)
'0b100101'
>>> (37).bit_length()
6
Returns self, the complex conjugate of any int.
Return the integer represented by the given array of bytes.
bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder' as the byte order value. signed Indicates whether two's complement is used to represent the integer.
Return an array of bytes representing an integer.
length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder' as the byte order value. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
View Source
@typing.final class ComponentType(int, enums.Enum): """Types of components found within Discord.""" ACTION_ROW = 1 """A non-interactive container component for other types of components. .. note:: As this is a container component it can never be contained within another component and therefore will always be top-level. .. note:: As of writing this can only contain one component type. """ BUTTON = 2 """A button component. .. note:: This cannot be top-level and must be within a container component such as `ComponentType.ACTION_ROW`. """ SELECT_MENU = 3 """A select menu component. .. note:: This cannot be top-level and must be within a container component such as `ComponentType.ACTION_ROW`. """
Types of components found within Discord.
Variables and properties
A non-interactive container component for other types of components.
Note: As this is a container component it can never be contained within another component and therefore will always be top-level.
Note: As of writing this can only contain one component type.
A button component.
Note: This cannot be top-level and must be within a container component such as ComponentType.ACTION_ROW
.
A select menu component.
Note: This cannot be top-level and must be within a container component such as ComponentType.ACTION_ROW
.
the denominator of a rational number in lowest terms
the imaginary part of a complex number
Return the name of the enum member as a str
.
the numerator of a rational number in lowest terms
the real part of a complex number
Return the value of the enum member.
Methods
View Source
def __call__(cls, value: typing.Any) -> typing.Any: """Cast a value to the enum, returning the raw value that was passed if value not found.""" try: return cls._value_to_member_map_[value] except KeyError: # If we can't find the value, just return what got casted in return value
Cast a value to the enum, returning the raw value that was passed if value not found.
Return integer ratio.
Return a pair of integers, whose ratio is exactly equal to the original int and with a positive denominator.
>>> (10).as_integer_ratio()
(10, 1)
>>> (-10).as_integer_ratio()
(-10, 1)
>>> (0).as_integer_ratio()
(0, 1)
Number of bits necessary to represent self in binary.
>>> bin(37)
'0b100101'
>>> (37).bit_length()
6
Returns self, the complex conjugate of any int.
Return the integer represented by the given array of bytes.
bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder' as the byte order value. signed Indicates whether two's complement is used to represent the integer.
Return an array of bytes representing an integer.
length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder' as the byte order value. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
Set of the ButtonType
s which are valid for interactive buttons.
The following values are included in this:
Type hints of the ButtonStyle
values which are valid for interactive buttons.
The following values are valid for this:
View Source
@attr_extensions.with_copy @attr.define(hash=False, kw_only=True, weakref_slot=False) class Mentions: """Description of mentions that exist in the message.""" # We refer back to the containing message so that we can provide info about # entities that were not notified, and provide access to cached roles # through this mechanism. _message: PartialMessage = attr.field(repr=False) users: undefined.UndefinedOr[typing.Mapping[snowflakes.Snowflake, users_.User]] = attr.field() """Users who were notified by their mention in the message.""" role_ids: undefined.UndefinedOr[typing.Sequence[snowflakes.Snowflake]] = attr.field() """IDs of roles that were notified by their mention in the message.""" channels: undefined.UndefinedOr[typing.Mapping[snowflakes.Snowflake, channels_.PartialChannel]] = attr.field() """Channel mentions that reference channels in the target crosspost's guild. If the message is not crossposted, this will always be empty. """ everyone: undefined.UndefinedOr[bool] = attr.field() """Whether the message notifies using `@everyone` or `@here`.""" @property def channels_ids(self) -> undefined.UndefinedOr[typing.Sequence[snowflakes.Snowflake]]: if self.channels is undefined.UNDEFINED: return undefined.UNDEFINED return list(self.channels.keys()) @property def user_ids(self) -> undefined.UndefinedOr[typing.Sequence[snowflakes.Snowflake]]: if self.users is undefined.UNDEFINED: return undefined.UNDEFINED return list(self.users.keys()) def get_members(self) -> undefined.UndefinedOr[typing.Mapping[snowflakes.Snowflake, guilds.Member]]: """Discover any cached members notified by this message. If this message was sent in a DM, this will always be empty. .. warning:: This will only return valid results on gateway events. For REST endpoints, this will potentially be empty. This is a limitation of Discord's API, as they do not consistently notify of the ID of the guild a message was sent in. .. note:: If you are using a stateless application such as a stateless bot or a REST-only client, this will always be empty. Furthermore, if you are running a stateful bot and have the GUILD_MEMBERS intent disabled, this will also be empty. Members that are not cached will not appear in this mapping. This means that there is a very small chance that some users provided in `notified_users` may not be present here. """ if self.users is undefined.UNDEFINED: return undefined.UNDEFINED if isinstance(self._message.app, traits.CacheAware) and self._message.guild_id is not None: app = self._message.app guild_id = self._message.guild_id return self._map_cache_maybe_discover( self.users, lambda user_id: app.cache.get_member(guild_id, user_id), ) return {} def get_roles(self) -> undefined.UndefinedOr[typing.Mapping[snowflakes.Snowflake, guilds.Role]]: """Attempt to look up the roles that are notified by this message. If this message was sent in a DM, this will always be empty. .. warning:: This will only return valid results on gateway events. For REST endpoints, this will potentially be empty. This is a limitation of Discord's API, as they do not consistently notify of the ID of the guild a message was sent in. .. note:: If you are using a stateless application such as a stateless bot or a REST-only client, this will always be empty. Furthermore, if you are running a stateful bot and have the GUILD intent disabled, this will also be empty. Roles that are not cached will not appear in this mapping. This means that there is a very small chance that some role IDs provided in `notifies_role_ids` may not be present here. This is a limitation of Discord, again. """ if self.role_ids is undefined.UNDEFINED: return undefined.UNDEFINED if isinstance(self._message.app, traits.CacheAware) and self._message.guild_id is not None: app = self._message.app return self._map_cache_maybe_discover( self.role_ids, app.cache.get_role, ) return {} @staticmethod def _map_cache_maybe_discover( ids: typing.Iterable[snowflakes.Snowflake], cache_call: typing.Callable[[snowflakes.Snowflake], typing.Optional[_T]], ) -> typing.Dict[snowflakes.Snowflake, _T]: results: typing.Dict[snowflakes.Snowflake, _T] = {} for id_ in ids: obj = cache_call(id_) if obj is not None: results[id_] = obj return results
Description of mentions that exist in the message.
Variables and properties
Channel mentions that reference channels in the target crosspost's guild.
If the message is not crossposted, this will always be empty.
Whether the message notifies using @everyone
or @here
.
IDs of roles that were notified by their mention in the message.
Users who were notified by their mention in the message.
Methods
self,
*,
message: hikari.messages.PartialMessage,
users: Union[Mapping[hikari.snowflakes.Snowflake, hikari.users.User], hikari.undefined.UndefinedType],
role_ids: Union[Sequence[hikari.snowflakes.Snowflake], hikari.undefined.UndefinedType],
channels: Union[Mapping[hikari.snowflakes.Snowflake, hikari.channels.PartialChannel], hikari.undefined.UndefinedType],
everyone: Union[bool, hikari.undefined.UndefinedType]
):
View Source
def __init__(self, *, message, users, role_ids, channels, everyone): self._message = message self.users = users self.role_ids = role_ids self.channels = channels self.everyone = everyone
Method generated by attrs for class Mentions.
self
) -> Union[Mapping[hikari.snowflakes.Snowflake, hikari.guilds.Member], hikari.undefined.UndefinedType]:
View Source
def get_members(self) -> undefined.UndefinedOr[typing.Mapping[snowflakes.Snowflake, guilds.Member]]: """Discover any cached members notified by this message. If this message was sent in a DM, this will always be empty. .. warning:: This will only return valid results on gateway events. For REST endpoints, this will potentially be empty. This is a limitation of Discord's API, as they do not consistently notify of the ID of the guild a message was sent in. .. note:: If you are using a stateless application such as a stateless bot or a REST-only client, this will always be empty. Furthermore, if you are running a stateful bot and have the GUILD_MEMBERS intent disabled, this will also be empty. Members that are not cached will not appear in this mapping. This means that there is a very small chance that some users provided in `notified_users` may not be present here. """ if self.users is undefined.UNDEFINED: return undefined.UNDEFINED if isinstance(self._message.app, traits.CacheAware) and self._message.guild_id is not None: app = self._message.app guild_id = self._message.guild_id return self._map_cache_maybe_discover( self.users, lambda user_id: app.cache.get_member(guild_id, user_id), ) return {}
Discover any cached members notified by this message.
If this message was sent in a DM, this will always be empty.
Warning: This will only return valid results on gateway events. For REST endpoints, this will potentially be empty. This is a limitation of Discord's API, as they do not consistently notify of the ID of the guild a message was sent in.
Note: If you are using a stateless application such as a stateless bot or a REST-only client, this will always be empty. Furthermore, if you are running a stateful bot and have the GUILD_MEMBERS intent disabled, this will also be empty.
Members that are not cached will not appear in this mapping. This means that there is a very small chance that some users provided in notified_users
may not be present here.
self
) -> Union[Mapping[hikari.snowflakes.Snowflake, hikari.guilds.Role], hikari.undefined.UndefinedType]:
View Source
def get_roles(self) -> undefined.UndefinedOr[typing.Mapping[snowflakes.Snowflake, guilds.Role]]: """Attempt to look up the roles that are notified by this message. If this message was sent in a DM, this will always be empty. .. warning:: This will only return valid results on gateway events. For REST endpoints, this will potentially be empty. This is a limitation of Discord's API, as they do not consistently notify of the ID of the guild a message was sent in. .. note:: If you are using a stateless application such as a stateless bot or a REST-only client, this will always be empty. Furthermore, if you are running a stateful bot and have the GUILD intent disabled, this will also be empty. Roles that are not cached will not appear in this mapping. This means that there is a very small chance that some role IDs provided in `notifies_role_ids` may not be present here. This is a limitation of Discord, again. """ if self.role_ids is undefined.UNDEFINED: return undefined.UNDEFINED if isinstance(self._message.app, traits.CacheAware) and self._message.guild_id is not None: app = self._message.app return self._map_cache_maybe_discover( self.role_ids, app.cache.get_role, ) return {}
Attempt to look up the roles that are notified by this message.
If this message was sent in a DM, this will always be empty.
Warning: This will only return valid results on gateway events. For REST endpoints, this will potentially be empty. This is a limitation of Discord's API, as they do not consistently notify of the ID of the guild a message was sent in.
Note: If you are using a stateless application such as a stateless bot or a REST-only client, this will always be empty. Furthermore, if you are running a stateful bot and have the GUILD intent disabled, this will also be empty.
Roles that are not cached will not appear in this mapping. This means that there is a very small chance that some role IDs provided in notifies_role_ids
may not be present here. This is a limitation of Discord, again.
View Source
@attr.define(hash=True, kw_only=True, weakref_slot=False) class Message(PartialMessage): """Represents a message with all known details.""" author: users_.User = attr.field(hash=False, eq=False, repr=True) """The author of this message.""" member: typing.Optional[guilds.Member] = attr.field(hash=False, eq=False, repr=False) """The member properties for the message's author.""" content: typing.Optional[str] = attr.field(hash=False, eq=False, repr=False) """The content of the message.""" timestamp: datetime.datetime = attr.field(hash=False, eq=False, repr=False) """The timestamp that the message was sent at.""" edited_timestamp: typing.Optional[datetime.datetime] = attr.field(hash=False, eq=False, repr=False) """The timestamp that the message was last edited at. Will be `None` if it wasn't ever edited. """ is_tts: bool = attr.field(hash=False, eq=False, repr=False) """Whether the message is a TTS message.""" attachments: typing.Sequence[Attachment] = attr.field(hash=False, eq=False, repr=False) """The message attachments.""" embeds: typing.Sequence[embeds_.Embed] = attr.field(hash=False, eq=False, repr=False) """The message embeds.""" reactions: typing.Sequence[Reaction] = attr.field(hash=False, eq=False, repr=False) """The message reactions.""" is_pinned: bool = attr.field(hash=False, eq=False, repr=False) """Whether the message is pinned.""" webhook_id: typing.Optional[snowflakes.Snowflake] = attr.field(hash=False, eq=False, repr=False) """If the message was generated by a webhook, the webhook's id.""" type: typing.Union[MessageType, int] = attr.field(hash=False, eq=False, repr=False) """The message type.""" activity: typing.Optional[MessageActivity] = attr.field(hash=False, eq=False, repr=False) """The message activity. .. note:: This will only be provided for messages with rich-presence related chat embeds. """ application: typing.Optional[MessageApplication] = attr.field(hash=False, eq=False, repr=False) """The message application. .. note:: This will only be provided for messages with rich-presence related chat embeds. """ message_reference: typing.Optional[MessageReference] = attr.field(hash=False, eq=False, repr=False) """The message reference data.""" flags: MessageFlag = attr.field(hash=False, eq=False, repr=True) """The message flags.""" stickers: typing.Sequence[stickers_.PartialSticker] = attr.field(hash=False, eq=False, repr=False) """The stickers sent with this message.""" nonce: typing.Optional[str] = attr.field(hash=False, eq=False, repr=False) """The message nonce. This is a string used for validating a message was sent.""" referenced_message: typing.Optional[Message] = attr.field(hash=False, eq=False, repr=False) """The message that was replied to.""" interaction: typing.Optional[MessageInteraction] = attr.field(hash=False, eq=False, repr=False) """Information about the interaction this message was created by.""" application_id: typing.Optional[snowflakes.Snowflake] = attr.field(hash=False, eq=False, repr=False) """ID of the application this message was sent by. .. note:: This will only be provided for interaction messages. """ components: typing.Sequence[PartialComponent] = attr.field(hash=False, eq=False, repr=False) """Sequence of the components attached to this message."""
Represents a message with all known details.
Variables and properties
The message activity.
Note: This will only be provided for messages with rich-presence related chat embeds.
The client application that models may use for procedures.
The message application.
Note: This will only be provided for messages with rich-presence related chat embeds.
ID of the application this message was sent by.
Note: This will only be provided for interaction messages.
The message attachments.
The ID of the channel that the message was sent in.
Sequence of the components attached to this message.
The content of the message.
When the object was created.
The timestamp that the message was last edited at.
Will be None
if it wasn't ever edited.
The message embeds.
The message flags.
The ID of the guild that the message was sent in or None
for messages out of guilds.
Warning: This will also be None
for messages received from the REST API. This is a Discord limitation as stated here https://github.com/discord/discord-api-docs/issues/912
The ID of this entity.
Information about the interaction this message was created by.
Whether the message is pinned.
Whether the message is a TTS message.
The member properties for the message's author.
Description of who is mentioned in a message.
Warning: If the contents have not mutated and this is a message update event, some fields that are not affected may be empty instead.
This is a Discord limitation.
The message reference data.
The message nonce. This is a string used for validating a message was sent.
The message reactions.
The message that was replied to.
The stickers sent with this message.
The timestamp that the message was sent at.
The message type.
If the message was generated by a webhook, the webhook's id.
Methods
self,
*,
app: hikari.traits.RESTAware,
id: hikari.snowflakes.Snowflake,
channel_id: hikari.snowflakes.Snowflake,
guild_id: Optional[hikari.snowflakes.Snowflake],
mentions: hikari.messages.Mentions,
author: hikari.users.User,
member: Optional[hikari.guilds.Member],
content: Optional[str],
timestamp: datetime.datetime,
edited_timestamp: Optional[datetime.datetime],
is_tts: bool,
attachments: Sequence[hikari.messages.Attachment],
embeds: Sequence[hikari.embeds.Embed],
reactions: Sequence[hikari.messages.Reaction],
is_pinned: bool,
webhook_id: Optional[hikari.snowflakes.Snowflake],
type: Union[hikari.messages.MessageType, int],
activity: Optional[hikari.messages.MessageActivity],
application: Optional[hikari.messages.MessageApplication],
message_reference: Optional[hikari.messages.MessageReference],
flags: hikari.messages.MessageFlag,
stickers: Sequence[hikari.stickers.PartialSticker],
nonce: Optional[str],
referenced_message: Optional[hikari.messages.Message],
interaction: Optional[hikari.messages.MessageInteraction],
application_id: Optional[hikari.snowflakes.Snowflake],
components: Sequence[hikari.messages.PartialComponent]
):
View Source
def __init__(self, *, app, id, channel_id, guild_id, mentions, author, member, content, timestamp, edited_timestamp, is_tts, attachments, embeds, reactions, is_pinned, webhook_id, type, activity, application, message_reference, flags, stickers, nonce, referenced_message, interaction, application_id, components): self.app = app self.id = id self.channel_id = channel_id self.guild_id = guild_id self.mentions = mentions self.author = author self.member = member self.content = content self.timestamp = timestamp self.edited_timestamp = edited_timestamp self.is_tts = is_tts self.attachments = attachments self.embeds = embeds self.reactions = reactions self.is_pinned = is_pinned self.webhook_id = webhook_id self.type = type self.activity = activity self.application = application self.message_reference = message_reference self.flags = flags self.stickers = stickers self.nonce = nonce self.referenced_message = referenced_message self.interaction = interaction self.application_id = application_id self.components = components
Method generated by attrs for class Message.
self,
emoji: Union[str, hikari.emojis.Emoji],
emoji_id: Union[hikari.emojis.CustomEmoji, hikari.snowflakes.Snowflake, int, hikari.undefined.UndefinedType] = UNDEFINED
) -> None:
View Source
async def add_reaction( self, emoji: typing.Union[str, emojis_.Emoji], emoji_id: undefined.UndefinedOr[snowflakes.SnowflakeishOr[emojis_.CustomEmoji]] = undefined.UNDEFINED, ) -> None: r"""Add a reaction to this message. Parameters ---------- emoji: typing.Union[str, hikari.emojis.Emoji] Object or name of the emoji to react with. Note that if the emoji is an `hikari.emojis.CustomEmoji` and is not from a guild the bot user is in, then this will fail. Other Parameters ---------------- emoji_id : hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]] ID of the custom emoji to react with. This should only be provided when a custom emoji's name is passed for `emoji`. Note that this will fail if the emoji is from a guild the bot isn't in. Examples -------- ```py # Using a unicode emoji. await message.add_reaction("👌") # Using a unicode emoji name. await message.add_reaction("\N{OK HAND SIGN}") # Using the name and id. await message.add_reaction("rooAYAYA", 705837374319493284) # Using an Emoji-derived object. await message.add_reaction(some_emoji_object) ``` Raises ------ hikari.errors.BadRequestError If the emoji is invalid, unknown, or formatted incorrectly. hikari.errors.ForbiddenError If this is the first reaction using this specific emoji on this message and you lack the `ADD_REACTIONS` permission. If you lack `READ_MESSAGE_HISTORY`, this may also raise this error. hikari.errors.NotFoundError If the channel or message is not found, or if the emoji is not found. This will also occur if you try to add an emoji from a guild you are not part of if no one else has previously reacted with the same emoji. """ await self.app.rest.add_reaction(channel=self.channel_id, message=self.id, emoji=emoji, emoji_id=emoji_id)
Add a reaction to this message.
Parameters
emoji (typing.Union[str, hikari.emojis.Emoji]): Object or name of the emoji to react with.
Note that if the emoji is an
hikari.emojis.CustomEmoji
and is not from a guild the bot user is in, then this will fail.
Other Parameters
emoji_id (hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]]): ID of the custom emoji to react with. This should only be provided when a custom emoji's name is passed for
emoji
.Note that this will fail if the emoji is from a guild the bot isn't in.
Examples
# Using a unicode emoji.
await message.add_reaction("👌")
# Using a unicode emoji name.
await message.add_reaction("\N{OK HAND SIGN}")
# Using the name and id.
await message.add_reaction("rooAYAYA", 705837374319493284)
# Using an Emoji-derived object.
await message.add_reaction(some_emoji_object)
Raises
- hikari.errors.BadRequestError: If the emoji is invalid, unknown, or formatted incorrectly.
- hikari.errors.ForbiddenError: If this is the first reaction using this specific emoji on this message and you lack the
ADD_REACTIONS
permission. If you lackREAD_MESSAGE_HISTORY
, this may also raise this error. - hikari.errors.NotFoundError: If the channel or message is not found, or if the emoji is not found.
This will also occur if you try to add an emoji from a guild you are not part of if no one else has previously reacted with the same emoji.
View Source
async def delete(self) -> None: """Delete this message. Raises ------ hikari.errors.NotFoundError If the channel this message was created in is not found, or if the message has already been deleted. hikari.errors.ForbiddenError If you lack the permissions to delete the message. """ await self.app.rest.delete_message(self.channel_id, self.id)
Delete this message.
Raises
- hikari.errors.NotFoundError: If the channel this message was created in is not found, or if the message has already been deleted.
- hikari.errors.ForbiddenError: If you lack the permissions to delete the message.
self,
content: Union[Any, hikari.undefined.UndefinedType] = UNDEFINED,
*,
attachment: Union[hikari.files.Resource[Any], os.PathLike[str], str, bytes, bytearray, memoryview, _io.BytesIO, _io.StringIO, hikari.undefined.UndefinedType] = UNDEFINED,
attachments: Union[Sequence[Union[hikari.files.Resource[Any], os.PathLike[str], str, bytes, bytearray, memoryview, _io.BytesIO, _io.StringIO]], hikari.undefined.UndefinedType] = UNDEFINED,
component: Union[hikari.api.special_endpoints.ComponentBuilder, hikari.undefined.UndefinedType, NoneType] = UNDEFINED,
components: Union[Sequence[hikari.api.special_endpoints.ComponentBuilder], hikari.undefined.UndefinedType, NoneType] = UNDEFINED,
embed: Union[hikari.embeds.Embed, hikari.undefined.UndefinedType, NoneType] = UNDEFINED,
embeds: Union[Sequence[hikari.embeds.Embed], hikari.undefined.UndefinedType, NoneType] = UNDEFINED,
replace_attachments: bool = False,
mentions_everyone: Union[bool, hikari.undefined.UndefinedType] = UNDEFINED,
mentions_reply: Union[bool, hikari.undefined.UndefinedType] = UNDEFINED,
user_mentions: Union[Sequence[Union[hikari.users.PartialUser, hikari.snowflakes.Snowflake, int]], bool, hikari.undefined.UndefinedType] = UNDEFINED,
role_mentions: Union[Sequence[Union[hikari.guilds.PartialRole, hikari.snowflakes.Snowflake, int]], bool, hikari.undefined.UndefinedType] = UNDEFINED,
flags: Union[hikari.messages.MessageFlag, hikari.undefined.UndefinedType] = UNDEFINED
) -> hikari.messages.Message:
View Source
async def edit( self, content: undefined.UndefinedOr[typing.Any] = undefined.UNDEFINED, *, attachment: undefined.UndefinedOr[files.Resourceish] = undefined.UNDEFINED, attachments: undefined.UndefinedOr[typing.Sequence[files.Resourceish]] = undefined.UNDEFINED, component: undefined.UndefinedNoneOr[special_endpoints.ComponentBuilder] = undefined.UNDEFINED, components: undefined.UndefinedNoneOr[ typing.Sequence[special_endpoints.ComponentBuilder] ] = undefined.UNDEFINED, embed: undefined.UndefinedNoneOr[embeds_.Embed] = undefined.UNDEFINED, embeds: undefined.UndefinedNoneOr[typing.Sequence[embeds_.Embed]] = undefined.UNDEFINED, replace_attachments: bool = False, mentions_everyone: undefined.UndefinedOr[bool] = undefined.UNDEFINED, mentions_reply: undefined.UndefinedOr[bool] = undefined.UNDEFINED, user_mentions: undefined.UndefinedOr[ typing.Union[snowflakes.SnowflakeishSequence[users_.PartialUser], bool] ] = undefined.UNDEFINED, role_mentions: undefined.UndefinedOr[ typing.Union[snowflakes.SnowflakeishSequence[guilds.PartialRole], bool] ] = undefined.UNDEFINED, flags: undefined.UndefinedOr[MessageFlag] = undefined.UNDEFINED, ) -> Message: """Edit an existing message in a given channel. .. note:: Mentioning everyone, roles, or users in message edits currently will not send a push notification showing a new mention to people on Discord. It will still highlight in their chat as if they were mentioned, however. .. warning:: If you specify a text `content`, `mentions_everyone`, `mentions_reply`, `user_mentions`, and `role_mentions` will default to `False` as the message will be re-parsed for mentions. This will also occur if only one of the four are specified This is a limitation of Discord's design. If in doubt, specify all four of them each time. .. warning:: If the message was not sent by your user, the only parameter you may provide to this call is the `flags` parameter. Anything else will result in a `hikari.errors.ForbiddenError` being raised. Parameters ---------- content : hikari.undefined.UndefinedOr[typing.Any] If provided, the message content to update with. If `hikari.undefined.UNDEFINED`, then the content will not be changed. If `None`, then the content will be removed. Any other value will be cast to a `str` before sending. If this is a `hikari.embeds.Embed` and neither the `embed` or `embeds` kwargs are provided or if this is a `hikari.files.Resourceish` and neither the `attachment` or `attachments` kwargs are provided, the values will be overwritten. This allows for simpler syntax when sending an embed or an attachment alone. Other Parameters ---------------- attachment : hikari.undefined.UndefinedOr[hikari.files.Resourceish] If provided, the attachment to set on the message. If `hikari.undefined.UNDEFINED`, the previous attachment, if present, is not changed. If this is `None`, then the attachment is removed, if present. Otherwise, the new attachment that was provided will be attached. attachments : hikari.undefined.UndefinedOr[typing.Sequence[hikari.files.Resourceish]] If provided, the attachments to set on the message. If `hikari.undefined.UNDEFINED`, the previous attachments, if present, are not changed. If this is `None`, then the attachments is removed, if present. Otherwise, the new attachments that were provided will be attached. component : hikari.undefined.UndefinedNoneOr[hikari.api.special_endpoints.ComponentBuilder] If provided, builder object of the component to set for this message. This component will replace any previously set components and passing `None` will remove all components. components : hikari.undefined.UndefinedNoneOr[typing.Sequence[hikari.api.special_endpoints.ComponentBuilder]] If provided, a sequence of the component builder objects set for this message. These components will replace any previously set components and passing `None` or an empty sequence will remove all components. embed : hikari.undefined.UndefinedNoneOr[hikari.embeds.Embed] If provided, the embed to set on the message. If `hikari.undefined.UNDEFINED`, the previous embed(s) are not changed. If this is `None` then any present embeds are removed. Otherwise, the new embed that was provided will be used as the replacement. embeds : hikari.undefined.UndefinedNoneOr[typing.Sequence[hikari.embeds.Embed]] If provided, the embeds to set on the message. If `hikari.undefined.UNDEFINED`, the previous embed(s) are not changed. If this is `None` then any present embeds are removed. Otherwise, the new embeds that were provided will be used as the replacement. replace_attachments: bool Whether to replace the attachments with the provided ones. Defaults to `False`. Note this will also overwrite the embed attachments. mentions_everyone : hikari.undefined.UndefinedOr[bool] Sanitation for `@everyone` mentions. If `hikari.undefined.UNDEFINED`, then the previous setting is not changed. If `True`, then `@everyone`/`@here` mentions in the message content will show up as mentioning everyone that can view the chat. mentions_reply : hikari.undefined.UndefinedOr[bool] If provided, whether to mention the author of the message that is being replied to. This will not do anything if this is not a reply message. user_mentions : hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.users.PartialUser], bool]] Sanitation for user mentions. If `hikari.undefined.UNDEFINED`, then the previous setting is not changed. If `True`, all valid user mentions will behave as mentions. If `False`, all valid user mentions will not behave as mentions. You may alternatively pass a collection of `hikari.snowflakes.Snowflake` user IDs, or `hikari.users.PartialUser`-derived objects. role_mentions : hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.guilds.PartialRole], bool]] Sanitation for role mentions. If `hikari.undefined.UNDEFINED`, then the previous setting is not changed. If `True`, all valid role mentions will behave as mentions. If `False`, all valid role mentions will not behave as mentions. You may alternatively pass a collection of `hikari.snowflakes.Snowflake` role IDs, or `hikari.guilds.PartialRole`-derived objects. flags : hikari.undefined.UndefinedOr[hikari.messages.MessageFlag] Optional flags to set on the message. If `hikari.undefined.UNDEFINED`, then nothing is changed. Note that some flags may not be able to be set. Currently the only flags that can be set are `NONE` and `SUPPRESS_EMBEDS`. If you have `MANAGE_MESSAGES` permissions, you can use this call to suppress embeds on another user's message. Returns ------- hikari.messages.Message The edited message. Raises ------ hikari.errors.BadRequestError This may be raised in several discrete situations, such as messages being empty with no embeds; messages with more than 2000 characters in them, embeds that exceed one of the many embed limits; invalid image URLs in embeds. hikari.errors.UnauthorizedError If you are unauthorized to make the request (invalid/missing token). hikari.errors.ForbiddenError If you lack permissions to send messages in the given channel; if you try to change the contents of another user's message; or if you try to edit the flags on another user's message without the permissions to manage messages. hikari.errors.NotFoundError If the channel or message is not found. hikari.errors.InternalServerError If an internal error occurs on Discord while handling the request. """ # noqa: E501 - Line too long return await self.app.rest.edit_message( message=self.id, channel=self.channel_id, content=content, attachment=attachment, attachments=attachments, component=component, components=components, embed=embed, embeds=embeds, replace_attachments=replace_attachments, mentions_everyone=mentions_everyone, mentions_reply=mentions_reply, user_mentions=user_mentions, role_mentions=role_mentions, flags=flags, )
Edit an existing message in a given channel.
Note: Mentioning everyone, roles, or users in message edits currently will not send a push notification showing a new mention to people on Discord. It will still highlight in their chat as if they were mentioned, however.
Warning: If you specify a text content
, mentions_everyone
, mentions_reply
, user_mentions
, and role_mentions
will default to False
as the message will be re-parsed for mentions. This will also occur if only one of the four are specified
This is a limitation of Discord's design. If in doubt, specify all four of them each time.
Warning: If the message was not sent by your user, the only parameter you may provide to this call is the flags
parameter. Anything else will result in a hikari.errors.ForbiddenError
being raised.
Parameters
content (hikari.undefined.UndefinedOr[typing.Any]): If provided, the message content to update with. If
hikari.undefined.UNDEFINED
, then the content will not be changed. IfNone
, then the content will be removed.Any other value will be cast to a
str
before sending.If this is a
hikari.embeds.Embed
and neither theembed
orembeds
kwargs are provided or if this is ahikari.files.Resourceish
and neither theattachment
orattachments
kwargs are provided, the values will be overwritten. This allows for simpler syntax when sending an embed or an attachment alone.
Other Parameters
- attachment (hikari.undefined.UndefinedOr[hikari.files.Resourceish]): If provided, the attachment to set on the message. If
hikari.undefined.UNDEFINED
, the previous attachment, if present, is not changed. If this isNone
, then the attachment is removed, if present. Otherwise, the new attachment that was provided will be attached. - attachments (hikari.undefined.UndefinedOr[typing.Sequence[hikari.files.Resourceish]]): If provided, the attachments to set on the message. If
hikari.undefined.UNDEFINED
, the previous attachments, if present, are not changed. If this isNone
, then the attachments is removed, if present. Otherwise, the new attachments that were provided will be attached. - component (hikari.undefined.UndefinedNoneOr[hikari.api.special_endpoints.ComponentBuilder]): If provided, builder object of the component to set for this message. This component will replace any previously set components and passing
None
will remove all components. - components (hikari.undefined.UndefinedNoneOr[typing.Sequence[hikari.api.special_endpoints.ComponentBuilder]]): If provided, a sequence of the component builder objects set for this message. These components will replace any previously set components and passing
None
or an empty sequence will remove all components. - embed (hikari.undefined.UndefinedNoneOr[hikari.embeds.Embed]): If provided, the embed to set on the message. If
hikari.undefined.UNDEFINED
, the previous embed(s) are not changed. If this isNone
then any present embeds are removed. Otherwise, the new embed that was provided will be used as the replacement. - embeds (hikari.undefined.UndefinedNoneOr[typing.Sequence[hikari.embeds.Embed]]): If provided, the embeds to set on the message. If
hikari.undefined.UNDEFINED
, the previous embed(s) are not changed. If this isNone
then any present embeds are removed. Otherwise, the new embeds that were provided will be used as the replacement. replace_attachments (bool): Whether to replace the attachments with the provided ones. Defaults to
False
.Note this will also overwrite the embed attachments.
- mentions_everyone (hikari.undefined.UndefinedOr[bool]): Sanitation for
@everyone
mentions. Ifhikari.undefined.UNDEFINED
, then the previous setting is not changed. IfTrue
, then@everyone
/@here
mentions in the message content will show up as mentioning everyone that can view the chat. mentions_reply (hikari.undefined.UndefinedOr[bool]): If provided, whether to mention the author of the message that is being replied to.
This will not do anything if this is not a reply message.
user_mentions (hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.users.PartialUser], bool]]): Sanitation for user mentions. If
hikari.undefined.UNDEFINED
, then the previous setting is not changed. IfTrue
, all valid user mentions will behave as mentions. IfFalse
, all valid user mentions will not behave as mentions.You may alternatively pass a collection of
hikari.snowflakes.Snowflake
user IDs, orhikari.users.PartialUser
-derived objects.role_mentions (hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.guilds.PartialRole], bool]]): Sanitation for role mentions. If
hikari.undefined.UNDEFINED
, then the previous setting is not changed. IfTrue
, all valid role mentions will behave as mentions. IfFalse
, all valid role mentions will not behave as mentions.You may alternatively pass a collection of
hikari.snowflakes.Snowflake
role IDs, orhikari.guilds.PartialRole
-derived objects.flags (hikari.undefined.UndefinedOr[hikari.messages.MessageFlag]): Optional flags to set on the message. If
hikari.undefined.UNDEFINED
, then nothing is changed.Note that some flags may not be able to be set. Currently the only flags that can be set are
NONE
andSUPPRESS_EMBEDS
. If you haveMANAGE_MESSAGES
permissions, you can use this call to suppress embeds on another user's message.
Returns
- hikari.messages.Message: The edited message.
Raises
- hikari.errors.BadRequestError: This may be raised in several discrete situations, such as messages being empty with no embeds; messages with more than 2000 characters in them, embeds that exceed one of the many embed limits; invalid image URLs in embeds.
- hikari.errors.UnauthorizedError: If you are unauthorized to make the request (invalid/missing token).
- hikari.errors.ForbiddenError: If you lack permissions to send messages in the given channel; if you try to change the contents of another user's message; or if you try to edit the flags on another user's message without the permissions to manage messages.
- hikari.errors.NotFoundError: If the channel or message is not found.
- hikari.errors.InternalServerError: If an internal error occurs on Discord while handling the request.
View Source
async def fetch_channel(self) -> channels_.PartialChannel: """Fetch the channel this message was created in. Returns ------- hikari.channels.PartialChannel The object of the channel this message belongs to. Raises ------ hikari.errors.BadRequestError If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer. hikari.errors.ForbiddenError If you don't have access to the channel this message belongs to. hikari.errors.NotFoundError If the channel this message was created in does not exist. hikari.errors.UnauthorizedError If you are unauthorized to make the request (invalid/missing token). hikari.errors.RateLimitTooLongError Raised in the event that a rate limit occurs that is longer than `max_rate_limit` when making a request. hikari.errors.RateLimitedError Usually, Hikari will handle and retry on hitting rate-limits automatically. This includes most bucket-specific rate-limits and global rate-limits. In some rare edge cases, however, Discord implements other undocumented rules for rate-limiting, such as limits per attribute. These cannot be detected or handled normally by Hikari due to their undocumented nature, and will trigger this exception if they occur. hikari.errors.InternalServerError If an internal error occurs on Discord while handling the request. """ return await self.app.rest.fetch_channel(self.channel_id)
Fetch the channel this message was created in.
Returns
- hikari.channels.PartialChannel: The object of the channel this message belongs to.
Raises
- hikari.errors.BadRequestError: If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer.
- hikari.errors.ForbiddenError: If you don't have access to the channel this message belongs to.
- hikari.errors.NotFoundError: If the channel this message was created in does not exist.
- hikari.errors.UnauthorizedError: If you are unauthorized to make the request (invalid/missing token).
- hikari.errors.RateLimitTooLongError: Raised in the event that a rate limit occurs that is longer than
max_rate_limit
when making a request. - hikari.errors.RateLimitedError: Usually, Hikari will handle and retry on hitting rate-limits automatically. This includes most bucket-specific rate-limits and global rate-limits. In some rare edge cases, however, Discord implements other undocumented rules for rate-limiting, such as limits per attribute. These cannot be detected or handled normally by Hikari due to their undocumented nature, and will trigger this exception if they occur.
- hikari.errors.InternalServerError: If an internal error occurs on Discord while handling the request.
self,
guild: Union[hikari.guilds.PartialGuild, hikari.snowflakes.Snowflake, int, NoneType]
) -> str:
View Source
def make_link(self, guild: typing.Optional[snowflakes.SnowflakeishOr[guilds.PartialGuild]]) -> str: """Generate a jump link to this message. Other Parameters ---------------- guild : typing.Optional[hikari.snowflakes.SnowflakeishOr[hikari.guilds.PartialGuild]] Object or ID of the guild this message is in or `None` to generate a DM message link. This parameter is necessary since `PartialMessage.guild_id` isn't returned by the REST API regardless of whether the message is in a DM or not. Returns ------- str The jump link to the message. """ guild_id_str = "@me" if guild is None else str(int(guild)) return f"{urls.BASE_URL}/channels/{guild_id_str}/{self.channel_id}/{self.id}"
Generate a jump link to this message.
Other Parameters
guild (typing.Optional[hikari.snowflakes.SnowflakeishOr[hikari.guilds.PartialGuild]]): Object or ID of the guild this message is in or
None
to generate a DM message link.This parameter is necessary since
PartialMessage.guild_id
isn't returned by the REST API regardless of whether the message is in a DM or not.
Returns
- str: The jump link to the message.
self,
emoji: Union[str, hikari.emojis.Emoji, hikari.undefined.UndefinedType] = UNDEFINED,
emoji_id: Union[hikari.emojis.CustomEmoji, hikari.snowflakes.Snowflake, int, hikari.undefined.UndefinedType] = UNDEFINED
) -> None:
View Source
async def remove_all_reactions( self, emoji: undefined.UndefinedOr[typing.Union[str, emojis_.Emoji]] = undefined.UNDEFINED, emoji_id: undefined.UndefinedOr[snowflakes.SnowflakeishOr[emojis_.CustomEmoji]] = undefined.UNDEFINED, ) -> None: r"""Remove all users' reactions for a specific emoji from the message. Other Parameters ---------------- emoji : hikari.undefined.UndefinedOr[typing.Union[str, hikari.emojis.Emoji]] Object or name of the emoji to get the reactions for. If not specified then all reactions are removed. emoji_id : hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]] ID of the custom emoji to react with. This should only be provided when a custom emoji's name is passed for `emoji`. Examples -------- ```py # Using a unicode emoji and removing all 👌 reacts from the message. # reaction. await message.remove_all_reactions("\N{OK HAND SIGN}") # Using the name and id. await message.add_reaction("rooAYAYA", 705837374319493284) # Removing all reactions entirely. await message.remove_all_reactions() ``` Raises ------ hikari.errors.ForbiddenError If you are missing the `MANAGE_MESSAGES` permission, or the permission to view the channel hikari.errors.NotFoundError If the channel or message is not found, or if the emoji is not found. hikari.errors.BadRequestError If the emoji is invalid, unknown, or formatted incorrectly. If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer. """ if emoji is undefined.UNDEFINED: await self.app.rest.delete_all_reactions(channel=self.channel_id, message=self.id) else: await self.app.rest.delete_all_reactions_for_emoji( channel=self.channel_id, message=self.id, emoji=emoji, emoji_id=emoji_id )
Remove all users' reactions for a specific emoji from the message.
Other Parameters
- emoji (hikari.undefined.UndefinedOr[typing.Union[str, hikari.emojis.Emoji]]): Object or name of the emoji to get the reactions for. If not specified then all reactions are removed.
- emoji_id (hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]]): ID of the custom emoji to react with. This should only be provided when a custom emoji's name is passed for
emoji
.
Examples
# Using a unicode emoji and removing all 👌 reacts from the message.
# reaction.
await message.remove_all_reactions("\N{OK HAND SIGN}")
# Using the name and id.
await message.add_reaction("rooAYAYA", 705837374319493284)
# Removing all reactions entirely.
await message.remove_all_reactions()
Raises
- hikari.errors.ForbiddenError: If you are missing the
MANAGE_MESSAGES
permission, or the permission to view the channel - hikari.errors.NotFoundError: If the channel or message is not found, or if the emoji is not found.
- hikari.errors.BadRequestError: If the emoji is invalid, unknown, or formatted incorrectly. If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer.
self,
emoji: Union[str, hikari.emojis.Emoji],
emoji_id: Union[hikari.emojis.CustomEmoji, hikari.snowflakes.Snowflake, int, hikari.undefined.UndefinedType] = UNDEFINED,
*,
user: Union[hikari.users.PartialUser, hikari.snowflakes.Snowflake, int, hikari.undefined.UndefinedType] = UNDEFINED
) -> None:
View Source
async def remove_reaction( self, emoji: typing.Union[str, emojis_.Emoji], emoji_id: undefined.UndefinedOr[snowflakes.SnowflakeishOr[emojis_.CustomEmoji]] = undefined.UNDEFINED, *, user: undefined.UndefinedOr[snowflakes.SnowflakeishOr[users_.PartialUser]] = undefined.UNDEFINED, ) -> None: r"""Remove a reaction from this message. Parameters ---------- emoji : typing.Union[str, hikari.emojis.Emoji] Object or name of the emoji to remove the reaction for. Other Parameters ---------------- emoji_id : hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]] ID of the custom emoji to remove the reaction for. This should only be provided when a custom emoji's name is passed for `emoji`. user : hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.users.PartialUser]] The user of the reaction to remove. If unspecified, then the bot's reaction is removed instead. Examples -------- ```py # Using a unicode emoji and removing the bot's reaction from this # reaction. await message.remove_reaction("\N{OK HAND SIGN}") # Using a custom emoji's name and ID to remove a specific user's # reaction from this reaction. await message.remove_reaction("a:Distraction", 745991233939439616, user=some_user) # Using a unicode emoji and removing a specific user from this # reaction. await message.remove_reaction("\N{OK HAND SIGN}", user=some_user) # Using the name and id. await message.add_reaction("rooAYAYA", 705837374319493284) # Using an Emoji object and removing a specific user from this # reaction. await message.remove_reaction(some_emoji_object, user=some_user) ``` Raises ------ hikari.errors.BadRequestError If the emoji is invalid, unknown, or formatted incorrectly. If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer. hikari.errors.ForbiddenError If this is the first reaction using this specific emoji on this message and you lack the `ADD_REACTIONS` permission. If you lack `READ_MESSAGE_HISTORY`, this may also raise this error. If you remove the reaction of another user without `MANAGE_MESSAGES`, this will be raised. hikari.errors.NotFoundError If the channel or message is not found, or if the emoji is not found. """ if user is undefined.UNDEFINED: await self.app.rest.delete_my_reaction( channel=self.channel_id, message=self.id, emoji=emoji, emoji_id=emoji_id ) else: await self.app.rest.delete_reaction( channel=self.channel_id, message=self.id, emoji=emoji, emoji_id=emoji_id, user=user )
Remove a reaction from this message.
Parameters
- emoji (typing.Union[str, hikari.emojis.Emoji]): Object or name of the emoji to remove the reaction for.
Other Parameters
- emoji_id (hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]]): ID of the custom emoji to remove the reaction for. This should only be provided when a custom emoji's name is passed for
emoji
. - user (hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.users.PartialUser]]): The user of the reaction to remove. If unspecified, then the bot's reaction is removed instead.
Examples
# Using a unicode emoji and removing the bot's reaction from this
# reaction.
await message.remove_reaction("\N{OK HAND SIGN}")
# Using a custom emoji's name and ID to remove a specific user's
# reaction from this reaction.
await message.remove_reaction("a:Distraction", 745991233939439616, user=some_user)
# Using a unicode emoji and removing a specific user from this
# reaction.
await message.remove_reaction("\N{OK HAND SIGN}", user=some_user)
# Using the name and id.
await message.add_reaction("rooAYAYA", 705837374319493284)
# Using an Emoji object and removing a specific user from this
# reaction.
await message.remove_reaction(some_emoji_object, user=some_user)
Raises
- hikari.errors.BadRequestError: If the emoji is invalid, unknown, or formatted incorrectly. If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer.
- hikari.errors.ForbiddenError: If this is the first reaction using this specific emoji on this message and you lack the
ADD_REACTIONS
permission. If you lackREAD_MESSAGE_HISTORY
, this may also raise this error. If you remove the reaction of another user withoutMANAGE_MESSAGES
, this will be raised. - hikari.errors.NotFoundError: If the channel or message is not found, or if the emoji is not found.
self,
content: Union[Any, hikari.undefined.UndefinedType] = UNDEFINED,
*,
attachment: Union[hikari.files.Resource[Any], os.PathLike[str], str, bytes, bytearray, memoryview, _io.BytesIO, _io.StringIO, hikari.undefined.UndefinedType] = UNDEFINED,
attachments: Union[Sequence[Union[hikari.files.Resource[Any], os.PathLike[str], str, bytes, bytearray, memoryview, _io.BytesIO, _io.StringIO]], hikari.undefined.UndefinedType] = UNDEFINED,
component: Union[hikari.api.special_endpoints.ComponentBuilder, hikari.undefined.UndefinedType] = UNDEFINED,
components: Union[Sequence[hikari.api.special_endpoints.ComponentBuilder], hikari.undefined.UndefinedType] = UNDEFINED,
embed: Union[hikari.embeds.Embed, hikari.undefined.UndefinedType] = UNDEFINED,
embeds: Union[Sequence[hikari.embeds.Embed], hikari.undefined.UndefinedType] = UNDEFINED,
tts: Union[bool, hikari.undefined.UndefinedType] = UNDEFINED,
reply: Union[hikari.undefined.UndefinedType, hikari.messages.PartialMessage, hikari.snowflakes.Snowflake, int, bool] = UNDEFINED,
mentions_everyone: Union[bool, hikari.undefined.UndefinedType] = UNDEFINED,
mentions_reply: Union[bool, hikari.undefined.UndefinedType] = UNDEFINED,
user_mentions: Union[Sequence[Union[hikari.users.PartialUser, hikari.snowflakes.Snowflake, int]], bool, hikari.undefined.UndefinedType] = UNDEFINED,
role_mentions: Union[Sequence[Union[hikari.guilds.PartialRole, hikari.snowflakes.Snowflake, int]], bool, hikari.undefined.UndefinedType] = UNDEFINED
) -> hikari.messages.Message:
View Source
async def respond( self, content: undefined.UndefinedOr[typing.Any] = undefined.UNDEFINED, *, attachment: undefined.UndefinedOr[files.Resourceish] = undefined.UNDEFINED, attachments: undefined.UndefinedOr[typing.Sequence[files.Resourceish]] = undefined.UNDEFINED, component: undefined.UndefinedOr[special_endpoints.ComponentBuilder] = undefined.UNDEFINED, components: undefined.UndefinedOr[typing.Sequence[special_endpoints.ComponentBuilder]] = undefined.UNDEFINED, embed: undefined.UndefinedOr[embeds_.Embed] = undefined.UNDEFINED, embeds: undefined.UndefinedOr[typing.Sequence[embeds_.Embed]] = undefined.UNDEFINED, tts: undefined.UndefinedOr[bool] = undefined.UNDEFINED, reply: typing.Union[ undefined.UndefinedType, snowflakes.SnowflakeishOr[PartialMessage], bool ] = undefined.UNDEFINED, mentions_everyone: undefined.UndefinedOr[bool] = undefined.UNDEFINED, mentions_reply: undefined.UndefinedOr[bool] = undefined.UNDEFINED, user_mentions: undefined.UndefinedOr[ typing.Union[snowflakes.SnowflakeishSequence[users_.PartialUser], bool] ] = undefined.UNDEFINED, role_mentions: undefined.UndefinedOr[ typing.Union[snowflakes.SnowflakeishSequence[guilds.PartialRole], bool] ] = undefined.UNDEFINED, ) -> Message: """Create a message in the channel this message belongs to. Parameters ---------- content : hikari.undefined.UndefinedOr[typing.Any] If provided, the message contents. If `hikari.undefined.UNDEFINED`, then nothing will be sent in the content. Any other value here will be cast to a `str`. If this is a `hikari.embeds.Embed` and no `embed` nor `embeds` kwarg is provided, then this will instead update the embed. This allows for simpler syntax when sending an embed alone. Likewise, if this is a `hikari.files.Resource`, then the content is instead treated as an attachment if no `attachment` and no `attachments` kwargs are provided. Other Parameters ---------------- attachment : hikari.undefined.UndefinedOr[hikari.files.Resourceish], If provided, the message attachment. This can be a resource, or string of a path on your computer or a URL. Attachments can be passed as many different things, to aid in convenience. - If a `pathlib.PurePath` or `str` to a valid URL, the resource at the given URL will be streamed to Discord when sending the message. Subclasses of `hikari.files.WebResource` such as `hikari.files.URL`, `hikari.messages.Attachment`, `hikari.emojis.Emoji`, `EmbedResource`, etc will also be uploaded this way. This will use bit-inception, so only a small percentage of the resource will remain in memory at any one time, thus aiding in scalability. - If a `hikari.files.Bytes` is passed, or a `str` that contains a valid data URI is passed, then this is uploaded with a randomized file name if not provided. - If a `hikari.files.File`, `pathlib.PurePath` or `str` that is an absolute or relative path to a file on your file system is passed, then this resource is uploaded as an attachment using non-blocking code internally and streamed using bit-inception where possible. This depends on the type of `concurrent.futures.Executor` that is being used for the application (default is a thread pool which supports this behaviour). attachments : hikari.undefined.UndefinedOr[typing.Sequence[hikari.files.Resourceish]], If provided, the message attachments. These can be resources, or strings consisting of paths on your computer or URLs. component : hikari.undefined.UndefinedOr[hikari.api.special_endpoints.ComponentBuilder] If provided, builder object of the component to include in this message. components : hikari.undefined.UndefinedOr[typing.Sequence[hikari.api.special_endpoints.ComponentBuilder]] If provided, a sequence of the component builder objects to include in this message. embed : hikari.undefined.UndefinedOr[hikari.embeds.Embed] If provided, the message embed. embeds : hikari.undefined.UndefinedOr[typing.Sequence[hikari.embeds.Embed]] If provided, the message embeds. tts : hikari.undefined.UndefinedOr[bool] If provided, whether the message will be TTS (Text To Speech). reply : typing.Union[hikari.undefined.UndefinedType, hikari.snowflakes.SnowflakeishOr[hikari.messages.PartialMessage], bool] If provided and `True`, reply to this message. If provided and not `bool`, the message to reply to. mentions_everyone : hikari.undefined.UndefinedOr[bool] If provided, whether the message should parse @everyone/@here mentions. mentions_reply : hikari.undefined.UndefinedOr[bool] If provided, whether to mention the author of the message that is being replied to. This will not do anything if not being used with `reply`. user_mentions : hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.users.PartialUser], bool]] If provided, and `True`, all mentions will be parsed. If provided, and `False`, no mentions will be parsed. Alternatively this may be a collection of `hikari.snowflakes.Snowflake`, or `hikari.users.PartialUser` derivatives to enforce mentioning specific users. role_mentions : hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.guilds.PartialRole], bool]] If provided, and `True`, all mentions will be parsed. If provided, and `False`, no mentions will be parsed. Alternatively this may be a collection of `hikari.snowflakes.Snowflake`, or `hikari.guilds.PartialRole` derivatives to enforce mentioning specific roles. Returns ------- hikari.messages.Message The created message. Raises ------ hikari.errors.BadRequestError This may be raised in several discrete situations, such as messages being empty with no attachments or embeds; messages with more than 2000 characters in them, embeds that exceed one of the many embed limits; too many attachments; attachments that are too large; invalid image URLs in embeds; `reply` not found or not in the same channel; too many components. hikari.errors.UnauthorizedError If you are unauthorized to make the request (invalid/missing token). hikari.errors.ForbiddenError If you lack permissions to send messages in the given channel. hikari.errors.NotFoundError If the channel is not found. hikari.errors.InternalServerError If an internal error occurs on Discord while handling the request. ValueError If more than 100 unique objects/entities are passed for `role_mentions` or `user_mentions`. TypeError If both `attachment` and `attachments` are specified. """ # noqa: E501 - Line too long if reply is True: reply = self elif reply is False: reply = undefined.UNDEFINED return await self.app.rest.create_message( channel=self.channel_id, content=content, attachment=attachment, attachments=attachments, component=component, components=components, embed=embed, embeds=embeds, tts=tts, reply=reply, mentions_everyone=mentions_everyone, user_mentions=user_mentions, role_mentions=role_mentions, mentions_reply=mentions_reply, )
Create a message in the channel this message belongs to.
Parameters
content (hikari.undefined.UndefinedOr[typing.Any]): If provided, the message contents. If
hikari.undefined.UNDEFINED
, then nothing will be sent in the content. Any other value here will be cast to astr
.If this is a
hikari.embeds.Embed
and noembed
norembeds
kwarg is provided, then this will instead update the embed. This allows for simpler syntax when sending an embed alone.Likewise, if this is a
hikari.files.Resource
, then the content is instead treated as an attachment if noattachment
and noattachments
kwargs are provided.
Other Parameters
attachment (hikari.undefined.UndefinedOr[hikari.files.Resourceish],): If provided, the message attachment. This can be a resource, or string of a path on your computer or a URL.
Attachments can be passed as many different things, to aid in convenience.
- If a
pathlib.PurePath
orstr
to a valid URL, the resource at the given URL will be streamed to Discord when sending the message. Subclasses ofhikari.files.WebResource
such ashikari.files.URL
,hikari.messages.Attachment
,hikari.emojis.Emoji
,EmbedResource
, etc will also be uploaded this way. This will use bit-inception, so only a small percentage of the resource will remain in memory at any one time, thus aiding in scalability. - If a
hikari.files.Bytes
is passed, or astr
that contains a valid data URI is passed, then this is uploaded with a randomized file name if not provided. - If a
hikari.files.File
,pathlib.PurePath
orstr
that is an absolute or relative path to a file on your file system is passed, then this resource is uploaded as an attachment using non-blocking code internally and streamed using bit-inception where possible. This depends on the type ofconcurrent.futures.Executor
that is being used for the application (default is a thread pool which supports this behaviour).
- If a
- attachments (hikari.undefined.UndefinedOr[typing.Sequence[hikari.files.Resourceish]],): If provided, the message attachments. These can be resources, or strings consisting of paths on your computer or URLs.
- component (hikari.undefined.UndefinedOr[hikari.api.special_endpoints.ComponentBuilder]): If provided, builder object of the component to include in this message.
- components (hikari.undefined.UndefinedOr[typing.Sequence[hikari.api.special_endpoints.ComponentBuilder]]): If provided, a sequence of the component builder objects to include in this message.
- embed (hikari.undefined.UndefinedOr[hikari.embeds.Embed]): If provided, the message embed.
- embeds (hikari.undefined.UndefinedOr[typing.Sequence[hikari.embeds.Embed]]): If provided, the message embeds.
- tts (hikari.undefined.UndefinedOr[bool]): If provided, whether the message will be TTS (Text To Speech).
- reply (typing.Union[hikari.undefined.UndefinedType, hikari.snowflakes.SnowflakeishOr[hikari.messages.PartialMessage], bool]): If provided and
True
, reply to this message. If provided and notbool
, the message to reply to. - mentions_everyone (hikari.undefined.UndefinedOr[bool]): If provided, whether the message should parse @everyone/@here mentions.
mentions_reply (hikari.undefined.UndefinedOr[bool]): If provided, whether to mention the author of the message that is being replied to.
This will not do anything if not being used with
reply
.- user_mentions (hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.users.PartialUser], bool]]): If provided, and
True
, all mentions will be parsed. If provided, andFalse
, no mentions will be parsed. Alternatively this may be a collection ofhikari.snowflakes.Snowflake
, orhikari.users.PartialUser
derivatives to enforce mentioning specific users. - role_mentions (hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.guilds.PartialRole], bool]]): If provided, and
True
, all mentions will be parsed. If provided, andFalse
, no mentions will be parsed. Alternatively this may be a collection ofhikari.snowflakes.Snowflake
, orhikari.guilds.PartialRole
derivatives to enforce mentioning specific roles.
Returns
- hikari.messages.Message: The created message.
Raises
- hikari.errors.BadRequestError: This may be raised in several discrete situations, such as messages being empty with no attachments or embeds; messages with more than 2000 characters in them, embeds that exceed one of the many embed limits; too many attachments; attachments that are too large; invalid image URLs in embeds;
reply
not found or not in the same channel; too many components. - hikari.errors.UnauthorizedError: If you are unauthorized to make the request (invalid/missing token).
- hikari.errors.ForbiddenError: If you lack permissions to send messages in the given channel.
- hikari.errors.NotFoundError: If the channel is not found.
- hikari.errors.InternalServerError: If an internal error occurs on Discord while handling the request.
- ValueError: If more than 100 unique objects/entities are passed for
role_mentions
oruser_mentions
. - TypeError: If both
attachment
andattachments
are specified.
View Source
@attr_extensions.with_copy @attr.define(hash=False, kw_only=True, weakref_slot=False) class MessageActivity: """Represents the activity of a rich presence-enabled message.""" type: typing.Union[MessageActivityType, int] = attr.field(repr=True) """The type of message activity.""" party_id: typing.Optional[str] = attr.field(repr=True) """The party ID of the message activity."""
Represents the activity of a rich presence-enabled message.
Variables and properties
The party ID of the message activity.
The type of message activity.
Methods
self,
*,
type: Union[hikari.messages.MessageActivityType, int],
party_id: Optional[str]
):
View Source
def __init__(self, *, type, party_id): self.type = type self.party_id = party_id
Method generated by attrs for class MessageActivity.
View Source
@typing.final class MessageActivityType(int, enums.Enum): """The type of a rich presence message activity.""" NONE = 0 """No activity.""" JOIN = 1 """Join an activity.""" SPECTATE = 2 """Spectating something.""" LISTEN = 3 """Listening to something.""" JOIN_REQUEST = 5 """Request to join an activity."""
The type of a rich presence message activity.
Variables and properties
Join an activity.
Request to join an activity.
Listening to something.
No activity.
Spectating something.
the denominator of a rational number in lowest terms
the imaginary part of a complex number
Return the name of the enum member as a str
.
the numerator of a rational number in lowest terms
the real part of a complex number
Return the value of the enum member.
Methods
View Source
def __call__(cls, value: typing.Any) -> typing.Any: """Cast a value to the enum, returning the raw value that was passed if value not found.""" try: return cls._value_to_member_map_[value] except KeyError: # If we can't find the value, just return what got casted in return value
Cast a value to the enum, returning the raw value that was passed if value not found.
Return integer ratio.
Return a pair of integers, whose ratio is exactly equal to the original int and with a positive denominator.
>>> (10).as_integer_ratio()
(10, 1)
>>> (-10).as_integer_ratio()
(-10, 1)
>>> (0).as_integer_ratio()
(0, 1)
Number of bits necessary to represent self in binary.
>>> bin(37)
'0b100101'
>>> (37).bit_length()
6
Returns self, the complex conjugate of any int.
Return the integer represented by the given array of bytes.
bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder' as the byte order value. signed Indicates whether two's complement is used to represent the integer.
Return an array of bytes representing an integer.
length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder' as the byte order value. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
View Source
@typing.final class MessageFlag(enums.Flag): """Additional flags for message options.""" NONE = 0 """None""" CROSSPOSTED = 1 << 0 """This message has been published to subscribed channels via channel following.""" IS_CROSSPOST = 1 << 1 """This message originated from a message in another channel via channel following.""" SUPPRESS_EMBEDS = 1 << 2 """Any embeds on this message should be omitted when serializing the message.""" SOURCE_MESSAGE_DELETED = 1 << 3 """The message this crosspost originated from was deleted via channel following.""" URGENT = 1 << 4 """This message came from the urgent message system.""" EPHEMERAL = 1 << 6 """This message is only visible to the user that invoked the interaction.""" LOADING = 1 << 7 """This message symbolizes that the interaction is 'thinking'."""
Additional flags for message options.
Variables and properties
This message has been published to subscribed channels via channel following.
This message is only visible to the user that invoked the interaction.
This message originated from a message in another channel via channel following.
This message symbolizes that the interaction is 'thinking'.
None
The message this crosspost originated from was deleted via channel following.
Any embeds on this message should be omitted when serializing the message.
This message came from the urgent message system.
the denominator of a rational number in lowest terms
the imaginary part of a complex number
Return the name of the flag combination as a str
.
the numerator of a rational number in lowest terms
the real part of a complex number
Return the int
value of the flag.
Methods
View Source
def __call__(cls, value: int = 0) -> typing.Any: """Cast a value to the flag enum, returning the raw value that was passed if values not found.""" # We want to handle value invariantly to avoid issues brought in by different behaviours from sub-classed ints # and floats. This also ensures that .__int__ only returns an invariant int. value = int(value) try: return cls._value_to_member_map_[value] except KeyError: # We only need this ability here usually, so overloading operators # is an overkill and would add more overhead. if value < 0: # Convert to a positive value instead. return cls.__everything__ - ~value temp_members = cls._temp_members_ # For huge enums, don't ever cache anything. We could consume masses of memory otherwise # (e.g. Permissions) try: # Try to get a cached value. return temp_members[value] except KeyError: # If we can't find the value, just return what got casted in by generating a pseudomember # and caching it. We can't use weakref because int is not weak referenceable, annoyingly. pseudomember = cls.__new__(cls, value) pseudomember._name_ = None pseudomember._value_ = value temp_members[value] = pseudomember if len(temp_members) > _MAX_CACHED_MEMBERS: temp_members.popitem() return pseudomember
Cast a value to the flag enum, returning the raw value that was passed if values not found.
View Source
def all(self: _T, *flags: _T) -> bool: """Check if all of the given flags are part of this value. Returns ------- bool `True` if any of the given flags are part of this value. Otherwise, return `False`. """ return all((flag & self) == flag for flag in flags)
Check if all of the given flags are part of this value.
Returns
- bool:
True
if any of the given flags are part of this value. Otherwise, returnFalse
.
View Source
def any(self: _T, *flags: _T) -> bool: """Check if any of the given flags are part of this value. Returns ------- bool `True` if any of the given flags are part of this value. Otherwise, return `False`. """ return any((flag & self) == flag for flag in flags)
Check if any of the given flags are part of this value.
Returns
- bool:
True
if any of the given flags are part of this value. Otherwise, returnFalse
.
Return integer ratio.
Return a pair of integers, whose ratio is exactly equal to the original int and with a positive denominator.
>>> (10).as_integer_ratio()
(10, 1)
>>> (-10).as_integer_ratio()
(-10, 1)
>>> (0).as_integer_ratio()
(0, 1)
Number of bits necessary to represent self in binary.
>>> bin(37)
'0b100101'
>>> (37).bit_length()
6
Returns self, the complex conjugate of any int.
View Source
def difference(self: _T, other: typing.Union[_T, int]) -> _T: """Perform a set difference with the other set. This will return all flags in this set that are not in the other value. Equivalent to using the subtraction `-` operator. """ return self.__class__(self & ~int(other))
Perform a set difference with the other set.
This will return all flags in this set that are not in the other value.
Equivalent to using the subtraction -
operator.
Return the integer represented by the given array of bytes.
bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder' as the byte order value. signed Indicates whether two's complement is used to represent the integer.
View Source
def intersection(self: _T, other: typing.Union[_T, int]) -> _T: """Return a combination of flags that are set for both given values. Equivalent to using the "AND" `&` operator. """ return self.__class__(self._value_ & int(other))
Return a combination of flags that are set for both given values.
Equivalent to using the "AND" &
operator.
View Source
def invert(self: _T) -> _T: """Return a set of all flags not in the current set.""" return self.__class__(self.__class__.__everything__._value_ & ~self._value_)
Return a set of all flags not in the current set.
View Source
def is_disjoint(self: _T, other: typing.Union[_T, int]) -> bool: """Return whether two sets have a intersection or not. If the two sets have an intersection, then this returns `False`. If no common flag values exist between them, then this returns `True`. """ return not (self & other)
Return whether two sets have a intersection or not.
If the two sets have an intersection, then this returns False
. If no common flag values exist between them, then this returns True
.
View Source
def is_subset(self: _T, other: typing.Union[_T, int]) -> bool: """Return whether another set contains this set or not. Equivalent to using the "in" operator. """ return (self & other) == other
Return whether another set contains this set or not.
Equivalent to using the "in" operator.
View Source
def is_superset(self: _T, other: typing.Union[_T, int]) -> bool: """Return whether this set contains another set or not.""" return (self & other) == self
Return whether this set contains another set or not.
View Source
def is_disjoint(self: _T, other: typing.Union[_T, int]) -> bool: """Return whether two sets have a intersection or not. If the two sets have an intersection, then this returns `False`. If no common flag values exist between them, then this returns `True`. """ return not (self & other)
Return whether two sets have a intersection or not.
If the two sets have an intersection, then this returns False
. If no common flag values exist between them, then this returns True
.
View Source
def is_subset(self: _T, other: typing.Union[_T, int]) -> bool: """Return whether another set contains this set or not. Equivalent to using the "in" operator. """ return (self & other) == other
Return whether another set contains this set or not.
Equivalent to using the "in" operator.
View Source
def is_superset(self: _T, other: typing.Union[_T, int]) -> bool: """Return whether this set contains another set or not.""" return (self & other) == self
Return whether this set contains another set or not.
View Source
def none(self: _T, *flags: _T) -> bool: """Check if none of the given flags are part of this value. .. note:: This is essentially the opposite of `Flag.any`. Returns ------- bool `True` if none of the given flags are part of this value. Otherwise, return `False`. """ return not self.any(*flags)
Check if none of the given flags are part of this value.
Note: This is essentially the opposite of Flag.any
.
Returns
- bool:
True
if none of the given flags are part of this value. Otherwise, returnFalse
.
View Source
def split(self: _T) -> typing.Sequence[_T]: """Return a list of all defined atomic values for this flag. Any unrecognised bits will be omitted for brevity. The result will be a name-sorted `typing.Sequence` of each member """ return sorted( (member for member in self.__class__._powers_of_2_to_member_map_.values() if member.value & self), # Assumption: powers of 2 already have a cached value. key=lambda m: m._name_, )
Return a list of all defined atomic values for this flag.
Any unrecognised bits will be omitted for brevity.
The result will be a name-sorted typing.Sequence
of each member
View Source
def symmetric_difference(self: _T, other: typing.Union[_T, int]) -> _T: """Return a set with the symmetric differences of two flag sets. Equivalent to using the "XOR" `^` operator. For `a ^ b`, this can be considered the same as `(a - b) | (b - a)`. """ return self.__class__(self._value_ ^ int(other))
Return a set with the symmetric differences of two flag sets.
Equivalent to using the "XOR" ^
operator.
For a ^ b
, this can be considered the same as (a - b) | (b - a)
.
View Source
def symmetric_difference(self: _T, other: typing.Union[_T, int]) -> _T: """Return a set with the symmetric differences of two flag sets. Equivalent to using the "XOR" `^` operator. For `a ^ b`, this can be considered the same as `(a - b) | (b - a)`. """ return self.__class__(self._value_ ^ int(other))
Return a set with the symmetric differences of two flag sets.
Equivalent to using the "XOR" ^
operator.
For a ^ b
, this can be considered the same as (a - b) | (b - a)
.
Return an array of bytes representing an integer.
length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder' as the byte order value. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
View Source
def union(self: _T, other: typing.Union[_T, int]) -> _T: """Return a combination of all flags in this set and the other set. Equivalent to using the "OR" `~` operator. """ return self.__class__(self._value_ | int(other))
Return a combination of all flags in this set and the other set.
Equivalent to using the "OR" ~
operator.
View Source
@attr_extensions.with_copy @attr.define(kw_only=True, repr=True, hash=True, weakref_slot=False) class MessageInteraction: """Representation of information provided for a message from an interaction.""" id: snowflakes.Snowflake = attr.field(hash=True, repr=True) """ID of the interaction this message was sent by.""" type: typing.Union[base_interactions.InteractionType, int] = attr.field(eq=False, repr=True) """The type of interaction this message was created by.""" name: str = attr.field(eq=False, repr=True) """Name of the application command the interaction is tied to.""" user: users_.User = attr.field(eq=False, repr=True) """Object of the user who invoked this interaction."""
Representation of information provided for a message from an interaction.
Variables and properties
ID of the interaction this message was sent by.
Name of the application command the interaction is tied to.
The type of interaction this message was created by.
Object of the user who invoked this interaction.
Methods
self,
*,
id: hikari.snowflakes.Snowflake,
type: Union[hikari.interactions.base_interactions.InteractionType, int],
name: str,
user: hikari.users.User
):
View Source
def __init__(self, *, id, type, name, user): self.id = id self.type = type self.name = name self.user = user
Method generated by attrs for class MessageInteraction.
View Source
@attr_extensions.with_copy @attr.define(hash=False, kw_only=True, weakref_slot=False) class MessageReference: """Represents information about a referenced message. This will be included in crossposted messages, channel follow add message, pin add messages and replies. """ app: traits.RESTAware = attr.field( repr=False, eq=False, hash=False, metadata={attr_extensions.SKIP_DEEP_COPY: True} ) """The client application that models may use for procedures.""" id: typing.Optional[snowflakes.Snowflake] = attr.field(repr=True) """The ID of the original message. This will be `None` for channel follow add messages. This may point to a deleted message. """ channel_id: snowflakes.Snowflake = attr.field(repr=True) """The ID of the channel that the original message originated from.""" guild_id: typing.Optional[snowflakes.Snowflake] = attr.field(repr=True) """The ID of the guild that the message originated from. This will be `None` when the original message is not from a guild. """
Represents information about a referenced message.
This will be included in crossposted messages, channel follow add message, pin add messages and replies.
Variables and properties
The client application that models may use for procedures.
The ID of the channel that the original message originated from.
The ID of the guild that the message originated from.
This will be None
when the original message is not from a guild.
The ID of the original message.
This will be None
for channel follow add messages. This may point to a deleted message.
Methods
self,
*,
app: hikari.traits.RESTAware,
id: Optional[hikari.snowflakes.Snowflake],
channel_id: hikari.snowflakes.Snowflake,
guild_id: Optional[hikari.snowflakes.Snowflake]
):
View Source
def __init__(self, *, app, id, channel_id, guild_id): self.app = app self.id = id self.channel_id = channel_id self.guild_id = guild_id
Method generated by attrs for class MessageReference.
View Source
@typing.final class MessageType(int, enums.Enum): """The type of a message.""" DEFAULT = 0 """A normal message.""" RECIPIENT_ADD = 1 """A message to denote a new recipient in a group.""" RECIPIENT_REMOVE = 2 """A message to denote that a recipient left the group.""" CALL = 3 """A message to denote a VoIP call.""" CHANNEL_NAME_CHANGE = 4 """A message to denote that the name of a channel changed.""" CHANNEL_ICON_CHANGE = 5 """A message to denote that the icon of a channel changed.""" CHANNEL_PINNED_MESSAGE = 6 """A message to denote that a message was pinned.""" GUILD_MEMBER_JOIN = 7 """A message to denote that a member joined the guild.""" USER_PREMIUM_GUILD_SUBSCRIPTION = 8 """A message to denote a Nitro subscription.""" USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1 = 9 """A message to denote a tier 1 Nitro subscription.""" USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2 = 10 """A message to denote a tier 2 Nitro subscription.""" USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3 = 11 """A message to denote a tier 3 Nitro subscription.""" CHANNEL_FOLLOW_ADD = 12 """Channel follow add.""" GUILD_DISCOVERY_DISQUALIFIED = 14 """A message to indicate that a guild has been disqualified from discovery.""" GUILD_DISCOVERY_REQUALIFIED = 15 """A message to indicate that a guild has re-qualified for discovery.""" GUILD_DISCOVERY_GRACE_PERIOD_INITIAL_WARNING = 16 """A message to indicate that the grace period before removal from discovery has started.""" GUILD_DISCOVERY_GRACE_PERIOD_FINAL_WARNING = 17 """A message to indicate the final warning before removal from discovery.""" REPLY = 19 """A message that replies to another message.""" CHAT_INPUT = 20 """A message sent to indicate a chat input application command has been executed.""" GUILD_INVITE_REMINDER = 22 """A message sent to remind to invite people to the guild.""" CONTEXT_MENU_COMMAND = 23 """A message sent to indicate a context menu has been executed."""
The type of a message.
Variables and properties
A message to denote a VoIP call.
Channel follow add.
A message to denote that the icon of a channel changed.
A message to denote that the name of a channel changed.
A message to denote that a message was pinned.
A message sent to indicate a chat input application command has been executed.
A message sent to indicate a context menu has been executed.
A normal message.
A message to indicate that a guild has been disqualified from discovery.
A message to indicate the final warning before removal from discovery.
A message to indicate that the grace period before removal from discovery has started.
A message to indicate that a guild has re-qualified for discovery.
A message sent to remind to invite people to the guild.
A message to denote that a member joined the guild.
A message to denote a new recipient in a group.
A message to denote that a recipient left the group.
A message that replies to another message.
A message to denote a Nitro subscription.
A message to denote a tier 1 Nitro subscription.
A message to denote a tier 2 Nitro subscription.
A message to denote a tier 3 Nitro subscription.
the denominator of a rational number in lowest terms
the imaginary part of a complex number
Return the name of the enum member as a str
.
the numerator of a rational number in lowest terms
the real part of a complex number
Return the value of the enum member.
Methods
View Source
def __call__(cls, value: typing.Any) -> typing.Any: """Cast a value to the enum, returning the raw value that was passed if value not found.""" try: return cls._value_to_member_map_[value] except KeyError: # If we can't find the value, just return what got casted in return value
Cast a value to the enum, returning the raw value that was passed if value not found.
Return integer ratio.
Return a pair of integers, whose ratio is exactly equal to the original int and with a positive denominator.
>>> (10).as_integer_ratio()
(10, 1)
>>> (-10).as_integer_ratio()
(-10, 1)
>>> (0).as_integer_ratio()
(0, 1)
Number of bits necessary to represent self in binary.
>>> bin(37)
'0b100101'
>>> (37).bit_length()
6
Returns self, the complex conjugate of any int.
Return the integer represented by the given array of bytes.
bytes Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder' as the byte order value. signed Indicates whether two's complement is used to represent the integer.
Return an array of bytes representing an integer.
length Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. byteorder The byte order used to represent the integer. If byteorder is 'big', the most significant byte is at the beginning of the byte array. If byteorder is 'little', the most significant byte is at the end of the byte array. To request the native byte order of the host system, use `sys.byteorder' as the byte order value. signed Determines whether two's complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.
View Source
@attr.define(kw_only=True, weakref_slot=False) class PartialComponent: """Base class for all component entities.""" type: typing.Union[ComponentType, int] = attr.field() """The type of component this is."""
Base class for all component entities.
Variables and properties
The type of component this is.
Methods
View Source
def __init__(self, *, type): self.type = type
Method generated by attrs for class PartialComponent.
View Source
@attr_extensions.with_copy @attr.define(kw_only=True, repr=True, eq=False, weakref_slot=False) class PartialMessage(snowflakes.Unique): """A message representation containing partially populated information. This contains arbitrary fields that may be updated in a `MessageUpdateEvent`, but for all other purposes should be treated as being optionally specified. .. warning:: All fields on this model except `channel` and `id` may be set to `hikari.undefined.UNDEFINED` (a singleton) if we have not received information about their state from Discord alongside field nullability. """ app: traits.RESTAware = attr.field( repr=False, eq=False, hash=False, metadata={attr_extensions.SKIP_DEEP_COPY: True} ) """The client application that models may use for procedures.""" id: snowflakes.Snowflake = attr.field(hash=True, repr=True) """The ID of this entity.""" channel_id: snowflakes.Snowflake = attr.field(hash=False, eq=False, repr=True) """The ID of the channel that the message was sent in.""" guild_id: typing.Optional[snowflakes.Snowflake] = attr.field(hash=False, eq=False, repr=True) """The ID of the guild that the message was sent in or `None` for messages out of guilds. .. warning:: This will also be `None` for messages received from the REST API. This is a Discord limitation as stated here <https://github.com/discord/discord-api-docs/issues/912> """ author: undefined.UndefinedOr[users_.User] = attr.field(hash=False, eq=False, repr=True) """The author of this message. This will also be `hikari.undefined.UNDEFINED` in some cases such as when Discord updates a message with an embed URL preview or in messages fetched from the REST API. """ member: undefined.UndefinedNoneOr[guilds.Member] = attr.field(hash=False, eq=False, repr=False) """The member for the author who created the message. If the message is not in a guild, this will be `None`. This will also be `hikari.undefined.UNDEFINED` in some cases such as when Discord updates a message with an embed URL preview. .. warning:: This will also be `None` for messages received from the REST API. This is a Discord limitation as stated here <https://github.com/discord/discord-api-docs/issues/912> """ content: undefined.UndefinedNoneOr[str] = attr.field(hash=False, eq=False, repr=False) """The content of the message.""" timestamp: undefined.UndefinedOr[datetime.datetime] = attr.field(hash=False, eq=False, repr=False) """The timestamp that the message was sent at.""" edited_timestamp: undefined.UndefinedNoneOr[datetime.datetime] = attr.field(hash=False, eq=False, repr=False) """The timestamp that the message was last edited at. Will be `None` if the message wasn't ever edited, or `undefined` if the info is not available. """ is_tts: undefined.UndefinedOr[bool] = attr.field(hash=False, eq=False, repr=False) """Whether the message is a TTS message.""" mentions: Mentions = attr.field(hash=False, eq=False, repr=True) """Description of who is mentioned in a message. .. warning:: If the contents have not mutated and this is a message update event, some fields that are not affected may be empty instead. This is a Discord limitation. """ attachments: undefined.UndefinedOr[typing.Sequence[Attachment]] = attr.field(hash=False, eq=False, repr=False) """The message attachments.""" embeds: undefined.UndefinedOr[typing.Sequence[embeds_.Embed]] = attr.field(hash=False, eq=False, repr=False) """The message embeds.""" reactions: undefined.UndefinedOr[typing.Sequence[Reaction]] = attr.field(hash=False, eq=False, repr=False) """The message reactions.""" is_pinned: undefined.UndefinedOr[bool] = attr.field(hash=False, eq=False, repr=False) """Whether the message is pinned.""" webhook_id: undefined.UndefinedNoneOr[snowflakes.Snowflake] = attr.field(hash=False, eq=False, repr=False) """If the message was generated by a webhook, the webhook's ID.""" type: undefined.UndefinedOr[typing.Union[MessageType, int]] = attr.field(hash=False, eq=False, repr=False) """The message type.""" activity: undefined.UndefinedNoneOr[MessageActivity] = attr.field(hash=False, eq=False, repr=False) """The message activity. .. note:: This will only be provided for messages with rich-presence related chat embeds. """ application: undefined.UndefinedNoneOr[MessageApplication] = attr.field(hash=False, eq=False, repr=False) """The message application. .. note:: This will only be provided for messages with rich-presence related chat embeds. """ message_reference: undefined.UndefinedNoneOr[MessageReference] = attr.field(hash=False, eq=False, repr=False) """The message reference data.""" flags: undefined.UndefinedOr[MessageFlag] = attr.field(hash=False, eq=False, repr=False) """The message flags.""" stickers: undefined.UndefinedOr[typing.Sequence[stickers_.PartialSticker]] = attr.field( hash=False, eq=False, repr=False ) """The stickers sent with this message.""" nonce: undefined.UndefinedNoneOr[str] = attr.field(hash=False, eq=False, repr=False) """The message nonce. This is a string used for validating a message was sent. """ referenced_message: undefined.UndefinedNoneOr[Message] = attr.field(hash=False, eq=False, repr=False) """The message that was replied to. If `type` is `MessageType.REPLY` and `hikari.undefined.UNDEFINED`, Discord's backend didn't attempt to fetch the message, so the status is unknown. If `type` is `MessageType.REPLY` and `None`, the message was deleted. """ interaction: undefined.UndefinedNoneOr[MessageInteraction] = attr.field(hash=False, eq=False, repr=False) """Information about the interaction this message was created by.""" application_id: undefined.UndefinedNoneOr[snowflakes.Snowflake] = attr.field(hash=False, eq=False, repr=False) """ID of the application this message was sent by. .. note:: This will only be provided for interaction messages. """ components: undefined.UndefinedOr[typing.Sequence[PartialComponent]] = attr.field(hash=False, eq=False, repr=False) """Sequence of the components attached to this message.""" def make_link(self, guild: typing.Optional[snowflakes.SnowflakeishOr[guilds.PartialGuild]]) -> str: """Generate a jump link to this message. Other Parameters ---------------- guild : typing.Optional[hikari.snowflakes.SnowflakeishOr[hikari.guilds.PartialGuild]] Object or ID of the guild this message is in or `None` to generate a DM message link. This parameter is necessary since `PartialMessage.guild_id` isn't returned by the REST API regardless of whether the message is in a DM or not. Returns ------- str The jump link to the message. """ guild_id_str = "@me" if guild is None else str(int(guild)) return f"{urls.BASE_URL}/channels/{guild_id_str}/{self.channel_id}/{self.id}" async def fetch_channel(self) -> channels_.PartialChannel: """Fetch the channel this message was created in. Returns ------- hikari.channels.PartialChannel The object of the channel this message belongs to. Raises ------ hikari.errors.BadRequestError If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer. hikari.errors.ForbiddenError If you don't have access to the channel this message belongs to. hikari.errors.NotFoundError If the channel this message was created in does not exist. hikari.errors.UnauthorizedError If you are unauthorized to make the request (invalid/missing token). hikari.errors.RateLimitTooLongError Raised in the event that a rate limit occurs that is longer than `max_rate_limit` when making a request. hikari.errors.RateLimitedError Usually, Hikari will handle and retry on hitting rate-limits automatically. This includes most bucket-specific rate-limits and global rate-limits. In some rare edge cases, however, Discord implements other undocumented rules for rate-limiting, such as limits per attribute. These cannot be detected or handled normally by Hikari due to their undocumented nature, and will trigger this exception if they occur. hikari.errors.InternalServerError If an internal error occurs on Discord while handling the request. """ return await self.app.rest.fetch_channel(self.channel_id) async def edit( self, content: undefined.UndefinedOr[typing.Any] = undefined.UNDEFINED, *, attachment: undefined.UndefinedOr[files.Resourceish] = undefined.UNDEFINED, attachments: undefined.UndefinedOr[typing.Sequence[files.Resourceish]] = undefined.UNDEFINED, component: undefined.UndefinedNoneOr[special_endpoints.ComponentBuilder] = undefined.UNDEFINED, components: undefined.UndefinedNoneOr[ typing.Sequence[special_endpoints.ComponentBuilder] ] = undefined.UNDEFINED, embed: undefined.UndefinedNoneOr[embeds_.Embed] = undefined.UNDEFINED, embeds: undefined.UndefinedNoneOr[typing.Sequence[embeds_.Embed]] = undefined.UNDEFINED, replace_attachments: bool = False, mentions_everyone: undefined.UndefinedOr[bool] = undefined.UNDEFINED, mentions_reply: undefined.UndefinedOr[bool] = undefined.UNDEFINED, user_mentions: undefined.UndefinedOr[ typing.Union[snowflakes.SnowflakeishSequence[users_.PartialUser], bool] ] = undefined.UNDEFINED, role_mentions: undefined.UndefinedOr[ typing.Union[snowflakes.SnowflakeishSequence[guilds.PartialRole], bool] ] = undefined.UNDEFINED, flags: undefined.UndefinedOr[MessageFlag] = undefined.UNDEFINED, ) -> Message: """Edit an existing message in a given channel. .. note:: Mentioning everyone, roles, or users in message edits currently will not send a push notification showing a new mention to people on Discord. It will still highlight in their chat as if they were mentioned, however. .. warning:: If you specify a text `content`, `mentions_everyone`, `mentions_reply`, `user_mentions`, and `role_mentions` will default to `False` as the message will be re-parsed for mentions. This will also occur if only one of the four are specified This is a limitation of Discord's design. If in doubt, specify all four of them each time. .. warning:: If the message was not sent by your user, the only parameter you may provide to this call is the `flags` parameter. Anything else will result in a `hikari.errors.ForbiddenError` being raised. Parameters ---------- content : hikari.undefined.UndefinedOr[typing.Any] If provided, the message content to update with. If `hikari.undefined.UNDEFINED`, then the content will not be changed. If `None`, then the content will be removed. Any other value will be cast to a `str` before sending. If this is a `hikari.embeds.Embed` and neither the `embed` or `embeds` kwargs are provided or if this is a `hikari.files.Resourceish` and neither the `attachment` or `attachments` kwargs are provided, the values will be overwritten. This allows for simpler syntax when sending an embed or an attachment alone. Other Parameters ---------------- attachment : hikari.undefined.UndefinedOr[hikari.files.Resourceish] If provided, the attachment to set on the message. If `hikari.undefined.UNDEFINED`, the previous attachment, if present, is not changed. If this is `None`, then the attachment is removed, if present. Otherwise, the new attachment that was provided will be attached. attachments : hikari.undefined.UndefinedOr[typing.Sequence[hikari.files.Resourceish]] If provided, the attachments to set on the message. If `hikari.undefined.UNDEFINED`, the previous attachments, if present, are not changed. If this is `None`, then the attachments is removed, if present. Otherwise, the new attachments that were provided will be attached. component : hikari.undefined.UndefinedNoneOr[hikari.api.special_endpoints.ComponentBuilder] If provided, builder object of the component to set for this message. This component will replace any previously set components and passing `None` will remove all components. components : hikari.undefined.UndefinedNoneOr[typing.Sequence[hikari.api.special_endpoints.ComponentBuilder]] If provided, a sequence of the component builder objects set for this message. These components will replace any previously set components and passing `None` or an empty sequence will remove all components. embed : hikari.undefined.UndefinedNoneOr[hikari.embeds.Embed] If provided, the embed to set on the message. If `hikari.undefined.UNDEFINED`, the previous embed(s) are not changed. If this is `None` then any present embeds are removed. Otherwise, the new embed that was provided will be used as the replacement. embeds : hikari.undefined.UndefinedNoneOr[typing.Sequence[hikari.embeds.Embed]] If provided, the embeds to set on the message. If `hikari.undefined.UNDEFINED`, the previous embed(s) are not changed. If this is `None` then any present embeds are removed. Otherwise, the new embeds that were provided will be used as the replacement. replace_attachments: bool Whether to replace the attachments with the provided ones. Defaults to `False`. Note this will also overwrite the embed attachments. mentions_everyone : hikari.undefined.UndefinedOr[bool] Sanitation for `@everyone` mentions. If `hikari.undefined.UNDEFINED`, then the previous setting is not changed. If `True`, then `@everyone`/`@here` mentions in the message content will show up as mentioning everyone that can view the chat. mentions_reply : hikari.undefined.UndefinedOr[bool] If provided, whether to mention the author of the message that is being replied to. This will not do anything if this is not a reply message. user_mentions : hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.users.PartialUser], bool]] Sanitation for user mentions. If `hikari.undefined.UNDEFINED`, then the previous setting is not changed. If `True`, all valid user mentions will behave as mentions. If `False`, all valid user mentions will not behave as mentions. You may alternatively pass a collection of `hikari.snowflakes.Snowflake` user IDs, or `hikari.users.PartialUser`-derived objects. role_mentions : hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.guilds.PartialRole], bool]] Sanitation for role mentions. If `hikari.undefined.UNDEFINED`, then the previous setting is not changed. If `True`, all valid role mentions will behave as mentions. If `False`, all valid role mentions will not behave as mentions. You may alternatively pass a collection of `hikari.snowflakes.Snowflake` role IDs, or `hikari.guilds.PartialRole`-derived objects. flags : hikari.undefined.UndefinedOr[hikari.messages.MessageFlag] Optional flags to set on the message. If `hikari.undefined.UNDEFINED`, then nothing is changed. Note that some flags may not be able to be set. Currently the only flags that can be set are `NONE` and `SUPPRESS_EMBEDS`. If you have `MANAGE_MESSAGES` permissions, you can use this call to suppress embeds on another user's message. Returns ------- hikari.messages.Message The edited message. Raises ------ hikari.errors.BadRequestError This may be raised in several discrete situations, such as messages being empty with no embeds; messages with more than 2000 characters in them, embeds that exceed one of the many embed limits; invalid image URLs in embeds. hikari.errors.UnauthorizedError If you are unauthorized to make the request (invalid/missing token). hikari.errors.ForbiddenError If you lack permissions to send messages in the given channel; if you try to change the contents of another user's message; or if you try to edit the flags on another user's message without the permissions to manage messages. hikari.errors.NotFoundError If the channel or message is not found. hikari.errors.InternalServerError If an internal error occurs on Discord while handling the request. """ # noqa: E501 - Line too long return await self.app.rest.edit_message( message=self.id, channel=self.channel_id, content=content, attachment=attachment, attachments=attachments, component=component, components=components, embed=embed, embeds=embeds, replace_attachments=replace_attachments, mentions_everyone=mentions_everyone, mentions_reply=mentions_reply, user_mentions=user_mentions, role_mentions=role_mentions, flags=flags, ) async def respond( self, content: undefined.UndefinedOr[typing.Any] = undefined.UNDEFINED, *, attachment: undefined.UndefinedOr[files.Resourceish] = undefined.UNDEFINED, attachments: undefined.UndefinedOr[typing.Sequence[files.Resourceish]] = undefined.UNDEFINED, component: undefined.UndefinedOr[special_endpoints.ComponentBuilder] = undefined.UNDEFINED, components: undefined.UndefinedOr[typing.Sequence[special_endpoints.ComponentBuilder]] = undefined.UNDEFINED, embed: undefined.UndefinedOr[embeds_.Embed] = undefined.UNDEFINED, embeds: undefined.UndefinedOr[typing.Sequence[embeds_.Embed]] = undefined.UNDEFINED, tts: undefined.UndefinedOr[bool] = undefined.UNDEFINED, reply: typing.Union[ undefined.UndefinedType, snowflakes.SnowflakeishOr[PartialMessage], bool ] = undefined.UNDEFINED, mentions_everyone: undefined.UndefinedOr[bool] = undefined.UNDEFINED, mentions_reply: undefined.UndefinedOr[bool] = undefined.UNDEFINED, user_mentions: undefined.UndefinedOr[ typing.Union[snowflakes.SnowflakeishSequence[users_.PartialUser], bool] ] = undefined.UNDEFINED, role_mentions: undefined.UndefinedOr[ typing.Union[snowflakes.SnowflakeishSequence[guilds.PartialRole], bool] ] = undefined.UNDEFINED, ) -> Message: """Create a message in the channel this message belongs to. Parameters ---------- content : hikari.undefined.UndefinedOr[typing.Any] If provided, the message contents. If `hikari.undefined.UNDEFINED`, then nothing will be sent in the content. Any other value here will be cast to a `str`. If this is a `hikari.embeds.Embed` and no `embed` nor `embeds` kwarg is provided, then this will instead update the embed. This allows for simpler syntax when sending an embed alone. Likewise, if this is a `hikari.files.Resource`, then the content is instead treated as an attachment if no `attachment` and no `attachments` kwargs are provided. Other Parameters ---------------- attachment : hikari.undefined.UndefinedOr[hikari.files.Resourceish], If provided, the message attachment. This can be a resource, or string of a path on your computer or a URL. Attachments can be passed as many different things, to aid in convenience. - If a `pathlib.PurePath` or `str` to a valid URL, the resource at the given URL will be streamed to Discord when sending the message. Subclasses of `hikari.files.WebResource` such as `hikari.files.URL`, `hikari.messages.Attachment`, `hikari.emojis.Emoji`, `EmbedResource`, etc will also be uploaded this way. This will use bit-inception, so only a small percentage of the resource will remain in memory at any one time, thus aiding in scalability. - If a `hikari.files.Bytes` is passed, or a `str` that contains a valid data URI is passed, then this is uploaded with a randomized file name if not provided. - If a `hikari.files.File`, `pathlib.PurePath` or `str` that is an absolute or relative path to a file on your file system is passed, then this resource is uploaded as an attachment using non-blocking code internally and streamed using bit-inception where possible. This depends on the type of `concurrent.futures.Executor` that is being used for the application (default is a thread pool which supports this behaviour). attachments : hikari.undefined.UndefinedOr[typing.Sequence[hikari.files.Resourceish]], If provided, the message attachments. These can be resources, or strings consisting of paths on your computer or URLs. component : hikari.undefined.UndefinedOr[hikari.api.special_endpoints.ComponentBuilder] If provided, builder object of the component to include in this message. components : hikari.undefined.UndefinedOr[typing.Sequence[hikari.api.special_endpoints.ComponentBuilder]] If provided, a sequence of the component builder objects to include in this message. embed : hikari.undefined.UndefinedOr[hikari.embeds.Embed] If provided, the message embed. embeds : hikari.undefined.UndefinedOr[typing.Sequence[hikari.embeds.Embed]] If provided, the message embeds. tts : hikari.undefined.UndefinedOr[bool] If provided, whether the message will be TTS (Text To Speech). reply : typing.Union[hikari.undefined.UndefinedType, hikari.snowflakes.SnowflakeishOr[hikari.messages.PartialMessage], bool] If provided and `True`, reply to this message. If provided and not `bool`, the message to reply to. mentions_everyone : hikari.undefined.UndefinedOr[bool] If provided, whether the message should parse @everyone/@here mentions. mentions_reply : hikari.undefined.UndefinedOr[bool] If provided, whether to mention the author of the message that is being replied to. This will not do anything if not being used with `reply`. user_mentions : hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.users.PartialUser], bool]] If provided, and `True`, all mentions will be parsed. If provided, and `False`, no mentions will be parsed. Alternatively this may be a collection of `hikari.snowflakes.Snowflake`, or `hikari.users.PartialUser` derivatives to enforce mentioning specific users. role_mentions : hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.guilds.PartialRole], bool]] If provided, and `True`, all mentions will be parsed. If provided, and `False`, no mentions will be parsed. Alternatively this may be a collection of `hikari.snowflakes.Snowflake`, or `hikari.guilds.PartialRole` derivatives to enforce mentioning specific roles. Returns ------- hikari.messages.Message The created message. Raises ------ hikari.errors.BadRequestError This may be raised in several discrete situations, such as messages being empty with no attachments or embeds; messages with more than 2000 characters in them, embeds that exceed one of the many embed limits; too many attachments; attachments that are too large; invalid image URLs in embeds; `reply` not found or not in the same channel; too many components. hikari.errors.UnauthorizedError If you are unauthorized to make the request (invalid/missing token). hikari.errors.ForbiddenError If you lack permissions to send messages in the given channel. hikari.errors.NotFoundError If the channel is not found. hikari.errors.InternalServerError If an internal error occurs on Discord while handling the request. ValueError If more than 100 unique objects/entities are passed for `role_mentions` or `user_mentions`. TypeError If both `attachment` and `attachments` are specified. """ # noqa: E501 - Line too long if reply is True: reply = self elif reply is False: reply = undefined.UNDEFINED return await self.app.rest.create_message( channel=self.channel_id, content=content, attachment=attachment, attachments=attachments, component=component, components=components, embed=embed, embeds=embeds, tts=tts, reply=reply, mentions_everyone=mentions_everyone, user_mentions=user_mentions, role_mentions=role_mentions, mentions_reply=mentions_reply, ) async def delete(self) -> None: """Delete this message. Raises ------ hikari.errors.NotFoundError If the channel this message was created in is not found, or if the message has already been deleted. hikari.errors.ForbiddenError If you lack the permissions to delete the message. """ await self.app.rest.delete_message(self.channel_id, self.id) @typing.overload async def add_reaction( self, emoji: typing.Union[str, emojis_.Emoji], ) -> None: ... @typing.overload async def add_reaction( self, emoji: str, emoji_id: snowflakes.SnowflakeishOr[emojis_.CustomEmoji], ) -> None: ... async def add_reaction( self, emoji: typing.Union[str, emojis_.Emoji], emoji_id: undefined.UndefinedOr[snowflakes.SnowflakeishOr[emojis_.CustomEmoji]] = undefined.UNDEFINED, ) -> None: r"""Add a reaction to this message. Parameters ---------- emoji: typing.Union[str, hikari.emojis.Emoji] Object or name of the emoji to react with. Note that if the emoji is an `hikari.emojis.CustomEmoji` and is not from a guild the bot user is in, then this will fail. Other Parameters ---------------- emoji_id : hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]] ID of the custom emoji to react with. This should only be provided when a custom emoji's name is passed for `emoji`. Note that this will fail if the emoji is from a guild the bot isn't in. Examples -------- ```py # Using a unicode emoji. await message.add_reaction("👌") # Using a unicode emoji name. await message.add_reaction("\N{OK HAND SIGN}") # Using the name and id. await message.add_reaction("rooAYAYA", 705837374319493284) # Using an Emoji-derived object. await message.add_reaction(some_emoji_object) ``` Raises ------ hikari.errors.BadRequestError If the emoji is invalid, unknown, or formatted incorrectly. hikari.errors.ForbiddenError If this is the first reaction using this specific emoji on this message and you lack the `ADD_REACTIONS` permission. If you lack `READ_MESSAGE_HISTORY`, this may also raise this error. hikari.errors.NotFoundError If the channel or message is not found, or if the emoji is not found. This will also occur if you try to add an emoji from a guild you are not part of if no one else has previously reacted with the same emoji. """ await self.app.rest.add_reaction(channel=self.channel_id, message=self.id, emoji=emoji, emoji_id=emoji_id) @typing.overload async def remove_reaction( self, emoji: typing.Union[str, emojis_.Emoji], *, user: undefined.UndefinedOr[snowflakes.SnowflakeishOr[users_.PartialUser]] = undefined.UNDEFINED, ) -> None: ... @typing.overload async def remove_reaction( self, emoji: str, emoji_id: snowflakes.SnowflakeishOr[emojis_.CustomEmoji], *, user: undefined.UndefinedOr[snowflakes.SnowflakeishOr[users_.PartialUser]] = undefined.UNDEFINED, ) -> None: ... async def remove_reaction( self, emoji: typing.Union[str, emojis_.Emoji], emoji_id: undefined.UndefinedOr[snowflakes.SnowflakeishOr[emojis_.CustomEmoji]] = undefined.UNDEFINED, *, user: undefined.UndefinedOr[snowflakes.SnowflakeishOr[users_.PartialUser]] = undefined.UNDEFINED, ) -> None: r"""Remove a reaction from this message. Parameters ---------- emoji : typing.Union[str, hikari.emojis.Emoji] Object or name of the emoji to remove the reaction for. Other Parameters ---------------- emoji_id : hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]] ID of the custom emoji to remove the reaction for. This should only be provided when a custom emoji's name is passed for `emoji`. user : hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.users.PartialUser]] The user of the reaction to remove. If unspecified, then the bot's reaction is removed instead. Examples -------- ```py # Using a unicode emoji and removing the bot's reaction from this # reaction. await message.remove_reaction("\N{OK HAND SIGN}") # Using a custom emoji's name and ID to remove a specific user's # reaction from this reaction. await message.remove_reaction("a:Distraction", 745991233939439616, user=some_user) # Using a unicode emoji and removing a specific user from this # reaction. await message.remove_reaction("\N{OK HAND SIGN}", user=some_user) # Using the name and id. await message.add_reaction("rooAYAYA", 705837374319493284) # Using an Emoji object and removing a specific user from this # reaction. await message.remove_reaction(some_emoji_object, user=some_user) ``` Raises ------ hikari.errors.BadRequestError If the emoji is invalid, unknown, or formatted incorrectly. If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer. hikari.errors.ForbiddenError If this is the first reaction using this specific emoji on this message and you lack the `ADD_REACTIONS` permission. If you lack `READ_MESSAGE_HISTORY`, this may also raise this error. If you remove the reaction of another user without `MANAGE_MESSAGES`, this will be raised. hikari.errors.NotFoundError If the channel or message is not found, or if the emoji is not found. """ if user is undefined.UNDEFINED: await self.app.rest.delete_my_reaction( channel=self.channel_id, message=self.id, emoji=emoji, emoji_id=emoji_id ) else: await self.app.rest.delete_reaction( channel=self.channel_id, message=self.id, emoji=emoji, emoji_id=emoji_id, user=user ) @typing.overload async def remove_all_reactions(self) -> None: ... @typing.overload async def remove_all_reactions( self, emoji: typing.Union[str, emojis_.Emoji], ) -> None: ... @typing.overload async def remove_all_reactions( self, emoji: str, emoji_id: snowflakes.SnowflakeishOr[emojis_.CustomEmoji], ) -> None: ... async def remove_all_reactions( self, emoji: undefined.UndefinedOr[typing.Union[str, emojis_.Emoji]] = undefined.UNDEFINED, emoji_id: undefined.UndefinedOr[snowflakes.SnowflakeishOr[emojis_.CustomEmoji]] = undefined.UNDEFINED, ) -> None: r"""Remove all users' reactions for a specific emoji from the message. Other Parameters ---------------- emoji : hikari.undefined.UndefinedOr[typing.Union[str, hikari.emojis.Emoji]] Object or name of the emoji to get the reactions for. If not specified then all reactions are removed. emoji_id : hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]] ID of the custom emoji to react with. This should only be provided when a custom emoji's name is passed for `emoji`. Examples -------- ```py # Using a unicode emoji and removing all 👌 reacts from the message. # reaction. await message.remove_all_reactions("\N{OK HAND SIGN}") # Using the name and id. await message.add_reaction("rooAYAYA", 705837374319493284) # Removing all reactions entirely. await message.remove_all_reactions() ``` Raises ------ hikari.errors.ForbiddenError If you are missing the `MANAGE_MESSAGES` permission, or the permission to view the channel hikari.errors.NotFoundError If the channel or message is not found, or if the emoji is not found. hikari.errors.BadRequestError If the emoji is invalid, unknown, or formatted incorrectly. If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer. """ if emoji is undefined.UNDEFINED: await self.app.rest.delete_all_reactions(channel=self.channel_id, message=self.id) else: await self.app.rest.delete_all_reactions_for_emoji( channel=self.channel_id, message=self.id, emoji=emoji, emoji_id=emoji_id )
A message representation containing partially populated information.
This contains arbitrary fields that may be updated in a MessageUpdateEvent
, but for all other purposes should be treated as being optionally specified.
Warning: All fields on this model except channel
and id
may be set to hikari.undefined.UNDEFINED
(a singleton) if we have not received information about their state from Discord alongside field nullability.
Variables and properties
The message activity.
Note: This will only be provided for messages with rich-presence related chat embeds.
The client application that models may use for procedures.
The message application.
Note: This will only be provided for messages with rich-presence related chat embeds.
ID of the application this message was sent by.
Note: This will only be provided for interaction messages.
The message attachments.
The ID of the channel that the message was sent in.
Sequence of the components attached to this message.
The content of the message.
When the object was created.
The timestamp that the message was last edited at.
Will be None
if the message wasn't ever edited, or undefined
if the info is not available.
The message embeds.
The message flags.
The ID of the guild that the message was sent in or None
for messages out of guilds.
Warning: This will also be None
for messages received from the REST API. This is a Discord limitation as stated here https://github.com/discord/discord-api-docs/issues/912
The ID of this entity.
Information about the interaction this message was created by.
Whether the message is pinned.
Whether the message is a TTS message.
The member for the author who created the message.
If the message is not in a guild, this will be None
.
This will also be hikari.undefined.UNDEFINED
in some cases such as when Discord updates a message with an embed URL preview.
Warning: This will also be None
for messages received from the REST API. This is a Discord limitation as stated here https://github.com/discord/discord-api-docs/issues/912
Description of who is mentioned in a message.
Warning: If the contents have not mutated and this is a message update event, some fields that are not affected may be empty instead.
This is a Discord limitation.
The message reference data.
The message nonce.
This is a string used for validating a message was sent.
The message reactions.
The message that was replied to.
If type
is MessageType.REPLY
and hikari.undefined.UNDEFINED
, Discord's backend didn't attempt to fetch the message, so the status is unknown. If type
is MessageType.REPLY
and None
, the message was deleted.
The stickers sent with this message.
The timestamp that the message was sent at.
The message type.
If the message was generated by a webhook, the webhook's ID.
Methods
self,
*,
app: hikari.traits.RESTAware,
id: hikari.snowflakes.Snowflake,
channel_id: hikari.snowflakes.Snowflake,
guild_id: Optional[hikari.snowflakes.Snowflake],
author: Union[hikari.users.User, hikari.undefined.UndefinedType],
member: Union[hikari.guilds.Member, hikari.undefined.UndefinedType, NoneType],
content: Union[str, hikari.undefined.UndefinedType, NoneType],
timestamp: Union[datetime.datetime, hikari.undefined.UndefinedType],
edited_timestamp: Union[datetime.datetime, hikari.undefined.UndefinedType, NoneType],
is_tts: Union[bool, hikari.undefined.UndefinedType],
mentions: hikari.messages.Mentions,
attachments: Union[Sequence[hikari.messages.Attachment], hikari.undefined.UndefinedType],
embeds: Union[Sequence[hikari.embeds.Embed], hikari.undefined.UndefinedType],
reactions: Union[Sequence[hikari.messages.Reaction], hikari.undefined.UndefinedType],
is_pinned: Union[bool, hikari.undefined.UndefinedType],
webhook_id: Union[hikari.snowflakes.Snowflake, hikari.undefined.UndefinedType, NoneType],
type: Union[hikari.messages.MessageType, int, hikari.undefined.UndefinedType],
activity: Union[hikari.messages.MessageActivity, hikari.undefined.UndefinedType, NoneType],
application: Union[hikari.messages.MessageApplication, hikari.undefined.UndefinedType, NoneType],
message_reference: Union[hikari.messages.MessageReference, hikari.undefined.UndefinedType, NoneType],
flags: Union[hikari.messages.MessageFlag, hikari.undefined.UndefinedType],
stickers: Union[Sequence[hikari.stickers.PartialSticker], hikari.undefined.UndefinedType],
nonce: Union[str, hikari.undefined.UndefinedType, NoneType],
referenced_message: Union[hikari.messages.Message, hikari.undefined.UndefinedType, NoneType],
interaction: Union[hikari.messages.MessageInteraction, hikari.undefined.UndefinedType, NoneType],
application_id: Union[hikari.snowflakes.Snowflake, hikari.undefined.UndefinedType, NoneType],
components: Union[Sequence[hikari.messages.PartialComponent], hikari.undefined.UndefinedType]
):
View Source
def __init__(self, *, app, id, channel_id, guild_id, author, member, content, timestamp, edited_timestamp, is_tts, mentions, attachments, embeds, reactions, is_pinned, webhook_id, type, activity, application, message_reference, flags, stickers, nonce, referenced_message, interaction, application_id, components): self.app = app self.id = id self.channel_id = channel_id self.guild_id = guild_id self.author = author self.member = member self.content = content self.timestamp = timestamp self.edited_timestamp = edited_timestamp self.is_tts = is_tts self.mentions = mentions self.attachments = attachments self.embeds = embeds self.reactions = reactions self.is_pinned = is_pinned self.webhook_id = webhook_id self.type = type self.activity = activity self.application = application self.message_reference = message_reference self.flags = flags self.stickers = stickers self.nonce = nonce self.referenced_message = referenced_message self.interaction = interaction self.application_id = application_id self.components = components
Method generated by attrs for class PartialMessage.
self,
emoji: Union[str, hikari.emojis.Emoji],
emoji_id: Union[hikari.emojis.CustomEmoji, hikari.snowflakes.Snowflake, int, hikari.undefined.UndefinedType] = UNDEFINED
) -> None:
View Source
async def add_reaction( self, emoji: typing.Union[str, emojis_.Emoji], emoji_id: undefined.UndefinedOr[snowflakes.SnowflakeishOr[emojis_.CustomEmoji]] = undefined.UNDEFINED, ) -> None: r"""Add a reaction to this message. Parameters ---------- emoji: typing.Union[str, hikari.emojis.Emoji] Object or name of the emoji to react with. Note that if the emoji is an `hikari.emojis.CustomEmoji` and is not from a guild the bot user is in, then this will fail. Other Parameters ---------------- emoji_id : hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]] ID of the custom emoji to react with. This should only be provided when a custom emoji's name is passed for `emoji`. Note that this will fail if the emoji is from a guild the bot isn't in. Examples -------- ```py # Using a unicode emoji. await message.add_reaction("👌") # Using a unicode emoji name. await message.add_reaction("\N{OK HAND SIGN}") # Using the name and id. await message.add_reaction("rooAYAYA", 705837374319493284) # Using an Emoji-derived object. await message.add_reaction(some_emoji_object) ``` Raises ------ hikari.errors.BadRequestError If the emoji is invalid, unknown, or formatted incorrectly. hikari.errors.ForbiddenError If this is the first reaction using this specific emoji on this message and you lack the `ADD_REACTIONS` permission. If you lack `READ_MESSAGE_HISTORY`, this may also raise this error. hikari.errors.NotFoundError If the channel or message is not found, or if the emoji is not found. This will also occur if you try to add an emoji from a guild you are not part of if no one else has previously reacted with the same emoji. """ await self.app.rest.add_reaction(channel=self.channel_id, message=self.id, emoji=emoji, emoji_id=emoji_id)
Add a reaction to this message.
Parameters
emoji (typing.Union[str, hikari.emojis.Emoji]): Object or name of the emoji to react with.
Note that if the emoji is an
hikari.emojis.CustomEmoji
and is not from a guild the bot user is in, then this will fail.
Other Parameters
emoji_id (hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]]): ID of the custom emoji to react with. This should only be provided when a custom emoji's name is passed for
emoji
.Note that this will fail if the emoji is from a guild the bot isn't in.
Examples
# Using a unicode emoji.
await message.add_reaction("👌")
# Using a unicode emoji name.
await message.add_reaction("\N{OK HAND SIGN}")
# Using the name and id.
await message.add_reaction("rooAYAYA", 705837374319493284)
# Using an Emoji-derived object.
await message.add_reaction(some_emoji_object)
Raises
- hikari.errors.BadRequestError: If the emoji is invalid, unknown, or formatted incorrectly.
- hikari.errors.ForbiddenError: If this is the first reaction using this specific emoji on this message and you lack the
ADD_REACTIONS
permission. If you lackREAD_MESSAGE_HISTORY
, this may also raise this error. - hikari.errors.NotFoundError: If the channel or message is not found, or if the emoji is not found.
This will also occur if you try to add an emoji from a guild you are not part of if no one else has previously reacted with the same emoji.
View Source
async def delete(self) -> None: """Delete this message. Raises ------ hikari.errors.NotFoundError If the channel this message was created in is not found, or if the message has already been deleted. hikari.errors.ForbiddenError If you lack the permissions to delete the message. """ await self.app.rest.delete_message(self.channel_id, self.id)
Delete this message.
Raises
- hikari.errors.NotFoundError: If the channel this message was created in is not found, or if the message has already been deleted.
- hikari.errors.ForbiddenError: If you lack the permissions to delete the message.
self,
content: Union[Any, hikari.undefined.UndefinedType] = UNDEFINED,
*,
attachment: Union[hikari.files.Resource[Any], os.PathLike[str], str, bytes, bytearray, memoryview, _io.BytesIO, _io.StringIO, hikari.undefined.UndefinedType] = UNDEFINED,
attachments: Union[Sequence[Union[hikari.files.Resource[Any], os.PathLike[str], str, bytes, bytearray, memoryview, _io.BytesIO, _io.StringIO]], hikari.undefined.UndefinedType] = UNDEFINED,
component: Union[hikari.api.special_endpoints.ComponentBuilder, hikari.undefined.UndefinedType, NoneType] = UNDEFINED,
components: Union[Sequence[hikari.api.special_endpoints.ComponentBuilder], hikari.undefined.UndefinedType, NoneType] = UNDEFINED,
embed: Union[hikari.embeds.Embed, hikari.undefined.UndefinedType, NoneType] = UNDEFINED,
embeds: Union[Sequence[hikari.embeds.Embed], hikari.undefined.UndefinedType, NoneType] = UNDEFINED,
replace_attachments: bool = False,
mentions_everyone: Union[bool, hikari.undefined.UndefinedType] = UNDEFINED,
mentions_reply: Union[bool, hikari.undefined.UndefinedType] = UNDEFINED,
user_mentions: Union[Sequence[Union[hikari.users.PartialUser, hikari.snowflakes.Snowflake, int]], bool, hikari.undefined.UndefinedType] = UNDEFINED,
role_mentions: Union[Sequence[Union[hikari.guilds.PartialRole, hikari.snowflakes.Snowflake, int]], bool, hikari.undefined.UndefinedType] = UNDEFINED,
flags: Union[hikari.messages.MessageFlag, hikari.undefined.UndefinedType] = UNDEFINED
) -> hikari.messages.Message:
View Source
async def edit( self, content: undefined.UndefinedOr[typing.Any] = undefined.UNDEFINED, *, attachment: undefined.UndefinedOr[files.Resourceish] = undefined.UNDEFINED, attachments: undefined.UndefinedOr[typing.Sequence[files.Resourceish]] = undefined.UNDEFINED, component: undefined.UndefinedNoneOr[special_endpoints.ComponentBuilder] = undefined.UNDEFINED, components: undefined.UndefinedNoneOr[ typing.Sequence[special_endpoints.ComponentBuilder] ] = undefined.UNDEFINED, embed: undefined.UndefinedNoneOr[embeds_.Embed] = undefined.UNDEFINED, embeds: undefined.UndefinedNoneOr[typing.Sequence[embeds_.Embed]] = undefined.UNDEFINED, replace_attachments: bool = False, mentions_everyone: undefined.UndefinedOr[bool] = undefined.UNDEFINED, mentions_reply: undefined.UndefinedOr[bool] = undefined.UNDEFINED, user_mentions: undefined.UndefinedOr[ typing.Union[snowflakes.SnowflakeishSequence[users_.PartialUser], bool] ] = undefined.UNDEFINED, role_mentions: undefined.UndefinedOr[ typing.Union[snowflakes.SnowflakeishSequence[guilds.PartialRole], bool] ] = undefined.UNDEFINED, flags: undefined.UndefinedOr[MessageFlag] = undefined.UNDEFINED, ) -> Message: """Edit an existing message in a given channel. .. note:: Mentioning everyone, roles, or users in message edits currently will not send a push notification showing a new mention to people on Discord. It will still highlight in their chat as if they were mentioned, however. .. warning:: If you specify a text `content`, `mentions_everyone`, `mentions_reply`, `user_mentions`, and `role_mentions` will default to `False` as the message will be re-parsed for mentions. This will also occur if only one of the four are specified This is a limitation of Discord's design. If in doubt, specify all four of them each time. .. warning:: If the message was not sent by your user, the only parameter you may provide to this call is the `flags` parameter. Anything else will result in a `hikari.errors.ForbiddenError` being raised. Parameters ---------- content : hikari.undefined.UndefinedOr[typing.Any] If provided, the message content to update with. If `hikari.undefined.UNDEFINED`, then the content will not be changed. If `None`, then the content will be removed. Any other value will be cast to a `str` before sending. If this is a `hikari.embeds.Embed` and neither the `embed` or `embeds` kwargs are provided or if this is a `hikari.files.Resourceish` and neither the `attachment` or `attachments` kwargs are provided, the values will be overwritten. This allows for simpler syntax when sending an embed or an attachment alone. Other Parameters ---------------- attachment : hikari.undefined.UndefinedOr[hikari.files.Resourceish] If provided, the attachment to set on the message. If `hikari.undefined.UNDEFINED`, the previous attachment, if present, is not changed. If this is `None`, then the attachment is removed, if present. Otherwise, the new attachment that was provided will be attached. attachments : hikari.undefined.UndefinedOr[typing.Sequence[hikari.files.Resourceish]] If provided, the attachments to set on the message. If `hikari.undefined.UNDEFINED`, the previous attachments, if present, are not changed. If this is `None`, then the attachments is removed, if present. Otherwise, the new attachments that were provided will be attached. component : hikari.undefined.UndefinedNoneOr[hikari.api.special_endpoints.ComponentBuilder] If provided, builder object of the component to set for this message. This component will replace any previously set components and passing `None` will remove all components. components : hikari.undefined.UndefinedNoneOr[typing.Sequence[hikari.api.special_endpoints.ComponentBuilder]] If provided, a sequence of the component builder objects set for this message. These components will replace any previously set components and passing `None` or an empty sequence will remove all components. embed : hikari.undefined.UndefinedNoneOr[hikari.embeds.Embed] If provided, the embed to set on the message. If `hikari.undefined.UNDEFINED`, the previous embed(s) are not changed. If this is `None` then any present embeds are removed. Otherwise, the new embed that was provided will be used as the replacement. embeds : hikari.undefined.UndefinedNoneOr[typing.Sequence[hikari.embeds.Embed]] If provided, the embeds to set on the message. If `hikari.undefined.UNDEFINED`, the previous embed(s) are not changed. If this is `None` then any present embeds are removed. Otherwise, the new embeds that were provided will be used as the replacement. replace_attachments: bool Whether to replace the attachments with the provided ones. Defaults to `False`. Note this will also overwrite the embed attachments. mentions_everyone : hikari.undefined.UndefinedOr[bool] Sanitation for `@everyone` mentions. If `hikari.undefined.UNDEFINED`, then the previous setting is not changed. If `True`, then `@everyone`/`@here` mentions in the message content will show up as mentioning everyone that can view the chat. mentions_reply : hikari.undefined.UndefinedOr[bool] If provided, whether to mention the author of the message that is being replied to. This will not do anything if this is not a reply message. user_mentions : hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.users.PartialUser], bool]] Sanitation for user mentions. If `hikari.undefined.UNDEFINED`, then the previous setting is not changed. If `True`, all valid user mentions will behave as mentions. If `False`, all valid user mentions will not behave as mentions. You may alternatively pass a collection of `hikari.snowflakes.Snowflake` user IDs, or `hikari.users.PartialUser`-derived objects. role_mentions : hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.guilds.PartialRole], bool]] Sanitation for role mentions. If `hikari.undefined.UNDEFINED`, then the previous setting is not changed. If `True`, all valid role mentions will behave as mentions. If `False`, all valid role mentions will not behave as mentions. You may alternatively pass a collection of `hikari.snowflakes.Snowflake` role IDs, or `hikari.guilds.PartialRole`-derived objects. flags : hikari.undefined.UndefinedOr[hikari.messages.MessageFlag] Optional flags to set on the message. If `hikari.undefined.UNDEFINED`, then nothing is changed. Note that some flags may not be able to be set. Currently the only flags that can be set are `NONE` and `SUPPRESS_EMBEDS`. If you have `MANAGE_MESSAGES` permissions, you can use this call to suppress embeds on another user's message. Returns ------- hikari.messages.Message The edited message. Raises ------ hikari.errors.BadRequestError This may be raised in several discrete situations, such as messages being empty with no embeds; messages with more than 2000 characters in them, embeds that exceed one of the many embed limits; invalid image URLs in embeds. hikari.errors.UnauthorizedError If you are unauthorized to make the request (invalid/missing token). hikari.errors.ForbiddenError If you lack permissions to send messages in the given channel; if you try to change the contents of another user's message; or if you try to edit the flags on another user's message without the permissions to manage messages. hikari.errors.NotFoundError If the channel or message is not found. hikari.errors.InternalServerError If an internal error occurs on Discord while handling the request. """ # noqa: E501 - Line too long return await self.app.rest.edit_message( message=self.id, channel=self.channel_id, content=content, attachment=attachment, attachments=attachments, component=component, components=components, embed=embed, embeds=embeds, replace_attachments=replace_attachments, mentions_everyone=mentions_everyone, mentions_reply=mentions_reply, user_mentions=user_mentions, role_mentions=role_mentions, flags=flags, )
Edit an existing message in a given channel.
Note: Mentioning everyone, roles, or users in message edits currently will not send a push notification showing a new mention to people on Discord. It will still highlight in their chat as if they were mentioned, however.
Warning: If you specify a text content
, mentions_everyone
, mentions_reply
, user_mentions
, and role_mentions
will default to False
as the message will be re-parsed for mentions. This will also occur if only one of the four are specified
This is a limitation of Discord's design. If in doubt, specify all four of them each time.
Warning: If the message was not sent by your user, the only parameter you may provide to this call is the flags
parameter. Anything else will result in a hikari.errors.ForbiddenError
being raised.
Parameters
content (hikari.undefined.UndefinedOr[typing.Any]): If provided, the message content to update with. If
hikari.undefined.UNDEFINED
, then the content will not be changed. IfNone
, then the content will be removed.Any other value will be cast to a
str
before sending.If this is a
hikari.embeds.Embed
and neither theembed
orembeds
kwargs are provided or if this is ahikari.files.Resourceish
and neither theattachment
orattachments
kwargs are provided, the values will be overwritten. This allows for simpler syntax when sending an embed or an attachment alone.
Other Parameters
- attachment (hikari.undefined.UndefinedOr[hikari.files.Resourceish]): If provided, the attachment to set on the message. If
hikari.undefined.UNDEFINED
, the previous attachment, if present, is not changed. If this isNone
, then the attachment is removed, if present. Otherwise, the new attachment that was provided will be attached. - attachments (hikari.undefined.UndefinedOr[typing.Sequence[hikari.files.Resourceish]]): If provided, the attachments to set on the message. If
hikari.undefined.UNDEFINED
, the previous attachments, if present, are not changed. If this isNone
, then the attachments is removed, if present. Otherwise, the new attachments that were provided will be attached. - component (hikari.undefined.UndefinedNoneOr[hikari.api.special_endpoints.ComponentBuilder]): If provided, builder object of the component to set for this message. This component will replace any previously set components and passing
None
will remove all components. - components (hikari.undefined.UndefinedNoneOr[typing.Sequence[hikari.api.special_endpoints.ComponentBuilder]]): If provided, a sequence of the component builder objects set for this message. These components will replace any previously set components and passing
None
or an empty sequence will remove all components. - embed (hikari.undefined.UndefinedNoneOr[hikari.embeds.Embed]): If provided, the embed to set on the message. If
hikari.undefined.UNDEFINED
, the previous embed(s) are not changed. If this isNone
then any present embeds are removed. Otherwise, the new embed that was provided will be used as the replacement. - embeds (hikari.undefined.UndefinedNoneOr[typing.Sequence[hikari.embeds.Embed]]): If provided, the embeds to set on the message. If
hikari.undefined.UNDEFINED
, the previous embed(s) are not changed. If this isNone
then any present embeds are removed. Otherwise, the new embeds that were provided will be used as the replacement. replace_attachments (bool): Whether to replace the attachments with the provided ones. Defaults to
False
.Note this will also overwrite the embed attachments.
- mentions_everyone (hikari.undefined.UndefinedOr[bool]): Sanitation for
@everyone
mentions. Ifhikari.undefined.UNDEFINED
, then the previous setting is not changed. IfTrue
, then@everyone
/@here
mentions in the message content will show up as mentioning everyone that can view the chat. mentions_reply (hikari.undefined.UndefinedOr[bool]): If provided, whether to mention the author of the message that is being replied to.
This will not do anything if this is not a reply message.
user_mentions (hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.users.PartialUser], bool]]): Sanitation for user mentions. If
hikari.undefined.UNDEFINED
, then the previous setting is not changed. IfTrue
, all valid user mentions will behave as mentions. IfFalse
, all valid user mentions will not behave as mentions.You may alternatively pass a collection of
hikari.snowflakes.Snowflake
user IDs, orhikari.users.PartialUser
-derived objects.role_mentions (hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.guilds.PartialRole], bool]]): Sanitation for role mentions. If
hikari.undefined.UNDEFINED
, then the previous setting is not changed. IfTrue
, all valid role mentions will behave as mentions. IfFalse
, all valid role mentions will not behave as mentions.You may alternatively pass a collection of
hikari.snowflakes.Snowflake
role IDs, orhikari.guilds.PartialRole
-derived objects.flags (hikari.undefined.UndefinedOr[hikari.messages.MessageFlag]): Optional flags to set on the message. If
hikari.undefined.UNDEFINED
, then nothing is changed.Note that some flags may not be able to be set. Currently the only flags that can be set are
NONE
andSUPPRESS_EMBEDS
. If you haveMANAGE_MESSAGES
permissions, you can use this call to suppress embeds on another user's message.
Returns
- hikari.messages.Message: The edited message.
Raises
- hikari.errors.BadRequestError: This may be raised in several discrete situations, such as messages being empty with no embeds; messages with more than 2000 characters in them, embeds that exceed one of the many embed limits; invalid image URLs in embeds.
- hikari.errors.UnauthorizedError: If you are unauthorized to make the request (invalid/missing token).
- hikari.errors.ForbiddenError: If you lack permissions to send messages in the given channel; if you try to change the contents of another user's message; or if you try to edit the flags on another user's message without the permissions to manage messages.
- hikari.errors.NotFoundError: If the channel or message is not found.
- hikari.errors.InternalServerError: If an internal error occurs on Discord while handling the request.
View Source
async def fetch_channel(self) -> channels_.PartialChannel: """Fetch the channel this message was created in. Returns ------- hikari.channels.PartialChannel The object of the channel this message belongs to. Raises ------ hikari.errors.BadRequestError If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer. hikari.errors.ForbiddenError If you don't have access to the channel this message belongs to. hikari.errors.NotFoundError If the channel this message was created in does not exist. hikari.errors.UnauthorizedError If you are unauthorized to make the request (invalid/missing token). hikari.errors.RateLimitTooLongError Raised in the event that a rate limit occurs that is longer than `max_rate_limit` when making a request. hikari.errors.RateLimitedError Usually, Hikari will handle and retry on hitting rate-limits automatically. This includes most bucket-specific rate-limits and global rate-limits. In some rare edge cases, however, Discord implements other undocumented rules for rate-limiting, such as limits per attribute. These cannot be detected or handled normally by Hikari due to their undocumented nature, and will trigger this exception if they occur. hikari.errors.InternalServerError If an internal error occurs on Discord while handling the request. """ return await self.app.rest.fetch_channel(self.channel_id)
Fetch the channel this message was created in.
Returns
- hikari.channels.PartialChannel: The object of the channel this message belongs to.
Raises
- hikari.errors.BadRequestError: If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer.
- hikari.errors.ForbiddenError: If you don't have access to the channel this message belongs to.
- hikari.errors.NotFoundError: If the channel this message was created in does not exist.
- hikari.errors.UnauthorizedError: If you are unauthorized to make the request (invalid/missing token).
- hikari.errors.RateLimitTooLongError: Raised in the event that a rate limit occurs that is longer than
max_rate_limit
when making a request. - hikari.errors.RateLimitedError: Usually, Hikari will handle and retry on hitting rate-limits automatically. This includes most bucket-specific rate-limits and global rate-limits. In some rare edge cases, however, Discord implements other undocumented rules for rate-limiting, such as limits per attribute. These cannot be detected or handled normally by Hikari due to their undocumented nature, and will trigger this exception if they occur.
- hikari.errors.InternalServerError: If an internal error occurs on Discord while handling the request.
self,
guild: Union[hikari.guilds.PartialGuild, hikari.snowflakes.Snowflake, int, NoneType]
) -> str:
View Source
def make_link(self, guild: typing.Optional[snowflakes.SnowflakeishOr[guilds.PartialGuild]]) -> str: """Generate a jump link to this message. Other Parameters ---------------- guild : typing.Optional[hikari.snowflakes.SnowflakeishOr[hikari.guilds.PartialGuild]] Object or ID of the guild this message is in or `None` to generate a DM message link. This parameter is necessary since `PartialMessage.guild_id` isn't returned by the REST API regardless of whether the message is in a DM or not. Returns ------- str The jump link to the message. """ guild_id_str = "@me" if guild is None else str(int(guild)) return f"{urls.BASE_URL}/channels/{guild_id_str}/{self.channel_id}/{self.id}"
Generate a jump link to this message.
Other Parameters
guild (typing.Optional[hikari.snowflakes.SnowflakeishOr[hikari.guilds.PartialGuild]]): Object or ID of the guild this message is in or
None
to generate a DM message link.This parameter is necessary since
PartialMessage.guild_id
isn't returned by the REST API regardless of whether the message is in a DM or not.
Returns
- str: The jump link to the message.
self,
emoji: Union[str, hikari.emojis.Emoji, hikari.undefined.UndefinedType] = UNDEFINED,
emoji_id: Union[hikari.emojis.CustomEmoji, hikari.snowflakes.Snowflake, int, hikari.undefined.UndefinedType] = UNDEFINED
) -> None:
View Source
async def remove_all_reactions( self, emoji: undefined.UndefinedOr[typing.Union[str, emojis_.Emoji]] = undefined.UNDEFINED, emoji_id: undefined.UndefinedOr[snowflakes.SnowflakeishOr[emojis_.CustomEmoji]] = undefined.UNDEFINED, ) -> None: r"""Remove all users' reactions for a specific emoji from the message. Other Parameters ---------------- emoji : hikari.undefined.UndefinedOr[typing.Union[str, hikari.emojis.Emoji]] Object or name of the emoji to get the reactions for. If not specified then all reactions are removed. emoji_id : hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]] ID of the custom emoji to react with. This should only be provided when a custom emoji's name is passed for `emoji`. Examples -------- ```py # Using a unicode emoji and removing all 👌 reacts from the message. # reaction. await message.remove_all_reactions("\N{OK HAND SIGN}") # Using the name and id. await message.add_reaction("rooAYAYA", 705837374319493284) # Removing all reactions entirely. await message.remove_all_reactions() ``` Raises ------ hikari.errors.ForbiddenError If you are missing the `MANAGE_MESSAGES` permission, or the permission to view the channel hikari.errors.NotFoundError If the channel or message is not found, or if the emoji is not found. hikari.errors.BadRequestError If the emoji is invalid, unknown, or formatted incorrectly. If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer. """ if emoji is undefined.UNDEFINED: await self.app.rest.delete_all_reactions(channel=self.channel_id, message=self.id) else: await self.app.rest.delete_all_reactions_for_emoji( channel=self.channel_id, message=self.id, emoji=emoji, emoji_id=emoji_id )
Remove all users' reactions for a specific emoji from the message.
Other Parameters
- emoji (hikari.undefined.UndefinedOr[typing.Union[str, hikari.emojis.Emoji]]): Object or name of the emoji to get the reactions for. If not specified then all reactions are removed.
- emoji_id (hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]]): ID of the custom emoji to react with. This should only be provided when a custom emoji's name is passed for
emoji
.
Examples
# Using a unicode emoji and removing all 👌 reacts from the message.
# reaction.
await message.remove_all_reactions("\N{OK HAND SIGN}")
# Using the name and id.
await message.add_reaction("rooAYAYA", 705837374319493284)
# Removing all reactions entirely.
await message.remove_all_reactions()
Raises
- hikari.errors.ForbiddenError: If you are missing the
MANAGE_MESSAGES
permission, or the permission to view the channel - hikari.errors.NotFoundError: If the channel or message is not found, or if the emoji is not found.
- hikari.errors.BadRequestError: If the emoji is invalid, unknown, or formatted incorrectly. If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer.
self,
emoji: Union[str, hikari.emojis.Emoji],
emoji_id: Union[hikari.emojis.CustomEmoji, hikari.snowflakes.Snowflake, int, hikari.undefined.UndefinedType] = UNDEFINED,
*,
user: Union[hikari.users.PartialUser, hikari.snowflakes.Snowflake, int, hikari.undefined.UndefinedType] = UNDEFINED
) -> None:
View Source
async def remove_reaction( self, emoji: typing.Union[str, emojis_.Emoji], emoji_id: undefined.UndefinedOr[snowflakes.SnowflakeishOr[emojis_.CustomEmoji]] = undefined.UNDEFINED, *, user: undefined.UndefinedOr[snowflakes.SnowflakeishOr[users_.PartialUser]] = undefined.UNDEFINED, ) -> None: r"""Remove a reaction from this message. Parameters ---------- emoji : typing.Union[str, hikari.emojis.Emoji] Object or name of the emoji to remove the reaction for. Other Parameters ---------------- emoji_id : hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]] ID of the custom emoji to remove the reaction for. This should only be provided when a custom emoji's name is passed for `emoji`. user : hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.users.PartialUser]] The user of the reaction to remove. If unspecified, then the bot's reaction is removed instead. Examples -------- ```py # Using a unicode emoji and removing the bot's reaction from this # reaction. await message.remove_reaction("\N{OK HAND SIGN}") # Using a custom emoji's name and ID to remove a specific user's # reaction from this reaction. await message.remove_reaction("a:Distraction", 745991233939439616, user=some_user) # Using a unicode emoji and removing a specific user from this # reaction. await message.remove_reaction("\N{OK HAND SIGN}", user=some_user) # Using the name and id. await message.add_reaction("rooAYAYA", 705837374319493284) # Using an Emoji object and removing a specific user from this # reaction. await message.remove_reaction(some_emoji_object, user=some_user) ``` Raises ------ hikari.errors.BadRequestError If the emoji is invalid, unknown, or formatted incorrectly. If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer. hikari.errors.ForbiddenError If this is the first reaction using this specific emoji on this message and you lack the `ADD_REACTIONS` permission. If you lack `READ_MESSAGE_HISTORY`, this may also raise this error. If you remove the reaction of another user without `MANAGE_MESSAGES`, this will be raised. hikari.errors.NotFoundError If the channel or message is not found, or if the emoji is not found. """ if user is undefined.UNDEFINED: await self.app.rest.delete_my_reaction( channel=self.channel_id, message=self.id, emoji=emoji, emoji_id=emoji_id ) else: await self.app.rest.delete_reaction( channel=self.channel_id, message=self.id, emoji=emoji, emoji_id=emoji_id, user=user )
Remove a reaction from this message.
Parameters
- emoji (typing.Union[str, hikari.emojis.Emoji]): Object or name of the emoji to remove the reaction for.
Other Parameters
- emoji_id (hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.emojis.CustomEmoji]]): ID of the custom emoji to remove the reaction for. This should only be provided when a custom emoji's name is passed for
emoji
. - user (hikari.undefined.UndefinedOr[hikari.snowflakes.SnowflakeishOr[hikari.users.PartialUser]]): The user of the reaction to remove. If unspecified, then the bot's reaction is removed instead.
Examples
# Using a unicode emoji and removing the bot's reaction from this
# reaction.
await message.remove_reaction("\N{OK HAND SIGN}")
# Using a custom emoji's name and ID to remove a specific user's
# reaction from this reaction.
await message.remove_reaction("a:Distraction", 745991233939439616, user=some_user)
# Using a unicode emoji and removing a specific user from this
# reaction.
await message.remove_reaction("\N{OK HAND SIGN}", user=some_user)
# Using the name and id.
await message.add_reaction("rooAYAYA", 705837374319493284)
# Using an Emoji object and removing a specific user from this
# reaction.
await message.remove_reaction(some_emoji_object, user=some_user)
Raises
- hikari.errors.BadRequestError: If the emoji is invalid, unknown, or formatted incorrectly. If any invalid snowflake IDs are passed; a snowflake may be invalid due to it being outside of the range of a 64 bit integer.
- hikari.errors.ForbiddenError: If this is the first reaction using this specific emoji on this message and you lack the
ADD_REACTIONS
permission. If you lackREAD_MESSAGE_HISTORY
, this may also raise this error. If you remove the reaction of another user withoutMANAGE_MESSAGES
, this will be raised. - hikari.errors.NotFoundError: If the channel or message is not found, or if the emoji is not found.
self,
content: Union[Any, hikari.undefined.UndefinedType] = UNDEFINED,
*,
attachment: Union[hikari.files.Resource[Any], os.PathLike[str], str, bytes, bytearray, memoryview, _io.BytesIO, _io.StringIO, hikari.undefined.UndefinedType] = UNDEFINED,
attachments: Union[Sequence[Union[hikari.files.Resource[Any], os.PathLike[str], str, bytes, bytearray, memoryview, _io.BytesIO, _io.StringIO]], hikari.undefined.UndefinedType] = UNDEFINED,
component: Union[hikari.api.special_endpoints.ComponentBuilder, hikari.undefined.UndefinedType] = UNDEFINED,
components: Union[Sequence[hikari.api.special_endpoints.ComponentBuilder], hikari.undefined.UndefinedType] = UNDEFINED,
embed: Union[hikari.embeds.Embed, hikari.undefined.UndefinedType] = UNDEFINED,
embeds: Union[Sequence[hikari.embeds.Embed], hikari.undefined.UndefinedType] = UNDEFINED,
tts: Union[bool, hikari.undefined.UndefinedType] = UNDEFINED,
reply: Union[hikari.undefined.UndefinedType, hikari.messages.PartialMessage, hikari.snowflakes.Snowflake, int, bool] = UNDEFINED,
mentions_everyone: Union[bool, hikari.undefined.UndefinedType] = UNDEFINED,
mentions_reply: Union[bool, hikari.undefined.UndefinedType] = UNDEFINED,
user_mentions: Union[Sequence[Union[hikari.users.PartialUser, hikari.snowflakes.Snowflake, int]], bool, hikari.undefined.UndefinedType] = UNDEFINED,
role_mentions: Union[Sequence[Union[hikari.guilds.PartialRole, hikari.snowflakes.Snowflake, int]], bool, hikari.undefined.UndefinedType] = UNDEFINED
) -> hikari.messages.Message:
View Source
async def respond( self, content: undefined.UndefinedOr[typing.Any] = undefined.UNDEFINED, *, attachment: undefined.UndefinedOr[files.Resourceish] = undefined.UNDEFINED, attachments: undefined.UndefinedOr[typing.Sequence[files.Resourceish]] = undefined.UNDEFINED, component: undefined.UndefinedOr[special_endpoints.ComponentBuilder] = undefined.UNDEFINED, components: undefined.UndefinedOr[typing.Sequence[special_endpoints.ComponentBuilder]] = undefined.UNDEFINED, embed: undefined.UndefinedOr[embeds_.Embed] = undefined.UNDEFINED, embeds: undefined.UndefinedOr[typing.Sequence[embeds_.Embed]] = undefined.UNDEFINED, tts: undefined.UndefinedOr[bool] = undefined.UNDEFINED, reply: typing.Union[ undefined.UndefinedType, snowflakes.SnowflakeishOr[PartialMessage], bool ] = undefined.UNDEFINED, mentions_everyone: undefined.UndefinedOr[bool] = undefined.UNDEFINED, mentions_reply: undefined.UndefinedOr[bool] = undefined.UNDEFINED, user_mentions: undefined.UndefinedOr[ typing.Union[snowflakes.SnowflakeishSequence[users_.PartialUser], bool] ] = undefined.UNDEFINED, role_mentions: undefined.UndefinedOr[ typing.Union[snowflakes.SnowflakeishSequence[guilds.PartialRole], bool] ] = undefined.UNDEFINED, ) -> Message: """Create a message in the channel this message belongs to. Parameters ---------- content : hikari.undefined.UndefinedOr[typing.Any] If provided, the message contents. If `hikari.undefined.UNDEFINED`, then nothing will be sent in the content. Any other value here will be cast to a `str`. If this is a `hikari.embeds.Embed` and no `embed` nor `embeds` kwarg is provided, then this will instead update the embed. This allows for simpler syntax when sending an embed alone. Likewise, if this is a `hikari.files.Resource`, then the content is instead treated as an attachment if no `attachment` and no `attachments` kwargs are provided. Other Parameters ---------------- attachment : hikari.undefined.UndefinedOr[hikari.files.Resourceish], If provided, the message attachment. This can be a resource, or string of a path on your computer or a URL. Attachments can be passed as many different things, to aid in convenience. - If a `pathlib.PurePath` or `str` to a valid URL, the resource at the given URL will be streamed to Discord when sending the message. Subclasses of `hikari.files.WebResource` such as `hikari.files.URL`, `hikari.messages.Attachment`, `hikari.emojis.Emoji`, `EmbedResource`, etc will also be uploaded this way. This will use bit-inception, so only a small percentage of the resource will remain in memory at any one time, thus aiding in scalability. - If a `hikari.files.Bytes` is passed, or a `str` that contains a valid data URI is passed, then this is uploaded with a randomized file name if not provided. - If a `hikari.files.File`, `pathlib.PurePath` or `str` that is an absolute or relative path to a file on your file system is passed, then this resource is uploaded as an attachment using non-blocking code internally and streamed using bit-inception where possible. This depends on the type of `concurrent.futures.Executor` that is being used for the application (default is a thread pool which supports this behaviour). attachments : hikari.undefined.UndefinedOr[typing.Sequence[hikari.files.Resourceish]], If provided, the message attachments. These can be resources, or strings consisting of paths on your computer or URLs. component : hikari.undefined.UndefinedOr[hikari.api.special_endpoints.ComponentBuilder] If provided, builder object of the component to include in this message. components : hikari.undefined.UndefinedOr[typing.Sequence[hikari.api.special_endpoints.ComponentBuilder]] If provided, a sequence of the component builder objects to include in this message. embed : hikari.undefined.UndefinedOr[hikari.embeds.Embed] If provided, the message embed. embeds : hikari.undefined.UndefinedOr[typing.Sequence[hikari.embeds.Embed]] If provided, the message embeds. tts : hikari.undefined.UndefinedOr[bool] If provided, whether the message will be TTS (Text To Speech). reply : typing.Union[hikari.undefined.UndefinedType, hikari.snowflakes.SnowflakeishOr[hikari.messages.PartialMessage], bool] If provided and `True`, reply to this message. If provided and not `bool`, the message to reply to. mentions_everyone : hikari.undefined.UndefinedOr[bool] If provided, whether the message should parse @everyone/@here mentions. mentions_reply : hikari.undefined.UndefinedOr[bool] If provided, whether to mention the author of the message that is being replied to. This will not do anything if not being used with `reply`. user_mentions : hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.users.PartialUser], bool]] If provided, and `True`, all mentions will be parsed. If provided, and `False`, no mentions will be parsed. Alternatively this may be a collection of `hikari.snowflakes.Snowflake`, or `hikari.users.PartialUser` derivatives to enforce mentioning specific users. role_mentions : hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.guilds.PartialRole], bool]] If provided, and `True`, all mentions will be parsed. If provided, and `False`, no mentions will be parsed. Alternatively this may be a collection of `hikari.snowflakes.Snowflake`, or `hikari.guilds.PartialRole` derivatives to enforce mentioning specific roles. Returns ------- hikari.messages.Message The created message. Raises ------ hikari.errors.BadRequestError This may be raised in several discrete situations, such as messages being empty with no attachments or embeds; messages with more than 2000 characters in them, embeds that exceed one of the many embed limits; too many attachments; attachments that are too large; invalid image URLs in embeds; `reply` not found or not in the same channel; too many components. hikari.errors.UnauthorizedError If you are unauthorized to make the request (invalid/missing token). hikari.errors.ForbiddenError If you lack permissions to send messages in the given channel. hikari.errors.NotFoundError If the channel is not found. hikari.errors.InternalServerError If an internal error occurs on Discord while handling the request. ValueError If more than 100 unique objects/entities are passed for `role_mentions` or `user_mentions`. TypeError If both `attachment` and `attachments` are specified. """ # noqa: E501 - Line too long if reply is True: reply = self elif reply is False: reply = undefined.UNDEFINED return await self.app.rest.create_message( channel=self.channel_id, content=content, attachment=attachment, attachments=attachments, component=component, components=components, embed=embed, embeds=embeds, tts=tts, reply=reply, mentions_everyone=mentions_everyone, user_mentions=user_mentions, role_mentions=role_mentions, mentions_reply=mentions_reply, )
Create a message in the channel this message belongs to.
Parameters
content (hikari.undefined.UndefinedOr[typing.Any]): If provided, the message contents. If
hikari.undefined.UNDEFINED
, then nothing will be sent in the content. Any other value here will be cast to astr
.If this is a
hikari.embeds.Embed
and noembed
norembeds
kwarg is provided, then this will instead update the embed. This allows for simpler syntax when sending an embed alone.Likewise, if this is a
hikari.files.Resource
, then the content is instead treated as an attachment if noattachment
and noattachments
kwargs are provided.
Other Parameters
attachment (hikari.undefined.UndefinedOr[hikari.files.Resourceish],): If provided, the message attachment. This can be a resource, or string of a path on your computer or a URL.
Attachments can be passed as many different things, to aid in convenience.
- If a
pathlib.PurePath
orstr
to a valid URL, the resource at the given URL will be streamed to Discord when sending the message. Subclasses ofhikari.files.WebResource
such ashikari.files.URL
,hikari.messages.Attachment
,hikari.emojis.Emoji
,EmbedResource
, etc will also be uploaded this way. This will use bit-inception, so only a small percentage of the resource will remain in memory at any one time, thus aiding in scalability. - If a
hikari.files.Bytes
is passed, or astr
that contains a valid data URI is passed, then this is uploaded with a randomized file name if not provided. - If a
hikari.files.File
,pathlib.PurePath
orstr
that is an absolute or relative path to a file on your file system is passed, then this resource is uploaded as an attachment using non-blocking code internally and streamed using bit-inception where possible. This depends on the type ofconcurrent.futures.Executor
that is being used for the application (default is a thread pool which supports this behaviour).
- If a
- attachments (hikari.undefined.UndefinedOr[typing.Sequence[hikari.files.Resourceish]],): If provided, the message attachments. These can be resources, or strings consisting of paths on your computer or URLs.
- component (hikari.undefined.UndefinedOr[hikari.api.special_endpoints.ComponentBuilder]): If provided, builder object of the component to include in this message.
- components (hikari.undefined.UndefinedOr[typing.Sequence[hikari.api.special_endpoints.ComponentBuilder]]): If provided, a sequence of the component builder objects to include in this message.
- embed (hikari.undefined.UndefinedOr[hikari.embeds.Embed]): If provided, the message embed.
- embeds (hikari.undefined.UndefinedOr[typing.Sequence[hikari.embeds.Embed]]): If provided, the message embeds.
- tts (hikari.undefined.UndefinedOr[bool]): If provided, whether the message will be TTS (Text To Speech).
- reply (typing.Union[hikari.undefined.UndefinedType, hikari.snowflakes.SnowflakeishOr[hikari.messages.PartialMessage], bool]): If provided and
True
, reply to this message. If provided and notbool
, the message to reply to. - mentions_everyone (hikari.undefined.UndefinedOr[bool]): If provided, whether the message should parse @everyone/@here mentions.
mentions_reply (hikari.undefined.UndefinedOr[bool]): If provided, whether to mention the author of the message that is being replied to.
This will not do anything if not being used with
reply
.- user_mentions (hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.users.PartialUser], bool]]): If provided, and
True
, all mentions will be parsed. If provided, andFalse
, no mentions will be parsed. Alternatively this may be a collection ofhikari.snowflakes.Snowflake
, orhikari.users.PartialUser
derivatives to enforce mentioning specific users. - role_mentions (hikari.undefined.UndefinedOr[typing.Union[hikari.snowflakes.SnowflakeishSequence[hikari.guilds.PartialRole], bool]]): If provided, and
True
, all mentions will be parsed. If provided, andFalse
, no mentions will be parsed. Alternatively this may be a collection ofhikari.snowflakes.Snowflake
, orhikari.guilds.PartialRole
derivatives to enforce mentioning specific roles.
Returns
- hikari.messages.Message: The created message.
Raises
- hikari.errors.BadRequestError: This may be raised in several discrete situations, such as messages being empty with no attachments or embeds; messages with more than 2000 characters in them, embeds that exceed one of the many embed limits; too many attachments; attachments that are too large; invalid image URLs in embeds;
reply
not found or not in the same channel; too many components. - hikari.errors.UnauthorizedError: If you are unauthorized to make the request (invalid/missing token).
- hikari.errors.ForbiddenError: If you lack permissions to send messages in the given channel.
- hikari.errors.NotFoundError: If the channel is not found.
- hikari.errors.InternalServerError: If an internal error occurs on Discord while handling the request.
- ValueError: If more than 100 unique objects/entities are passed for
role_mentions
oruser_mentions
. - TypeError: If both
attachment
andattachments
are specified.
View Source
@attr_extensions.with_copy @attr.define(hash=True, kw_only=True, weakref_slot=False) class Reaction: """Represents a reaction in a message.""" count: int = attr.field(eq=False, hash=False, repr=True) """The number of times the emoji has been used to react.""" emoji: typing.Union[emojis_.UnicodeEmoji, emojis_.CustomEmoji] = attr.field(hash=True, repr=True) """The emoji used to react.""" is_me: bool = attr.field(eq=False, hash=False, repr=False) """Whether the current user reacted using this emoji.""" def __str__(self) -> str: return str(self.emoji)
Represents a reaction in a message.
Variables and properties
The number of times the emoji has been used to react.
The emoji used to react.
Whether the current user reacted using this emoji.
Methods
self,
*,
count: int,
emoji: Union[hikari.emojis.UnicodeEmoji, hikari.emojis.CustomEmoji],
is_me: bool
):
View Source
def __init__(self, *, count, emoji, is_me): self.count = count self.emoji = emoji self.is_me = is_me
Method generated by attrs for class Reaction.
View Source
@attr.define(hash=True, kw_only=True, weakref_slot=False) class SelectMenuComponent(PartialComponent): """Represents a message button component. .. note:: This is an embedded component and will only ever be found within top-level container components such as `ActionRowComponent`. """ custom_id: str = attr.field(hash=True) """Developer defined identifier for this menu (will be <= 100 characters).""" options: typing.Sequence[SelectMenuOption] = attr.field(eq=False) """Sequence of up to 25 of the options set for this menu.""" placeholder: typing.Optional[str] = attr.field(eq=False) """Custom placeholder text shown if nothing is selected, max 100 characters.""" min_values: int = attr.field(eq=False) """The minimum amount of options which must be chosen for this menu. This will be greater than or equal to 0 and will be less than or equal to `SelectMenuComponent.max_values`. """ max_values: int = attr.field(eq=False) """The minimum amount of options which can be chosen for this menu. This will be less than or equal to 25 and will be greater than or equal to `SelectMenuComponent.min_values`. """ is_disabled: bool = attr.field(eq=False) """Whether the select menu is disabled."""
Represents a message button component.
Note: This is an embedded component and will only ever be found within top-level container components such as ActionRowComponent
.
Variables and properties
Developer defined identifier for this menu (will be <= 100 characters).
Whether the select menu is disabled.
The minimum amount of options which can be chosen for this menu.
This will be less than or equal to 25 and will be greater than or equal to SelectMenuComponent.min_values
.
The minimum amount of options which must be chosen for this menu.
This will be greater than or equal to 0 and will be less than or equal to SelectMenuComponent.max_values
.
Sequence of up to 25 of the options set for this menu.
Custom placeholder text shown if nothing is selected, max 100 characters.
The type of component this is.
Methods
self,
*,
type: Union[hikari.messages.ComponentType, int],
custom_id: str,
options: Sequence[hikari.messages.SelectMenuOption],
placeholder: Optional[str],
min_values: int,
max_values: int,
is_disabled: bool
):
View Source
def __init__(self, *, type, custom_id, options, placeholder, min_values, max_values, is_disabled): self.type = type self.custom_id = custom_id self.options = options self.placeholder = placeholder self.min_values = min_values self.max_values = max_values self.is_disabled = is_disabled
Method generated by attrs for class SelectMenuComponent.
View Source
@attr.define(kw_only=True, weakref_slot=False) class SelectMenuOption: """Represents an option for a `SelectMenuComponent`.""" label: str = attr.field() """User-facing name of the option, max 100 characters.""" value: str = attr.field() """Dev-defined value of the option, max 100 characters.""" description: typing.Optional[str] = attr.field() """Optional description of the option, max 100 characters.""" emoji: typing.Optional[emojis_.Emoji] = attr.field(eq=False) """Custom or unicode emoji which appears on the button.""" is_default: bool = attr.field() """Whether this option will be selected by default."""
Represents an option for a SelectMenuComponent
.
Variables and properties
Optional description of the option, max 100 characters.
Custom or unicode emoji which appears on the button.
Whether this option will be selected by default.
User-facing name of the option, max 100 characters.
Dev-defined value of the option, max 100 characters.
Methods
self,
*,
label: str,
value: str,
description: Optional[str],
emoji: Optional[hikari.emojis.Emoji],
is_default: bool
):
View Source
def __init__(self, *, label, value, description, emoji, is_default): self.label = label self.value = value self.description = description self.emoji = emoji self.is_default = is_default
Method generated by attrs for class SelectMenuOption.