mirror of
				https://github.com/Rapptz/discord.py.git
				synced 2025-10-31 05:23:03 +00:00 
			
		
		
		
	Add support for bot integrations
This commit is contained in:
		| @@ -45,7 +45,7 @@ from .iterators import AuditLogIterator, MemberIterator | ||||
| from .widget import Widget | ||||
| from .asset import Asset | ||||
| from .flags import SystemChannelFlags | ||||
| from .integrations import Integration | ||||
| from .integrations import BotIntegration, StreamIntegration, _integration_factory | ||||
|  | ||||
| __all__ = ( | ||||
|     'Guild', | ||||
| @@ -1803,7 +1803,14 @@ class Guild(Hashable): | ||||
|             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] | ||||
|          | ||||
|         def convert(d): | ||||
|             factory, itype = _integration_factory(d['type']) | ||||
|             if factory is None: | ||||
|                 raise InvalidData('Unknown integration type {type!r} for integration ID {id}'.format_map(d)) | ||||
|             return factory(guild=self, data=d) | ||||
|  | ||||
|         return [convert(d) for d in data] | ||||
|  | ||||
|     async def fetch_emojis(self): | ||||
|         r"""|coro| | ||||
|   | ||||
| @@ -27,19 +27,25 @@ from __future__ import annotations | ||||
| import datetime | ||||
| from typing import Optional, TYPE_CHECKING, overload | ||||
| from .utils import _get_as_snowflake, get, parse_time | ||||
| from .role import Role | ||||
| from .user import User | ||||
| from .errors import InvalidArgument | ||||
| from .enums import try_enum, ExpireBehaviour | ||||
|  | ||||
| __all__ = ( | ||||
|     'IntegrationAccount', | ||||
|     'IntegrationApplication', | ||||
|     'Integration', | ||||
|     'StreamIntegration', | ||||
|     'BotIntegration', | ||||
| ) | ||||
|  | ||||
| if TYPE_CHECKING: | ||||
|     from .types.integration import ( | ||||
|         IntegrationAccount as IntegrationAccountPayload, | ||||
|         Integration as IntegrationPayload, | ||||
|         IntegrationType, | ||||
|         IntegrationApplication as IntegrationApplicationPayload, | ||||
|     ) | ||||
|     from .guild import Guild | ||||
|  | ||||
| @@ -74,6 +80,75 @@ class Integration: | ||||
|  | ||||
|     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. | ||||
|     account: :class:`IntegrationAccount` | ||||
|         The account linked to this integration. | ||||
|     user: :class:`User` | ||||
|         The user that added this integration. | ||||
|     """ | ||||
|  | ||||
|     __slots__ = ( | ||||
|         'guild', | ||||
|         'id', | ||||
|         '_state', | ||||
|         'type', | ||||
|         'name', | ||||
|         'account', | ||||
|         'user', | ||||
|         'enabled', | ||||
|     ) | ||||
|  | ||||
|     def __init__(self, *, data: IntegrationPayload, guild: Guild) -> None: | ||||
|         self.guild = guild | ||||
|         self._state = guild._state | ||||
|         self._from_data(data) | ||||
|  | ||||
|     def __repr__(self): | ||||
|         return f"<{self.__class__.__name__} id={self.id} name={self.name!r}>" | ||||
|  | ||||
|     def _from_data(self, data: IntegrationPayload) -> None: | ||||
|         self.id: int = int(data['id']) | ||||
|         self.type: IntegrationType = data['type'] | ||||
|         self.name: str = data['name'] | ||||
|         self.account: IntegrationAccount = IntegrationAccount(data['account']) | ||||
|  | ||||
|         user = data.get('user') | ||||
|         self.user = User(state=self._state, data=user) if user else None | ||||
|         self.enabled: bool = data['enabled'] | ||||
|  | ||||
|     async def delete(self) -> None: | ||||
|         """|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) | ||||
|  | ||||
| class StreamIntegration(Integration): | ||||
|     """Represents a stream integration for Twitch or YouTube. | ||||
|  | ||||
|     .. versionadded:: 2.0 | ||||
|  | ||||
|     Attributes | ||||
|     ---------- | ||||
|     id: :class:`int` | ||||
|         The integration ID. | ||||
|     name: :class:`str` | ||||
| @@ -102,49 +177,30 @@ class Integration: | ||||
|         An aware UTC datetime representing when the integration was last synced. | ||||
|     """ | ||||
|  | ||||
|     __slots__ = ( | ||||
|         'id', | ||||
|         '_state', | ||||
|         'guild', | ||||
|         'name', | ||||
|         'enabled', | ||||
|         'type', | ||||
|         'syncing', | ||||
|         'role', | ||||
|     __slots__ = Integration.__slots__ + ( | ||||
|         'revoked', | ||||
|         'expire_behaviour', | ||||
|         'expire_behavior', | ||||
|         'expire_grace_period', | ||||
|         'synced_at', | ||||
|         'user', | ||||
|         'account', | ||||
|         'enable_emoticons', | ||||
|         '_role_id', | ||||
|         'role', | ||||
|         'syncing', | ||||
|         'enable_emoticons', | ||||
|         'subscriber_count' | ||||
|     ) | ||||
|  | ||||
|     def __init__(self, *, data: IntegrationPayload, guild: Guild) -> None: | ||||
|         self.guild = guild | ||||
|         self._state = guild._state | ||||
|         self._from_data(data) | ||||
|  | ||||
|     def __repr__(self) -> str: | ||||
|         return f'<Integration id={self.id} name={self.name!r} type={self.type!r}>' | ||||
|  | ||||
|     def _from_data(self, integ: IntegrationPayload): | ||||
|         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']) | ||||
|     def _from_data(self, data: IntegrationPayload) -> None: | ||||
|         super()._from_data(data) | ||||
|         self.revoked: bool = data['revoked'] | ||||
|         self.expire_behaviour: ExpireBehaviour = try_enum(ExpireBehaviour, data['expire_behavior']) | ||||
|         self.expire_grace_period: int = data['expire_grace_period'] | ||||
|         self.synced_at: datetime.datetime = parse_time(data['synced_at']) | ||||
|         self._role_id: int = int(data['role_id']) | ||||
|         self.role: Role = self.guild.get_role(self._role_id) | ||||
|         self.syncing: bool = data['syncing'] | ||||
|         self.enable_emoticons: bool = data['enable_emoticons'] | ||||
|         self.subscriber_count: int = data['subscriber_count'] | ||||
|  | ||||
|     @overload | ||||
|     async def edit( | ||||
| @@ -231,19 +287,81 @@ class Integration: | ||||
|         await self._state.http.sync_integration(self.guild.id, self.id) | ||||
|         self.synced_at = datetime.datetime.now(datetime.timezone.utc) | ||||
|  | ||||
|     async def delete(self) -> None: | ||||
|         """|coro| | ||||
| class IntegrationApplication: | ||||
|     """Represents an application for a bot integration. | ||||
|  | ||||
|         Deletes the integration. | ||||
|     .. versionadded:: 2.0 | ||||
|  | ||||
|         You must have the :attr:`~Permissions.manage_guild` permission to | ||||
|         do this. | ||||
|     Attributes | ||||
|     ---------- | ||||
|     id: :class:`int` | ||||
|         The ID for this application. | ||||
|     name: :class:`str` | ||||
|         The application's name. | ||||
|     icon: Optional[:class:`str`] | ||||
|         The application's icon hash. | ||||
|     description: :class:`str` | ||||
|         The application's description. Can be an empty string. | ||||
|     summary: :class:`str` | ||||
|         The summary of the application. Can be an empty string. | ||||
|     user: Optional[:class:`User`] | ||||
|         The bot user on this application. | ||||
|     """ | ||||
|  | ||||
|         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) | ||||
|     __slots__ = ( | ||||
|         'id',  | ||||
|         'name',  | ||||
|         'icon',  | ||||
|         'description',  | ||||
|         'summary',  | ||||
|         'user', | ||||
|     ) | ||||
|      | ||||
|     def __init__(self, *, data: IntegrationApplicationPayload, state): | ||||
|         self.id: int = int(data['id']) | ||||
|         self.name: str = data['name'] | ||||
|         self.icon: Optional[str] = data['icon'] | ||||
|         self.description: str = data['description'] | ||||
|         self.summary: str = data['summary'] | ||||
|         user = data.get('bot') | ||||
|         self.user: Optional[User] = User(state=state, data=user) if user else None | ||||
|  | ||||
| class BotIntegration(Integration): | ||||
|     """Represents a bot integration on discord. | ||||
|      | ||||
|     .. versionadded:: 2.0 | ||||
|  | ||||
|     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. | ||||
|     user: :class:`User` | ||||
|         The user that added this integration. | ||||
|     account: :class:`IntegrationAccount` | ||||
|         The integration account information. | ||||
|     application: :class:`IntegrationApplication` | ||||
|         The application tied to this integration. | ||||
|     """ | ||||
|  | ||||
|     __slots__ = Integration.__slots__ + ('application',) | ||||
|  | ||||
|     def _from_data(self, data: IntegrationPayload) -> None: | ||||
|         super()._from_data(data) | ||||
|         self.application = IntegrationApplication(data=data['application'], state=self._state) | ||||
|  | ||||
|  | ||||
| def _integration_factory(value): | ||||
|     if value == 'discord': | ||||
|         return BotIntegration, value | ||||
|     elif value in ('twitch', 'youtube'): | ||||
|         return StreamIntegration, value | ||||
|     else: | ||||
|         return Integration, value | ||||
|   | ||||
		Reference in New Issue
	
	Block a user