linq-python 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- linq/__init__.py +102 -0
- linq/_base_client.py +2149 -0
- linq/_client.py +2479 -0
- linq/_compat.py +226 -0
- linq/_constants.py +14 -0
- linq/_exceptions.py +108 -0
- linq/_files.py +123 -0
- linq/_models.py +878 -0
- linq/_qs.py +153 -0
- linq/_resource.py +43 -0
- linq/_response.py +833 -0
- linq/_streaming.py +338 -0
- linq/_types.py +271 -0
- linq/_utils/__init__.py +65 -0
- linq/_utils/_compat.py +45 -0
- linq/_utils/_datetime_parse.py +136 -0
- linq/_utils/_json.py +35 -0
- linq/_utils/_logs.py +25 -0
- linq/_utils/_path.py +127 -0
- linq/_utils/_proxy.py +65 -0
- linq/_utils/_reflection.py +42 -0
- linq/_utils/_resources_proxy.py +24 -0
- linq/_utils/_streams.py +12 -0
- linq/_utils/_sync.py +58 -0
- linq/_utils/_transform.py +457 -0
- linq/_utils/_typing.py +156 -0
- linq/_utils/_utils.py +421 -0
- linq/_version.py +4 -0
- linq/lib/.keep +4 -0
- linq/pagination.py +95 -0
- linq/py.typed +0 -0
- linq/resources/__init__.py +134 -0
- linq/resources/attachments.py +589 -0
- linq/resources/capability.py +297 -0
- linq/resources/chats/__init__.py +61 -0
- linq/resources/chats/chats.py +1492 -0
- linq/resources/chats/messages.py +416 -0
- linq/resources/chats/participants.py +322 -0
- linq/resources/chats/typing.py +299 -0
- linq/resources/contact_card.py +472 -0
- linq/resources/messages.py +686 -0
- linq/resources/phone_numbers.py +163 -0
- linq/resources/phonenumbers.py +165 -0
- linq/resources/webhook_events.py +319 -0
- linq/resources/webhook_subscriptions.py +776 -0
- linq/resources/webhooks.py +34 -0
- linq/types/__init__.py +90 -0
- linq/types/attachment_create_params.py +42 -0
- linq/types/attachment_create_response.py +44 -0
- linq/types/attachment_retrieve_response.py +55 -0
- linq/types/capability_check_RCS_params.py +20 -0
- linq/types/capability_check_i_message_params.py +20 -0
- linq/types/chat.py +44 -0
- linq/types/chat_create_params.py +33 -0
- linq/types/chat_create_response.py +44 -0
- linq/types/chat_created_webhook_event.py +87 -0
- linq/types/chat_group_icon_update_failed_webhook_event.py +65 -0
- linq/types/chat_group_icon_updated_webhook_event.py +66 -0
- linq/types/chat_group_name_update_failed_webhook_event.py +65 -0
- linq/types/chat_group_name_updated_webhook_event.py +66 -0
- linq/types/chat_leave_chat_response.py +15 -0
- linq/types/chat_list_chats_params.py +36 -0
- linq/types/chat_send_voicememo_params.py +23 -0
- linq/types/chat_send_voicememo_response.py +79 -0
- linq/types/chat_typing_indicator_started_webhook_event.py +52 -0
- linq/types/chat_typing_indicator_stopped_webhook_event.py +52 -0
- linq/types/chat_update_params.py +15 -0
- linq/types/chat_update_response.py +13 -0
- linq/types/chats/__init__.py +12 -0
- linq/types/chats/message_list_params.py +15 -0
- linq/types/chats/message_send_params.py +18 -0
- linq/types/chats/message_send_response.py +16 -0
- linq/types/chats/participant_add_params.py +12 -0
- linq/types/chats/participant_add_response.py +15 -0
- linq/types/chats/participant_remove_params.py +12 -0
- linq/types/chats/participant_remove_response.py +15 -0
- linq/types/chats/sent_message.py +69 -0
- linq/types/contact_card_create_params.py +24 -0
- linq/types/contact_card_retrieve_params.py +15 -0
- linq/types/contact_card_retrieve_response.py +23 -0
- linq/types/contact_card_update_params.py +21 -0
- linq/types/events_webhook_event.py +50 -0
- linq/types/handle_check_response.py +13 -0
- linq/types/link_part_param.py +22 -0
- linq/types/media_part_param.py +54 -0
- linq/types/message.py +87 -0
- linq/types/message_add_reaction_params.py +32 -0
- linq/types/message_add_reaction_response.py +15 -0
- linq/types/message_content_param.py +82 -0
- linq/types/message_delivered_webhook_event.py +65 -0
- linq/types/message_edited_webhook_event.py +100 -0
- linq/types/message_effect.py +23 -0
- linq/types/message_effect_param.py +22 -0
- linq/types/message_event_v2.py +116 -0
- linq/types/message_failed_webhook_event.py +72 -0
- linq/types/message_list_messages_thread_params.py +18 -0
- linq/types/message_read_webhook_event.py +65 -0
- linq/types/message_received_webhook_event.py +65 -0
- linq/types/message_sent_webhook_event.py +65 -0
- linq/types/message_update_params.py +15 -0
- linq/types/participant_added_webhook_event.py +66 -0
- linq/types/participant_removed_webhook_event.py +66 -0
- linq/types/phone_number_list_response.py +20 -0
- linq/types/phone_number_status_updated_webhook_event.py +82 -0
- linq/types/phonenumber_list_response.py +39 -0
- linq/types/reaction_added_webhook_event.py +46 -0
- linq/types/reaction_event_base.py +85 -0
- linq/types/reaction_removed_webhook_event.py +46 -0
- linq/types/reply_to.py +21 -0
- linq/types/reply_to_param.py +21 -0
- linq/types/schemas_media_part_response.py +29 -0
- linq/types/schemas_message_effect.py +18 -0
- linq/types/schemas_text_part_response.py +22 -0
- linq/types/set_contact_card.py +24 -0
- linq/types/shared/__init__.py +9 -0
- linq/types/shared/chat_handle.py +33 -0
- linq/types/shared/media_part_response.py +34 -0
- linq/types/shared/reaction.py +56 -0
- linq/types/shared/reaction_type.py +7 -0
- linq/types/shared/service_type.py +7 -0
- linq/types/shared/text_decoration.py +23 -0
- linq/types/shared/text_part_response.py +26 -0
- linq/types/shared_params/__init__.py +5 -0
- linq/types/shared_params/reaction_type.py +9 -0
- linq/types/shared_params/service_type.py +9 -0
- linq/types/shared_params/text_decoration.py +23 -0
- linq/types/supported_content_type.py +60 -0
- linq/types/text_part_param.py +44 -0
- linq/types/webhook_event_list_response.py +17 -0
- linq/types/webhook_event_type.py +33 -0
- linq/types/webhook_subscription.py +35 -0
- linq/types/webhook_subscription_create_params.py +27 -0
- linq/types/webhook_subscription_create_response.py +46 -0
- linq/types/webhook_subscription_list_response.py +13 -0
- linq/types/webhook_subscription_update_params.py +30 -0
- linq_python-0.1.0.dist-info/METADATA +572 -0
- linq_python-0.1.0.dist-info/RECORD +139 -0
- linq_python-0.1.0.dist-info/WHEEL +4 -0
- linq_python-0.1.0.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,1492 @@
|
|
|
1
|
+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import httpx
|
|
6
|
+
|
|
7
|
+
from .typing import (
|
|
8
|
+
TypingResource,
|
|
9
|
+
AsyncTypingResource,
|
|
10
|
+
TypingResourceWithRawResponse,
|
|
11
|
+
AsyncTypingResourceWithRawResponse,
|
|
12
|
+
TypingResourceWithStreamingResponse,
|
|
13
|
+
AsyncTypingResourceWithStreamingResponse,
|
|
14
|
+
)
|
|
15
|
+
from ...types import (
|
|
16
|
+
chat_create_params,
|
|
17
|
+
chat_update_params,
|
|
18
|
+
chat_list_chats_params,
|
|
19
|
+
chat_send_voicememo_params,
|
|
20
|
+
)
|
|
21
|
+
from ..._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given
|
|
22
|
+
from ..._utils import path_template, maybe_transform, async_maybe_transform
|
|
23
|
+
from .messages import (
|
|
24
|
+
MessagesResource,
|
|
25
|
+
AsyncMessagesResource,
|
|
26
|
+
MessagesResourceWithRawResponse,
|
|
27
|
+
AsyncMessagesResourceWithRawResponse,
|
|
28
|
+
MessagesResourceWithStreamingResponse,
|
|
29
|
+
AsyncMessagesResourceWithStreamingResponse,
|
|
30
|
+
)
|
|
31
|
+
from ..._compat import cached_property
|
|
32
|
+
from ..._resource import SyncAPIResource, AsyncAPIResource
|
|
33
|
+
from ..._response import (
|
|
34
|
+
to_raw_response_wrapper,
|
|
35
|
+
to_streamed_response_wrapper,
|
|
36
|
+
async_to_raw_response_wrapper,
|
|
37
|
+
async_to_streamed_response_wrapper,
|
|
38
|
+
)
|
|
39
|
+
from ...pagination import SyncListChatsPagination, AsyncListChatsPagination
|
|
40
|
+
from ...types.chat import Chat
|
|
41
|
+
from .participants import (
|
|
42
|
+
ParticipantsResource,
|
|
43
|
+
AsyncParticipantsResource,
|
|
44
|
+
ParticipantsResourceWithRawResponse,
|
|
45
|
+
AsyncParticipantsResourceWithRawResponse,
|
|
46
|
+
ParticipantsResourceWithStreamingResponse,
|
|
47
|
+
AsyncParticipantsResourceWithStreamingResponse,
|
|
48
|
+
)
|
|
49
|
+
from ..._base_client import AsyncPaginator, make_request_options
|
|
50
|
+
from ...types.chat_create_response import ChatCreateResponse
|
|
51
|
+
from ...types.chat_update_response import ChatUpdateResponse
|
|
52
|
+
from ...types.message_content_param import MessageContentParam
|
|
53
|
+
from ...types.chat_leave_chat_response import ChatLeaveChatResponse
|
|
54
|
+
from ...types.chat_send_voicememo_response import ChatSendVoicememoResponse
|
|
55
|
+
|
|
56
|
+
__all__ = ["ChatsResource", "AsyncChatsResource"]
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class ChatsResource(SyncAPIResource):
|
|
60
|
+
@cached_property
|
|
61
|
+
def participants(self) -> ParticipantsResource:
|
|
62
|
+
"""A Chat is a conversation thread with one or more participants.
|
|
63
|
+
|
|
64
|
+
To begin a chat, you must create a Chat with at least one recipient handle.
|
|
65
|
+
Including multiple handles creates a group chat.
|
|
66
|
+
|
|
67
|
+
When creating a chat, the `from` field specifies which of your
|
|
68
|
+
authorized phone numbers the message originates from. Your authentication token grants
|
|
69
|
+
access to one or more phone numbers, but the `from` field determines the actual sender.
|
|
70
|
+
|
|
71
|
+
**Handle Format:**
|
|
72
|
+
- Handles can be phone numbers or email addresses
|
|
73
|
+
- Phone numbers MUST be in E.164 format (starting with +)
|
|
74
|
+
- Phone format: `+[country code][subscriber number]`
|
|
75
|
+
- Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
|
|
76
|
+
- Example email: `user@example.com`
|
|
77
|
+
- No spaces, dashes, or parentheses in phone numbers
|
|
78
|
+
"""
|
|
79
|
+
return ParticipantsResource(self._client)
|
|
80
|
+
|
|
81
|
+
@cached_property
|
|
82
|
+
def typing(self) -> TypingResource:
|
|
83
|
+
"""A Chat is a conversation thread with one or more participants.
|
|
84
|
+
|
|
85
|
+
To begin a chat, you must create a Chat with at least one recipient handle.
|
|
86
|
+
Including multiple handles creates a group chat.
|
|
87
|
+
|
|
88
|
+
When creating a chat, the `from` field specifies which of your
|
|
89
|
+
authorized phone numbers the message originates from. Your authentication token grants
|
|
90
|
+
access to one or more phone numbers, but the `from` field determines the actual sender.
|
|
91
|
+
|
|
92
|
+
**Handle Format:**
|
|
93
|
+
- Handles can be phone numbers or email addresses
|
|
94
|
+
- Phone numbers MUST be in E.164 format (starting with +)
|
|
95
|
+
- Phone format: `+[country code][subscriber number]`
|
|
96
|
+
- Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
|
|
97
|
+
- Example email: `user@example.com`
|
|
98
|
+
- No spaces, dashes, or parentheses in phone numbers
|
|
99
|
+
"""
|
|
100
|
+
return TypingResource(self._client)
|
|
101
|
+
|
|
102
|
+
@cached_property
|
|
103
|
+
def messages(self) -> MessagesResource:
|
|
104
|
+
"""Messages are individual communications within a chat thread.
|
|
105
|
+
|
|
106
|
+
Messages can include text, media attachments, rich link previews, special effects
|
|
107
|
+
(like confetti or fireworks), and reactions. All messages are associated with a
|
|
108
|
+
specific chat and sent from a phone number you own.
|
|
109
|
+
|
|
110
|
+
Messages support delivery status tracking, read receipts, and editing capabilities.
|
|
111
|
+
|
|
112
|
+
## Rich Link Previews
|
|
113
|
+
|
|
114
|
+
Send a URL as a `link` part to deliver it with a rich preview card showing the
|
|
115
|
+
page's title, description, and image (when available). A `link` part must be the
|
|
116
|
+
**only** part in the message — it cannot be combined with text or media parts.
|
|
117
|
+
To send a URL without a preview card, include it in a `text` part instead.
|
|
118
|
+
|
|
119
|
+
**Limitations:**
|
|
120
|
+
- A `link` part cannot be combined with other parts in the same message.
|
|
121
|
+
- Maximum URL length: 2,048 characters.
|
|
122
|
+
"""
|
|
123
|
+
return MessagesResource(self._client)
|
|
124
|
+
|
|
125
|
+
@cached_property
|
|
126
|
+
def with_raw_response(self) -> ChatsResourceWithRawResponse:
|
|
127
|
+
"""
|
|
128
|
+
This property can be used as a prefix for any HTTP method call to return
|
|
129
|
+
the raw response object instead of the parsed content.
|
|
130
|
+
|
|
131
|
+
For more information, see https://www.github.com/linq-team/linq-python#accessing-raw-response-data-eg-headers
|
|
132
|
+
"""
|
|
133
|
+
return ChatsResourceWithRawResponse(self)
|
|
134
|
+
|
|
135
|
+
@cached_property
|
|
136
|
+
def with_streaming_response(self) -> ChatsResourceWithStreamingResponse:
|
|
137
|
+
"""
|
|
138
|
+
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
|
139
|
+
|
|
140
|
+
For more information, see https://www.github.com/linq-team/linq-python#with_streaming_response
|
|
141
|
+
"""
|
|
142
|
+
return ChatsResourceWithStreamingResponse(self)
|
|
143
|
+
|
|
144
|
+
def create(
|
|
145
|
+
self,
|
|
146
|
+
*,
|
|
147
|
+
from_: str,
|
|
148
|
+
message: MessageContentParam,
|
|
149
|
+
to: SequenceNotStr[str],
|
|
150
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
151
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
152
|
+
extra_headers: Headers | None = None,
|
|
153
|
+
extra_query: Query | None = None,
|
|
154
|
+
extra_body: Body | None = None,
|
|
155
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
156
|
+
) -> ChatCreateResponse:
|
|
157
|
+
"""Create a new chat with specified participants and send an initial message.
|
|
158
|
+
|
|
159
|
+
The
|
|
160
|
+
initial message is required when creating a chat.
|
|
161
|
+
|
|
162
|
+
## Message Effects
|
|
163
|
+
|
|
164
|
+
You can add iMessage effects to make your messages more expressive. Effects are
|
|
165
|
+
optional and can be either screen effects (full-screen animations) or bubble
|
|
166
|
+
effects (message bubble animations).
|
|
167
|
+
|
|
168
|
+
**Screen Effects:** `confetti`, `fireworks`, `lasers`, `sparkles`,
|
|
169
|
+
`celebration`, `hearts`, `love`, `balloons`, `happy_birthday`, `echo`,
|
|
170
|
+
`spotlight`
|
|
171
|
+
|
|
172
|
+
**Bubble Effects:** `slam`, `loud`, `gentle`, `invisible`
|
|
173
|
+
|
|
174
|
+
Only one effect type can be applied per message.
|
|
175
|
+
|
|
176
|
+
## Inline Text Decorations (iMessage only)
|
|
177
|
+
|
|
178
|
+
Use the `text_decorations` array on a text part to apply styling and animations
|
|
179
|
+
to character ranges.
|
|
180
|
+
|
|
181
|
+
Each decoration specifies a `range: [start, end)` and exactly one of `style` or
|
|
182
|
+
`animation`.
|
|
183
|
+
|
|
184
|
+
**Styles:** `bold`, `italic`, `strikethrough`, `underline` **Animations:**
|
|
185
|
+
`big`, `small`, `shake`, `nod`, `explode`, `ripple`, `bloom`, `jitter`
|
|
186
|
+
|
|
187
|
+
```json
|
|
188
|
+
{
|
|
189
|
+
"type": "text",
|
|
190
|
+
"value": "Hello world",
|
|
191
|
+
"text_decorations": [
|
|
192
|
+
{ "range": [0, 5], "style": "bold" },
|
|
193
|
+
{ "range": [6, 11], "animation": "shake" }
|
|
194
|
+
]
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Note:** Style ranges (bold, italic, etc.) may overlap, but animation ranges
|
|
199
|
+
must not overlap with other animations or styles. Text decorations only render
|
|
200
|
+
for iMessage recipients. For SMS/RCS, text decorations are not applied.
|
|
201
|
+
|
|
202
|
+
Args:
|
|
203
|
+
from_: Sender phone number in E.164 format. Must be a phone number that the
|
|
204
|
+
authenticated partner has permission to send from.
|
|
205
|
+
|
|
206
|
+
message: Message content container. Groups all message-related fields together,
|
|
207
|
+
separating the "what" (message content) from the "where" (routing fields like
|
|
208
|
+
from/to).
|
|
209
|
+
|
|
210
|
+
to: Array of recipient handles (phone numbers in E.164 format or email addresses).
|
|
211
|
+
For individual chats, provide one recipient. For group chats, provide multiple.
|
|
212
|
+
|
|
213
|
+
extra_headers: Send extra headers
|
|
214
|
+
|
|
215
|
+
extra_query: Add additional query parameters to the request
|
|
216
|
+
|
|
217
|
+
extra_body: Add additional JSON properties to the request
|
|
218
|
+
|
|
219
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
220
|
+
"""
|
|
221
|
+
return self._post(
|
|
222
|
+
"/v3/chats",
|
|
223
|
+
body=maybe_transform(
|
|
224
|
+
{
|
|
225
|
+
"from_": from_,
|
|
226
|
+
"message": message,
|
|
227
|
+
"to": to,
|
|
228
|
+
},
|
|
229
|
+
chat_create_params.ChatCreateParams,
|
|
230
|
+
),
|
|
231
|
+
options=make_request_options(
|
|
232
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
233
|
+
),
|
|
234
|
+
cast_to=ChatCreateResponse,
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
def retrieve(
|
|
238
|
+
self,
|
|
239
|
+
chat_id: str,
|
|
240
|
+
*,
|
|
241
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
242
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
243
|
+
extra_headers: Headers | None = None,
|
|
244
|
+
extra_query: Query | None = None,
|
|
245
|
+
extra_body: Body | None = None,
|
|
246
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
247
|
+
) -> Chat:
|
|
248
|
+
"""
|
|
249
|
+
Retrieve a chat by its unique identifier.
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
extra_headers: Send extra headers
|
|
253
|
+
|
|
254
|
+
extra_query: Add additional query parameters to the request
|
|
255
|
+
|
|
256
|
+
extra_body: Add additional JSON properties to the request
|
|
257
|
+
|
|
258
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
259
|
+
"""
|
|
260
|
+
if not chat_id:
|
|
261
|
+
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
|
|
262
|
+
return self._get(
|
|
263
|
+
path_template("/v3/chats/{chat_id}", chat_id=chat_id),
|
|
264
|
+
options=make_request_options(
|
|
265
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
266
|
+
),
|
|
267
|
+
cast_to=Chat,
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
def update(
|
|
271
|
+
self,
|
|
272
|
+
chat_id: str,
|
|
273
|
+
*,
|
|
274
|
+
display_name: str | Omit = omit,
|
|
275
|
+
group_chat_icon: str | Omit = omit,
|
|
276
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
277
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
278
|
+
extra_headers: Headers | None = None,
|
|
279
|
+
extra_query: Query | None = None,
|
|
280
|
+
extra_body: Body | None = None,
|
|
281
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
282
|
+
) -> ChatUpdateResponse:
|
|
283
|
+
"""
|
|
284
|
+
Update chat properties such as display name and group chat icon.
|
|
285
|
+
|
|
286
|
+
Listen for `chat.group_name_updated`, `chat.group_icon_updated`,
|
|
287
|
+
`chat.group_name_update_failed`, or `chat.group_icon_update_failed` webhook
|
|
288
|
+
events to confirm the outcome.
|
|
289
|
+
|
|
290
|
+
Args:
|
|
291
|
+
display_name: New display name for the chat (group chats only)
|
|
292
|
+
|
|
293
|
+
group_chat_icon: URL of an image to set as the group chat icon (group chats only)
|
|
294
|
+
|
|
295
|
+
extra_headers: Send extra headers
|
|
296
|
+
|
|
297
|
+
extra_query: Add additional query parameters to the request
|
|
298
|
+
|
|
299
|
+
extra_body: Add additional JSON properties to the request
|
|
300
|
+
|
|
301
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
302
|
+
"""
|
|
303
|
+
if not chat_id:
|
|
304
|
+
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
|
|
305
|
+
return self._put(
|
|
306
|
+
path_template("/v3/chats/{chat_id}", chat_id=chat_id),
|
|
307
|
+
body=maybe_transform(
|
|
308
|
+
{
|
|
309
|
+
"display_name": display_name,
|
|
310
|
+
"group_chat_icon": group_chat_icon,
|
|
311
|
+
},
|
|
312
|
+
chat_update_params.ChatUpdateParams,
|
|
313
|
+
),
|
|
314
|
+
options=make_request_options(
|
|
315
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
316
|
+
),
|
|
317
|
+
cast_to=ChatUpdateResponse,
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
def leave_chat(
|
|
321
|
+
self,
|
|
322
|
+
chat_id: str,
|
|
323
|
+
*,
|
|
324
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
325
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
326
|
+
extra_headers: Headers | None = None,
|
|
327
|
+
extra_query: Query | None = None,
|
|
328
|
+
extra_body: Body | None = None,
|
|
329
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
330
|
+
) -> ChatLeaveChatResponse:
|
|
331
|
+
"""Removes your phone number from a group chat.
|
|
332
|
+
|
|
333
|
+
Once you leave, you will no longer
|
|
334
|
+
receive messages from the group and all interaction endpoints (send message,
|
|
335
|
+
typing, mark read, etc.) will return 409.
|
|
336
|
+
|
|
337
|
+
A `participant.removed` webhook will fire once the leave has been processed.
|
|
338
|
+
|
|
339
|
+
**Supported**
|
|
340
|
+
|
|
341
|
+
- iMessage group chats with 4 or more active participants (including yourself)
|
|
342
|
+
|
|
343
|
+
**Not supported**
|
|
344
|
+
|
|
345
|
+
- DM (1-on-1) chats — use the chat directly to continue the conversation
|
|
346
|
+
|
|
347
|
+
Args:
|
|
348
|
+
extra_headers: Send extra headers
|
|
349
|
+
|
|
350
|
+
extra_query: Add additional query parameters to the request
|
|
351
|
+
|
|
352
|
+
extra_body: Add additional JSON properties to the request
|
|
353
|
+
|
|
354
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
355
|
+
"""
|
|
356
|
+
if not chat_id:
|
|
357
|
+
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
|
|
358
|
+
return self._post(
|
|
359
|
+
path_template("/v3/chats/{chat_id}/leave", chat_id=chat_id),
|
|
360
|
+
options=make_request_options(
|
|
361
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
362
|
+
),
|
|
363
|
+
cast_to=ChatLeaveChatResponse,
|
|
364
|
+
)
|
|
365
|
+
|
|
366
|
+
def list_chats(
|
|
367
|
+
self,
|
|
368
|
+
*,
|
|
369
|
+
cursor: str | Omit = omit,
|
|
370
|
+
from_: str | Omit = omit,
|
|
371
|
+
limit: int | Omit = omit,
|
|
372
|
+
to: str | Omit = omit,
|
|
373
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
374
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
375
|
+
extra_headers: Headers | None = None,
|
|
376
|
+
extra_query: Query | None = None,
|
|
377
|
+
extra_body: Body | None = None,
|
|
378
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
379
|
+
) -> SyncListChatsPagination[Chat]:
|
|
380
|
+
"""
|
|
381
|
+
Retrieves a paginated list of chats for the authenticated partner.
|
|
382
|
+
|
|
383
|
+
**Filtering:**
|
|
384
|
+
|
|
385
|
+
- If `from` is provided, returns chats for that specific phone number
|
|
386
|
+
- If `from` is omitted, returns chats across all phone numbers owned by the
|
|
387
|
+
partner
|
|
388
|
+
- If `to` is provided, only returns chats where the specified handle is a
|
|
389
|
+
participant
|
|
390
|
+
|
|
391
|
+
**Pagination:**
|
|
392
|
+
|
|
393
|
+
- Use `limit` to control page size (default: 20, max: 100)
|
|
394
|
+
- The response includes `next_cursor` for fetching the next page
|
|
395
|
+
- When `next_cursor` is `null`, there are no more results to fetch
|
|
396
|
+
- Pass the `next_cursor` value as the `cursor` parameter for the next request
|
|
397
|
+
|
|
398
|
+
**Example pagination flow:**
|
|
399
|
+
|
|
400
|
+
1. First request: `GET /v3/chats?from=%2B12223334444&limit=20`
|
|
401
|
+
2. Response includes `next_cursor: "20"` (more results exist)
|
|
402
|
+
3. Next request: `GET /v3/chats?from=%2B12223334444&limit=20&cursor=20`
|
|
403
|
+
4. Response includes `next_cursor: null` (no more results)
|
|
404
|
+
|
|
405
|
+
Args:
|
|
406
|
+
cursor: Pagination cursor from the previous response's `next_cursor` field. Omit this
|
|
407
|
+
parameter for the first page of results.
|
|
408
|
+
|
|
409
|
+
from_: Phone number to filter chats by. Returns chats made from this phone number. Must
|
|
410
|
+
be in E.164 format (e.g., `+13343284472`). The `+` is automatically URL-encoded
|
|
411
|
+
by HTTP clients. If omitted, returns chats across all phone numbers owned by the
|
|
412
|
+
partner.
|
|
413
|
+
|
|
414
|
+
limit: Maximum number of chats to return per page
|
|
415
|
+
|
|
416
|
+
to: Filter chats by a participant handle. Only returns chats where this handle is a
|
|
417
|
+
participant. Can be an E.164 phone number (e.g., `+13343284472`) or an email
|
|
418
|
+
address (e.g., `user@example.com`). For phone numbers, the `+` is automatically
|
|
419
|
+
URL-encoded by HTTP clients.
|
|
420
|
+
|
|
421
|
+
extra_headers: Send extra headers
|
|
422
|
+
|
|
423
|
+
extra_query: Add additional query parameters to the request
|
|
424
|
+
|
|
425
|
+
extra_body: Add additional JSON properties to the request
|
|
426
|
+
|
|
427
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
428
|
+
"""
|
|
429
|
+
return self._get_api_list(
|
|
430
|
+
"/v3/chats",
|
|
431
|
+
page=SyncListChatsPagination[Chat],
|
|
432
|
+
options=make_request_options(
|
|
433
|
+
extra_headers=extra_headers,
|
|
434
|
+
extra_query=extra_query,
|
|
435
|
+
extra_body=extra_body,
|
|
436
|
+
timeout=timeout,
|
|
437
|
+
query=maybe_transform(
|
|
438
|
+
{
|
|
439
|
+
"cursor": cursor,
|
|
440
|
+
"from_": from_,
|
|
441
|
+
"limit": limit,
|
|
442
|
+
"to": to,
|
|
443
|
+
},
|
|
444
|
+
chat_list_chats_params.ChatListChatsParams,
|
|
445
|
+
),
|
|
446
|
+
),
|
|
447
|
+
model=Chat,
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
def mark_as_read(
|
|
451
|
+
self,
|
|
452
|
+
chat_id: str,
|
|
453
|
+
*,
|
|
454
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
455
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
456
|
+
extra_headers: Headers | None = None,
|
|
457
|
+
extra_query: Query | None = None,
|
|
458
|
+
extra_body: Body | None = None,
|
|
459
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
460
|
+
) -> None:
|
|
461
|
+
"""
|
|
462
|
+
Mark all messages in a chat as read.
|
|
463
|
+
|
|
464
|
+
Args:
|
|
465
|
+
extra_headers: Send extra headers
|
|
466
|
+
|
|
467
|
+
extra_query: Add additional query parameters to the request
|
|
468
|
+
|
|
469
|
+
extra_body: Add additional JSON properties to the request
|
|
470
|
+
|
|
471
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
472
|
+
"""
|
|
473
|
+
if not chat_id:
|
|
474
|
+
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
|
|
475
|
+
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
|
|
476
|
+
return self._post(
|
|
477
|
+
path_template("/v3/chats/{chat_id}/read", chat_id=chat_id),
|
|
478
|
+
options=make_request_options(
|
|
479
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
480
|
+
),
|
|
481
|
+
cast_to=NoneType,
|
|
482
|
+
)
|
|
483
|
+
|
|
484
|
+
def send_voicememo(
|
|
485
|
+
self,
|
|
486
|
+
chat_id: str,
|
|
487
|
+
*,
|
|
488
|
+
attachment_id: str | Omit = omit,
|
|
489
|
+
voice_memo_url: str | Omit = omit,
|
|
490
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
491
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
492
|
+
extra_headers: Headers | None = None,
|
|
493
|
+
extra_query: Query | None = None,
|
|
494
|
+
extra_body: Body | None = None,
|
|
495
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
496
|
+
) -> ChatSendVoicememoResponse:
|
|
497
|
+
"""
|
|
498
|
+
Send an audio file as an **iMessage voice memo bubble** to all participants in a
|
|
499
|
+
chat. Voice memos appear with iMessage's native inline playback UI, unlike
|
|
500
|
+
regular audio attachments sent via media parts which appear as downloadable
|
|
501
|
+
files.
|
|
502
|
+
|
|
503
|
+
**Supported audio formats:**
|
|
504
|
+
|
|
505
|
+
- MP3 (audio/mpeg)
|
|
506
|
+
- M4A (audio/x-m4a, audio/mp4)
|
|
507
|
+
- AAC (audio/aac)
|
|
508
|
+
- CAF (audio/x-caf) - Core Audio Format
|
|
509
|
+
- WAV (audio/wav)
|
|
510
|
+
- AIFF (audio/aiff, audio/x-aiff)
|
|
511
|
+
- AMR (audio/amr)
|
|
512
|
+
|
|
513
|
+
Args:
|
|
514
|
+
attachment_id: Reference to a voice memo file pre-uploaded via `POST /v3/attachments`. The file
|
|
515
|
+
is already stored, so sends using this ID skip the download step.
|
|
516
|
+
|
|
517
|
+
Either `voice_memo_url` or `attachment_id` must be provided, but not both.
|
|
518
|
+
|
|
519
|
+
voice_memo_url: URL of the voice memo audio file. Must be a publicly accessible HTTPS URL.
|
|
520
|
+
|
|
521
|
+
Either `voice_memo_url` or `attachment_id` must be provided, but not both.
|
|
522
|
+
|
|
523
|
+
extra_headers: Send extra headers
|
|
524
|
+
|
|
525
|
+
extra_query: Add additional query parameters to the request
|
|
526
|
+
|
|
527
|
+
extra_body: Add additional JSON properties to the request
|
|
528
|
+
|
|
529
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
530
|
+
"""
|
|
531
|
+
if not chat_id:
|
|
532
|
+
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
|
|
533
|
+
return self._post(
|
|
534
|
+
path_template("/v3/chats/{chat_id}/voicememo", chat_id=chat_id),
|
|
535
|
+
body=maybe_transform(
|
|
536
|
+
{
|
|
537
|
+
"attachment_id": attachment_id,
|
|
538
|
+
"voice_memo_url": voice_memo_url,
|
|
539
|
+
},
|
|
540
|
+
chat_send_voicememo_params.ChatSendVoicememoParams,
|
|
541
|
+
),
|
|
542
|
+
options=make_request_options(
|
|
543
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
544
|
+
),
|
|
545
|
+
cast_to=ChatSendVoicememoResponse,
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
def share_contact_card(
|
|
549
|
+
self,
|
|
550
|
+
chat_id: str,
|
|
551
|
+
*,
|
|
552
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
553
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
554
|
+
extra_headers: Headers | None = None,
|
|
555
|
+
extra_query: Query | None = None,
|
|
556
|
+
extra_body: Body | None = None,
|
|
557
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
558
|
+
) -> None:
|
|
559
|
+
"""
|
|
560
|
+
Share your contact information (Name and Photo Sharing) with a chat.
|
|
561
|
+
|
|
562
|
+
**Note:** A contact card must be configured before sharing. You can set up your
|
|
563
|
+
contact card via the [Contact Card API](#tag/Contact-Card) or on the
|
|
564
|
+
[Linq dashboard](https://dashboard.linqapp.com/contact-cards).
|
|
565
|
+
|
|
566
|
+
Args:
|
|
567
|
+
extra_headers: Send extra headers
|
|
568
|
+
|
|
569
|
+
extra_query: Add additional query parameters to the request
|
|
570
|
+
|
|
571
|
+
extra_body: Add additional JSON properties to the request
|
|
572
|
+
|
|
573
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
574
|
+
"""
|
|
575
|
+
if not chat_id:
|
|
576
|
+
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
|
|
577
|
+
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
|
|
578
|
+
return self._post(
|
|
579
|
+
path_template("/v3/chats/{chat_id}/share_contact_card", chat_id=chat_id),
|
|
580
|
+
options=make_request_options(
|
|
581
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
582
|
+
),
|
|
583
|
+
cast_to=NoneType,
|
|
584
|
+
)
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
class AsyncChatsResource(AsyncAPIResource):
|
|
588
|
+
@cached_property
|
|
589
|
+
def participants(self) -> AsyncParticipantsResource:
|
|
590
|
+
"""A Chat is a conversation thread with one or more participants.
|
|
591
|
+
|
|
592
|
+
To begin a chat, you must create a Chat with at least one recipient handle.
|
|
593
|
+
Including multiple handles creates a group chat.
|
|
594
|
+
|
|
595
|
+
When creating a chat, the `from` field specifies which of your
|
|
596
|
+
authorized phone numbers the message originates from. Your authentication token grants
|
|
597
|
+
access to one or more phone numbers, but the `from` field determines the actual sender.
|
|
598
|
+
|
|
599
|
+
**Handle Format:**
|
|
600
|
+
- Handles can be phone numbers or email addresses
|
|
601
|
+
- Phone numbers MUST be in E.164 format (starting with +)
|
|
602
|
+
- Phone format: `+[country code][subscriber number]`
|
|
603
|
+
- Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
|
|
604
|
+
- Example email: `user@example.com`
|
|
605
|
+
- No spaces, dashes, or parentheses in phone numbers
|
|
606
|
+
"""
|
|
607
|
+
return AsyncParticipantsResource(self._client)
|
|
608
|
+
|
|
609
|
+
@cached_property
|
|
610
|
+
def typing(self) -> AsyncTypingResource:
|
|
611
|
+
"""A Chat is a conversation thread with one or more participants.
|
|
612
|
+
|
|
613
|
+
To begin a chat, you must create a Chat with at least one recipient handle.
|
|
614
|
+
Including multiple handles creates a group chat.
|
|
615
|
+
|
|
616
|
+
When creating a chat, the `from` field specifies which of your
|
|
617
|
+
authorized phone numbers the message originates from. Your authentication token grants
|
|
618
|
+
access to one or more phone numbers, but the `from` field determines the actual sender.
|
|
619
|
+
|
|
620
|
+
**Handle Format:**
|
|
621
|
+
- Handles can be phone numbers or email addresses
|
|
622
|
+
- Phone numbers MUST be in E.164 format (starting with +)
|
|
623
|
+
- Phone format: `+[country code][subscriber number]`
|
|
624
|
+
- Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
|
|
625
|
+
- Example email: `user@example.com`
|
|
626
|
+
- No spaces, dashes, or parentheses in phone numbers
|
|
627
|
+
"""
|
|
628
|
+
return AsyncTypingResource(self._client)
|
|
629
|
+
|
|
630
|
+
@cached_property
|
|
631
|
+
def messages(self) -> AsyncMessagesResource:
|
|
632
|
+
"""Messages are individual communications within a chat thread.
|
|
633
|
+
|
|
634
|
+
Messages can include text, media attachments, rich link previews, special effects
|
|
635
|
+
(like confetti or fireworks), and reactions. All messages are associated with a
|
|
636
|
+
specific chat and sent from a phone number you own.
|
|
637
|
+
|
|
638
|
+
Messages support delivery status tracking, read receipts, and editing capabilities.
|
|
639
|
+
|
|
640
|
+
## Rich Link Previews
|
|
641
|
+
|
|
642
|
+
Send a URL as a `link` part to deliver it with a rich preview card showing the
|
|
643
|
+
page's title, description, and image (when available). A `link` part must be the
|
|
644
|
+
**only** part in the message — it cannot be combined with text or media parts.
|
|
645
|
+
To send a URL without a preview card, include it in a `text` part instead.
|
|
646
|
+
|
|
647
|
+
**Limitations:**
|
|
648
|
+
- A `link` part cannot be combined with other parts in the same message.
|
|
649
|
+
- Maximum URL length: 2,048 characters.
|
|
650
|
+
"""
|
|
651
|
+
return AsyncMessagesResource(self._client)
|
|
652
|
+
|
|
653
|
+
@cached_property
|
|
654
|
+
def with_raw_response(self) -> AsyncChatsResourceWithRawResponse:
|
|
655
|
+
"""
|
|
656
|
+
This property can be used as a prefix for any HTTP method call to return
|
|
657
|
+
the raw response object instead of the parsed content.
|
|
658
|
+
|
|
659
|
+
For more information, see https://www.github.com/linq-team/linq-python#accessing-raw-response-data-eg-headers
|
|
660
|
+
"""
|
|
661
|
+
return AsyncChatsResourceWithRawResponse(self)
|
|
662
|
+
|
|
663
|
+
@cached_property
|
|
664
|
+
def with_streaming_response(self) -> AsyncChatsResourceWithStreamingResponse:
|
|
665
|
+
"""
|
|
666
|
+
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
|
667
|
+
|
|
668
|
+
For more information, see https://www.github.com/linq-team/linq-python#with_streaming_response
|
|
669
|
+
"""
|
|
670
|
+
return AsyncChatsResourceWithStreamingResponse(self)
|
|
671
|
+
|
|
672
|
+
async def create(
|
|
673
|
+
self,
|
|
674
|
+
*,
|
|
675
|
+
from_: str,
|
|
676
|
+
message: MessageContentParam,
|
|
677
|
+
to: SequenceNotStr[str],
|
|
678
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
679
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
680
|
+
extra_headers: Headers | None = None,
|
|
681
|
+
extra_query: Query | None = None,
|
|
682
|
+
extra_body: Body | None = None,
|
|
683
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
684
|
+
) -> ChatCreateResponse:
|
|
685
|
+
"""Create a new chat with specified participants and send an initial message.
|
|
686
|
+
|
|
687
|
+
The
|
|
688
|
+
initial message is required when creating a chat.
|
|
689
|
+
|
|
690
|
+
## Message Effects
|
|
691
|
+
|
|
692
|
+
You can add iMessage effects to make your messages more expressive. Effects are
|
|
693
|
+
optional and can be either screen effects (full-screen animations) or bubble
|
|
694
|
+
effects (message bubble animations).
|
|
695
|
+
|
|
696
|
+
**Screen Effects:** `confetti`, `fireworks`, `lasers`, `sparkles`,
|
|
697
|
+
`celebration`, `hearts`, `love`, `balloons`, `happy_birthday`, `echo`,
|
|
698
|
+
`spotlight`
|
|
699
|
+
|
|
700
|
+
**Bubble Effects:** `slam`, `loud`, `gentle`, `invisible`
|
|
701
|
+
|
|
702
|
+
Only one effect type can be applied per message.
|
|
703
|
+
|
|
704
|
+
## Inline Text Decorations (iMessage only)
|
|
705
|
+
|
|
706
|
+
Use the `text_decorations` array on a text part to apply styling and animations
|
|
707
|
+
to character ranges.
|
|
708
|
+
|
|
709
|
+
Each decoration specifies a `range: [start, end)` and exactly one of `style` or
|
|
710
|
+
`animation`.
|
|
711
|
+
|
|
712
|
+
**Styles:** `bold`, `italic`, `strikethrough`, `underline` **Animations:**
|
|
713
|
+
`big`, `small`, `shake`, `nod`, `explode`, `ripple`, `bloom`, `jitter`
|
|
714
|
+
|
|
715
|
+
```json
|
|
716
|
+
{
|
|
717
|
+
"type": "text",
|
|
718
|
+
"value": "Hello world",
|
|
719
|
+
"text_decorations": [
|
|
720
|
+
{ "range": [0, 5], "style": "bold" },
|
|
721
|
+
{ "range": [6, 11], "animation": "shake" }
|
|
722
|
+
]
|
|
723
|
+
}
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
**Note:** Style ranges (bold, italic, etc.) may overlap, but animation ranges
|
|
727
|
+
must not overlap with other animations or styles. Text decorations only render
|
|
728
|
+
for iMessage recipients. For SMS/RCS, text decorations are not applied.
|
|
729
|
+
|
|
730
|
+
Args:
|
|
731
|
+
from_: Sender phone number in E.164 format. Must be a phone number that the
|
|
732
|
+
authenticated partner has permission to send from.
|
|
733
|
+
|
|
734
|
+
message: Message content container. Groups all message-related fields together,
|
|
735
|
+
separating the "what" (message content) from the "where" (routing fields like
|
|
736
|
+
from/to).
|
|
737
|
+
|
|
738
|
+
to: Array of recipient handles (phone numbers in E.164 format or email addresses).
|
|
739
|
+
For individual chats, provide one recipient. For group chats, provide multiple.
|
|
740
|
+
|
|
741
|
+
extra_headers: Send extra headers
|
|
742
|
+
|
|
743
|
+
extra_query: Add additional query parameters to the request
|
|
744
|
+
|
|
745
|
+
extra_body: Add additional JSON properties to the request
|
|
746
|
+
|
|
747
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
748
|
+
"""
|
|
749
|
+
return await self._post(
|
|
750
|
+
"/v3/chats",
|
|
751
|
+
body=await async_maybe_transform(
|
|
752
|
+
{
|
|
753
|
+
"from_": from_,
|
|
754
|
+
"message": message,
|
|
755
|
+
"to": to,
|
|
756
|
+
},
|
|
757
|
+
chat_create_params.ChatCreateParams,
|
|
758
|
+
),
|
|
759
|
+
options=make_request_options(
|
|
760
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
761
|
+
),
|
|
762
|
+
cast_to=ChatCreateResponse,
|
|
763
|
+
)
|
|
764
|
+
|
|
765
|
+
async def retrieve(
|
|
766
|
+
self,
|
|
767
|
+
chat_id: str,
|
|
768
|
+
*,
|
|
769
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
770
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
771
|
+
extra_headers: Headers | None = None,
|
|
772
|
+
extra_query: Query | None = None,
|
|
773
|
+
extra_body: Body | None = None,
|
|
774
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
775
|
+
) -> Chat:
|
|
776
|
+
"""
|
|
777
|
+
Retrieve a chat by its unique identifier.
|
|
778
|
+
|
|
779
|
+
Args:
|
|
780
|
+
extra_headers: Send extra headers
|
|
781
|
+
|
|
782
|
+
extra_query: Add additional query parameters to the request
|
|
783
|
+
|
|
784
|
+
extra_body: Add additional JSON properties to the request
|
|
785
|
+
|
|
786
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
787
|
+
"""
|
|
788
|
+
if not chat_id:
|
|
789
|
+
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
|
|
790
|
+
return await self._get(
|
|
791
|
+
path_template("/v3/chats/{chat_id}", chat_id=chat_id),
|
|
792
|
+
options=make_request_options(
|
|
793
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
794
|
+
),
|
|
795
|
+
cast_to=Chat,
|
|
796
|
+
)
|
|
797
|
+
|
|
798
|
+
async def update(
|
|
799
|
+
self,
|
|
800
|
+
chat_id: str,
|
|
801
|
+
*,
|
|
802
|
+
display_name: str | Omit = omit,
|
|
803
|
+
group_chat_icon: str | Omit = omit,
|
|
804
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
805
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
806
|
+
extra_headers: Headers | None = None,
|
|
807
|
+
extra_query: Query | None = None,
|
|
808
|
+
extra_body: Body | None = None,
|
|
809
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
810
|
+
) -> ChatUpdateResponse:
|
|
811
|
+
"""
|
|
812
|
+
Update chat properties such as display name and group chat icon.
|
|
813
|
+
|
|
814
|
+
Listen for `chat.group_name_updated`, `chat.group_icon_updated`,
|
|
815
|
+
`chat.group_name_update_failed`, or `chat.group_icon_update_failed` webhook
|
|
816
|
+
events to confirm the outcome.
|
|
817
|
+
|
|
818
|
+
Args:
|
|
819
|
+
display_name: New display name for the chat (group chats only)
|
|
820
|
+
|
|
821
|
+
group_chat_icon: URL of an image to set as the group chat icon (group chats only)
|
|
822
|
+
|
|
823
|
+
extra_headers: Send extra headers
|
|
824
|
+
|
|
825
|
+
extra_query: Add additional query parameters to the request
|
|
826
|
+
|
|
827
|
+
extra_body: Add additional JSON properties to the request
|
|
828
|
+
|
|
829
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
830
|
+
"""
|
|
831
|
+
if not chat_id:
|
|
832
|
+
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
|
|
833
|
+
return await self._put(
|
|
834
|
+
path_template("/v3/chats/{chat_id}", chat_id=chat_id),
|
|
835
|
+
body=await async_maybe_transform(
|
|
836
|
+
{
|
|
837
|
+
"display_name": display_name,
|
|
838
|
+
"group_chat_icon": group_chat_icon,
|
|
839
|
+
},
|
|
840
|
+
chat_update_params.ChatUpdateParams,
|
|
841
|
+
),
|
|
842
|
+
options=make_request_options(
|
|
843
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
844
|
+
),
|
|
845
|
+
cast_to=ChatUpdateResponse,
|
|
846
|
+
)
|
|
847
|
+
|
|
848
|
+
async def leave_chat(
|
|
849
|
+
self,
|
|
850
|
+
chat_id: str,
|
|
851
|
+
*,
|
|
852
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
853
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
854
|
+
extra_headers: Headers | None = None,
|
|
855
|
+
extra_query: Query | None = None,
|
|
856
|
+
extra_body: Body | None = None,
|
|
857
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
858
|
+
) -> ChatLeaveChatResponse:
|
|
859
|
+
"""Removes your phone number from a group chat.
|
|
860
|
+
|
|
861
|
+
Once you leave, you will no longer
|
|
862
|
+
receive messages from the group and all interaction endpoints (send message,
|
|
863
|
+
typing, mark read, etc.) will return 409.
|
|
864
|
+
|
|
865
|
+
A `participant.removed` webhook will fire once the leave has been processed.
|
|
866
|
+
|
|
867
|
+
**Supported**
|
|
868
|
+
|
|
869
|
+
- iMessage group chats with 4 or more active participants (including yourself)
|
|
870
|
+
|
|
871
|
+
**Not supported**
|
|
872
|
+
|
|
873
|
+
- DM (1-on-1) chats — use the chat directly to continue the conversation
|
|
874
|
+
|
|
875
|
+
Args:
|
|
876
|
+
extra_headers: Send extra headers
|
|
877
|
+
|
|
878
|
+
extra_query: Add additional query parameters to the request
|
|
879
|
+
|
|
880
|
+
extra_body: Add additional JSON properties to the request
|
|
881
|
+
|
|
882
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
883
|
+
"""
|
|
884
|
+
if not chat_id:
|
|
885
|
+
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
|
|
886
|
+
return await self._post(
|
|
887
|
+
path_template("/v3/chats/{chat_id}/leave", chat_id=chat_id),
|
|
888
|
+
options=make_request_options(
|
|
889
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
890
|
+
),
|
|
891
|
+
cast_to=ChatLeaveChatResponse,
|
|
892
|
+
)
|
|
893
|
+
|
|
894
|
+
def list_chats(
|
|
895
|
+
self,
|
|
896
|
+
*,
|
|
897
|
+
cursor: str | Omit = omit,
|
|
898
|
+
from_: str | Omit = omit,
|
|
899
|
+
limit: int | Omit = omit,
|
|
900
|
+
to: str | Omit = omit,
|
|
901
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
902
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
903
|
+
extra_headers: Headers | None = None,
|
|
904
|
+
extra_query: Query | None = None,
|
|
905
|
+
extra_body: Body | None = None,
|
|
906
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
907
|
+
) -> AsyncPaginator[Chat, AsyncListChatsPagination[Chat]]:
|
|
908
|
+
"""
|
|
909
|
+
Retrieves a paginated list of chats for the authenticated partner.
|
|
910
|
+
|
|
911
|
+
**Filtering:**
|
|
912
|
+
|
|
913
|
+
- If `from` is provided, returns chats for that specific phone number
|
|
914
|
+
- If `from` is omitted, returns chats across all phone numbers owned by the
|
|
915
|
+
partner
|
|
916
|
+
- If `to` is provided, only returns chats where the specified handle is a
|
|
917
|
+
participant
|
|
918
|
+
|
|
919
|
+
**Pagination:**
|
|
920
|
+
|
|
921
|
+
- Use `limit` to control page size (default: 20, max: 100)
|
|
922
|
+
- The response includes `next_cursor` for fetching the next page
|
|
923
|
+
- When `next_cursor` is `null`, there are no more results to fetch
|
|
924
|
+
- Pass the `next_cursor` value as the `cursor` parameter for the next request
|
|
925
|
+
|
|
926
|
+
**Example pagination flow:**
|
|
927
|
+
|
|
928
|
+
1. First request: `GET /v3/chats?from=%2B12223334444&limit=20`
|
|
929
|
+
2. Response includes `next_cursor: "20"` (more results exist)
|
|
930
|
+
3. Next request: `GET /v3/chats?from=%2B12223334444&limit=20&cursor=20`
|
|
931
|
+
4. Response includes `next_cursor: null` (no more results)
|
|
932
|
+
|
|
933
|
+
Args:
|
|
934
|
+
cursor: Pagination cursor from the previous response's `next_cursor` field. Omit this
|
|
935
|
+
parameter for the first page of results.
|
|
936
|
+
|
|
937
|
+
from_: Phone number to filter chats by. Returns chats made from this phone number. Must
|
|
938
|
+
be in E.164 format (e.g., `+13343284472`). The `+` is automatically URL-encoded
|
|
939
|
+
by HTTP clients. If omitted, returns chats across all phone numbers owned by the
|
|
940
|
+
partner.
|
|
941
|
+
|
|
942
|
+
limit: Maximum number of chats to return per page
|
|
943
|
+
|
|
944
|
+
to: Filter chats by a participant handle. Only returns chats where this handle is a
|
|
945
|
+
participant. Can be an E.164 phone number (e.g., `+13343284472`) or an email
|
|
946
|
+
address (e.g., `user@example.com`). For phone numbers, the `+` is automatically
|
|
947
|
+
URL-encoded by HTTP clients.
|
|
948
|
+
|
|
949
|
+
extra_headers: Send extra headers
|
|
950
|
+
|
|
951
|
+
extra_query: Add additional query parameters to the request
|
|
952
|
+
|
|
953
|
+
extra_body: Add additional JSON properties to the request
|
|
954
|
+
|
|
955
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
956
|
+
"""
|
|
957
|
+
return self._get_api_list(
|
|
958
|
+
"/v3/chats",
|
|
959
|
+
page=AsyncListChatsPagination[Chat],
|
|
960
|
+
options=make_request_options(
|
|
961
|
+
extra_headers=extra_headers,
|
|
962
|
+
extra_query=extra_query,
|
|
963
|
+
extra_body=extra_body,
|
|
964
|
+
timeout=timeout,
|
|
965
|
+
query=maybe_transform(
|
|
966
|
+
{
|
|
967
|
+
"cursor": cursor,
|
|
968
|
+
"from_": from_,
|
|
969
|
+
"limit": limit,
|
|
970
|
+
"to": to,
|
|
971
|
+
},
|
|
972
|
+
chat_list_chats_params.ChatListChatsParams,
|
|
973
|
+
),
|
|
974
|
+
),
|
|
975
|
+
model=Chat,
|
|
976
|
+
)
|
|
977
|
+
|
|
978
|
+
async def mark_as_read(
|
|
979
|
+
self,
|
|
980
|
+
chat_id: str,
|
|
981
|
+
*,
|
|
982
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
983
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
984
|
+
extra_headers: Headers | None = None,
|
|
985
|
+
extra_query: Query | None = None,
|
|
986
|
+
extra_body: Body | None = None,
|
|
987
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
988
|
+
) -> None:
|
|
989
|
+
"""
|
|
990
|
+
Mark all messages in a chat as read.
|
|
991
|
+
|
|
992
|
+
Args:
|
|
993
|
+
extra_headers: Send extra headers
|
|
994
|
+
|
|
995
|
+
extra_query: Add additional query parameters to the request
|
|
996
|
+
|
|
997
|
+
extra_body: Add additional JSON properties to the request
|
|
998
|
+
|
|
999
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
1000
|
+
"""
|
|
1001
|
+
if not chat_id:
|
|
1002
|
+
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
|
|
1003
|
+
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
|
|
1004
|
+
return await self._post(
|
|
1005
|
+
path_template("/v3/chats/{chat_id}/read", chat_id=chat_id),
|
|
1006
|
+
options=make_request_options(
|
|
1007
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
1008
|
+
),
|
|
1009
|
+
cast_to=NoneType,
|
|
1010
|
+
)
|
|
1011
|
+
|
|
1012
|
+
async def send_voicememo(
|
|
1013
|
+
self,
|
|
1014
|
+
chat_id: str,
|
|
1015
|
+
*,
|
|
1016
|
+
attachment_id: str | Omit = omit,
|
|
1017
|
+
voice_memo_url: str | Omit = omit,
|
|
1018
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
1019
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
1020
|
+
extra_headers: Headers | None = None,
|
|
1021
|
+
extra_query: Query | None = None,
|
|
1022
|
+
extra_body: Body | None = None,
|
|
1023
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
1024
|
+
) -> ChatSendVoicememoResponse:
|
|
1025
|
+
"""
|
|
1026
|
+
Send an audio file as an **iMessage voice memo bubble** to all participants in a
|
|
1027
|
+
chat. Voice memos appear with iMessage's native inline playback UI, unlike
|
|
1028
|
+
regular audio attachments sent via media parts which appear as downloadable
|
|
1029
|
+
files.
|
|
1030
|
+
|
|
1031
|
+
**Supported audio formats:**
|
|
1032
|
+
|
|
1033
|
+
- MP3 (audio/mpeg)
|
|
1034
|
+
- M4A (audio/x-m4a, audio/mp4)
|
|
1035
|
+
- AAC (audio/aac)
|
|
1036
|
+
- CAF (audio/x-caf) - Core Audio Format
|
|
1037
|
+
- WAV (audio/wav)
|
|
1038
|
+
- AIFF (audio/aiff, audio/x-aiff)
|
|
1039
|
+
- AMR (audio/amr)
|
|
1040
|
+
|
|
1041
|
+
Args:
|
|
1042
|
+
attachment_id: Reference to a voice memo file pre-uploaded via `POST /v3/attachments`. The file
|
|
1043
|
+
is already stored, so sends using this ID skip the download step.
|
|
1044
|
+
|
|
1045
|
+
Either `voice_memo_url` or `attachment_id` must be provided, but not both.
|
|
1046
|
+
|
|
1047
|
+
voice_memo_url: URL of the voice memo audio file. Must be a publicly accessible HTTPS URL.
|
|
1048
|
+
|
|
1049
|
+
Either `voice_memo_url` or `attachment_id` must be provided, but not both.
|
|
1050
|
+
|
|
1051
|
+
extra_headers: Send extra headers
|
|
1052
|
+
|
|
1053
|
+
extra_query: Add additional query parameters to the request
|
|
1054
|
+
|
|
1055
|
+
extra_body: Add additional JSON properties to the request
|
|
1056
|
+
|
|
1057
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
1058
|
+
"""
|
|
1059
|
+
if not chat_id:
|
|
1060
|
+
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
|
|
1061
|
+
return await self._post(
|
|
1062
|
+
path_template("/v3/chats/{chat_id}/voicememo", chat_id=chat_id),
|
|
1063
|
+
body=await async_maybe_transform(
|
|
1064
|
+
{
|
|
1065
|
+
"attachment_id": attachment_id,
|
|
1066
|
+
"voice_memo_url": voice_memo_url,
|
|
1067
|
+
},
|
|
1068
|
+
chat_send_voicememo_params.ChatSendVoicememoParams,
|
|
1069
|
+
),
|
|
1070
|
+
options=make_request_options(
|
|
1071
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
1072
|
+
),
|
|
1073
|
+
cast_to=ChatSendVoicememoResponse,
|
|
1074
|
+
)
|
|
1075
|
+
|
|
1076
|
+
async def share_contact_card(
|
|
1077
|
+
self,
|
|
1078
|
+
chat_id: str,
|
|
1079
|
+
*,
|
|
1080
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
1081
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
1082
|
+
extra_headers: Headers | None = None,
|
|
1083
|
+
extra_query: Query | None = None,
|
|
1084
|
+
extra_body: Body | None = None,
|
|
1085
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
1086
|
+
) -> None:
|
|
1087
|
+
"""
|
|
1088
|
+
Share your contact information (Name and Photo Sharing) with a chat.
|
|
1089
|
+
|
|
1090
|
+
**Note:** A contact card must be configured before sharing. You can set up your
|
|
1091
|
+
contact card via the [Contact Card API](#tag/Contact-Card) or on the
|
|
1092
|
+
[Linq dashboard](https://dashboard.linqapp.com/contact-cards).
|
|
1093
|
+
|
|
1094
|
+
Args:
|
|
1095
|
+
extra_headers: Send extra headers
|
|
1096
|
+
|
|
1097
|
+
extra_query: Add additional query parameters to the request
|
|
1098
|
+
|
|
1099
|
+
extra_body: Add additional JSON properties to the request
|
|
1100
|
+
|
|
1101
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
1102
|
+
"""
|
|
1103
|
+
if not chat_id:
|
|
1104
|
+
raise ValueError(f"Expected a non-empty value for `chat_id` but received {chat_id!r}")
|
|
1105
|
+
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
|
|
1106
|
+
return await self._post(
|
|
1107
|
+
path_template("/v3/chats/{chat_id}/share_contact_card", chat_id=chat_id),
|
|
1108
|
+
options=make_request_options(
|
|
1109
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
1110
|
+
),
|
|
1111
|
+
cast_to=NoneType,
|
|
1112
|
+
)
|
|
1113
|
+
|
|
1114
|
+
|
|
1115
|
+
class ChatsResourceWithRawResponse:
|
|
1116
|
+
def __init__(self, chats: ChatsResource) -> None:
|
|
1117
|
+
self._chats = chats
|
|
1118
|
+
|
|
1119
|
+
self.create = to_raw_response_wrapper(
|
|
1120
|
+
chats.create,
|
|
1121
|
+
)
|
|
1122
|
+
self.retrieve = to_raw_response_wrapper(
|
|
1123
|
+
chats.retrieve,
|
|
1124
|
+
)
|
|
1125
|
+
self.update = to_raw_response_wrapper(
|
|
1126
|
+
chats.update,
|
|
1127
|
+
)
|
|
1128
|
+
self.leave_chat = to_raw_response_wrapper(
|
|
1129
|
+
chats.leave_chat,
|
|
1130
|
+
)
|
|
1131
|
+
self.list_chats = to_raw_response_wrapper(
|
|
1132
|
+
chats.list_chats,
|
|
1133
|
+
)
|
|
1134
|
+
self.mark_as_read = to_raw_response_wrapper(
|
|
1135
|
+
chats.mark_as_read,
|
|
1136
|
+
)
|
|
1137
|
+
self.send_voicememo = to_raw_response_wrapper(
|
|
1138
|
+
chats.send_voicememo,
|
|
1139
|
+
)
|
|
1140
|
+
self.share_contact_card = to_raw_response_wrapper(
|
|
1141
|
+
chats.share_contact_card,
|
|
1142
|
+
)
|
|
1143
|
+
|
|
1144
|
+
@cached_property
|
|
1145
|
+
def participants(self) -> ParticipantsResourceWithRawResponse:
|
|
1146
|
+
"""A Chat is a conversation thread with one or more participants.
|
|
1147
|
+
|
|
1148
|
+
To begin a chat, you must create a Chat with at least one recipient handle.
|
|
1149
|
+
Including multiple handles creates a group chat.
|
|
1150
|
+
|
|
1151
|
+
When creating a chat, the `from` field specifies which of your
|
|
1152
|
+
authorized phone numbers the message originates from. Your authentication token grants
|
|
1153
|
+
access to one or more phone numbers, but the `from` field determines the actual sender.
|
|
1154
|
+
|
|
1155
|
+
**Handle Format:**
|
|
1156
|
+
- Handles can be phone numbers or email addresses
|
|
1157
|
+
- Phone numbers MUST be in E.164 format (starting with +)
|
|
1158
|
+
- Phone format: `+[country code][subscriber number]`
|
|
1159
|
+
- Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
|
|
1160
|
+
- Example email: `user@example.com`
|
|
1161
|
+
- No spaces, dashes, or parentheses in phone numbers
|
|
1162
|
+
"""
|
|
1163
|
+
return ParticipantsResourceWithRawResponse(self._chats.participants)
|
|
1164
|
+
|
|
1165
|
+
@cached_property
|
|
1166
|
+
def typing(self) -> TypingResourceWithRawResponse:
|
|
1167
|
+
"""A Chat is a conversation thread with one or more participants.
|
|
1168
|
+
|
|
1169
|
+
To begin a chat, you must create a Chat with at least one recipient handle.
|
|
1170
|
+
Including multiple handles creates a group chat.
|
|
1171
|
+
|
|
1172
|
+
When creating a chat, the `from` field specifies which of your
|
|
1173
|
+
authorized phone numbers the message originates from. Your authentication token grants
|
|
1174
|
+
access to one or more phone numbers, but the `from` field determines the actual sender.
|
|
1175
|
+
|
|
1176
|
+
**Handle Format:**
|
|
1177
|
+
- Handles can be phone numbers or email addresses
|
|
1178
|
+
- Phone numbers MUST be in E.164 format (starting with +)
|
|
1179
|
+
- Phone format: `+[country code][subscriber number]`
|
|
1180
|
+
- Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
|
|
1181
|
+
- Example email: `user@example.com`
|
|
1182
|
+
- No spaces, dashes, or parentheses in phone numbers
|
|
1183
|
+
"""
|
|
1184
|
+
return TypingResourceWithRawResponse(self._chats.typing)
|
|
1185
|
+
|
|
1186
|
+
@cached_property
|
|
1187
|
+
def messages(self) -> MessagesResourceWithRawResponse:
|
|
1188
|
+
"""Messages are individual communications within a chat thread.
|
|
1189
|
+
|
|
1190
|
+
Messages can include text, media attachments, rich link previews, special effects
|
|
1191
|
+
(like confetti or fireworks), and reactions. All messages are associated with a
|
|
1192
|
+
specific chat and sent from a phone number you own.
|
|
1193
|
+
|
|
1194
|
+
Messages support delivery status tracking, read receipts, and editing capabilities.
|
|
1195
|
+
|
|
1196
|
+
## Rich Link Previews
|
|
1197
|
+
|
|
1198
|
+
Send a URL as a `link` part to deliver it with a rich preview card showing the
|
|
1199
|
+
page's title, description, and image (when available). A `link` part must be the
|
|
1200
|
+
**only** part in the message — it cannot be combined with text or media parts.
|
|
1201
|
+
To send a URL without a preview card, include it in a `text` part instead.
|
|
1202
|
+
|
|
1203
|
+
**Limitations:**
|
|
1204
|
+
- A `link` part cannot be combined with other parts in the same message.
|
|
1205
|
+
- Maximum URL length: 2,048 characters.
|
|
1206
|
+
"""
|
|
1207
|
+
return MessagesResourceWithRawResponse(self._chats.messages)
|
|
1208
|
+
|
|
1209
|
+
|
|
1210
|
+
class AsyncChatsResourceWithRawResponse:
|
|
1211
|
+
def __init__(self, chats: AsyncChatsResource) -> None:
|
|
1212
|
+
self._chats = chats
|
|
1213
|
+
|
|
1214
|
+
self.create = async_to_raw_response_wrapper(
|
|
1215
|
+
chats.create,
|
|
1216
|
+
)
|
|
1217
|
+
self.retrieve = async_to_raw_response_wrapper(
|
|
1218
|
+
chats.retrieve,
|
|
1219
|
+
)
|
|
1220
|
+
self.update = async_to_raw_response_wrapper(
|
|
1221
|
+
chats.update,
|
|
1222
|
+
)
|
|
1223
|
+
self.leave_chat = async_to_raw_response_wrapper(
|
|
1224
|
+
chats.leave_chat,
|
|
1225
|
+
)
|
|
1226
|
+
self.list_chats = async_to_raw_response_wrapper(
|
|
1227
|
+
chats.list_chats,
|
|
1228
|
+
)
|
|
1229
|
+
self.mark_as_read = async_to_raw_response_wrapper(
|
|
1230
|
+
chats.mark_as_read,
|
|
1231
|
+
)
|
|
1232
|
+
self.send_voicememo = async_to_raw_response_wrapper(
|
|
1233
|
+
chats.send_voicememo,
|
|
1234
|
+
)
|
|
1235
|
+
self.share_contact_card = async_to_raw_response_wrapper(
|
|
1236
|
+
chats.share_contact_card,
|
|
1237
|
+
)
|
|
1238
|
+
|
|
1239
|
+
@cached_property
|
|
1240
|
+
def participants(self) -> AsyncParticipantsResourceWithRawResponse:
|
|
1241
|
+
"""A Chat is a conversation thread with one or more participants.
|
|
1242
|
+
|
|
1243
|
+
To begin a chat, you must create a Chat with at least one recipient handle.
|
|
1244
|
+
Including multiple handles creates a group chat.
|
|
1245
|
+
|
|
1246
|
+
When creating a chat, the `from` field specifies which of your
|
|
1247
|
+
authorized phone numbers the message originates from. Your authentication token grants
|
|
1248
|
+
access to one or more phone numbers, but the `from` field determines the actual sender.
|
|
1249
|
+
|
|
1250
|
+
**Handle Format:**
|
|
1251
|
+
- Handles can be phone numbers or email addresses
|
|
1252
|
+
- Phone numbers MUST be in E.164 format (starting with +)
|
|
1253
|
+
- Phone format: `+[country code][subscriber number]`
|
|
1254
|
+
- Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
|
|
1255
|
+
- Example email: `user@example.com`
|
|
1256
|
+
- No spaces, dashes, or parentheses in phone numbers
|
|
1257
|
+
"""
|
|
1258
|
+
return AsyncParticipantsResourceWithRawResponse(self._chats.participants)
|
|
1259
|
+
|
|
1260
|
+
@cached_property
|
|
1261
|
+
def typing(self) -> AsyncTypingResourceWithRawResponse:
|
|
1262
|
+
"""A Chat is a conversation thread with one or more participants.
|
|
1263
|
+
|
|
1264
|
+
To begin a chat, you must create a Chat with at least one recipient handle.
|
|
1265
|
+
Including multiple handles creates a group chat.
|
|
1266
|
+
|
|
1267
|
+
When creating a chat, the `from` field specifies which of your
|
|
1268
|
+
authorized phone numbers the message originates from. Your authentication token grants
|
|
1269
|
+
access to one or more phone numbers, but the `from` field determines the actual sender.
|
|
1270
|
+
|
|
1271
|
+
**Handle Format:**
|
|
1272
|
+
- Handles can be phone numbers or email addresses
|
|
1273
|
+
- Phone numbers MUST be in E.164 format (starting with +)
|
|
1274
|
+
- Phone format: `+[country code][subscriber number]`
|
|
1275
|
+
- Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
|
|
1276
|
+
- Example email: `user@example.com`
|
|
1277
|
+
- No spaces, dashes, or parentheses in phone numbers
|
|
1278
|
+
"""
|
|
1279
|
+
return AsyncTypingResourceWithRawResponse(self._chats.typing)
|
|
1280
|
+
|
|
1281
|
+
@cached_property
|
|
1282
|
+
def messages(self) -> AsyncMessagesResourceWithRawResponse:
|
|
1283
|
+
"""Messages are individual communications within a chat thread.
|
|
1284
|
+
|
|
1285
|
+
Messages can include text, media attachments, rich link previews, special effects
|
|
1286
|
+
(like confetti or fireworks), and reactions. All messages are associated with a
|
|
1287
|
+
specific chat and sent from a phone number you own.
|
|
1288
|
+
|
|
1289
|
+
Messages support delivery status tracking, read receipts, and editing capabilities.
|
|
1290
|
+
|
|
1291
|
+
## Rich Link Previews
|
|
1292
|
+
|
|
1293
|
+
Send a URL as a `link` part to deliver it with a rich preview card showing the
|
|
1294
|
+
page's title, description, and image (when available). A `link` part must be the
|
|
1295
|
+
**only** part in the message — it cannot be combined with text or media parts.
|
|
1296
|
+
To send a URL without a preview card, include it in a `text` part instead.
|
|
1297
|
+
|
|
1298
|
+
**Limitations:**
|
|
1299
|
+
- A `link` part cannot be combined with other parts in the same message.
|
|
1300
|
+
- Maximum URL length: 2,048 characters.
|
|
1301
|
+
"""
|
|
1302
|
+
return AsyncMessagesResourceWithRawResponse(self._chats.messages)
|
|
1303
|
+
|
|
1304
|
+
|
|
1305
|
+
class ChatsResourceWithStreamingResponse:
|
|
1306
|
+
def __init__(self, chats: ChatsResource) -> None:
|
|
1307
|
+
self._chats = chats
|
|
1308
|
+
|
|
1309
|
+
self.create = to_streamed_response_wrapper(
|
|
1310
|
+
chats.create,
|
|
1311
|
+
)
|
|
1312
|
+
self.retrieve = to_streamed_response_wrapper(
|
|
1313
|
+
chats.retrieve,
|
|
1314
|
+
)
|
|
1315
|
+
self.update = to_streamed_response_wrapper(
|
|
1316
|
+
chats.update,
|
|
1317
|
+
)
|
|
1318
|
+
self.leave_chat = to_streamed_response_wrapper(
|
|
1319
|
+
chats.leave_chat,
|
|
1320
|
+
)
|
|
1321
|
+
self.list_chats = to_streamed_response_wrapper(
|
|
1322
|
+
chats.list_chats,
|
|
1323
|
+
)
|
|
1324
|
+
self.mark_as_read = to_streamed_response_wrapper(
|
|
1325
|
+
chats.mark_as_read,
|
|
1326
|
+
)
|
|
1327
|
+
self.send_voicememo = to_streamed_response_wrapper(
|
|
1328
|
+
chats.send_voicememo,
|
|
1329
|
+
)
|
|
1330
|
+
self.share_contact_card = to_streamed_response_wrapper(
|
|
1331
|
+
chats.share_contact_card,
|
|
1332
|
+
)
|
|
1333
|
+
|
|
1334
|
+
@cached_property
|
|
1335
|
+
def participants(self) -> ParticipantsResourceWithStreamingResponse:
|
|
1336
|
+
"""A Chat is a conversation thread with one or more participants.
|
|
1337
|
+
|
|
1338
|
+
To begin a chat, you must create a Chat with at least one recipient handle.
|
|
1339
|
+
Including multiple handles creates a group chat.
|
|
1340
|
+
|
|
1341
|
+
When creating a chat, the `from` field specifies which of your
|
|
1342
|
+
authorized phone numbers the message originates from. Your authentication token grants
|
|
1343
|
+
access to one or more phone numbers, but the `from` field determines the actual sender.
|
|
1344
|
+
|
|
1345
|
+
**Handle Format:**
|
|
1346
|
+
- Handles can be phone numbers or email addresses
|
|
1347
|
+
- Phone numbers MUST be in E.164 format (starting with +)
|
|
1348
|
+
- Phone format: `+[country code][subscriber number]`
|
|
1349
|
+
- Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
|
|
1350
|
+
- Example email: `user@example.com`
|
|
1351
|
+
- No spaces, dashes, or parentheses in phone numbers
|
|
1352
|
+
"""
|
|
1353
|
+
return ParticipantsResourceWithStreamingResponse(self._chats.participants)
|
|
1354
|
+
|
|
1355
|
+
@cached_property
|
|
1356
|
+
def typing(self) -> TypingResourceWithStreamingResponse:
|
|
1357
|
+
"""A Chat is a conversation thread with one or more participants.
|
|
1358
|
+
|
|
1359
|
+
To begin a chat, you must create a Chat with at least one recipient handle.
|
|
1360
|
+
Including multiple handles creates a group chat.
|
|
1361
|
+
|
|
1362
|
+
When creating a chat, the `from` field specifies which of your
|
|
1363
|
+
authorized phone numbers the message originates from. Your authentication token grants
|
|
1364
|
+
access to one or more phone numbers, but the `from` field determines the actual sender.
|
|
1365
|
+
|
|
1366
|
+
**Handle Format:**
|
|
1367
|
+
- Handles can be phone numbers or email addresses
|
|
1368
|
+
- Phone numbers MUST be in E.164 format (starting with +)
|
|
1369
|
+
- Phone format: `+[country code][subscriber number]`
|
|
1370
|
+
- Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
|
|
1371
|
+
- Example email: `user@example.com`
|
|
1372
|
+
- No spaces, dashes, or parentheses in phone numbers
|
|
1373
|
+
"""
|
|
1374
|
+
return TypingResourceWithStreamingResponse(self._chats.typing)
|
|
1375
|
+
|
|
1376
|
+
@cached_property
|
|
1377
|
+
def messages(self) -> MessagesResourceWithStreamingResponse:
|
|
1378
|
+
"""Messages are individual communications within a chat thread.
|
|
1379
|
+
|
|
1380
|
+
Messages can include text, media attachments, rich link previews, special effects
|
|
1381
|
+
(like confetti or fireworks), and reactions. All messages are associated with a
|
|
1382
|
+
specific chat and sent from a phone number you own.
|
|
1383
|
+
|
|
1384
|
+
Messages support delivery status tracking, read receipts, and editing capabilities.
|
|
1385
|
+
|
|
1386
|
+
## Rich Link Previews
|
|
1387
|
+
|
|
1388
|
+
Send a URL as a `link` part to deliver it with a rich preview card showing the
|
|
1389
|
+
page's title, description, and image (when available). A `link` part must be the
|
|
1390
|
+
**only** part in the message — it cannot be combined with text or media parts.
|
|
1391
|
+
To send a URL without a preview card, include it in a `text` part instead.
|
|
1392
|
+
|
|
1393
|
+
**Limitations:**
|
|
1394
|
+
- A `link` part cannot be combined with other parts in the same message.
|
|
1395
|
+
- Maximum URL length: 2,048 characters.
|
|
1396
|
+
"""
|
|
1397
|
+
return MessagesResourceWithStreamingResponse(self._chats.messages)
|
|
1398
|
+
|
|
1399
|
+
|
|
1400
|
+
class AsyncChatsResourceWithStreamingResponse:
|
|
1401
|
+
def __init__(self, chats: AsyncChatsResource) -> None:
|
|
1402
|
+
self._chats = chats
|
|
1403
|
+
|
|
1404
|
+
self.create = async_to_streamed_response_wrapper(
|
|
1405
|
+
chats.create,
|
|
1406
|
+
)
|
|
1407
|
+
self.retrieve = async_to_streamed_response_wrapper(
|
|
1408
|
+
chats.retrieve,
|
|
1409
|
+
)
|
|
1410
|
+
self.update = async_to_streamed_response_wrapper(
|
|
1411
|
+
chats.update,
|
|
1412
|
+
)
|
|
1413
|
+
self.leave_chat = async_to_streamed_response_wrapper(
|
|
1414
|
+
chats.leave_chat,
|
|
1415
|
+
)
|
|
1416
|
+
self.list_chats = async_to_streamed_response_wrapper(
|
|
1417
|
+
chats.list_chats,
|
|
1418
|
+
)
|
|
1419
|
+
self.mark_as_read = async_to_streamed_response_wrapper(
|
|
1420
|
+
chats.mark_as_read,
|
|
1421
|
+
)
|
|
1422
|
+
self.send_voicememo = async_to_streamed_response_wrapper(
|
|
1423
|
+
chats.send_voicememo,
|
|
1424
|
+
)
|
|
1425
|
+
self.share_contact_card = async_to_streamed_response_wrapper(
|
|
1426
|
+
chats.share_contact_card,
|
|
1427
|
+
)
|
|
1428
|
+
|
|
1429
|
+
@cached_property
|
|
1430
|
+
def participants(self) -> AsyncParticipantsResourceWithStreamingResponse:
|
|
1431
|
+
"""A Chat is a conversation thread with one or more participants.
|
|
1432
|
+
|
|
1433
|
+
To begin a chat, you must create a Chat with at least one recipient handle.
|
|
1434
|
+
Including multiple handles creates a group chat.
|
|
1435
|
+
|
|
1436
|
+
When creating a chat, the `from` field specifies which of your
|
|
1437
|
+
authorized phone numbers the message originates from. Your authentication token grants
|
|
1438
|
+
access to one or more phone numbers, but the `from` field determines the actual sender.
|
|
1439
|
+
|
|
1440
|
+
**Handle Format:**
|
|
1441
|
+
- Handles can be phone numbers or email addresses
|
|
1442
|
+
- Phone numbers MUST be in E.164 format (starting with +)
|
|
1443
|
+
- Phone format: `+[country code][subscriber number]`
|
|
1444
|
+
- Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
|
|
1445
|
+
- Example email: `user@example.com`
|
|
1446
|
+
- No spaces, dashes, or parentheses in phone numbers
|
|
1447
|
+
"""
|
|
1448
|
+
return AsyncParticipantsResourceWithStreamingResponse(self._chats.participants)
|
|
1449
|
+
|
|
1450
|
+
@cached_property
|
|
1451
|
+
def typing(self) -> AsyncTypingResourceWithStreamingResponse:
|
|
1452
|
+
"""A Chat is a conversation thread with one or more participants.
|
|
1453
|
+
|
|
1454
|
+
To begin a chat, you must create a Chat with at least one recipient handle.
|
|
1455
|
+
Including multiple handles creates a group chat.
|
|
1456
|
+
|
|
1457
|
+
When creating a chat, the `from` field specifies which of your
|
|
1458
|
+
authorized phone numbers the message originates from. Your authentication token grants
|
|
1459
|
+
access to one or more phone numbers, but the `from` field determines the actual sender.
|
|
1460
|
+
|
|
1461
|
+
**Handle Format:**
|
|
1462
|
+
- Handles can be phone numbers or email addresses
|
|
1463
|
+
- Phone numbers MUST be in E.164 format (starting with +)
|
|
1464
|
+
- Phone format: `+[country code][subscriber number]`
|
|
1465
|
+
- Example phone: `+12223334444` (US), `+442071234567` (UK), `+81312345678` (Japan)
|
|
1466
|
+
- Example email: `user@example.com`
|
|
1467
|
+
- No spaces, dashes, or parentheses in phone numbers
|
|
1468
|
+
"""
|
|
1469
|
+
return AsyncTypingResourceWithStreamingResponse(self._chats.typing)
|
|
1470
|
+
|
|
1471
|
+
@cached_property
|
|
1472
|
+
def messages(self) -> AsyncMessagesResourceWithStreamingResponse:
|
|
1473
|
+
"""Messages are individual communications within a chat thread.
|
|
1474
|
+
|
|
1475
|
+
Messages can include text, media attachments, rich link previews, special effects
|
|
1476
|
+
(like confetti or fireworks), and reactions. All messages are associated with a
|
|
1477
|
+
specific chat and sent from a phone number you own.
|
|
1478
|
+
|
|
1479
|
+
Messages support delivery status tracking, read receipts, and editing capabilities.
|
|
1480
|
+
|
|
1481
|
+
## Rich Link Previews
|
|
1482
|
+
|
|
1483
|
+
Send a URL as a `link` part to deliver it with a rich preview card showing the
|
|
1484
|
+
page's title, description, and image (when available). A `link` part must be the
|
|
1485
|
+
**only** part in the message — it cannot be combined with text or media parts.
|
|
1486
|
+
To send a URL without a preview card, include it in a `text` part instead.
|
|
1487
|
+
|
|
1488
|
+
**Limitations:**
|
|
1489
|
+
- A `link` part cannot be combined with other parts in the same message.
|
|
1490
|
+
- Maximum URL length: 2,048 characters.
|
|
1491
|
+
"""
|
|
1492
|
+
return AsyncMessagesResourceWithStreamingResponse(self._chats.messages)
|