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,776 @@
|
|
|
1
|
+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import List, Optional
|
|
6
|
+
|
|
7
|
+
import httpx
|
|
8
|
+
|
|
9
|
+
from ..types import webhook_subscription_create_params, webhook_subscription_update_params
|
|
10
|
+
from .._types import Body, Omit, Query, Headers, NoneType, NotGiven, SequenceNotStr, omit, not_given
|
|
11
|
+
from .._utils import path_template, maybe_transform, async_maybe_transform
|
|
12
|
+
from .._compat import cached_property
|
|
13
|
+
from .._resource import SyncAPIResource, AsyncAPIResource
|
|
14
|
+
from .._response import (
|
|
15
|
+
to_raw_response_wrapper,
|
|
16
|
+
to_streamed_response_wrapper,
|
|
17
|
+
async_to_raw_response_wrapper,
|
|
18
|
+
async_to_streamed_response_wrapper,
|
|
19
|
+
)
|
|
20
|
+
from .._base_client import make_request_options
|
|
21
|
+
from ..types.webhook_event_type import WebhookEventType
|
|
22
|
+
from ..types.webhook_subscription import WebhookSubscription
|
|
23
|
+
from ..types.webhook_subscription_list_response import WebhookSubscriptionListResponse
|
|
24
|
+
from ..types.webhook_subscription_create_response import WebhookSubscriptionCreateResponse
|
|
25
|
+
|
|
26
|
+
__all__ = ["WebhookSubscriptionsResource", "AsyncWebhookSubscriptionsResource"]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class WebhookSubscriptionsResource(SyncAPIResource):
|
|
30
|
+
"""
|
|
31
|
+
Webhook Subscriptions allow you to receive real-time notifications when events
|
|
32
|
+
occur on your account.
|
|
33
|
+
|
|
34
|
+
Configure webhook endpoints to receive events such as messages sent/received,
|
|
35
|
+
delivery status changes, reactions, typing indicators, and more.
|
|
36
|
+
|
|
37
|
+
Failed deliveries (5xx, 429, network errors) are retried up to 10 times over
|
|
38
|
+
~25 minutes with exponential backoff. Each event includes a unique ID for
|
|
39
|
+
deduplication.
|
|
40
|
+
|
|
41
|
+
## Webhook Headers
|
|
42
|
+
|
|
43
|
+
Each webhook request includes the following headers:
|
|
44
|
+
|
|
45
|
+
| Header | Description |
|
|
46
|
+
|--------|-------------|
|
|
47
|
+
| `X-Webhook-Event` | The event type (e.g., `message.sent`, `message.received`) |
|
|
48
|
+
| `X-Webhook-Subscription-ID` | Your webhook subscription ID |
|
|
49
|
+
| `X-Webhook-Timestamp` | Unix timestamp (seconds) when the webhook was sent |
|
|
50
|
+
| `X-Webhook-Signature` | HMAC-SHA256 signature for verification |
|
|
51
|
+
|
|
52
|
+
## Verifying Webhook Signatures
|
|
53
|
+
|
|
54
|
+
All webhooks are signed using HMAC-SHA256. You should always verify the signature
|
|
55
|
+
to ensure the webhook originated from Linq and hasn't been tampered with.
|
|
56
|
+
|
|
57
|
+
**Signature Construction:**
|
|
58
|
+
|
|
59
|
+
The signature is computed over a concatenation of the timestamp and payload:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
{timestamp}.{payload}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Where:
|
|
66
|
+
- `timestamp` is the value from the `X-Webhook-Timestamp` header
|
|
67
|
+
- `payload` is the raw JSON request body (exact bytes, not re-serialized)
|
|
68
|
+
|
|
69
|
+
**Verification Steps:**
|
|
70
|
+
|
|
71
|
+
1. Extract the `X-Webhook-Timestamp` and `X-Webhook-Signature` headers
|
|
72
|
+
2. Get the raw request body bytes (do not parse and re-serialize)
|
|
73
|
+
3. Concatenate: `"{timestamp}.{payload}"`
|
|
74
|
+
4. Compute HMAC-SHA256 using your signing secret as the key
|
|
75
|
+
5. Hex-encode the result and compare with `X-Webhook-Signature`
|
|
76
|
+
6. Use constant-time comparison to prevent timing attacks
|
|
77
|
+
|
|
78
|
+
**Example (Python):**
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
import hmac
|
|
82
|
+
import hashlib
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def verify_webhook(signing_secret, payload, timestamp, signature):
|
|
86
|
+
message = f"{timestamp}.{payload.decode('utf-8')}"
|
|
87
|
+
expected = hmac.new(signing_secret.encode("utf-8"), message.encode("utf-8"), hashlib.sha256).hexdigest()
|
|
88
|
+
return hmac.compare_digest(expected, signature)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Example (Node.js):**
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
const crypto = require('crypto');
|
|
95
|
+
|
|
96
|
+
function verifyWebhook(signingSecret, payload, timestamp, signature) {
|
|
97
|
+
const message = `${timestamp}.${payload}`;
|
|
98
|
+
const expected = crypto
|
|
99
|
+
.createHmac('sha256', signingSecret)
|
|
100
|
+
.update(message)
|
|
101
|
+
.digest('hex');
|
|
102
|
+
return crypto.timingSafeEqual(
|
|
103
|
+
Buffer.from(expected),
|
|
104
|
+
Buffer.from(signature)
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Security Best Practices:**
|
|
110
|
+
|
|
111
|
+
- Reject webhooks with timestamps older than 5 minutes to prevent replay attacks
|
|
112
|
+
- Always use constant-time comparison for signature verification
|
|
113
|
+
- Store your signing secret securely (e.g., environment variable, secrets manager)
|
|
114
|
+
- Return a 2xx status code quickly, then process the webhook asynchronously
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
@cached_property
|
|
118
|
+
def with_raw_response(self) -> WebhookSubscriptionsResourceWithRawResponse:
|
|
119
|
+
"""
|
|
120
|
+
This property can be used as a prefix for any HTTP method call to return
|
|
121
|
+
the raw response object instead of the parsed content.
|
|
122
|
+
|
|
123
|
+
For more information, see https://www.github.com/linq-team/linq-python#accessing-raw-response-data-eg-headers
|
|
124
|
+
"""
|
|
125
|
+
return WebhookSubscriptionsResourceWithRawResponse(self)
|
|
126
|
+
|
|
127
|
+
@cached_property
|
|
128
|
+
def with_streaming_response(self) -> WebhookSubscriptionsResourceWithStreamingResponse:
|
|
129
|
+
"""
|
|
130
|
+
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
|
131
|
+
|
|
132
|
+
For more information, see https://www.github.com/linq-team/linq-python#with_streaming_response
|
|
133
|
+
"""
|
|
134
|
+
return WebhookSubscriptionsResourceWithStreamingResponse(self)
|
|
135
|
+
|
|
136
|
+
def create(
|
|
137
|
+
self,
|
|
138
|
+
*,
|
|
139
|
+
subscribed_events: List[WebhookEventType],
|
|
140
|
+
target_url: str,
|
|
141
|
+
phone_numbers: SequenceNotStr[str] | Omit = omit,
|
|
142
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
143
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
144
|
+
extra_headers: Headers | None = None,
|
|
145
|
+
extra_query: Query | None = None,
|
|
146
|
+
extra_body: Body | None = None,
|
|
147
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
148
|
+
) -> WebhookSubscriptionCreateResponse:
|
|
149
|
+
"""Create a new webhook subscription to receive events at a target URL.
|
|
150
|
+
|
|
151
|
+
Upon
|
|
152
|
+
creation, a signing secret is generated for verifying webhook authenticity.
|
|
153
|
+
**Store this secret securely — it cannot be retrieved later.**
|
|
154
|
+
|
|
155
|
+
**Phone Number Filtering:**
|
|
156
|
+
|
|
157
|
+
- Optionally specify `phone_numbers` to only receive events for specific lines
|
|
158
|
+
- If omitted, events from all phone numbers are delivered (default behavior)
|
|
159
|
+
- Use multiple subscriptions with different `phone_numbers` to route different
|
|
160
|
+
lines to different endpoints
|
|
161
|
+
- Each `target_url` can only be used once per account. To route different lines
|
|
162
|
+
to different destinations, use a unique URL per subscription (e.g., append a
|
|
163
|
+
query parameter: `https://example.com/webhook?line=1`)
|
|
164
|
+
|
|
165
|
+
**Webhook Delivery:**
|
|
166
|
+
|
|
167
|
+
- Events are sent via HTTP POST to the target URL
|
|
168
|
+
- Each request includes `X-Webhook-Signature` and `X-Webhook-Timestamp` headers
|
|
169
|
+
- Signature is HMAC-SHA256 over `{timestamp}.{payload}` — see
|
|
170
|
+
[Webhook Events](/docs/webhook-events) for verification details
|
|
171
|
+
- Failed deliveries (5xx, 429, network errors) are retried up to 10 times over
|
|
172
|
+
~25 minutes with exponential backoff
|
|
173
|
+
- Client errors (4xx except 429) are not retried
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
subscribed_events: List of event types to subscribe to
|
|
177
|
+
|
|
178
|
+
target_url: URL where webhook events will be sent. Must be HTTPS.
|
|
179
|
+
|
|
180
|
+
phone_numbers: Optional list of phone numbers to filter events for. Only events originating
|
|
181
|
+
from these phone numbers will be delivered to this subscription. If omitted or
|
|
182
|
+
empty, events from all phone numbers are delivered. Phone numbers must be in
|
|
183
|
+
E.164 format.
|
|
184
|
+
|
|
185
|
+
extra_headers: Send extra headers
|
|
186
|
+
|
|
187
|
+
extra_query: Add additional query parameters to the request
|
|
188
|
+
|
|
189
|
+
extra_body: Add additional JSON properties to the request
|
|
190
|
+
|
|
191
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
192
|
+
"""
|
|
193
|
+
return self._post(
|
|
194
|
+
"/v3/webhook-subscriptions",
|
|
195
|
+
body=maybe_transform(
|
|
196
|
+
{
|
|
197
|
+
"subscribed_events": subscribed_events,
|
|
198
|
+
"target_url": target_url,
|
|
199
|
+
"phone_numbers": phone_numbers,
|
|
200
|
+
},
|
|
201
|
+
webhook_subscription_create_params.WebhookSubscriptionCreateParams,
|
|
202
|
+
),
|
|
203
|
+
options=make_request_options(
|
|
204
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
205
|
+
),
|
|
206
|
+
cast_to=WebhookSubscriptionCreateResponse,
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
def retrieve(
|
|
210
|
+
self,
|
|
211
|
+
subscription_id: str,
|
|
212
|
+
*,
|
|
213
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
214
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
215
|
+
extra_headers: Headers | None = None,
|
|
216
|
+
extra_query: Query | None = None,
|
|
217
|
+
extra_body: Body | None = None,
|
|
218
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
219
|
+
) -> WebhookSubscription:
|
|
220
|
+
"""
|
|
221
|
+
Retrieve details for a specific webhook subscription including its target URL,
|
|
222
|
+
subscribed events, and current status.
|
|
223
|
+
|
|
224
|
+
Args:
|
|
225
|
+
extra_headers: Send extra headers
|
|
226
|
+
|
|
227
|
+
extra_query: Add additional query parameters to the request
|
|
228
|
+
|
|
229
|
+
extra_body: Add additional JSON properties to the request
|
|
230
|
+
|
|
231
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
232
|
+
"""
|
|
233
|
+
if not subscription_id:
|
|
234
|
+
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
|
|
235
|
+
return self._get(
|
|
236
|
+
path_template("/v3/webhook-subscriptions/{subscription_id}", subscription_id=subscription_id),
|
|
237
|
+
options=make_request_options(
|
|
238
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
239
|
+
),
|
|
240
|
+
cast_to=WebhookSubscription,
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
def update(
|
|
244
|
+
self,
|
|
245
|
+
subscription_id: str,
|
|
246
|
+
*,
|
|
247
|
+
is_active: bool | Omit = omit,
|
|
248
|
+
phone_numbers: Optional[SequenceNotStr[str]] | Omit = omit,
|
|
249
|
+
subscribed_events: List[WebhookEventType] | Omit = omit,
|
|
250
|
+
target_url: str | Omit = omit,
|
|
251
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
252
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
253
|
+
extra_headers: Headers | None = None,
|
|
254
|
+
extra_query: Query | None = None,
|
|
255
|
+
extra_body: Body | None = None,
|
|
256
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
257
|
+
) -> WebhookSubscription:
|
|
258
|
+
"""Update an existing webhook subscription.
|
|
259
|
+
|
|
260
|
+
You can modify the target URL,
|
|
261
|
+
subscribed events, or activate/deactivate the subscription.
|
|
262
|
+
|
|
263
|
+
**Note:** The signing secret cannot be changed via this endpoint.
|
|
264
|
+
|
|
265
|
+
Args:
|
|
266
|
+
is_active: Activate or deactivate the subscription
|
|
267
|
+
|
|
268
|
+
phone_numbers: Updated list of phone numbers to filter events for. Set to a non-empty array to
|
|
269
|
+
filter events to specific phone numbers. Set to an empty array or null to remove
|
|
270
|
+
the filter and receive events from all phone numbers. Phone numbers must be in
|
|
271
|
+
E.164 format.
|
|
272
|
+
|
|
273
|
+
subscribed_events: Updated list of event types to subscribe to
|
|
274
|
+
|
|
275
|
+
target_url: New target URL for webhook events
|
|
276
|
+
|
|
277
|
+
extra_headers: Send extra headers
|
|
278
|
+
|
|
279
|
+
extra_query: Add additional query parameters to the request
|
|
280
|
+
|
|
281
|
+
extra_body: Add additional JSON properties to the request
|
|
282
|
+
|
|
283
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
284
|
+
"""
|
|
285
|
+
if not subscription_id:
|
|
286
|
+
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
|
|
287
|
+
return self._put(
|
|
288
|
+
path_template("/v3/webhook-subscriptions/{subscription_id}", subscription_id=subscription_id),
|
|
289
|
+
body=maybe_transform(
|
|
290
|
+
{
|
|
291
|
+
"is_active": is_active,
|
|
292
|
+
"phone_numbers": phone_numbers,
|
|
293
|
+
"subscribed_events": subscribed_events,
|
|
294
|
+
"target_url": target_url,
|
|
295
|
+
},
|
|
296
|
+
webhook_subscription_update_params.WebhookSubscriptionUpdateParams,
|
|
297
|
+
),
|
|
298
|
+
options=make_request_options(
|
|
299
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
300
|
+
),
|
|
301
|
+
cast_to=WebhookSubscription,
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
def list(
|
|
305
|
+
self,
|
|
306
|
+
*,
|
|
307
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
308
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
309
|
+
extra_headers: Headers | None = None,
|
|
310
|
+
extra_query: Query | None = None,
|
|
311
|
+
extra_body: Body | None = None,
|
|
312
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
313
|
+
) -> WebhookSubscriptionListResponse:
|
|
314
|
+
"""Retrieve all webhook subscriptions for the authenticated partner.
|
|
315
|
+
|
|
316
|
+
Returns a list
|
|
317
|
+
of active and inactive subscriptions with their configuration and status.
|
|
318
|
+
"""
|
|
319
|
+
return self._get(
|
|
320
|
+
"/v3/webhook-subscriptions",
|
|
321
|
+
options=make_request_options(
|
|
322
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
323
|
+
),
|
|
324
|
+
cast_to=WebhookSubscriptionListResponse,
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
def delete(
|
|
328
|
+
self,
|
|
329
|
+
subscription_id: str,
|
|
330
|
+
*,
|
|
331
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
332
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
333
|
+
extra_headers: Headers | None = None,
|
|
334
|
+
extra_query: Query | None = None,
|
|
335
|
+
extra_body: Body | None = None,
|
|
336
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
337
|
+
) -> None:
|
|
338
|
+
"""
|
|
339
|
+
Delete a webhook subscription.
|
|
340
|
+
|
|
341
|
+
Args:
|
|
342
|
+
extra_headers: Send extra headers
|
|
343
|
+
|
|
344
|
+
extra_query: Add additional query parameters to the request
|
|
345
|
+
|
|
346
|
+
extra_body: Add additional JSON properties to the request
|
|
347
|
+
|
|
348
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
349
|
+
"""
|
|
350
|
+
if not subscription_id:
|
|
351
|
+
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
|
|
352
|
+
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
|
|
353
|
+
return self._delete(
|
|
354
|
+
path_template("/v3/webhook-subscriptions/{subscription_id}", subscription_id=subscription_id),
|
|
355
|
+
options=make_request_options(
|
|
356
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
357
|
+
),
|
|
358
|
+
cast_to=NoneType,
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
class AsyncWebhookSubscriptionsResource(AsyncAPIResource):
|
|
363
|
+
"""
|
|
364
|
+
Webhook Subscriptions allow you to receive real-time notifications when events
|
|
365
|
+
occur on your account.
|
|
366
|
+
|
|
367
|
+
Configure webhook endpoints to receive events such as messages sent/received,
|
|
368
|
+
delivery status changes, reactions, typing indicators, and more.
|
|
369
|
+
|
|
370
|
+
Failed deliveries (5xx, 429, network errors) are retried up to 10 times over
|
|
371
|
+
~25 minutes with exponential backoff. Each event includes a unique ID for
|
|
372
|
+
deduplication.
|
|
373
|
+
|
|
374
|
+
## Webhook Headers
|
|
375
|
+
|
|
376
|
+
Each webhook request includes the following headers:
|
|
377
|
+
|
|
378
|
+
| Header | Description |
|
|
379
|
+
|--------|-------------|
|
|
380
|
+
| `X-Webhook-Event` | The event type (e.g., `message.sent`, `message.received`) |
|
|
381
|
+
| `X-Webhook-Subscription-ID` | Your webhook subscription ID |
|
|
382
|
+
| `X-Webhook-Timestamp` | Unix timestamp (seconds) when the webhook was sent |
|
|
383
|
+
| `X-Webhook-Signature` | HMAC-SHA256 signature for verification |
|
|
384
|
+
|
|
385
|
+
## Verifying Webhook Signatures
|
|
386
|
+
|
|
387
|
+
All webhooks are signed using HMAC-SHA256. You should always verify the signature
|
|
388
|
+
to ensure the webhook originated from Linq and hasn't been tampered with.
|
|
389
|
+
|
|
390
|
+
**Signature Construction:**
|
|
391
|
+
|
|
392
|
+
The signature is computed over a concatenation of the timestamp and payload:
|
|
393
|
+
|
|
394
|
+
```
|
|
395
|
+
{timestamp}.{payload}
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
Where:
|
|
399
|
+
- `timestamp` is the value from the `X-Webhook-Timestamp` header
|
|
400
|
+
- `payload` is the raw JSON request body (exact bytes, not re-serialized)
|
|
401
|
+
|
|
402
|
+
**Verification Steps:**
|
|
403
|
+
|
|
404
|
+
1. Extract the `X-Webhook-Timestamp` and `X-Webhook-Signature` headers
|
|
405
|
+
2. Get the raw request body bytes (do not parse and re-serialize)
|
|
406
|
+
3. Concatenate: `"{timestamp}.{payload}"`
|
|
407
|
+
4. Compute HMAC-SHA256 using your signing secret as the key
|
|
408
|
+
5. Hex-encode the result and compare with `X-Webhook-Signature`
|
|
409
|
+
6. Use constant-time comparison to prevent timing attacks
|
|
410
|
+
|
|
411
|
+
**Example (Python):**
|
|
412
|
+
|
|
413
|
+
```python
|
|
414
|
+
import hmac
|
|
415
|
+
import hashlib
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
def verify_webhook(signing_secret, payload, timestamp, signature):
|
|
419
|
+
message = f"{timestamp}.{payload.decode('utf-8')}"
|
|
420
|
+
expected = hmac.new(signing_secret.encode("utf-8"), message.encode("utf-8"), hashlib.sha256).hexdigest()
|
|
421
|
+
return hmac.compare_digest(expected, signature)
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
**Example (Node.js):**
|
|
425
|
+
|
|
426
|
+
```javascript
|
|
427
|
+
const crypto = require('crypto');
|
|
428
|
+
|
|
429
|
+
function verifyWebhook(signingSecret, payload, timestamp, signature) {
|
|
430
|
+
const message = `${timestamp}.${payload}`;
|
|
431
|
+
const expected = crypto
|
|
432
|
+
.createHmac('sha256', signingSecret)
|
|
433
|
+
.update(message)
|
|
434
|
+
.digest('hex');
|
|
435
|
+
return crypto.timingSafeEqual(
|
|
436
|
+
Buffer.from(expected),
|
|
437
|
+
Buffer.from(signature)
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
**Security Best Practices:**
|
|
443
|
+
|
|
444
|
+
- Reject webhooks with timestamps older than 5 minutes to prevent replay attacks
|
|
445
|
+
- Always use constant-time comparison for signature verification
|
|
446
|
+
- Store your signing secret securely (e.g., environment variable, secrets manager)
|
|
447
|
+
- Return a 2xx status code quickly, then process the webhook asynchronously
|
|
448
|
+
"""
|
|
449
|
+
|
|
450
|
+
@cached_property
|
|
451
|
+
def with_raw_response(self) -> AsyncWebhookSubscriptionsResourceWithRawResponse:
|
|
452
|
+
"""
|
|
453
|
+
This property can be used as a prefix for any HTTP method call to return
|
|
454
|
+
the raw response object instead of the parsed content.
|
|
455
|
+
|
|
456
|
+
For more information, see https://www.github.com/linq-team/linq-python#accessing-raw-response-data-eg-headers
|
|
457
|
+
"""
|
|
458
|
+
return AsyncWebhookSubscriptionsResourceWithRawResponse(self)
|
|
459
|
+
|
|
460
|
+
@cached_property
|
|
461
|
+
def with_streaming_response(self) -> AsyncWebhookSubscriptionsResourceWithStreamingResponse:
|
|
462
|
+
"""
|
|
463
|
+
An alternative to `.with_raw_response` that doesn't eagerly read the response body.
|
|
464
|
+
|
|
465
|
+
For more information, see https://www.github.com/linq-team/linq-python#with_streaming_response
|
|
466
|
+
"""
|
|
467
|
+
return AsyncWebhookSubscriptionsResourceWithStreamingResponse(self)
|
|
468
|
+
|
|
469
|
+
async def create(
|
|
470
|
+
self,
|
|
471
|
+
*,
|
|
472
|
+
subscribed_events: List[WebhookEventType],
|
|
473
|
+
target_url: str,
|
|
474
|
+
phone_numbers: SequenceNotStr[str] | Omit = omit,
|
|
475
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
476
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
477
|
+
extra_headers: Headers | None = None,
|
|
478
|
+
extra_query: Query | None = None,
|
|
479
|
+
extra_body: Body | None = None,
|
|
480
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
481
|
+
) -> WebhookSubscriptionCreateResponse:
|
|
482
|
+
"""Create a new webhook subscription to receive events at a target URL.
|
|
483
|
+
|
|
484
|
+
Upon
|
|
485
|
+
creation, a signing secret is generated for verifying webhook authenticity.
|
|
486
|
+
**Store this secret securely — it cannot be retrieved later.**
|
|
487
|
+
|
|
488
|
+
**Phone Number Filtering:**
|
|
489
|
+
|
|
490
|
+
- Optionally specify `phone_numbers` to only receive events for specific lines
|
|
491
|
+
- If omitted, events from all phone numbers are delivered (default behavior)
|
|
492
|
+
- Use multiple subscriptions with different `phone_numbers` to route different
|
|
493
|
+
lines to different endpoints
|
|
494
|
+
- Each `target_url` can only be used once per account. To route different lines
|
|
495
|
+
to different destinations, use a unique URL per subscription (e.g., append a
|
|
496
|
+
query parameter: `https://example.com/webhook?line=1`)
|
|
497
|
+
|
|
498
|
+
**Webhook Delivery:**
|
|
499
|
+
|
|
500
|
+
- Events are sent via HTTP POST to the target URL
|
|
501
|
+
- Each request includes `X-Webhook-Signature` and `X-Webhook-Timestamp` headers
|
|
502
|
+
- Signature is HMAC-SHA256 over `{timestamp}.{payload}` — see
|
|
503
|
+
[Webhook Events](/docs/webhook-events) for verification details
|
|
504
|
+
- Failed deliveries (5xx, 429, network errors) are retried up to 10 times over
|
|
505
|
+
~25 minutes with exponential backoff
|
|
506
|
+
- Client errors (4xx except 429) are not retried
|
|
507
|
+
|
|
508
|
+
Args:
|
|
509
|
+
subscribed_events: List of event types to subscribe to
|
|
510
|
+
|
|
511
|
+
target_url: URL where webhook events will be sent. Must be HTTPS.
|
|
512
|
+
|
|
513
|
+
phone_numbers: Optional list of phone numbers to filter events for. Only events originating
|
|
514
|
+
from these phone numbers will be delivered to this subscription. If omitted or
|
|
515
|
+
empty, events from all phone numbers are delivered. Phone numbers must be in
|
|
516
|
+
E.164 format.
|
|
517
|
+
|
|
518
|
+
extra_headers: Send extra headers
|
|
519
|
+
|
|
520
|
+
extra_query: Add additional query parameters to the request
|
|
521
|
+
|
|
522
|
+
extra_body: Add additional JSON properties to the request
|
|
523
|
+
|
|
524
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
525
|
+
"""
|
|
526
|
+
return await self._post(
|
|
527
|
+
"/v3/webhook-subscriptions",
|
|
528
|
+
body=await async_maybe_transform(
|
|
529
|
+
{
|
|
530
|
+
"subscribed_events": subscribed_events,
|
|
531
|
+
"target_url": target_url,
|
|
532
|
+
"phone_numbers": phone_numbers,
|
|
533
|
+
},
|
|
534
|
+
webhook_subscription_create_params.WebhookSubscriptionCreateParams,
|
|
535
|
+
),
|
|
536
|
+
options=make_request_options(
|
|
537
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
538
|
+
),
|
|
539
|
+
cast_to=WebhookSubscriptionCreateResponse,
|
|
540
|
+
)
|
|
541
|
+
|
|
542
|
+
async def retrieve(
|
|
543
|
+
self,
|
|
544
|
+
subscription_id: str,
|
|
545
|
+
*,
|
|
546
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
547
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
548
|
+
extra_headers: Headers | None = None,
|
|
549
|
+
extra_query: Query | None = None,
|
|
550
|
+
extra_body: Body | None = None,
|
|
551
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
552
|
+
) -> WebhookSubscription:
|
|
553
|
+
"""
|
|
554
|
+
Retrieve details for a specific webhook subscription including its target URL,
|
|
555
|
+
subscribed events, and current status.
|
|
556
|
+
|
|
557
|
+
Args:
|
|
558
|
+
extra_headers: Send extra headers
|
|
559
|
+
|
|
560
|
+
extra_query: Add additional query parameters to the request
|
|
561
|
+
|
|
562
|
+
extra_body: Add additional JSON properties to the request
|
|
563
|
+
|
|
564
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
565
|
+
"""
|
|
566
|
+
if not subscription_id:
|
|
567
|
+
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
|
|
568
|
+
return await self._get(
|
|
569
|
+
path_template("/v3/webhook-subscriptions/{subscription_id}", subscription_id=subscription_id),
|
|
570
|
+
options=make_request_options(
|
|
571
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
572
|
+
),
|
|
573
|
+
cast_to=WebhookSubscription,
|
|
574
|
+
)
|
|
575
|
+
|
|
576
|
+
async def update(
|
|
577
|
+
self,
|
|
578
|
+
subscription_id: str,
|
|
579
|
+
*,
|
|
580
|
+
is_active: bool | Omit = omit,
|
|
581
|
+
phone_numbers: Optional[SequenceNotStr[str]] | Omit = omit,
|
|
582
|
+
subscribed_events: List[WebhookEventType] | Omit = omit,
|
|
583
|
+
target_url: str | Omit = omit,
|
|
584
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
585
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
586
|
+
extra_headers: Headers | None = None,
|
|
587
|
+
extra_query: Query | None = None,
|
|
588
|
+
extra_body: Body | None = None,
|
|
589
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
590
|
+
) -> WebhookSubscription:
|
|
591
|
+
"""Update an existing webhook subscription.
|
|
592
|
+
|
|
593
|
+
You can modify the target URL,
|
|
594
|
+
subscribed events, or activate/deactivate the subscription.
|
|
595
|
+
|
|
596
|
+
**Note:** The signing secret cannot be changed via this endpoint.
|
|
597
|
+
|
|
598
|
+
Args:
|
|
599
|
+
is_active: Activate or deactivate the subscription
|
|
600
|
+
|
|
601
|
+
phone_numbers: Updated list of phone numbers to filter events for. Set to a non-empty array to
|
|
602
|
+
filter events to specific phone numbers. Set to an empty array or null to remove
|
|
603
|
+
the filter and receive events from all phone numbers. Phone numbers must be in
|
|
604
|
+
E.164 format.
|
|
605
|
+
|
|
606
|
+
subscribed_events: Updated list of event types to subscribe to
|
|
607
|
+
|
|
608
|
+
target_url: New target URL for webhook events
|
|
609
|
+
|
|
610
|
+
extra_headers: Send extra headers
|
|
611
|
+
|
|
612
|
+
extra_query: Add additional query parameters to the request
|
|
613
|
+
|
|
614
|
+
extra_body: Add additional JSON properties to the request
|
|
615
|
+
|
|
616
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
617
|
+
"""
|
|
618
|
+
if not subscription_id:
|
|
619
|
+
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
|
|
620
|
+
return await self._put(
|
|
621
|
+
path_template("/v3/webhook-subscriptions/{subscription_id}", subscription_id=subscription_id),
|
|
622
|
+
body=await async_maybe_transform(
|
|
623
|
+
{
|
|
624
|
+
"is_active": is_active,
|
|
625
|
+
"phone_numbers": phone_numbers,
|
|
626
|
+
"subscribed_events": subscribed_events,
|
|
627
|
+
"target_url": target_url,
|
|
628
|
+
},
|
|
629
|
+
webhook_subscription_update_params.WebhookSubscriptionUpdateParams,
|
|
630
|
+
),
|
|
631
|
+
options=make_request_options(
|
|
632
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
633
|
+
),
|
|
634
|
+
cast_to=WebhookSubscription,
|
|
635
|
+
)
|
|
636
|
+
|
|
637
|
+
async def list(
|
|
638
|
+
self,
|
|
639
|
+
*,
|
|
640
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
641
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
642
|
+
extra_headers: Headers | None = None,
|
|
643
|
+
extra_query: Query | None = None,
|
|
644
|
+
extra_body: Body | None = None,
|
|
645
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
646
|
+
) -> WebhookSubscriptionListResponse:
|
|
647
|
+
"""Retrieve all webhook subscriptions for the authenticated partner.
|
|
648
|
+
|
|
649
|
+
Returns a list
|
|
650
|
+
of active and inactive subscriptions with their configuration and status.
|
|
651
|
+
"""
|
|
652
|
+
return await self._get(
|
|
653
|
+
"/v3/webhook-subscriptions",
|
|
654
|
+
options=make_request_options(
|
|
655
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
656
|
+
),
|
|
657
|
+
cast_to=WebhookSubscriptionListResponse,
|
|
658
|
+
)
|
|
659
|
+
|
|
660
|
+
async def delete(
|
|
661
|
+
self,
|
|
662
|
+
subscription_id: str,
|
|
663
|
+
*,
|
|
664
|
+
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
|
|
665
|
+
# The extra values given here take precedence over values defined on the client or passed to this method.
|
|
666
|
+
extra_headers: Headers | None = None,
|
|
667
|
+
extra_query: Query | None = None,
|
|
668
|
+
extra_body: Body | None = None,
|
|
669
|
+
timeout: float | httpx.Timeout | None | NotGiven = not_given,
|
|
670
|
+
) -> None:
|
|
671
|
+
"""
|
|
672
|
+
Delete a webhook subscription.
|
|
673
|
+
|
|
674
|
+
Args:
|
|
675
|
+
extra_headers: Send extra headers
|
|
676
|
+
|
|
677
|
+
extra_query: Add additional query parameters to the request
|
|
678
|
+
|
|
679
|
+
extra_body: Add additional JSON properties to the request
|
|
680
|
+
|
|
681
|
+
timeout: Override the client-level default timeout for this request, in seconds
|
|
682
|
+
"""
|
|
683
|
+
if not subscription_id:
|
|
684
|
+
raise ValueError(f"Expected a non-empty value for `subscription_id` but received {subscription_id!r}")
|
|
685
|
+
extra_headers = {"Accept": "*/*", **(extra_headers or {})}
|
|
686
|
+
return await self._delete(
|
|
687
|
+
path_template("/v3/webhook-subscriptions/{subscription_id}", subscription_id=subscription_id),
|
|
688
|
+
options=make_request_options(
|
|
689
|
+
extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
|
|
690
|
+
),
|
|
691
|
+
cast_to=NoneType,
|
|
692
|
+
)
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
class WebhookSubscriptionsResourceWithRawResponse:
|
|
696
|
+
def __init__(self, webhook_subscriptions: WebhookSubscriptionsResource) -> None:
|
|
697
|
+
self._webhook_subscriptions = webhook_subscriptions
|
|
698
|
+
|
|
699
|
+
self.create = to_raw_response_wrapper(
|
|
700
|
+
webhook_subscriptions.create,
|
|
701
|
+
)
|
|
702
|
+
self.retrieve = to_raw_response_wrapper(
|
|
703
|
+
webhook_subscriptions.retrieve,
|
|
704
|
+
)
|
|
705
|
+
self.update = to_raw_response_wrapper(
|
|
706
|
+
webhook_subscriptions.update,
|
|
707
|
+
)
|
|
708
|
+
self.list = to_raw_response_wrapper(
|
|
709
|
+
webhook_subscriptions.list,
|
|
710
|
+
)
|
|
711
|
+
self.delete = to_raw_response_wrapper(
|
|
712
|
+
webhook_subscriptions.delete,
|
|
713
|
+
)
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
class AsyncWebhookSubscriptionsResourceWithRawResponse:
|
|
717
|
+
def __init__(self, webhook_subscriptions: AsyncWebhookSubscriptionsResource) -> None:
|
|
718
|
+
self._webhook_subscriptions = webhook_subscriptions
|
|
719
|
+
|
|
720
|
+
self.create = async_to_raw_response_wrapper(
|
|
721
|
+
webhook_subscriptions.create,
|
|
722
|
+
)
|
|
723
|
+
self.retrieve = async_to_raw_response_wrapper(
|
|
724
|
+
webhook_subscriptions.retrieve,
|
|
725
|
+
)
|
|
726
|
+
self.update = async_to_raw_response_wrapper(
|
|
727
|
+
webhook_subscriptions.update,
|
|
728
|
+
)
|
|
729
|
+
self.list = async_to_raw_response_wrapper(
|
|
730
|
+
webhook_subscriptions.list,
|
|
731
|
+
)
|
|
732
|
+
self.delete = async_to_raw_response_wrapper(
|
|
733
|
+
webhook_subscriptions.delete,
|
|
734
|
+
)
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
class WebhookSubscriptionsResourceWithStreamingResponse:
|
|
738
|
+
def __init__(self, webhook_subscriptions: WebhookSubscriptionsResource) -> None:
|
|
739
|
+
self._webhook_subscriptions = webhook_subscriptions
|
|
740
|
+
|
|
741
|
+
self.create = to_streamed_response_wrapper(
|
|
742
|
+
webhook_subscriptions.create,
|
|
743
|
+
)
|
|
744
|
+
self.retrieve = to_streamed_response_wrapper(
|
|
745
|
+
webhook_subscriptions.retrieve,
|
|
746
|
+
)
|
|
747
|
+
self.update = to_streamed_response_wrapper(
|
|
748
|
+
webhook_subscriptions.update,
|
|
749
|
+
)
|
|
750
|
+
self.list = to_streamed_response_wrapper(
|
|
751
|
+
webhook_subscriptions.list,
|
|
752
|
+
)
|
|
753
|
+
self.delete = to_streamed_response_wrapper(
|
|
754
|
+
webhook_subscriptions.delete,
|
|
755
|
+
)
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
class AsyncWebhookSubscriptionsResourceWithStreamingResponse:
|
|
759
|
+
def __init__(self, webhook_subscriptions: AsyncWebhookSubscriptionsResource) -> None:
|
|
760
|
+
self._webhook_subscriptions = webhook_subscriptions
|
|
761
|
+
|
|
762
|
+
self.create = async_to_streamed_response_wrapper(
|
|
763
|
+
webhook_subscriptions.create,
|
|
764
|
+
)
|
|
765
|
+
self.retrieve = async_to_streamed_response_wrapper(
|
|
766
|
+
webhook_subscriptions.retrieve,
|
|
767
|
+
)
|
|
768
|
+
self.update = async_to_streamed_response_wrapper(
|
|
769
|
+
webhook_subscriptions.update,
|
|
770
|
+
)
|
|
771
|
+
self.list = async_to_streamed_response_wrapper(
|
|
772
|
+
webhook_subscriptions.list,
|
|
773
|
+
)
|
|
774
|
+
self.delete = async_to_streamed_response_wrapper(
|
|
775
|
+
webhook_subscriptions.delete,
|
|
776
|
+
)
|