diff --git a/discord/abc.py b/discord/abc.py index f4cdf9d4e..9b271014c 100644 --- a/discord/abc.py +++ b/discord/abc.py @@ -1415,7 +1415,7 @@ class Messageable: previous_allowed_mention = state.allowed_mentions if nonce is MISSING: - nonce = str(utils.time_snowflake(datetime.utcnow())) + nonce = utils._generate_nonce() if stickers is not None: sticker_ids: SnowflakeList = [sticker.id for sticker in stickers] diff --git a/discord/commands.py b/discord/commands.py index 6976c5dee..fa8fcc1ed 100644 --- a/discord/commands.py +++ b/discord/commands.py @@ -24,13 +24,12 @@ DEALINGS IN THE SOFTWARE. from __future__ import annotations -from datetime import datetime from typing import Any, Dict, List, Optional, Protocol, Tuple, Type, runtime_checkable, TYPE_CHECKING, Union from .enums import AppCommandOptionType, AppCommandType, ChannelType, InteractionType, try_enum from .errors import InvalidData from .mixins import Hashable -from .utils import time_snowflake +from .utils import _generate_nonce if TYPE_CHECKING: from .abc import Messageable, Snowflake @@ -92,7 +91,7 @@ class ApplicationCommand(Protocol): raise TypeError('__call__() missing 1 required argument: \'channel\'') state = self._state acc_channel = await channel._get_channel() - nonce = str(time_snowflake(datetime.utcnow())) + nonce = _generate_nonce() type = InteractionType.application_command state._interaction_cache[nonce] = (type.value, data['name'], acc_channel) diff --git a/discord/components.py b/discord/components.py index 1e32dc02e..7e3aceae9 100644 --- a/discord/components.py +++ b/discord/components.py @@ -29,7 +29,7 @@ from typing import Any, ClassVar, Dict, List, Optional, TYPE_CHECKING, Tuple, Un from .enums import try_enum, ComponentType, ButtonStyle, TextStyle, InteractionType from .errors import InvalidData -from .utils import get_slots, MISSING, time_snowflake, utcnow +from .utils import _generate_nonce, get_slots, MISSING from .partial_emoji import PartialEmoji, _EmojiTag if TYPE_CHECKING: @@ -219,7 +219,7 @@ class Button(Component): message = self.message state = message._state - nonce = str(time_snowflake(utcnow())) + nonce = _generate_nonce() type = InteractionType.component state._interaction_cache[nonce] = (int(type), None, message.channel) @@ -315,7 +315,7 @@ class SelectMenu(Component): """ message = self.message state = message._state - nonce = str(time_snowflake(utcnow())) + nonce = _generate_nonce() type = InteractionType.component state._interaction_cache[nonce] = (int(type), None, message.channel) diff --git a/discord/http.py b/discord/http.py index bc7af3823..c408bd674 100644 --- a/discord/http.py +++ b/discord/http.py @@ -150,7 +150,7 @@ def handle_message_parameters( username: str = MISSING, avatar_url: Any = MISSING, tts: bool = False, - nonce: Optional[Union[int, str]] = None, + nonce: Optional[Union[int, str]] = MISSING, flags: MessageFlags = MISSING, file: File = MISSING, files: Sequence[File] = MISSING, @@ -193,8 +193,10 @@ def handle_message_parameters( else: payload['content'] = None - if nonce is not None: - payload['nonce'] = str(nonce) + if nonce is MISSING: + payload['nonce'] = utils._generate_nonce() + elif nonce: + payload['nonce'] = nonce if message_reference is not MISSING: payload['message_reference'] = message_reference @@ -597,6 +599,8 @@ class HTTPClient: previous['captcha_key'] = await captcha_handler.fetch_token(e.json, self.proxy, self.proxy_auth) if (rqtoken := e.json.get('captcha_rqtoken')) is not None: previous['captcha_rqtoken'] = rqtoken + if 'nonce' in previous: + previous['nonce'] = utils._generate_nonce() kwargs['headers']['Content-Type'] = 'application/json' kwargs['data'] = utils._to_json(previous) @@ -2361,7 +2365,7 @@ class HTTPClient: 'application_id': str((message.application_id or message.author.id) if message else application_id), 'channel_id': str(channel.id), 'data': data, - 'nonce': nonce if nonce is not MISSING else str(utils.time_snowflake(utils.utcnow())), + 'nonce': nonce if nonce is not MISSING else utils._generate_nonce(), 'session_id': state.session_id or utils._generate_session_id(), 'type': type.value, } diff --git a/discord/iterators.py b/discord/iterators.py index 929272f18..99da7a461 100644 --- a/discord/iterators.py +++ b/discord/iterators.py @@ -28,7 +28,7 @@ import asyncio from typing import Awaitable, TYPE_CHECKING, TypeVar, Optional, Any, Callable, Union, List, Tuple, AsyncIterator, Dict from .errors import InvalidData -from .utils import time_snowflake, utcnow +from .utils import _generate_nonce from .object import Object from .commands import _command_factory from .enums import AppCommandType @@ -163,7 +163,7 @@ class CommandIterator: state = self.state kwargs = self.kwargs retrieve = self.retrieve - nonce = str(time_snowflake(utcnow())) + nonce = _generate_nonce() def predicate(d): return d.get('nonce') == nonce diff --git a/discord/modal.py b/discord/modal.py index 8b9eea506..422739d5c 100644 --- a/discord/modal.py +++ b/discord/modal.py @@ -30,7 +30,7 @@ from .components import _component_factory from .enums import InteractionType from .errors import InvalidData from .mixins import Hashable -from .utils import time_snowflake, utcnow +from .utils import _generate_nonce if TYPE_CHECKING: from .components import Component @@ -128,7 +128,7 @@ class Modal(Hashable): """ interaction = self.interaction state = self._state - nonce = str(time_snowflake(utcnow())) + nonce = _generate_nonce() type = InteractionType.modal_submit state._interaction_cache[nonce] = (int(type), None, interaction.channel) diff --git a/discord/utils.py b/discord/utils.py index 54e732e4e..149593614 100644 --- a/discord/utils.py +++ b/discord/utils.py @@ -1206,6 +1206,10 @@ def _generate_session_id() -> str: return ''.join(random.choices(string.ascii_letters + string.digits, k=16)) +def _generate_nonce() -> str: + return str(time_snowflake(utcnow())) + + class ExpiringString(collections.UserString): def __init__(self, data: str, timeout: int) -> None: super().__init__(data)