Skip to content

Commit b0493dc

Browse files
plun1331pre-commit-ci[bot]LulalabyDorukyum
authored
feat: application role connections (#1791)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Lala Sabathil <[email protected]> Co-authored-by: Dorukyum <[email protected]>
1 parent 615f48d commit b0493dc

File tree

9 files changed

+311
-0
lines changed

9 files changed

+311
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ These changes are available on the `master` branch, but have not yet been releas
1717
([#1809](https://github.com/Pycord-Development/pycord/pull/1809))
1818
- Added missing `image` parameter to `Guild.create_scheduled_event()` method.
1919
([#1831](https://github.com/Pycord-Development/pycord/pull/1831))
20+
- New `ApplicationRoleConnectionMetadata` class for application role connection
21+
metadata, along with the `fetch_role_connection_metadata_records` and
22+
`update_role_connection_metadata_records` methods in `Client`.
23+
([#1791](https://github.com/Pycord-Development/pycord/pull/1791))
2024
- Added new message types, `interaction_premium_upsell`, `stage_start`, `stage_end`,
2125
`stage_speaker`, `stage_raise_hand`, `stage_topic`, and
2226
`guild_application_premium_subscription`.

discord/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from . import abc, opus, sinks, ui, utils
2828
from .activity import *
2929
from .appinfo import *
30+
from .application_role_connection import *
3031
from .asset import *
3132
from .audit_logs import *
3233
from .automod import *
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
"""
2+
The MIT License (MIT)
3+
4+
Copyright (c) 2021-present Pycord Development
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a
7+
copy of this software and associated documentation files (the "Software"),
8+
to deal in the Software without restriction, including without limitation
9+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
10+
and/or sell copies of the Software, and to permit persons to whom the
11+
Software is furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in
14+
all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22+
DEALINGS IN THE SOFTWARE.
23+
"""
24+
25+
from __future__ import annotations
26+
27+
from typing import TYPE_CHECKING
28+
29+
from .enums import ApplicationRoleConnectionMetadataType, try_enum
30+
from .utils import MISSING
31+
32+
if TYPE_CHECKING:
33+
from .types.application_role_connection import (
34+
ApplicationRoleConnectionMetadata as ApplicationRoleConnectionMetadataPayload,
35+
)
36+
37+
__all__ = ("ApplicationRoleConnectionMetadata",)
38+
39+
40+
class ApplicationRoleConnectionMetadata:
41+
r"""Represents role connection metadata for a Discord application.
42+
43+
.. versionadded:: 2.4
44+
45+
Parameters
46+
----------
47+
type: :class:`ApplicationRoleConnectionMetadataType`
48+
The type of metadata value.
49+
key: :class:`str`
50+
The key for this metadata field.
51+
May only be the ``a-z``, ``0-9``, or ``_`` characters, with a maximum of 50 characters.
52+
name: :class:`str`
53+
The name for this metadata field. Maximum 100 characters.
54+
description: :class:`str`
55+
The description for this metadata field. Maximum 200 characters.
56+
name_localizations: Optional[Dict[:class:`str`, :class:`str`]]
57+
The name localizations for this metadata field. The values of this should be ``"locale": "name"``.
58+
See `here <https://discord.com/developers/docs/reference#locales>`_ for a list of valid locales.
59+
description_localizations: Optional[Dict[:class:`str`, :class:`str`]]
60+
The description localizations for this metadata field. The values of this should be ``"locale": "name"``.
61+
See `here <https://discord.com/developers/docs/reference#locales>`_ for a list of valid locales.
62+
"""
63+
64+
__slots__ = (
65+
"type",
66+
"key",
67+
"name",
68+
"description",
69+
"name_localizations",
70+
"description_localizations",
71+
)
72+
73+
def __init__(
74+
self,
75+
*,
76+
type: ApplicationRoleConnectionMetadataType,
77+
key: str,
78+
name: str,
79+
description: str,
80+
name_localizations: dict[str, str] = MISSING,
81+
description_localizations: dict[str, str] = MISSING,
82+
):
83+
self.type: ApplicationRoleConnectionMetadataType = type
84+
self.key: str = key
85+
self.name: str = name
86+
self.name_localizations: dict[str, str] = name_localizations
87+
self.description: str = description
88+
self.description_localizations: dict[str, str] = description_localizations
89+
90+
def __repr__(self):
91+
return (
92+
f"<ApplicationRoleConnectionMetadata "
93+
f"type={self.type!r} "
94+
f"key={self.key!r} "
95+
f"name={self.name!r} "
96+
f"description={self.description!r} "
97+
f"name_localizations={self.name_localizations!r} "
98+
f"description_localizations={self.description_localizations!r}>"
99+
)
100+
101+
def __str__(self):
102+
return self.name
103+
104+
@classmethod
105+
def from_dict(
106+
cls, data: ApplicationRoleConnectionMetadataPayload
107+
) -> ApplicationRoleConnectionMetadata:
108+
return cls(
109+
type=try_enum(ApplicationRoleConnectionMetadataType, data["type"]),
110+
key=data["key"],
111+
name=data["name"],
112+
description=data["description"],
113+
name_localizations=data.get("name_localizations"),
114+
description_localizations=data.get("description_localizations"),
115+
)
116+
117+
def to_dict(self) -> ApplicationRoleConnectionMetadataPayload:
118+
data = {
119+
"type": self.type.value,
120+
"key": self.key,
121+
"name": self.name,
122+
"description": self.description,
123+
}
124+
if self.name_localizations is not MISSING:
125+
data["name_localizations"] = self.name_localizations
126+
if self.description_localizations is not MISSING:
127+
data["description_localizations"] = self.description_localizations
128+
return data

discord/client.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
from . import utils
3838
from .activity import ActivityTypes, BaseActivity, create_activity
3939
from .appinfo import AppInfo, PartialAppInfo
40+
from .application_role_connection import ApplicationRoleConnectionMetadata
4041
from .backoff import ExponentialBackoff
4142
from .channel import PartialMessageable, _threaded_channel_factory
4243
from .emoji import Emoji
@@ -1782,3 +1783,47 @@ def persistent_views(self) -> Sequence[View]:
17821783
.. versionadded:: 2.0
17831784
"""
17841785
return self._connection.persistent_views
1786+
1787+
async def fetch_role_connection_metadata_records(
1788+
self,
1789+
) -> list[ApplicationRoleConnectionMetadata]:
1790+
"""|coro|
1791+
1792+
Fetches the bot's role connection metadata records.
1793+
1794+
.. versionadded:: 2.4
1795+
1796+
Returns
1797+
-------
1798+
List[:class:`.ApplicationRoleConnectionMetadata`]
1799+
The bot's role connection metadata records.
1800+
"""
1801+
data = await self._connection.http.get_application_role_connection_metadata_records(
1802+
self.application_id
1803+
)
1804+
return [ApplicationRoleConnectionMetadata.from_dict(r) for r in data]
1805+
1806+
async def update_role_connection_metadata_records(
1807+
self, *role_connection_metadata
1808+
) -> list[ApplicationRoleConnectionMetadata]:
1809+
"""|coro|
1810+
1811+
Updates the bot's role connection metadata records.
1812+
1813+
.. versionadded:: 2.4
1814+
1815+
Parameters
1816+
----------
1817+
*role_connection_metadata: :class:`ApplicationRoleConnectionMetadata`
1818+
The new metadata records to send to Discord.
1819+
1820+
Returns
1821+
-------
1822+
List[:class:`.ApplicationRoleConnectionMetadata`]
1823+
The updated role connection metadata records.
1824+
"""
1825+
payload = [r.to_dict() for r in role_connection_metadata]
1826+
data = await self._connection.http.update_application_role_connection_metadata_records(
1827+
self.application_id, payload
1828+
)
1829+
return [ApplicationRoleConnectionMetadata.from_dict(r) for r in data]

discord/enums.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
"AutoModEventType",
6868
"AutoModActionType",
6969
"AutoModKeywordPresetType",
70+
"ApplicationRoleConnectionMetadataType",
7071
)
7172

7273

@@ -930,6 +931,19 @@ class AutoModKeywordPresetType(Enum):
930931
slurs = 3
931932

932933

934+
class ApplicationRoleConnectionMetadataType(Enum):
935+
"""Application role connection metadata type"""
936+
937+
integer_less_than_or_equal = 1
938+
integer_greater_than_or_equal = 2
939+
integer_equal = 3
940+
integer_not_equal = 4
941+
datetime_less_than_or_equal = 5
942+
datetime_greater_than_or_equal = 6
943+
boolean_equal = 7
944+
boolean_not_equal = 8
945+
946+
933947
T = TypeVar("T")
934948

935949

discord/http.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
from .file import File
5757
from .types import (
5858
appinfo,
59+
application_role_connection,
5960
audit_log,
6061
automod,
6162
channel,
@@ -2818,6 +2819,31 @@ def bulk_edit_guild_application_command_permissions(
28182819
)
28192820
return self.request(r, json=payload)
28202821

2822+
# Application Role Connections
2823+
2824+
def get_application_role_connection_metadata_records(
2825+
self,
2826+
application_id: Snowflake,
2827+
) -> Response[list[application_role_connection.ApplicationRoleConnectionMetadata]]:
2828+
r = Route(
2829+
"GET",
2830+
"/applications/{application_id}/role-connections/metadata",
2831+
application_id=application_id,
2832+
)
2833+
return self.request(r)
2834+
2835+
def update_application_role_connection_metadata_records(
2836+
self,
2837+
application_id: Snowflake,
2838+
payload: list[application_role_connection.ApplicationRoleConnectionMetadata],
2839+
) -> Response[list[application_role_connection.ApplicationRoleConnectionMetadata]]:
2840+
r = Route(
2841+
"PUT",
2842+
"/applications/{application_id}/role-connections/metadata",
2843+
application_id=application_id,
2844+
)
2845+
return self.request(r, json=payload)
2846+
28212847
# Misc
28222848

28232849
def application_info(self) -> Response[appinfo.AppInfo]:
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""
2+
The MIT License (MIT)
3+
4+
Copyright (c) 2021-present Pycord Development
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a
7+
copy of this software and associated documentation files (the "Software"),
8+
to deal in the Software without restriction, including without limitation
9+
the rights to use, copy, modify, merge, publish, distribute, sublicense,
10+
and/or sell copies of the Software, and to permit persons to whom the
11+
Software is furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in
14+
all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22+
DEALINGS IN THE SOFTWARE.
23+
"""
24+
25+
from __future__ import annotations
26+
27+
from typing import Literal
28+
29+
from .._typed_dict import NotRequired, TypedDict
30+
31+
ApplicationRoleConnectionMetadataType = Literal[1, 2, 3, 4, 5, 6, 7, 8]
32+
33+
34+
class ApplicationRoleConnectionMetadata(TypedDict):
35+
type: ApplicationRoleConnectionMetadataType
36+
key: str
37+
name: str
38+
name_localizations: NotRequired[dict[str, str]]
39+
description: str
40+
description_localizations: NotRequired[dict[str, str]]

docs/api/data_classes.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,11 @@ Permissions
154154

155155
.. autoclass:: PermissionOverwrite
156156
:members:
157+
158+
Application Role Connections
159+
-----------------------------
160+
161+
.. attributetable:: ApplicationRoleConnectionMetadata
162+
163+
.. autoclass:: ApplicationRoleConnectionMetadata
164+
:members:

docs/api/enums.rst

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2056,6 +2056,51 @@ of :class:`enum.Enum`.
20562056

20572057
Represents a scheduled event that is only available to members inside the guild.
20582058

2059+
.. class:: ApplicationRoleConnectionMetadataType
2060+
2061+
Represents an application role connection metadata type.
2062+
2063+
Each metadata type offers a comparison operation that allows guilds to
2064+
configure role requirements based on metadata values stored by the bot.
2065+
Bots specify a ``metadata value`` for each user and guilds specify the
2066+
required ``guild's configured value`` within the guild role settings.
2067+
2068+
.. versionadded:: 2.4
2069+
2070+
.. attribute:: integer_less_than_or_equal
2071+
2072+
The metadata value (``integer``) is less than or equal to the guild's configured value (``integer``).
2073+
2074+
.. attribute:: integer_greater_than_or_equal
2075+
2076+
The metadata value (``integer``) is greater than or equal to the guild's configured value (``integer``).
2077+
2078+
.. attribute:: integer_equal
2079+
2080+
The metadata value (``integer``) is equal to the guild's configured value (``integer``).
2081+
2082+
.. attribute:: integer_not_equal
2083+
2084+
The metadata value (``integer``) is not equal to the guild's configured value (``integer``).
2085+
2086+
.. attribute:: datetime_less_than_or_equal
2087+
2088+
The metadata value (``datetime``) is less than or equal to the guild's configured value
2089+
(``integer``; the number of days before the current date).
2090+
2091+
.. attribute:: datetime_greater_than_or_equal
2092+
2093+
The metadata value (``datetime``) is greater than or equal to the guild's configured value
2094+
(``integer``; the number of days before the current date).
2095+
2096+
.. attribute:: boolean_equal
2097+
2098+
The metadata value (``integer``) is equal to the guild's configured value (``integer``; 1).
2099+
2100+
.. attribute:: boolean_not_equal
2101+
2102+
The metadata value (``integer``) is not equal to the guild's configured value (``integer``; 1).
2103+
20592104
.. class:: AutoModTriggerType
20602105

20612106
Represents an AutoMod trigger type.

0 commit comments

Comments
 (0)