diff --git a/discordoauth2/async_oauth.py b/discordoauth2/async_oauth.py index 52009b8..edeeea0 100644 --- a/discordoauth2/async_oauth.py +++ b/discordoauth2/async_oauth.py @@ -31,7 +31,7 @@ async def fetch_identify(self) -> dict: return await response.json() elif response.status == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status == 429: raise Exceptions.RateLimited( @@ -54,7 +54,7 @@ async def fetch_connections(self) -> list[dict]: return await response.json() elif response.status == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status == 429: raise Exceptions.RateLimited( @@ -78,7 +78,7 @@ async def fetch_guilds(self) -> list[dict]: return await response.json() elif response.status == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status == 429: raise Exceptions.RateLimited( @@ -104,7 +104,7 @@ async def fetch_guild_member(self, guild_id: int) -> dict: return await response.json() elif response.status == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status == 404: raise Exceptions.HTTPException( @@ -133,10 +133,10 @@ async def join_guild( guild_id: The guild ID to add the user to user_id: The ID of the user. Retrievable with `PartialAccessToken.fetch_identify()['id']` - nick: The nickname to give the user apon joining. Bot must also have `MANAGE_NICKNAMES` - role_ids: A list of role IDs to give the user apon joining (bypasses Membership Screening). Bot must also have `MANAGE_ROLES` - mute: Wether the user is muted in voice channels apon joining. Bot must also have `MUTE_MEMBERS` - deaf: Wether the user is deaf in voice channels apon joining. Bot must also have `DEAFEN_MEMBERS` + nick: The nickname to give the user upon joining. Bot must also have `MANAGE_NICKNAMES` + role_ids: A list of role IDs to give the user upon joining (bypasses Membership Screening). Bot must also have `MANAGE_ROLES` + mute: Wether the user is muted in voice channels upon joining. Bot must also have `MUTE_MEMBERS` + deaf: Wether the user is deaf in voice channels upon joining. Bot must also have `DEAFEN_MEMBERS` """ async with aiohttp.ClientSession() as session: async with session.put( @@ -187,7 +187,7 @@ async def fetch_metadata(self): return await response.json() elif response.status == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status == 429: raise Exceptions.RateLimited( @@ -234,7 +234,7 @@ def metadataTypeHook(item): return await response.json() elif response.status == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status == 429: raise Exceptions.RateLimited( @@ -258,7 +258,7 @@ async def clear_metadata(self): return await response.json() elif response.status == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status == 429: raise Exceptions.RateLimited( @@ -320,7 +320,7 @@ async def update_linked_roles_metadata(self, metadata: list[dict]): return await response.json() elif response.status == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status == 429: raise Exceptions.RateLimited( @@ -333,7 +333,7 @@ async def update_linked_roles_metadata(self, metadata: list[dict]): ) def from_access_token(self, access_token: str) -> AsyncPartialAccessToken: - """Creates a `PartialAccessToken` from a access token string. + """Creates a `PartialAccessToken` from an access token string. access_token: access token from `PartialAccessToken.token` """ @@ -342,7 +342,7 @@ def from_access_token(self, access_token: str) -> AsyncPartialAccessToken: async def exchange_code(self, code: str) -> AsyncAccessToken: """Converts a code from the redirect url into a `AccessToken` - code: `code` paramater from OAuth2 redirect URL + code: `code` parameter from OAuth2 redirect URL """ async with aiohttp.ClientSession() as session: async with session.post( @@ -402,7 +402,7 @@ async def refresh_token(self, refresh_token: str) -> AsyncAccessToken: f"Unexpected HTTP {response.status}" ) - async def client_credentails_grant( + async def client_credentials_grant( self, scope: list[str] ) -> AsyncAccessToken: """Creates an `AccessToken` on behalf of the application's owner. If the owner is a team, then only `identify` and `applications.commands.update` are allowed. @@ -467,6 +467,7 @@ def generate_uri( scope: Union[str, list[str]], state: Optional[str] = None, skip_prompt: Optional[bool] = False, + integration_type: Optional[Literal["guild", "user"]] = "user", response_type: Optional[Literal["code", "token"]] = "code", guild_id: Optional[Union[int, str]] = None, disable_guild_select: Optional[bool] = None, @@ -493,4 +494,6 @@ def generate_uri( "disable_guild_select": disable_guild_select, "permissions": permissions, } + if "applications.commands" in scope: + params["integration_type"] = 0 if integration_type == "guild" else 1 return f"https://discord.com/oauth2/authorize?{parse.urlencode({key: value for key, value in params.items() if value is not None})}" diff --git a/discordoauth2/sync_oauth.py b/discordoauth2/sync_oauth.py index 5704587..e3cb718 100644 --- a/discordoauth2/sync_oauth.py +++ b/discordoauth2/sync_oauth.py @@ -27,7 +27,7 @@ def fetch_identify(self) -> dict: return response.json() elif response.status_code == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status_code == 429: raise Exceptions.RateLimited( @@ -50,7 +50,7 @@ def fetch_connections(self) -> list[dict]: return response.json() elif response.status_code == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status_code == 429: raise Exceptions.RateLimited( @@ -74,7 +74,7 @@ def fetch_guilds(self) -> list[dict]: return response.json() elif response.status_code == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status_code == 429: raise Exceptions.RateLimited( @@ -100,7 +100,7 @@ def fetch_guild_member(self, guild_id: int) -> dict: return response.json() elif response.status_code == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status_code == 404: raise Exceptions.HTTPException(f"user is not in this guild.") @@ -127,10 +127,10 @@ def join_guild( guild_id: The guild ID to add the user to user_id: The ID of the user. Retrievable with `PartialAccessToken.fetch_identify()['id']` - nick: The nickname to give the user apon joining. Bot must also have `MANAGE_NICKNAMES` - role_ids: A list of role IDs to give the user apon joining (bypasses Membership Screening). Bot must also have `MANAGE_ROLES` - mute: Wether the user is muted in voice channels apon joining. Bot must also have `MUTE_MEMBERS` - deaf: Wether the user is deaf in voice channels apon joining. Bot must also have `DEAFEN_MEMBERS` + nick: The nickname to give the user upon joining. Bot must also have `MANAGE_NICKNAMES` + role_ids: A list of role IDs to give the user upon joining (bypasses Membership Screening). Bot must also have `MANAGE_ROLES` + mute: Wether the user is muted in voice channels upon joining. Bot must also have `MUTE_MEMBERS` + deaf: Wether the user is deaf in voice channels upon joining. Bot must also have `DEAFEN_MEMBERS` """ response = requests.put( f"https://discord.com/api/v10/guilds/{guild_id}/members/{user_id}", @@ -150,7 +150,7 @@ def join_guild( return response.json() elif response.status_code == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status_code == 403: raise Exceptions.Forbidden( @@ -177,7 +177,7 @@ def fetch_metadata(self): return response.json() elif response.status_code == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status_code == 429: raise Exceptions.RateLimited( @@ -224,7 +224,7 @@ def metadataTypeHook(item): return response.json() elif response.status_code == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status_code == 429: raise Exceptions.RateLimited( @@ -248,7 +248,7 @@ def clear_metadata(self): return response.json() elif response.status_code == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status_code == 429: raise Exceptions.RateLimited( @@ -307,7 +307,7 @@ def update_linked_roles_metadata(self, metadata: list[dict]): ) def from_access_token(self, access_token: str) -> PartialAccessToken: - """Creates a `PartialAccessToken` from a access token string. + """Creates a `PartialAccessToken` from an access token string. access_token: access token from `PartialAccessToken.token` """ @@ -316,7 +316,7 @@ def from_access_token(self, access_token: str) -> PartialAccessToken: def exchange_code(self, code: str) -> AccessToken: """Converts a code from the redirect url into a `AccessToken` - code: `code` paramater from OAuth2 redirect URL + code: `code` parameter from OAuth2 redirect URL """ response = requests.post( "https://discord.com/api/v10/oauth2/token", @@ -376,7 +376,7 @@ def refresh_token(self, refresh_token: str) -> AccessToken: f"Unexpected HTTP {response.status_code}" ) - def client_credentails_grant(self, scope: list[str]) -> AccessToken: + def client_credentials_grant(self, scope: list[str]) -> AccessToken: """Creates an `AccessToken` on behalf of the application's owner. If the owner is a team, then only `identify` and `applications.commands.update` are allowed. scope: list of string scopes to authorize. @@ -421,7 +421,7 @@ def revoke_token(self, token: str, token_type: str = None): return elif response.status_code == 401: raise Exceptions.Forbidden( - f"this AccessToken does not have the nessasary scope." + f"this AccessToken does not have the necessary scope." ) elif response.status_code == 429: raise Exceptions.RateLimited( @@ -438,6 +438,7 @@ def generate_uri( scope: Union[str, list[str]], state: Optional[str] = None, skip_prompt: Optional[bool] = False, + integration_type: Optional[Literal["guild", "user"]] = "user", response_type: Optional[Literal["code", "token"]] = "code", guild_id: Optional[Union[int, str]] = None, disable_guild_select: Optional[bool] = None, @@ -464,4 +465,6 @@ def generate_uri( "disable_guild_select": disable_guild_select, "permissions": permissions, } + if "applications.commands" in scope: + params["integration_type"] = 0 if integration_type == "guild" else 1 return f"https://discord.com/oauth2/authorize?{parse.urlencode({key: value for key, value in params.items() if value is not None})}" diff --git a/docs/source/access_token.rst b/docs/source/access_token.rst index a1c0445..c4b1064 100644 --- a/docs/source/access_token.rst +++ b/docs/source/access_token.rst @@ -37,7 +37,7 @@ AccessToken .. attribute:: webhook - A `parital webhook object `__ if they was a ``webhook.incoming`` scope. + A `partial webhook object `__ if they was a ``webhook.incoming`` scope. :type: dict @@ -94,7 +94,7 @@ AccessToken :param str nick: The nickname the member should have when they join. :param list[int] role_ids: a List of role IDs to assign them when they join. :param bool mute: Wether they should be server muted when they join. - :param bool deaf: Wether they should be server deafend when they join. + :param bool deaf: Wether they should be server deafened when they join. :returns: dict :raises discordoauth2.exceptions.HTTPException: The request failed @@ -122,8 +122,8 @@ AccessToken .. versionadded:: 1.1 - :param str platform_name: Text that appears at the top of the app connection box, usally denoting the platform's name. - :param str platform_username: Text that appears under the platform name, large, and usally denoting the user's name on the platform. + :param str platform_name: Text that appears at the top of the app connection box, usually denoting the platform's name. + :param str platform_username: Text that appears under the platform name, large, and usually denoting the user's name on the platform. :param dict metadata: List of keys and values to set the user's metadata. Supported types: :class:`bool`, :class:`datetime.datetime`, :class:`int` :returns: dict @@ -227,7 +227,7 @@ AccessToken :param str nick: The nickname the member should have when they join. :param list[int] role_ids: a List of role IDs to assign them when they join. :param bool mute: Wether they should be server muted when they join. - :param bool deaf: Wether they should be server deafend when they join. + :param bool deaf: Wether they should be server deafened when they join. :returns: dict :raises discordoauth2.exceptions.HTTPException: The request failed @@ -251,8 +251,8 @@ AccessToken .. versionadded:: 1.1 - :param str platform_name: Text that appears at the top of the app connection box, usally denoting the platform's name. - :param str platform_username: Text that appears under the platform name, large, and usally denoting the user's name on the platform. + :param str platform_name: Text that appears at the top of the app connection box, usually denoting the platform's name. + :param str platform_username: Text that appears under the platform name, large, and usually denoting the user's name on the platform. :param dict metadata: List of keys and values to set the user's metadata. Supported types: :class:`bool`, :class:`datetime.datetime`, :class:`int` :returns: dict diff --git a/docs/source/client.rst b/docs/source/client.rst index 4c509ee..dd3e85c 100644 --- a/docs/source/client.rst +++ b/docs/source/client.rst @@ -8,7 +8,7 @@ Client :param int id: The application ID :param str secret: The applications secret, this should be secret! :param str redirect: The redirect URL for oauth2 - :param str bot_token: When adding a user to a guild, a bot with sufficent permissions is required. if you're not going to add members to a guild leave this empty. + :param str bot_token: When adding a user to a guild, a bot with sufficient permissions is required. if you're not going to add members to a guild leave this empty. .. attribute:: id @@ -26,7 +26,7 @@ Client Creates a :class:`discordoauth2.PartialAccessToken` object from a code. This is useful so you can store the :attr:`PartialAccessToken.token` and then continue using it. - :param str access_token: The code from oauth2, it is the code paramater on successful return redirect urls from discord's oauth2. + :param str access_token: The code from oauth2, it is the code parameter on successful return redirect urls from discord's oauth2. :returns: :class:`discordoauth2.PartialAccessToken` @@ -34,10 +34,10 @@ Client Converts a code from the redirect url into a :class:`discordoauth2.AccessToken` - :param str code: `code` paramater from OAuth2 redirect URL + :param str code: `code` parameter from OAuth2 redirect URL :returns: :class:`discordoauth2.AccessToken` - :raises discordoauth2.exceptions.HTTPException: The request failed, usally because the client ID, client, secret, redirect or code is incorrect + :raises discordoauth2.exceptions.HTTPException: The request failed, usually because the client ID, client, secret, redirect or code is incorrect :raises discordoauth2.exceptions.RateLimited: You're being rate limited. .. method:: refresh_token(refresh_token) @@ -47,17 +47,17 @@ Client :param str refresh_token: The refresh token, can be found from :attr:`discordoauth2.AccessToken.refresh_token` :returns: :class:`discordoauth2.AccessToken` - :raises discordoauth2.exceptions.HTTPException: The request failed, usally because the client ID, client, secret, redirect or code is incorrect + :raises discordoauth2.exceptions.HTTPException: The request failed, usually because the client ID, client, secret, redirect or code is incorrect :raises discordoauth2.exceptions.RateLimited: You're being rate limited. - .. method:: client_credentails_grant(scope) + .. method:: client_credentials_grant(scope) Creates an :class:`discordoauth2.AccessToken` on behalf of the application's owner. :param list[str] scope: List of scopes. :returns: :class:`discordoauth2.AccessToken` - :raises discordoauth2.exceptions.HTTPException: The request failed, usally because the client ID, client, secret, redirect or code is incorrect + :raises discordoauth2.exceptions.HTTPException: The request failed, usually because the client ID, client, secret, redirect or code is incorrect :raises discordoauth2.exceptions.RateLimited: You're being rate limited. .. warning:: @@ -73,7 +73,7 @@ Client :param str token: Access/Refresh token to revoke :param Optional[str] token_type: Not required, but should be either ``refresh_token`` or ``access_token`` - :raises discordoauth2.exceptions.HTTPException: The request failed, usally because the client ID, client, secret, redirect or code is incorrect + :raises discordoauth2.exceptions.HTTPException: The request failed, usually because the client ID, client, secret, redirect or code is incorrect :raises discordoauth2.exceptions.RateLimited: You're being rate limited. .. method:: update_linked_roles_metadata(metadata) @@ -94,7 +94,7 @@ Client .. versionadded:: 1.2 - :param Union[str, list[str]] scope: A list, or space-seperated string for the authorization scope + :param Union[str, list[str]] scope: A list, or space-separated string for the authorization scope :param Optional[str] state: State parameter. It is recommended for security. :param Optional[bool] skip_prompt: Doesn't require the end user to reauthorize if they've already authorized you app before. Defaults to ``False``. :param Optional[Literal["code", "token"]] response_type: either code, or token. token means the server can't access it, but the client can use it without converting.