diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 731a882..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,8 +0,0 @@ -# Changelog - -## [0.13.0](https://github.com/linq-team/linq-python/compare/v0.12.0...v0.13.0) (2026-06-08) - - -### Features - -* add delivery_status field and deprecate is_read/is_delivered ([#23](https://github.com/linq-team/linq-python/issues/23)) ([0f5f6fa](https://github.com/linq-team/linq-python/commit/0f5f6fab581ea5fab03f4fe29abc916cf7a3eef4)) diff --git a/src/linq/resources/capability.py b/src/linq/resources/capability.py index c4b20ee..409d8a9 100644 --- a/src/linq/resources/capability.py +++ b/src/linq/resources/capability.py @@ -82,7 +82,7 @@ def check_i_message( "address": address, "from_": from_, }, - capability_check_i_message_params.CapabilityCheckiMessageParams, + capability_check_i_message_params.CapabilityCheckIMessageParams, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout @@ -196,7 +196,7 @@ async def check_i_message( "address": address, "from_": from_, }, - capability_check_i_message_params.CapabilityCheckiMessageParams, + capability_check_i_message_params.CapabilityCheckIMessageParams, ), options=make_request_options( extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout diff --git a/src/linq/types/__init__.py b/src/linq/types/__init__.py index c7d0755..fae64a1 100644 --- a/src/linq/types/__init__.py +++ b/src/linq/types/__init__.py @@ -65,7 +65,7 @@ from .reaction_removed_webhook_event import ReactionRemovedWebhookEvent as ReactionRemovedWebhookEvent from .message_delivered_webhook_event import MessageDeliveredWebhookEvent as MessageDeliveredWebhookEvent from .participant_added_webhook_event import ParticipantAddedWebhookEvent as ParticipantAddedWebhookEvent -from .capability_check_i_message_params import CapabilityCheckiMessageParams as CapabilityCheckiMessageParams +from .capability_check_i_message_params import CapabilityCheckIMessageParams as CapabilityCheckIMessageParams from .participant_removed_webhook_event import ParticipantRemovedWebhookEvent as ParticipantRemovedWebhookEvent from .webhook_subscription_create_params import WebhookSubscriptionCreateParams as WebhookSubscriptionCreateParams from .webhook_subscription_list_response import WebhookSubscriptionListResponse as WebhookSubscriptionListResponse diff --git a/src/linq/types/capability_check_i_message_params.py b/src/linq/types/capability_check_i_message_params.py index a633d64..3c2cfaa 100644 --- a/src/linq/types/capability_check_i_message_params.py +++ b/src/linq/types/capability_check_i_message_params.py @@ -6,10 +6,10 @@ from .._utils import PropertyInfo -__all__ = ["CapabilityCheckiMessageParams"] +__all__ = ["CapabilityCheckIMessageParams"] -class CapabilityCheckiMessageParams(TypedDict, total=False): +class CapabilityCheckIMessageParams(TypedDict, total=False): address: Required[str] """The recipient phone number or email address to check""" diff --git a/src/linq/types/chats/sent_message.py b/src/linq/types/chats/sent_message.py index fcac475..c75dcac 100644 --- a/src/linq/types/chats/sent_message.py +++ b/src/linq/types/chats/sent_message.py @@ -7,15 +7,107 @@ from ..._models import BaseModel from ..reply_to import ReplyTo from ..message_effect import MessageEffect +from ..shared.reaction import Reaction from ..shared.chat_handle import ChatHandle from ..shared.service_type import ServiceType from ..shared.link_part_response import LinkPartResponse from ..shared.text_part_response import TextPartResponse from ..shared.media_part_response import MediaPartResponse -__all__ = ["SentMessage", "Part"] +__all__ = [ + "SentMessage", + "Part", + "PartIMessageAppPartResponse", + "PartIMessageAppPartResponseApp", + "PartIMessageAppPartResponseLayout", +] -Part: TypeAlias = Union[TextPartResponse, MediaPartResponse, LinkPartResponse] + +class PartIMessageAppPartResponseApp(BaseModel): + """Identifies the iMessage app (Messages app extension) that backs the card.""" + + bundle_id: str + """Bundle identifier of the Messages app extension. Must not contain `:`.""" + + name: str + """Display name of the app, shown by Messages' fallback UI.""" + + team_id: str + """The app's 10-character uppercase alphanumeric team identifier.""" + + app_store_id: Optional[int] = None + """The owning app's App Store id (optional). + + When set, recipients without the iMessage app installed see a "Get the app" + affordance. + """ + + +class PartIMessageAppPartResponseLayout(BaseModel): + """Visible layout of the card. + + At least one of + `caption`, `subcaption`, `trailing_caption`, `trailing_subcaption`, or `image_url` must be + set, otherwise the card renders as an empty bubble. + """ + + caption: Optional[str] = None + """Primary label, top-left and bold.""" + + image_subtitle: Optional[str] = None + """Overlay text shown below `image_title`. Requires `image_url`.""" + + image_title: Optional[str] = None + """Overlay text shown above the image. Requires `image_url`.""" + + image_url: Optional[str] = None + """Optional HTTPS URL of a preview image. + + The server downloads it and embeds it in the card as JPEG (10MB max, same fetch + rules as media parts). + """ + + subcaption: Optional[str] = None + """Secondary label, below `caption` on the left.""" + + trailing_caption: Optional[str] = None + """Label shown top-right.""" + + trailing_subcaption: Optional[str] = None + """Label shown below `trailing_caption`, on the right.""" + + +class PartIMessageAppPartResponse(BaseModel): + """An iMessage app card part.""" + + app: PartIMessageAppPartResponseApp + """Identifies the iMessage app (Messages app extension) that backs the card.""" + + layout: PartIMessageAppPartResponseLayout + """Visible layout of the card. + + At least one of `caption`, `subcaption`, `trailing_caption`, + `trailing_subcaption`, or `image_url` must be set, otherwise the card renders as + an empty bubble. + """ + + reactions: Optional[List[Reaction]] = None + """Reactions on this message part""" + + type: Literal["imessage_app"] + """Indicates this is an iMessage app card part.""" + + url: str + """The URL delivered to the iMessage app on tap.""" + + fallback_text: Optional[str] = None + """Fallback text for surfaces that cannot render the card.""" + + session_id: Optional[str] = None + """Client-supplied session identifier, echoed back when provided.""" + + +Part: TypeAlias = Union[TextPartResponse, MediaPartResponse, LinkPartResponse, PartIMessageAppPartResponse] class SentMessage(BaseModel): diff --git a/src/linq/types/message.py b/src/linq/types/message.py index e4a3504..a362489 100644 --- a/src/linq/types/message.py +++ b/src/linq/types/message.py @@ -9,15 +9,107 @@ from .._models import BaseModel from .reply_to import ReplyTo from .message_effect import MessageEffect +from .shared.reaction import Reaction from .shared.chat_handle import ChatHandle from .shared.service_type import ServiceType from .shared.link_part_response import LinkPartResponse from .shared.text_part_response import TextPartResponse from .shared.media_part_response import MediaPartResponse -__all__ = ["Message", "Part"] +__all__ = [ + "Message", + "Part", + "PartIMessageAppPartResponse", + "PartIMessageAppPartResponseApp", + "PartIMessageAppPartResponseLayout", +] -Part: TypeAlias = Union[TextPartResponse, MediaPartResponse, LinkPartResponse] + +class PartIMessageAppPartResponseApp(BaseModel): + """Identifies the iMessage app (Messages app extension) that backs the card.""" + + bundle_id: str + """Bundle identifier of the Messages app extension. Must not contain `:`.""" + + name: str + """Display name of the app, shown by Messages' fallback UI.""" + + team_id: str + """The app's 10-character uppercase alphanumeric team identifier.""" + + app_store_id: Optional[int] = None + """The owning app's App Store id (optional). + + When set, recipients without the iMessage app installed see a "Get the app" + affordance. + """ + + +class PartIMessageAppPartResponseLayout(BaseModel): + """Visible layout of the card. + + At least one of + `caption`, `subcaption`, `trailing_caption`, `trailing_subcaption`, or `image_url` must be + set, otherwise the card renders as an empty bubble. + """ + + caption: Optional[str] = None + """Primary label, top-left and bold.""" + + image_subtitle: Optional[str] = None + """Overlay text shown below `image_title`. Requires `image_url`.""" + + image_title: Optional[str] = None + """Overlay text shown above the image. Requires `image_url`.""" + + image_url: Optional[str] = None + """Optional HTTPS URL of a preview image. + + The server downloads it and embeds it in the card as JPEG (10MB max, same fetch + rules as media parts). + """ + + subcaption: Optional[str] = None + """Secondary label, below `caption` on the left.""" + + trailing_caption: Optional[str] = None + """Label shown top-right.""" + + trailing_subcaption: Optional[str] = None + """Label shown below `trailing_caption`, on the right.""" + + +class PartIMessageAppPartResponse(BaseModel): + """An iMessage app card part.""" + + app: PartIMessageAppPartResponseApp + """Identifies the iMessage app (Messages app extension) that backs the card.""" + + layout: PartIMessageAppPartResponseLayout + """Visible layout of the card. + + At least one of `caption`, `subcaption`, `trailing_caption`, + `trailing_subcaption`, or `image_url` must be set, otherwise the card renders as + an empty bubble. + """ + + reactions: Optional[List[Reaction]] = None + """Reactions on this message part""" + + type: Literal["imessage_app"] + """Indicates this is an iMessage app card part.""" + + url: str + """The URL delivered to the iMessage app on tap.""" + + fallback_text: Optional[str] = None + """Fallback text for surfaces that cannot render the card.""" + + session_id: Optional[str] = None + """Client-supplied session identifier, echoed back when provided.""" + + +Part: TypeAlias = Union[TextPartResponse, MediaPartResponse, LinkPartResponse, PartIMessageAppPartResponse] class Message(BaseModel): diff --git a/src/linq/types/message_content_param.py b/src/linq/types/message_content_param.py index 2da1d83..2cbfb9e 100644 --- a/src/linq/types/message_content_param.py +++ b/src/linq/types/message_content_param.py @@ -3,7 +3,7 @@ from __future__ import annotations from typing import Union, Iterable -from typing_extensions import Required, TypeAlias, TypedDict +from typing_extensions import Literal, Required, TypeAlias, TypedDict from .reply_to_param import ReplyToParam from .link_part_param import LinkPartParam @@ -12,9 +12,106 @@ from .shared.service_type import ServiceType from .message_effect_param import MessageEffectParam -__all__ = ["MessageContentParam", "Part"] +__all__ = ["MessageContentParam", "Part", "PartIMessageAppPart", "PartIMessageAppPartApp", "PartIMessageAppPartLayout"] -Part: TypeAlias = Union[TextPartParam, MediaPartParam, LinkPartParam] + +class PartIMessageAppPartApp(TypedDict, total=False): + """Identifies the iMessage app (Messages app extension) that backs the card.""" + + bundle_id: Required[str] + """Bundle identifier of the Messages app extension. Must not contain `:`.""" + + name: Required[str] + """Display name of the app, shown by Messages' fallback UI.""" + + team_id: Required[str] + """The app's 10-character uppercase alphanumeric team identifier.""" + + app_store_id: int + """The owning app's App Store id (optional). + + When set, recipients without the iMessage app installed see a "Get the app" + affordance. + """ + + +class PartIMessageAppPartLayout(TypedDict, total=False): + """Visible layout of the card. + + At least one of + `caption`, `subcaption`, `trailing_caption`, `trailing_subcaption`, or `image_url` must be + set, otherwise the card renders as an empty bubble. + """ + + caption: str + """Primary label, top-left and bold.""" + + image_subtitle: str + """Overlay text shown below `image_title`. Requires `image_url`.""" + + image_title: str + """Overlay text shown above the image. Requires `image_url`.""" + + image_url: str + """Optional HTTPS URL of a preview image. + + The server downloads it and embeds it in the card as JPEG (10MB max, same fetch + rules as media parts). + """ + + subcaption: str + """Secondary label, below `caption` on the left.""" + + trailing_caption: str + """Label shown top-right.""" + + trailing_subcaption: str + """Label shown below `trailing_caption`, on the right.""" + + +class PartIMessageAppPart(TypedDict, total=False): + """An iMessage app card, backed by a Messages app extension. + + iMessage only — + an `imessage_app` part must be the **only** part in the message and is never delivered over + SMS/RCS. See the IMessageAppServiceUnsupported (2018) and RecipientUnsupportedMessageType + (4005) error codes. + """ + + app: Required[PartIMessageAppPartApp] + """Identifies the iMessage app (Messages app extension) that backs the card.""" + + layout: Required[PartIMessageAppPartLayout] + """Visible layout of the card. + + At least one of `caption`, `subcaption`, `trailing_caption`, + `trailing_subcaption`, or `image_url` must be set, otherwise the card renders as + an empty bubble. + """ + + type: Required[Literal["imessage_app"]] + """Indicates this is an iMessage app card part.""" + + url: Required[str] + """ + Absolute HTTPS URL delivered to the recipient's installed iMessage app when they + tap the card. Opaque to Messages. + """ + + fallback_text: str + """Text shown on surfaces that cannot render the card (notifications, lock screen). + + Defaults to the caption when omitted. + """ + + session_id: str + """ + Optional client-supplied identifier to correlate updatable/collaborative app + sessions (advanced). Not interpreted by Synapse. + """ + + +Part: TypeAlias = Union[TextPartParam, MediaPartParam, LinkPartParam, PartIMessageAppPart] class MessageContentParam(TypedDict, total=False): diff --git a/src/linq/types/message_event_v2.py b/src/linq/types/message_event_v2.py index 97daca0..ebc9446 100644 --- a/src/linq/types/message_event_v2.py +++ b/src/linq/types/message_event_v2.py @@ -12,7 +12,17 @@ from .schemas_text_part_response import SchemasTextPartResponse from .schemas_media_part_response import SchemasMediaPartResponse -__all__ = ["MessageEventV2", "Chat", "ChatHealthStatus", "Part", "PartSchemasLinkPartResponse", "ReplyTo"] +__all__ = [ + "MessageEventV2", + "Chat", + "ChatHealthStatus", + "Part", + "PartSchemasLinkPartResponse", + "PartSchemasIMessageAppPartResponse", + "PartSchemasIMessageAppPartResponseApp", + "PartSchemasIMessageAppPartResponseLayout", + "ReplyTo", +] class ChatHealthStatus(BaseModel): @@ -77,8 +87,76 @@ class PartSchemasLinkPartResponse(BaseModel): """The URL""" +class PartSchemasIMessageAppPartResponseApp(BaseModel): + """Identifies the iMessage app (Messages app extension) that backs the card.""" + + bundle_id: str + """Bundle identifier of the Messages app extension.""" + + name: str + """Display name of the app.""" + + team_id: str + """The app's 10-character team identifier.""" + + app_store_id: Optional[int] = None + """The owning app's App Store id, when known.""" + + +class PartSchemasIMessageAppPartResponseLayout(BaseModel): + """Visible layout of the card.""" + + caption: Optional[str] = None + """Primary label, top-left and bold.""" + + image_subtitle: Optional[str] = None + """Overlay text shown below image_title.""" + + image_title: Optional[str] = None + """Overlay text shown above the image.""" + + image_url: Optional[str] = None + """Presigned URL of the card preview image, when present.""" + + subcaption: Optional[str] = None + """Secondary label, below caption on the left.""" + + trailing_caption: Optional[str] = None + """Label shown top-right.""" + + trailing_subcaption: Optional[str] = None + """Label shown below trailing_caption.""" + + +class PartSchemasIMessageAppPartResponse(BaseModel): + """An iMessage app card part.""" + + app: PartSchemasIMessageAppPartResponseApp + """Identifies the iMessage app (Messages app extension) that backs the card.""" + + layout: PartSchemasIMessageAppPartResponseLayout + """Visible layout of the card.""" + + type: Literal["imessage_app"] + """Indicates this is an iMessage app card part.""" + + url: str + """The URL delivered to the iMessage app on tap.""" + + fallback_text: Optional[str] = None + """Fallback text for surfaces that cannot render the card.""" + + session_id: Optional[str] = None + """Client-supplied session identifier, echoed back when provided.""" + + Part: TypeAlias = Annotated[ - Union[SchemasTextPartResponse, SchemasMediaPartResponse, PartSchemasLinkPartResponse], + Union[ + SchemasTextPartResponse, + SchemasMediaPartResponse, + PartSchemasLinkPartResponse, + PartSchemasIMessageAppPartResponse, + ], PropertyInfo(discriminator="type"), ] diff --git a/uv.lock b/uv.lock index fcf7aa8..bae0cc1 100644 --- a/uv.lock +++ b/uv.lock @@ -530,7 +530,7 @@ wheels = [ [[package]] name = "linq-python" -version = "0.12.0" +version = "0.13.0" source = { editable = "." } dependencies = [ { name = "anyio" },