Skip to content

Commit

Permalink
Merge pull request #1665 from interactions-py/unstable
Browse files Browse the repository at this point in the history
 5.12.0
  • Loading branch information
silasary authored Apr 30, 2024
2 parents 1a7de56 + 92044a8 commit 7e01223
Show file tree
Hide file tree
Showing 92 changed files with 3,929 additions and 250 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ __pycache__
/coverage.xml
/TestResults.xml
/.coverage
.mypy_cache/
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ repos:
- id: check-merge-conflict
name: Merge Conflicts
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: 'v0.1.5'
rev: 'v0.3.2'
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
- repo: https://github.com/psf/black
rev: 23.11.0
rev: 24.2.0
hooks:
- id: black
name: Black Formatting
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
[![](https://img.shields.io/pypi/dm/discord-py-slash-command.svg?logo=python&label=Downloads)](https://pypi.org/project/discord-py-interactions/)

[![](https://img.shields.io/badge/Code%20Style-black-000000.svg)](https://github.com/psf/black)
[![License](https://img.shields.io/badge/License-GPL-blue)](https://github.com/interactions-py/interactions.py/blob/stable/LICENSE)
[![License](https://img.shields.io/badge/License-MIT-blue)](https://github.com/interactions-py/interactions.py/blob/stable/LICENSE)

[![](https://img.shields.io/badge/Docs-latest-x?logo=readthedocs)](https://interactions-py.github.io/interactions.py/)
[![](https://img.shields.io/badge/Guides-latest-x?logo=readthedocs)](https://interactions-py.github.io/interactions.py/Guides/01%20Getting%20Started)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
::: interactions.models.discord.entitlement
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ search:
- [Components](components)
- [Embed](embed)
- [Emoji](emoji)
- [Entitlement](entitlement)
- [Enums](enums)
- [File](file)
- [Guild](guild)
Expand Down
153 changes: 103 additions & 50 deletions docs/src/Guides/03 Creating Commands.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/src/Guides/05 Components.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ When responding to a component you need to satisfy Discord either by responding

You can also use this to check for a normal message instead of a component interaction.

For more information, please visit the API reference [here](/interactions.py/API Reference/API Reference/client/#interactions.client.client.Client.wait_for_component).
For more information, please visit the API reference [here](/interactions.py/API Reference/API Reference/Client/#interactions.client.Client.wait_for_component).


=== ":two: Persistent Callback: `@listen()`"
Expand Down
2 changes: 1 addition & 1 deletion docs/src/Guides/25 Error Tracking.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ And this is great when debugging. But it consumes your rate limit, can run into

interactions.py contains built-in support for Sentry.io, a cloud error tracking platform.

To enable it, call `bot.load_extension('interactions.ext.sentry', token=SENTRY_TOKEN)` as early as possible in your startup. (Load it before your own extensions, so it can catch intitialization errors in those extensions)
To enable it, call `bot.load_extension('interactions.ext.sentry', dsn=SENTRY_DSN)` as early as possible in your startup. Load this extension before your own extensions, so it can catch intitialization errors in those extensions. `SENTRY_DSN` is provided by your Sentry.io project and should look something like `https://[email protected]/1048576`.

# What does this do that vanilla Sentry doesn't?

Expand Down
12 changes: 12 additions & 0 deletions interactions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
EmbedField,
EmbedFooter,
EmbedProvider,
Entitlement,
ExplicitContentFilterLevel,
Extension,
File,
Expand Down Expand Up @@ -223,6 +224,11 @@
NoArgumentConverter,
NSFWLevel,
open_file,
Onboarding,
OnboardingMode,
OnboardingPrompt,
OnboardingPromptOption,
OnboardingPromptType,
OptionType,
OrTrigger,
OverwriteType,
Expand Down Expand Up @@ -455,6 +461,7 @@
"EmbedField",
"EmbedFooter",
"EmbedProvider",
"Entitlement",
"errors",
"events",
"ExplicitContentFilterLevel",
Expand Down Expand Up @@ -562,6 +569,11 @@
"NoArgumentConverter",
"NSFWLevel",
"open_file",
"Onboarding",
"OnboardingMode",
"OnboardingPrompt",
"OnboardingPromptOption",
"OnboardingPromptType",
"OptionType",
"OrTrigger",
"OverwriteType",
Expand Down
8 changes: 8 additions & 0 deletions interactions/api/events/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
ChannelDelete,
ChannelPinsUpdate,
ChannelUpdate,
EntitlementCreate,
EntitlementDelete,
EntitlementUpdate,
GuildAuditLogEntryCreate,
GuildAvailable,
GuildEmojisUpdate,
Expand Down Expand Up @@ -41,6 +44,7 @@
MessageReactionAdd,
MessageReactionRemove,
MessageReactionRemoveAll,
MessageReactionRemoveEmoji,
MessageUpdate,
NewThreadCreate,
PresenceUpdate,
Expand Down Expand Up @@ -120,6 +124,9 @@
"ComponentError",
"Connect",
"Disconnect",
"EntitlementCreate",
"EntitlementDelete",
"EntitlementUpdate",
"Error",
"ExtensionCommandParse",
"ExtensionLoad",
Expand Down Expand Up @@ -155,6 +162,7 @@
"MessageReactionAdd",
"MessageReactionRemove",
"MessageReactionRemoveAll",
"MessageReactionRemoveEmoji",
"MessageUpdate",
"ModalCompletion",
"ModalError",
Expand Down
1 change: 1 addition & 0 deletions interactions/api/events/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ async def some_func(self, event):
```
Returns:
A listener object.
"""
listener = models.Listener.create(cls().resolved_name)(coro)
client.add_listener(listener)
Expand Down
40 changes: 40 additions & 0 deletions interactions/api/events/discord.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ async def an_event_handler(event: ChannelCreate):
"ChannelDelete",
"ChannelPinsUpdate",
"ChannelUpdate",
"EntitlementCreate",
"EntitlementDelete",
"EntitlementUpdate",
"GuildAuditLogEntryCreate",
"GuildEmojisUpdate",
"GuildJoin",
Expand Down Expand Up @@ -72,6 +75,7 @@ async def an_event_handler(event: ChannelCreate):
"MessageReactionAdd",
"MessageReactionRemove",
"MessageReactionRemoveAll",
"MessageReactionRemoveEmoji",
"MessageUpdate",
"NewThreadCreate",
"PresenceUpdate",
Expand Down Expand Up @@ -108,6 +112,7 @@ async def an_event_handler(event: ChannelCreate):
VoiceChannel,
)
from interactions.models.discord.emoji import CustomEmoji, PartialEmoji
from interactions.models.discord.entitlement import Entitlement
from interactions.models.discord.guild import Guild, GuildIntegration
from interactions.models.discord.message import Message
from interactions.models.discord.reaction import Reaction
Expand Down Expand Up @@ -573,6 +578,16 @@ class MessageReactionRemoveAll(GuildEvent):
"""The message that was reacted to"""


@attrs.define(eq=False, order=False, hash=False, kw_only=False)
class MessageReactionRemoveEmoji(MessageReactionRemoveAll):
"""Dispatched when all reactions of a specifc emoji are removed from a message."""

emoji: "PartialEmoji" = attrs.field(
repr=False,
)
"""The emoji that was removed"""


@attrs.define(eq=False, order=False, hash=False, kw_only=False)
class PresenceUpdate(BaseEvent):
"""A user's presence has changed."""
Expand Down Expand Up @@ -821,3 +836,28 @@ def member(self) -> Optional["Member"]:
@attrs.define(eq=False, order=False, hash=False, kw_only=False)
class GuildScheduledEventUserRemove(GuildScheduledEventUserAdd):
"""Dispatched when scheduled event is removed"""


@attrs.define(eq=False, order=False, hash=False, kw_only=False)
class BaseEntitlementEvent(BaseEvent):
entitlement: "Entitlement" = attrs.field(repr=True)


@attrs.define(eq=False, order=False, hash=False, kw_only=False)
class EntitlementCreate(BaseEntitlementEvent):
"""Dispatched when a user subscribes to a SKU."""


@attrs.define(eq=False, order=False, hash=False, kw_only=False)
class EntitlementUpdate(BaseEntitlementEvent):
"""Dispatched when a user's subscription renews for the next billing period."""


@attrs.define(eq=False, order=False, hash=False, kw_only=False)
class EntitlementDelete(BaseEntitlementEvent):
"""
Dispatched when a user's entitlement is deleted.
Notably, this event is not dispatched when a user's subscription is cancelled.
Instead, you simply won't receive an EntitlementUpdate event for the next billing period.
"""
1 change: 1 addition & 0 deletions interactions/api/events/internal.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ async def an_event_handler(event: ChannelCreate):
While all of these events are documented, not all of them are used, currently.
"""

import re
import typing
from typing import Any, Optional, TYPE_CHECKING, Type
Expand Down
2 changes: 2 additions & 0 deletions interactions/api/events/processors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from .voice_events import VoiceEvents
from ._template import Processor
from .auto_mod import AutoModEvents
from .entitlement_events import EntitlementEvents

__all__ = (
"ChannelEvents",
Expand All @@ -28,4 +29,5 @@
"VoiceEvents",
"Processor",
"AutoModEvents",
"EntitlementEvents",
)
22 changes: 22 additions & 0 deletions interactions/api/events/processors/entitlement_events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from typing import TYPE_CHECKING

from interactions.models.discord.entitlement import Entitlement
import interactions.api.events as events
from ._template import EventMixinTemplate, Processor

if TYPE_CHECKING:
from interactions.api.events import RawGatewayEvent


class EntitlementEvents(EventMixinTemplate):
@Processor.define()
async def _on_raw_entitlement_create(self, event: "RawGatewayEvent") -> None:
self.dispatch(events.EntitlementCreate(Entitlement.from_dict(event.data, self)))

@Processor.define()
async def _on_raw_entitlement_update(self, event: "RawGatewayEvent") -> None:
self.dispatch(events.EntitlementUpdate(Entitlement.from_dict(event.data, self)))

@Processor.define()
async def _on_raw_entitlement_delete(self, event: "RawGatewayEvent") -> None:
self.dispatch(events.EntitlementDelete(Entitlement.from_dict(event.data, self)))
21 changes: 21 additions & 0 deletions interactions/api/events/processors/reaction_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,24 @@ async def _on_raw_message_reaction_remove_all(self, event: "RawGatewayEvent") ->
await self.cache.fetch_message(event.data["channel_id"], event.data["message_id"]),
)
)

@Processor.define()
async def _on_raw_message_reaction_remove_emoji(self, event: "RawGatewayEvent") -> None:
emoji = PartialEmoji.from_dict(event.data.get("emoji"))
message = self.cache.get_message(event.data.get("channel_id"), event.data.get("message_id"))

if message:
for i, reaction in enumerate(message.reactions):
if reaction.emoji == emoji:
message.reactions.pop(i)
break
else:
message = await self.cache.fetch_message(event.data.get("channel_id"), event.data.get("message_id"))

self.dispatch(
events.MessageReactionRemoveEmoji(
event.data.get("guild_id"),
message,
emoji,
)
)
6 changes: 4 additions & 2 deletions interactions/api/gateway/gateway.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Outlines the interaction between interactions and Discord's Gateway API."""

import asyncio
import logging
import sys
Expand Down Expand Up @@ -161,7 +162,7 @@ async def run(self) -> None:
self.sequence = seq

if op == OPCODE.DISPATCH:
_ = asyncio.create_task(self.dispatch_event(data, seq, event))
_ = asyncio.create_task(self.dispatch_event(data, seq, event)) # noqa: RUF006
continue

# This may try to reconnect the connection so it is best to wait
Expand Down Expand Up @@ -214,6 +215,7 @@ async def dispatch_event(self, data, seq, event) -> None:
return self.state.client.dispatch(events.WebsocketReady(data))

case "RESUMED":
self.state._shard_ready.set()
self.state.wrapped_logger(
logging.INFO, f"Successfully resumed connection! Session_ID: {self.session_id}"
)
Expand All @@ -228,7 +230,7 @@ async def dispatch_event(self, data, seq, event) -> None:
event_name = f"raw_{event.lower()}"
if processor := self.state.client.processors.get(event_name):
try:
_ = asyncio.create_task(
_ = asyncio.create_task( # noqa: RUF006
processor(events.RawGatewayEvent(data.copy(), override_name=event_name))
)
except Exception as ex:
Expand Down
2 changes: 2 additions & 0 deletions interactions/api/gateway/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ def wrapped_logger(self, level: int, message: str, **kwargs) -> None:
level: The logging level
message: The message to log
**kwargs: Any additional keyword arguments that Logger.log accepts
"""
self.logger.log(level, f"Shard ID {self.shard_id} | {message}", **kwargs)

Expand Down Expand Up @@ -178,6 +179,7 @@ async def change_presence(
ActivityType.LISTENING,
ActivityType.WATCHING,
ActivityType.COMPETING,
ActivityType.CUSTOM,
]:
self.wrapped_logger(
logging.WARNING, f"Activity type `{ActivityType(activity.type).name}` may not be enabled for bots"
Expand Down
6 changes: 2 additions & 4 deletions interactions/api/gateway/websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,12 +315,10 @@ async def _start_bee_gees(self) -> None:
return

@abstractmethod
async def _identify(self) -> None:
...
async def _identify(self) -> None: ...

@abstractmethod
async def _resume_connection(self) -> None:
...
async def _resume_connection(self) -> None: ...

@abstractmethod
async def send_heartbeat(self) -> None:
Expand Down
Loading

0 comments on commit 7e01223

Please sign in to comment.