Skip to content

Commit 2be0176

Browse files
🐛 make ComponentEmoji id and name optional (#91)
* fix: make ComponentEmoji id and name optional Discord only includes the `id` field for custom emojis, not for standard unicode emojis (e.g. 🔗). Defining `id` as required via `Field(...)` causes pydantic ValidationError when receiving MESSAGE_UPDATE events containing button components with unicode emojis. Change both `id` and `name` to use `Missing[...] = UNSET` to match the Discord API specification where both fields are optional in a partial emoji. Fixes #90 * fix: make ComponentEmoji id and name optional Discord only includes the id field for custom emojis, not for standard unicode emojis (e.g. 🔗). Defining id as required via Field(...) causes pydantic ValidationError when receiving MESSAGE_UPDATE events containing button components with unicode emojis. Change both id and ame to use Missing[...] = UNSET to match the Discord API specification where both fields are optional in a partial emoji. Fixes #90 * fix: align ComponentEmoji with partial emoji schema --------- Co-authored-by: shoucandanghehe <wallfjjd@gmail.com>
1 parent 66ea530 commit 2be0176

2 files changed

Lines changed: 22 additions & 2 deletions

File tree

nonebot/adapters/discord/api/model.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -641,9 +641,9 @@ class ComponentEmoji(BaseModel):
641641
see https://discord.com/developers/docs/interactions/message-components#button-object
642642
"""
643643

644-
id: str | None = Field(...)
644+
id: MissingOrNullable[Snowflake] = UNSET
645645
"""emoji id"""
646-
name: str | None = Field(...)
646+
name: MissingOrNullable[str] = UNSET
647647
"""emoji name"""
648648
animated: Missing[bool] = UNSET
649649
"""whether this emoji is animated"""

tests/test_api_nullability.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
from nonebot.adapters.discord.api import (
66
ActionRow,
7+
ComponentEmoji,
78
ComponentType,
89
SelectMenu,
910
SelectOption,
11+
Snowflake,
1012
)
1113
from nonebot.adapters.discord.api.model import (
1214
Embed,
@@ -23,6 +25,8 @@
2325
)
2426
from nonebot.adapters.discord.utils import omit_unset
2527

28+
from nonebot.compat import type_validate_python
29+
2630

2731
def _json_payload(prepared: PreparedRequest) -> dict[str, Any]:
2832
encoded = encode_prepared_request(prepared)
@@ -135,6 +139,22 @@ def test_parse_data_keeps_action_row_type_for_components() -> None:
135139
assert int(payload["components"][0]["type"]) == int(ComponentType.ActionRow)
136140

137141

142+
def test_component_emoji_allows_missing_partial_fields() -> None:
143+
emoji = type_validate_python(ComponentEmoji, {"name": "🔗"})
144+
145+
assert emoji.id is UNSET
146+
assert emoji.name == "🔗"
147+
assert emoji.animated is UNSET
148+
149+
150+
def test_component_emoji_id_is_nullable_snowflake() -> None:
151+
emoji = type_validate_python(ComponentEmoji, {"id": "41771983429993937"})
152+
153+
assert isinstance(emoji.id, Snowflake)
154+
assert emoji.id == Snowflake(41771983429993937)
155+
assert emoji.name is UNSET
156+
157+
138158
def test_parse_forum_thread_message_keeps_name() -> None:
139159
payload = _json_payload(
140160
parse_forum_thread_message({"name": "thread-name", "content": "hello"})

0 commit comments

Comments
 (0)