Add support for integrations
This commit is contained in:
		| @@ -39,6 +39,7 @@ from .permissions import Permissions, PermissionOverwrite | ||||
| from .role import Role | ||||
| from .file import File | ||||
| from .colour import Color, Colour | ||||
| from .integrations import Integration, IntegrationAccount | ||||
| from .invite import Invite, PartialInviteChannel, PartialInviteGuild | ||||
| from .template import Template | ||||
| from .widget import Widget, WidgetMember, WidgetChannel | ||||
|   | ||||
| @@ -50,6 +50,8 @@ __all__ = ( | ||||
|     'TeamMembershipState', | ||||
|     'Theme', | ||||
|     'WebhookType', | ||||
|     'ExpireBehaviour', | ||||
|     'ExpireBehavior' | ||||
| ) | ||||
|  | ||||
| def _create_value_cls(name): | ||||
| @@ -432,6 +434,12 @@ class WebhookType(Enum): | ||||
|     incoming = 1 | ||||
|     channel_follower = 2 | ||||
|  | ||||
| class ExpireBehaviour(Enum): | ||||
|     remove_role = 0 | ||||
|     kick = 1 | ||||
|  | ||||
| ExpireBehavior = ExpireBehaviour | ||||
|  | ||||
| def try_enum(cls, val): | ||||
|     """A function that tries to turn the value into enum ``cls``. | ||||
|  | ||||
|   | ||||
| @@ -46,6 +46,8 @@ from .webhook import Webhook | ||||
| from .widget import Widget | ||||
| from .asset import Asset | ||||
| from .flags import SystemChannelFlags | ||||
| from .integrations import Integration | ||||
|  | ||||
|  | ||||
| BanEntry = namedtuple('BanEntry', 'reason user') | ||||
| _GuildLimit = namedtuple('_GuildLimit', 'emoji bitrate filesize') | ||||
| @@ -1535,6 +1537,100 @@ class Guild(Hashable): | ||||
|         data = await self._state.http.get_custom_emoji(self.id, emoji_id) | ||||
|         return Emoji(guild=self, state=self._state, data=data) | ||||
|  | ||||
|     async def create_integration(self, *, type, id): | ||||
|         """|coro| | ||||
|  | ||||
|         Attaches an integration to the guild. | ||||
|  | ||||
|         You must have the :attr:`~Permissions.manage_guild` permission to | ||||
|         do this. | ||||
|  | ||||
|         .. versionadded:: 1.4 | ||||
|  | ||||
|         Parameters | ||||
|         ----------- | ||||
|         type: :class:`str` | ||||
|             The integration type (e.g. Twitch). | ||||
|         id: :class:`int` | ||||
|             The integration ID. | ||||
|  | ||||
|         Raises | ||||
|         ------- | ||||
|         Forbidden | ||||
|             You do not have permission to create the integration. | ||||
|         HTTPException | ||||
|             The account could not be found. | ||||
|         """ | ||||
|         await self._state.http.create_integration(self.id, type, id) | ||||
|  | ||||
|     async def integrations(self): | ||||
|         """|coro| | ||||
|  | ||||
|         Returns a list of all integrations attached to the guild. | ||||
|  | ||||
|         You must have the :attr:`~Permissions.manage_guild` permission to | ||||
|         do this. | ||||
|  | ||||
|         .. versionadded:: 1.4 | ||||
|  | ||||
|         Raises | ||||
|         ------- | ||||
|         Forbidden | ||||
|             You do not have permission to create the integration. | ||||
|         HTTPException | ||||
|             Fetching the integrations failed. | ||||
|  | ||||
|         Returns | ||||
|         -------- | ||||
|         List[:class:`Integration`] | ||||
|             The list of integrations that are attached to the guild. | ||||
|         """ | ||||
|         data = await self._state.http.get_all_integrations(self.id) | ||||
|         return [Integration(guild=self, data=d) for d in data] | ||||
|  | ||||
|     async def fetch_emojis(self): | ||||
|         """|coro| | ||||
|  | ||||
|         Retrieves all custom :class:`Emoji`s from the guild. | ||||
|  | ||||
|         Raises | ||||
|         --------- | ||||
|         HTTPException | ||||
|             An error occurred fetching the emojis. | ||||
|  | ||||
|         Returns | ||||
|         -------- | ||||
|         List[:class:`Emoji`] | ||||
|             The retrieved emojis. | ||||
|         """ | ||||
|         data = await self._state.http.get_all_custom_emojis(self.id) | ||||
|         return [Emoji(guild=self, state=self._state, data=d) for d in data] | ||||
|  | ||||
|     async def fetch_emoji(self, emoji_id): | ||||
|         """|coro| | ||||
|  | ||||
|         Retrieves a custom :class:`Emoji` from the guild. | ||||
|  | ||||
|         Parameters | ||||
|         ------------- | ||||
|         emoji_id: :class:`int` | ||||
|             The emoji's ID. | ||||
|  | ||||
|         Raises | ||||
|         --------- | ||||
|         NotFound | ||||
|             The emoji requested could not be found. | ||||
|         HTTPException | ||||
|             An error occurred fetching the emoji. | ||||
|  | ||||
|         Returns | ||||
|         -------- | ||||
|         :class:`Emoji` | ||||
|             The retrieved emoji. | ||||
|         """ | ||||
|         data = await self._state.http.get_custom_emoji(self.id, emoji_id) | ||||
|         return Emoji(guild=self, state=self._state, data=data) | ||||
|  | ||||
|     async def create_custom_emoji(self, *, name, image, roles=None, reason=None): | ||||
|         r"""|coro| | ||||
|  | ||||
|   | ||||
| @@ -712,6 +712,38 @@ class HTTPClient: | ||||
|         r = Route('PATCH', '/guilds/{guild_id}/emojis/{emoji_id}', guild_id=guild_id, emoji_id=emoji_id) | ||||
|         return self.request(r, json=payload, reason=reason) | ||||
|  | ||||
|     def get_all_integrations(self, guild_id): | ||||
|         r = Route('GET', '/guilds/{guild_id}/integrations', guild_id=guild_id) | ||||
|  | ||||
|         return self.request(r) | ||||
|  | ||||
|     def create_integration(self, guild_id, type, id): | ||||
|         payload = { | ||||
|             'type': type, | ||||
|             'id': id | ||||
|         } | ||||
|  | ||||
|         r = Route('POST', '/guilds/{guild_id}/integrations', guild_id=guild_id) | ||||
|         return self.request(r, json=payload) | ||||
|  | ||||
|     def edit_integration(self, guild_id, integration_id, **payload): | ||||
|         r = Route('PATCH', '/guilds/{guild_id}/integrations/{integration_id}', guild_id=guild_id, | ||||
|                   integration_id=integration_id) | ||||
|  | ||||
|         return self.request(r, json=payload) | ||||
|  | ||||
|     def sync_integration(self, guild_id, integration_id): | ||||
|         r = Route('POST', '/guilds/{guild_id}/integrations/{integration_id}/sync', guild_id=guild_id, | ||||
|                   integration_id=integration_id) | ||||
|  | ||||
|         return self.request(r) | ||||
|  | ||||
|     def delete_integration(self, guild_id, integration_id): | ||||
|         r = Route('DELETE', '/guilds/{guild_id}/integrations/{integration_id}', guild_id=guild_id, | ||||
|                   integration_id=integration_id) | ||||
|  | ||||
|         return self.request(r) | ||||
|  | ||||
|     def get_audit_logs(self, guild_id, limit=100, before=None, after=None, user_id=None, action_type=None): | ||||
|         params = {'limit': limit} | ||||
|         if before: | ||||
|   | ||||
							
								
								
									
										202
									
								
								discord/integrations.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								discord/integrations.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,202 @@ | ||||
| # -*- coding: utf-8 -*- | ||||
|  | ||||
| """ | ||||
| The MIT License (MIT) | ||||
|  | ||||
| Copyright (c) 2015-2020 Rapptz | ||||
|  | ||||
| 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. | ||||
| """ | ||||
|  | ||||
| import datetime | ||||
| from collections import namedtuple | ||||
| from .utils import _get_as_snowflake, get, parse_time | ||||
| from .user import User | ||||
| from .errors import InvalidArgument | ||||
| from .enums import try_enum, ExpireBehaviour | ||||
|  | ||||
| class IntegrationAccount(namedtuple('IntegrationAccount', 'id name')): | ||||
|     """Represents an integration account. | ||||
|  | ||||
|     .. versionadded:: 1.4 | ||||
|  | ||||
|     Attributes | ||||
|     ----------- | ||||
|     id: :class:`int` | ||||
|         The account ID. | ||||
|     name: :class:`str` | ||||
|         The account name. | ||||
|     """ | ||||
|  | ||||
|     __slots__ = () | ||||
|  | ||||
|     def __repr__(self): | ||||
|         return '<IntegrationAccount id={0.id} name={0.name!r}>'.format(self) | ||||
|  | ||||
| class Integration: | ||||
|     """Represents a guild integration. | ||||
|  | ||||
|     .. versionadded:: 1.4 | ||||
|  | ||||
|     Attributes | ||||
|     ----------- | ||||
|     id: :class:`int` | ||||
|         The integration ID. | ||||
|     name: :class:`str` | ||||
|         The integration name. | ||||
|     guild: :class:`Guild` | ||||
|         The guild of the integration. | ||||
|     type: :class:`str` | ||||
|         The integration type (i.e. Twitch). | ||||
|     enabled: :class:`bool` | ||||
|         Whether the integration is currently enabled. | ||||
|     syncing: :class:`bool` | ||||
|         Where the integration is currently syncing. | ||||
|     role: :class:`Role` | ||||
|         The role which the integration uses for subscribers. | ||||
|     enable_emoticons: :class:`bool` | ||||
|         Whether emoticons should be synced for this integration (currently twitch only). | ||||
|     expire_behaviour: :class:`ExpireBehaviour` | ||||
|         The behaviour of expiring subscribers. Aliased to ``expire_behavior`` as well. | ||||
|     expire_grace_period: :class:`int` | ||||
|         The grace period (in days) for expiring subscribers. | ||||
|     user: :class:`User` | ||||
|         The user for the integration. | ||||
|     account: :class:`IntegrationAccount` | ||||
|         The integration account information. | ||||
|     synced_at: :class:`datetime.datetime` | ||||
|         When the integration was last synced. | ||||
|     """ | ||||
|  | ||||
|     __slots__ = ('id', '_state', 'guild', 'name', 'enabled', 'type', | ||||
|                  'syncing', 'role', 'expire_behaviour', 'expire_behavior', | ||||
|                  'expire_grace_period', 'synced_at', 'user', 'account') | ||||
|  | ||||
|     def __init__(self, *, data, guild): | ||||
|         self.guild = guild | ||||
|         self._state = guild._state | ||||
|         self._from_data(data) | ||||
|  | ||||
|     def __repr__(self): | ||||
|         return '<Integration id={0.id} name={0.name!r} type={0.type!r}>'.format(self) | ||||
|  | ||||
|     def _from_data(self, integ): | ||||
|         self.id = _get_as_snowflake(integ, 'id') | ||||
|         self.name = integ['name'] | ||||
|         self.type = integ['type'] | ||||
|         self.enabled = integ['enabled'] | ||||
|         self.syncing = integ['syncing'] | ||||
|         self._role_id = _get_as_snowflake(integ, 'role_id') | ||||
|         self.role = get(self.guild.roles, id=self._role_id) | ||||
|         self.enable_emoticons = integ.get('enable_emoticons') | ||||
|         self.expire_behaviour = try_enum(ExpireBehaviour, integ['expire_behavior']) | ||||
|         self.expire_behavior = self.expire_behaviour | ||||
|         self.expire_grace_period = integ['expire_grace_period'] | ||||
|         self.synced_at = parse_time(integ['synced_at']) | ||||
|  | ||||
|         self.user = User(state=self._state, data=integ['user']) | ||||
|         self.account = IntegrationAccount(**integ['account']) | ||||
|  | ||||
|     async def edit(self, **fields): | ||||
|         """|coro| | ||||
|  | ||||
|         Edits the integration. | ||||
|  | ||||
|         You must have the :attr:`~Permissions.manage_guild` permission to | ||||
|         do this. | ||||
|  | ||||
|         Parameters | ||||
|         ----------- | ||||
|         expire_behaviour: :class:`ExpireBehaviour` | ||||
|             The behaviour when an integration subscription lapses. Aliased to ``expire_behavior`` as well. | ||||
|         expire_grace_period: :class:`int` | ||||
|             The period (in days) where the integration will ignore lapsed subscriptions. | ||||
|         enable_emoticons: :class:`bool` | ||||
|             Where emoticons should be synced for this integration (currently twitch only). | ||||
|  | ||||
|         Raises | ||||
|         ------- | ||||
|         Forbidden | ||||
|             You do not have permission to edit the integration. | ||||
|         HTTPException | ||||
|             Editing the guild failed. | ||||
|         InvalidArgument | ||||
|             ``expire_behaviour`` did not receive a :class:`ExpireBehaviour`. | ||||
|         """ | ||||
|         try: | ||||
|             expire_behaviour = fields['expire_behaviour'] | ||||
|         except KeyError: | ||||
|             expire_behaviour = fields.get('expire_behavior', self.expire_behaviour) | ||||
|  | ||||
|         if not isinstance(expire_behaviour, ExpireBehaviour): | ||||
|             raise InvalidArgument('expire_behaviour field must be of type ExpireBehaviour') | ||||
|  | ||||
|         expire_grace_period = fields.get('expire_grace_period', self.expire_grace_period) | ||||
|  | ||||
|         payload = { | ||||
|             'expire_behavior': expire_behaviour.value, | ||||
|             'expire_grace_period': expire_grace_period, | ||||
|         } | ||||
|  | ||||
|         enable_emoticons = fields.get('enable_emoticons') | ||||
|  | ||||
|         if enable_emoticons is not None: | ||||
|             payload['enable_emoticons'] = enable_emoticons | ||||
|  | ||||
|         await self._state.http.edit_integration(self.guild.id, self.id, **payload) | ||||
|  | ||||
|         self.expire_behaviour = expire_behavior | ||||
|         self.expire_behavior = self.expire_behaviour | ||||
|         self.expire_grace_period = expire_grace_period | ||||
|         self.enable_emoticons = enable_emoticons | ||||
|  | ||||
|     async def sync(self): | ||||
|         """|coro| | ||||
|  | ||||
|         Syncs the integration. | ||||
|  | ||||
|         You must have the :attr:`~Permissions.manage_guild` permission to | ||||
|         do this. | ||||
|  | ||||
|         Raises | ||||
|         ------- | ||||
|         Forbidden | ||||
|             You do not have permission to sync the integration. | ||||
|         HTTPException | ||||
|             Syncing the integration failed. | ||||
|         """ | ||||
|         await self._state.http.sync_integration(self.guild.id, self.id) | ||||
|         self.synced_at = datetime.datetime.utcnow() | ||||
|  | ||||
|     async def delete(self): | ||||
|         """|coro| | ||||
|  | ||||
|         Deletes the integration. | ||||
|  | ||||
|         You must have the :attr:`~Permissions.manage_guild` permission to | ||||
|         do this. | ||||
|  | ||||
|         Raises | ||||
|         ------- | ||||
|         Forbidden | ||||
|             You do not have permission to delete the integration. | ||||
|         HTTPException | ||||
|             Deleting the integration failed. | ||||
|         """ | ||||
|         await self._state.http.delete_integration(self.guild.id, self.id) | ||||
							
								
								
									
										31
									
								
								docs/api.rst
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								docs/api.rst
									
									
									
									
									
								
							| @@ -480,6 +480,8 @@ to handle it, which defaults to print a traceback and ignoring the exception. | ||||
|  | ||||
| .. function:: on_guild_integrations_update(guild) | ||||
|  | ||||
|     .. versionadded:: 1.4 | ||||
|  | ||||
|     Called whenever an integration is created, modified, or removed from a guild. | ||||
|  | ||||
|     :param guild: The guild that had its integrations updated. | ||||
| @@ -1670,7 +1672,6 @@ of :class:`enum.Enum`. | ||||
|  | ||||
|         The action is the update of something. | ||||
|  | ||||
|  | ||||
| .. class:: RelationshipType | ||||
|  | ||||
|     Specifies the type of :class:`Relationship`. | ||||
| @@ -1810,6 +1811,24 @@ of :class:`enum.Enum`. | ||||
|  | ||||
|         Represents a webhook that is internally managed by Discord, used for following channels. | ||||
|  | ||||
| .. class:: ExpireBehaviour | ||||
|  | ||||
|     Represents the behaviour the :class:`Integration` should perform | ||||
|     when a user's subscription has finished. | ||||
|  | ||||
|     There is an alias for this called ``ExpireBehavior``. | ||||
|  | ||||
|     .. versionadded:: 1.4 | ||||
|  | ||||
|     .. attribute:: remove_role | ||||
|  | ||||
|         This will remove the :attr:`Integration.role` from the user | ||||
|         when their subscription is finished. | ||||
|  | ||||
|     .. attribute:: kick | ||||
|  | ||||
|         This will kick the user when their subscription is finished. | ||||
|  | ||||
| .. class:: DefaultAvatar | ||||
|  | ||||
|     Represents the default avatar of a Discord :class:`User` | ||||
| @@ -1838,6 +1857,7 @@ of :class:`enum.Enum`. | ||||
|         Represents the default avatar with the color red. | ||||
|         See also :attr:`Colour.red` | ||||
|  | ||||
|  | ||||
| Async Iterator | ||||
| ---------------- | ||||
|  | ||||
| @@ -2507,6 +2527,15 @@ Guild | ||||
|     .. automethod:: audit_logs | ||||
|         :async-for: | ||||
|  | ||||
| Integration | ||||
| ~~~~~~~~~~~~ | ||||
|  | ||||
| .. autoclass:: Integration() | ||||
|     :members: | ||||
|  | ||||
| .. autoclass:: IntegrationAccount() | ||||
|     :members: | ||||
|  | ||||
| Member | ||||
| ~~~~~~ | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user