Skip to content

Commit

Permalink
Implement user installations (#2177)
Browse files Browse the repository at this point in the history
Co-authored-by: davfsa <davfsa@gmail.com>
  • Loading branch information
mplatypus and davfsa authored Mar 5, 2025
1 parent 0cf0eec commit 1306a12
Show file tree
Hide file tree
Showing 25 changed files with 750 additions and 30 deletions.
4 changes: 4 additions & 0 deletions changes/2177.breaking.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
User commands breaking changes:
- Remove previously deprecated `command_interactions.InteractionChannel` and `command_interactions.ResolvedOptionData`
- `CommandInteraction.app_permissions` is no longer optional
- Removal of `Commands.dm_permissions` and `Message.interaction`. Use `Commands.contexts` and `Message.interaction_metadata` respectively
1 change: 1 addition & 0 deletions changes/2177.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add user installations support
2 changes: 2 additions & 0 deletions hikari/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@
from hikari._about import __url__
from hikari._about import __version__
from hikari.applications import Application
from hikari.applications import ApplicationContextType
from hikari.applications import ApplicationFlags
from hikari.applications import ApplicationIntegrationType
from hikari.applications import ApplicationRoleConnectionMetadataRecord
from hikari.applications import ApplicationRoleConnectionMetadataRecordType
from hikari.applications import AuthorizationApplication
Expand Down
2 changes: 2 additions & 0 deletions hikari/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ from hikari._about import __maintainer__ as __maintainer__
from hikari._about import __url__ as __url__
from hikari._about import __version__ as __version__
from hikari.applications import Application as Application
from hikari.applications import ApplicationContextType as ApplicationContextType
from hikari.applications import ApplicationFlags as ApplicationFlags
from hikari.applications import ApplicationIntegrationType as ApplicationIntegrationType
from hikari.applications import ApplicationRoleConnectionMetadataRecord as ApplicationRoleConnectionMetadataRecord
from hikari.applications import (
ApplicationRoleConnectionMetadataRecordType as ApplicationRoleConnectionMetadataRecordType,
Expand Down
45 changes: 45 additions & 0 deletions hikari/api/special_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@

from typing_extensions import Self

from hikari import applications
from hikari import channels
from hikari import colors
from hikari import commands
Expand Down Expand Up @@ -1026,6 +1027,16 @@ def is_nsfw(self) -> undefined.UndefinedOr[bool]:
def name_localizations(self) -> typing.Mapping[typing.Union[locales.Locale, str], str]:
"""Name localizations set for this command."""

@property
@abc.abstractmethod
def integration_types(self) -> undefined.UndefinedOr[typing.Sequence[applications.ApplicationIntegrationType]]:
"""The integration types allowed for this command."""

@property
@abc.abstractmethod
def context_types(self) -> undefined.UndefinedOr[typing.Sequence[applications.ApplicationContextType]]:
"""The context types allowed for this command."""

@abc.abstractmethod
def set_name(self, name: str, /) -> Self:
"""Set the name of this command.
Expand Down Expand Up @@ -1123,6 +1134,40 @@ def set_name_localizations(
Object of this command builder.
"""

@abc.abstractmethod
def set_integration_types(
self, integration_types: undefined.UndefinedOr[typing.Sequence[applications.ApplicationIntegrationType]]
) -> Self:
"""Set the integration types for this command.
Parameters
----------
integration_types
The integration types to set for this command.
Returns
-------
CommandBuilder
Object of this command builder.
"""

@abc.abstractmethod
def set_context_types(
self, context_types: undefined.UndefinedOr[typing.Sequence[applications.ApplicationContextType]]
) -> Self:
"""Set the context types for this command.
Parameters
----------
context_types
The context types to set for this command.
Returns
-------
CommandBuilder
Object of this command builder.
"""

@abc.abstractmethod
def build(self, entity_factory: entity_factory_.EntityFactory, /) -> typing.MutableMapping[str, typing.Any]:
"""Build a JSON object from this builder.
Expand Down
55 changes: 55 additions & 0 deletions hikari/applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
"TokenType",
"ApplicationRoleConnectionMetadataRecordType",
"ApplicationRoleConnectionMetadataRecord",
"OAuth2InstallParameters",
"ApplicationContextType",
"ApplicationIntegrationType",
"ApplicationIntegrationConfiguration",
"get_token_id",
)

Expand Down Expand Up @@ -634,6 +638,11 @@ class Application(guilds.PartialApplication):
approximate_guild_count: int = attrs.field(eq=False, hash=False, repr=False)
"""The approximate number of guilds this application is part of."""

integration_types_config: typing.Mapping[ApplicationIntegrationType, ApplicationIntegrationConfiguration] = (
attrs.field(eq=False, hash=False, repr=False)
)
"""The default scopes and permissions for each integration type."""

@property
def cover_image_url(self) -> typing.Optional[files.URL]:
"""Rich presence cover image URL for this application, if set."""
Expand Down Expand Up @@ -846,6 +855,52 @@ class ApplicationRoleConnectionMetadataRecord:
"""A mapping of description localizations for this metadata field."""


@attrs_extensions.with_copy
@attrs.define(kw_only=True, weakref_slot=False)
class ApplicationIntegrationConfiguration:
"""The Application Integration Configuration for the related [ApplicationIntegrationType][]."""

oauth2_install_parameters: typing.Optional[OAuth2InstallParameters] = attrs.field(eq=False, hash=False, repr=True)
"""The OAuth2 Install parameters for the Application Integration."""


@attrs_extensions.with_copy
@attrs.define(kw_only=True, weakref_slot=False)
class OAuth2InstallParameters:
"""OAuth2 Install Parameters."""

scopes: typing.Sequence[OAuth2Scope] = attrs.field(eq=False, hash=False, repr=True)
"""The scopes the application will be added to the server with."""

permissions: permissions_.Permissions = attrs.field(eq=False, hash=False, repr=True)
"""The permissions that will be requested for the bot role."""


@typing.final
class ApplicationIntegrationType(int, enums.Enum):
"""Where an application can be installed."""

GUILD_INSTALL = 0
"""Application is installable to all guilds."""

USER_INSTALL = 1
"""Application is installable to all users."""


@typing.final
class ApplicationContextType(int, enums.Enum):
"""The context in which to install the application."""

GUILD = 0
"""Command can be ran inside servers."""

BOT_DM = 1
"""Command can be ran inside the bot's DM."""

PRIVATE_CHANNEL = 2
"""Command can be ran inside any of the user's DM or Group DM's, other than the bot's DM."""


def get_token_id(token: str) -> snowflakes.Snowflake:
"""Try to get the bot ID stored in a token.
Expand Down
9 changes: 9 additions & 0 deletions hikari/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
from hikari.internal import enums

if typing.TYPE_CHECKING:
from hikari import applications
from hikari import channels
from hikari import guilds
from hikari import locales
Expand Down Expand Up @@ -265,6 +266,14 @@ class PartialCommand(snowflakes.Unique):
)
"""A mapping of name localizations for this command."""

integration_types: typing.Sequence[applications.ApplicationIntegrationType] = attrs.field(
eq=False, hash=False, repr=False
)
"""The integration types allowed for this command."""

context_types: typing.Sequence[applications.ApplicationContextType] = attrs.field(eq=False, hash=False, repr=False)
"""The context types allowed for this command."""

async def fetch_self(self) -> PartialCommand:
"""Fetch an up-to-date version of this command object.
Expand Down
Loading

0 comments on commit 1306a12

Please sign in to comment.