@linqapp/sdk 0.24.2 → 0.26.0
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.
- package/CHANGELOG.md +2 -506
- package/client.d.mts +165 -87
- package/client.d.mts.map +1 -1
- package/client.d.ts +165 -87
- package/client.d.ts.map +1 -1
- package/client.js +162 -84
- package/client.js.map +1 -1
- package/client.mjs +162 -84
- package/client.mjs.map +1 -1
- package/package.json +1 -1
- package/resources/chats/chats.d.mts +67 -63
- package/resources/chats/chats.d.mts.map +1 -1
- package/resources/chats/chats.d.ts +67 -63
- package/resources/chats/chats.d.ts.map +1 -1
- package/resources/chats/chats.js +63 -59
- package/resources/chats/chats.js.map +1 -1
- package/resources/chats/chats.mjs +63 -59
- package/resources/chats/chats.mjs.map +1 -1
- package/resources/chats/index.d.mts +3 -2
- package/resources/chats/index.d.mts.map +1 -1
- package/resources/chats/index.d.ts +3 -2
- package/resources/chats/index.d.ts.map +1 -1
- package/resources/chats/index.js +3 -1
- package/resources/chats/index.js.map +1 -1
- package/resources/chats/index.mjs +1 -0
- package/resources/chats/index.mjs.map +1 -1
- package/resources/chats/location.d.mts +107 -0
- package/resources/chats/location.d.mts.map +1 -0
- package/resources/chats/location.d.ts +107 -0
- package/resources/chats/location.d.ts.map +1 -0
- package/resources/chats/location.js +68 -0
- package/resources/chats/location.js.map +1 -0
- package/resources/chats/location.mjs +64 -0
- package/resources/chats/location.mjs.map +1 -0
- package/resources/chats/messages.d.mts +17 -17
- package/resources/chats/messages.d.mts.map +1 -1
- package/resources/chats/messages.d.ts +17 -17
- package/resources/chats/messages.d.ts.map +1 -1
- package/resources/chats/messages.js +16 -16
- package/resources/chats/messages.js.map +1 -1
- package/resources/chats/messages.mjs +16 -16
- package/resources/chats/messages.mjs.map +1 -1
- package/resources/contact-card.d.mts +18 -18
- package/resources/contact-card.d.mts.map +1 -1
- package/resources/contact-card.d.ts +18 -18
- package/resources/contact-card.d.ts.map +1 -1
- package/resources/contact-card.js +12 -12
- package/resources/contact-card.js.map +1 -1
- package/resources/contact-card.mjs +12 -12
- package/resources/contact-card.mjs.map +1 -1
- package/resources/index.d.mts +3 -3
- package/resources/index.d.mts.map +1 -1
- package/resources/index.d.ts +3 -3
- package/resources/index.d.ts.map +1 -1
- package/resources/messages.d.mts +34 -34
- package/resources/messages.d.mts.map +1 -1
- package/resources/messages.d.ts +34 -34
- package/resources/messages.d.ts.map +1 -1
- package/resources/messages.js +29 -29
- package/resources/messages.js.map +1 -1
- package/resources/messages.mjs +29 -29
- package/resources/messages.mjs.map +1 -1
- package/resources/webhook-events.d.mts +83 -44
- package/resources/webhook-events.d.mts.map +1 -1
- package/resources/webhook-events.d.ts +83 -44
- package/resources/webhook-events.d.ts.map +1 -1
- package/resources/webhook-events.js +81 -42
- package/resources/webhook-events.js.map +1 -1
- package/resources/webhook-events.mjs +81 -42
- package/resources/webhook-events.mjs.map +1 -1
- package/resources/webhook-subscriptions.d.mts +100 -55
- package/resources/webhook-subscriptions.d.mts.map +1 -1
- package/resources/webhook-subscriptions.d.ts +100 -55
- package/resources/webhook-subscriptions.d.ts.map +1 -1
- package/resources/webhook-subscriptions.js +103 -58
- package/resources/webhook-subscriptions.js.map +1 -1
- package/resources/webhook-subscriptions.mjs +103 -58
- package/resources/webhook-subscriptions.mjs.map +1 -1
- package/resources/webhooks.d.mts +4 -4
- package/resources/webhooks.d.mts.map +1 -1
- package/resources/webhooks.d.ts +4 -4
- package/resources/webhooks.d.ts.map +1 -1
- package/src/client.ts +166 -88
- package/src/resources/chats/chats.ts +88 -78
- package/src/resources/chats/index.ts +3 -2
- package/src/resources/chats/location.ts +138 -0
- package/src/resources/chats/messages.ts +28 -28
- package/src/resources/contact-card.ts +25 -25
- package/src/resources/index.ts +4 -4
- package/src/resources/messages.ts +46 -46
- package/src/resources/webhook-events.ts +85 -44
- package/src/resources/webhook-subscriptions.ts +103 -58
- package/src/resources/webhooks.ts +6 -4
- package/src/version.ts +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
2
|
+
|
|
3
|
+
import { APIResource } from '../../core/resource';
|
|
4
|
+
import { APIPromise } from '../../core/api-promise';
|
|
5
|
+
import { buildHeaders } from '../../internal/headers';
|
|
6
|
+
import { RequestOptions } from '../../internal/request-options';
|
|
7
|
+
import { path } from '../../internal/utils/path';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Request and retrieve real-time location data via iMessage.
|
|
11
|
+
*
|
|
12
|
+
* Use these endpoints to request a contact's location, retrieve location data
|
|
13
|
+
* for contacts who are sharing with you, and subscribe to webhooks when someone
|
|
14
|
+
* starts or stops sharing their location.
|
|
15
|
+
*
|
|
16
|
+
* **Coordinates** are returned in [GeoJSON](https://datatracker.ietf.org/doc/html/rfc7946) format:
|
|
17
|
+
* `[longitude, latitude]` or `[longitude, latitude, altitude]` if altitude is available.
|
|
18
|
+
*/
|
|
19
|
+
export class Location extends APIResource {
|
|
20
|
+
/**
|
|
21
|
+
* Send a location sharing request to a contact. They will receive an iMessage
|
|
22
|
+
* prompt asking them to share their location.
|
|
23
|
+
*
|
|
24
|
+
* Location requests only work in **1:1 iMessage chats** (Apple limitation).
|
|
25
|
+
* Attempting to request location in a group chat, or in an SMS or RCS chat,
|
|
26
|
+
* returns `409` (Operation not supported on this chat's service type).
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const locationRequestResponse =
|
|
31
|
+
* await client.chats.location.request(
|
|
32
|
+
* '975d0776-bd17-4273-8337-f346b4c661b0',
|
|
33
|
+
* );
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
request(chatID: string, options?: RequestOptions): APIPromise<LocationRequestResponse> {
|
|
37
|
+
return this._client.post(path`/v3/chats/${chatID}/location/request`, options);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Retrieve the current location for contacts sharing with you in a chat.
|
|
42
|
+
*
|
|
43
|
+
* Returns a [GeoJSON](https://datatracker.ietf.org/doc/html/rfc7946)
|
|
44
|
+
* `FeatureCollection` with a `Feature` for each participant actively sharing their
|
|
45
|
+
* location.
|
|
46
|
+
*
|
|
47
|
+
* Works for both 1:1 and group chats. In group chats, returns a separate feature
|
|
48
|
+
* for each participant who is sharing. Each feature's `properties.handle`
|
|
49
|
+
* identifies the user.
|
|
50
|
+
*
|
|
51
|
+
* Returns an empty `features` array if no one is sharing or no location data is
|
|
52
|
+
* available yet.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* const getChatLocationResponse =
|
|
57
|
+
* await client.chats.location.retrieve(
|
|
58
|
+
* '975d0776-bd17-4273-8337-f346b4c661b0',
|
|
59
|
+
* );
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
retrieve(chatID: string, options?: RequestOptions): APIPromise<GetChatLocationResponse> {
|
|
63
|
+
return this._client.get(path`/v3/chats/${chatID}/location`, {
|
|
64
|
+
...options,
|
|
65
|
+
headers: buildHeaders([{ Accept: 'application/geo+json' }, options?.headers]),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface GetChatLocationResponse {
|
|
71
|
+
data: GetChatLocationResponse.Data;
|
|
72
|
+
|
|
73
|
+
success: boolean;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export namespace GetChatLocationResponse {
|
|
77
|
+
export interface Data {
|
|
78
|
+
features: Array<Data.Feature>;
|
|
79
|
+
|
|
80
|
+
type: 'FeatureCollection';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export namespace Data {
|
|
84
|
+
export interface Feature {
|
|
85
|
+
geometry: Feature.Geometry;
|
|
86
|
+
|
|
87
|
+
properties: Feature.Properties;
|
|
88
|
+
|
|
89
|
+
type: 'Feature';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export namespace Feature {
|
|
93
|
+
export interface Geometry {
|
|
94
|
+
/**
|
|
95
|
+
* [longitude, latitude] or [longitude, latitude, altitude]
|
|
96
|
+
*/
|
|
97
|
+
coordinates: Array<number>;
|
|
98
|
+
|
|
99
|
+
type: 'Point';
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface Properties {
|
|
103
|
+
/**
|
|
104
|
+
* Phone number or email of the person sharing their location
|
|
105
|
+
*/
|
|
106
|
+
handle: string;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Full street address
|
|
110
|
+
*/
|
|
111
|
+
address?: string;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* City or locality name
|
|
115
|
+
*/
|
|
116
|
+
locality?: string;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* When the location was last updated
|
|
120
|
+
*/
|
|
121
|
+
updated_at?: string;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export interface LocationRequestResponse {
|
|
128
|
+
message: string;
|
|
129
|
+
|
|
130
|
+
success: boolean;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export declare namespace Location {
|
|
134
|
+
export {
|
|
135
|
+
type GetChatLocationResponse as GetChatLocationResponse,
|
|
136
|
+
type LocationRequestResponse as LocationRequestResponse,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
@@ -35,31 +35,6 @@ import { path } from '../../internal/utils/path';
|
|
|
35
35
|
* - Maximum URL length: 2,048 characters.
|
|
36
36
|
*/
|
|
37
37
|
export class Messages extends APIResource {
|
|
38
|
-
/**
|
|
39
|
-
* Retrieve messages from a specific chat with pagination support.
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* ```ts
|
|
43
|
-
* // Automatically fetches more pages as needed.
|
|
44
|
-
* for await (const message of client.chats.messages.list(
|
|
45
|
-
* '550e8400-e29b-41d4-a716-446655440000',
|
|
46
|
-
* )) {
|
|
47
|
-
* // ...
|
|
48
|
-
* }
|
|
49
|
-
* ```
|
|
50
|
-
*/
|
|
51
|
-
list(
|
|
52
|
-
chatID: string,
|
|
53
|
-
query: MessageListParams | null | undefined = {},
|
|
54
|
-
options?: RequestOptions,
|
|
55
|
-
): PagePromise<MessagesListMessagesPagination, MessagesAPI.Message> {
|
|
56
|
-
return this._client.getAPIList(
|
|
57
|
-
path`/v3/chats/${chatID}/messages`,
|
|
58
|
-
ListMessagesPagination<MessagesAPI.Message>,
|
|
59
|
-
{ query, ...options },
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
38
|
/**
|
|
64
39
|
* Send a message to an existing chat. Use this endpoint when you already have a
|
|
65
40
|
* chat ID and want to send additional messages to it.
|
|
@@ -119,6 +94,31 @@ export class Messages extends APIResource {
|
|
|
119
94
|
send(chatID: string, body: MessageSendParams, options?: RequestOptions): APIPromise<MessageSendResponse> {
|
|
120
95
|
return this._client.post(path`/v3/chats/${chatID}/messages`, { body, ...options });
|
|
121
96
|
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Retrieve messages from a specific chat with pagination support.
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```ts
|
|
103
|
+
* // Automatically fetches more pages as needed.
|
|
104
|
+
* for await (const message of client.chats.messages.list(
|
|
105
|
+
* '550e8400-e29b-41d4-a716-446655440000',
|
|
106
|
+
* )) {
|
|
107
|
+
* // ...
|
|
108
|
+
* }
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
list(
|
|
112
|
+
chatID: string,
|
|
113
|
+
query: MessageListParams | null | undefined = {},
|
|
114
|
+
options?: RequestOptions,
|
|
115
|
+
): PagePromise<MessagesListMessagesPagination, MessagesAPI.Message> {
|
|
116
|
+
return this._client.getAPIList(
|
|
117
|
+
path`/v3/chats/${chatID}/messages`,
|
|
118
|
+
ListMessagesPagination<MessagesAPI.Message>,
|
|
119
|
+
{ query, ...options },
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
/**
|
|
@@ -201,8 +201,6 @@ export interface MessageSendResponse {
|
|
|
201
201
|
message: SentMessage;
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
-
export interface MessageListParams extends ListMessagesPaginationParams {}
|
|
205
|
-
|
|
206
204
|
export interface MessageSendParams {
|
|
207
205
|
/**
|
|
208
206
|
* Message content container. Groups all message-related fields together,
|
|
@@ -212,12 +210,14 @@ export interface MessageSendParams {
|
|
|
212
210
|
message: ChatsAPI.MessageContent;
|
|
213
211
|
}
|
|
214
212
|
|
|
213
|
+
export interface MessageListParams extends ListMessagesPaginationParams {}
|
|
214
|
+
|
|
215
215
|
export declare namespace Messages {
|
|
216
216
|
export {
|
|
217
217
|
type SentMessage as SentMessage,
|
|
218
218
|
type MessageSendResponse as MessageSendResponse,
|
|
219
|
-
type MessageListParams as MessageListParams,
|
|
220
219
|
type MessageSendParams as MessageSendParams,
|
|
220
|
+
type MessageListParams as MessageListParams,
|
|
221
221
|
};
|
|
222
222
|
}
|
|
223
223
|
|
|
@@ -14,6 +14,22 @@ import { RequestOptions } from '../internal/request-options';
|
|
|
14
14
|
* **Sharing behavior:** Sharing may not take effect in every chat due to limitations outside our control. We recommend calling the share endpoint once per day, after the first outbound activity.
|
|
15
15
|
*/
|
|
16
16
|
export class ContactCard extends APIResource {
|
|
17
|
+
/**
|
|
18
|
+
* Returns the contact card for a specific phone number, or all contact cards for
|
|
19
|
+
* the authenticated partner if no `phone_number` is provided.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const contactCard = await client.contactCard.retrieve();
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
retrieve(
|
|
27
|
+
query: ContactCardRetrieveParams | null | undefined = {},
|
|
28
|
+
options?: RequestOptions,
|
|
29
|
+
): APIPromise<ContactCardRetrieveResponse> {
|
|
30
|
+
return this._client.get('/v3/contact_card', { query, ...options });
|
|
31
|
+
}
|
|
32
|
+
|
|
17
33
|
/**
|
|
18
34
|
* Creates a contact card for a phone number. This endpoint is intended for
|
|
19
35
|
* initial, one-time setup only.
|
|
@@ -40,22 +56,6 @@ export class ContactCard extends APIResource {
|
|
|
40
56
|
return this._client.post('/v3/contact_card', { body, ...options });
|
|
41
57
|
}
|
|
42
58
|
|
|
43
|
-
/**
|
|
44
|
-
* Returns the contact card for a specific phone number, or all contact cards for
|
|
45
|
-
* the authenticated partner if no `phone_number` is provided.
|
|
46
|
-
*
|
|
47
|
-
* @example
|
|
48
|
-
* ```ts
|
|
49
|
-
* const contactCard = await client.contactCard.retrieve();
|
|
50
|
-
* ```
|
|
51
|
-
*/
|
|
52
|
-
retrieve(
|
|
53
|
-
query: ContactCardRetrieveParams | null | undefined = {},
|
|
54
|
-
options?: RequestOptions,
|
|
55
|
-
): APIPromise<ContactCardRetrieveResponse> {
|
|
56
|
-
return this._client.get('/v3/contact_card', { query, ...options });
|
|
57
|
-
}
|
|
58
|
-
|
|
59
59
|
/**
|
|
60
60
|
* Partially updates an existing active contact card for a phone number.
|
|
61
61
|
*
|
|
@@ -127,6 +127,14 @@ export namespace ContactCardRetrieveResponse {
|
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
export interface ContactCardRetrieveParams {
|
|
131
|
+
/**
|
|
132
|
+
* E.164 phone number to filter by. If omitted, all my cards for the partner are
|
|
133
|
+
* returned.
|
|
134
|
+
*/
|
|
135
|
+
phone_number?: string;
|
|
136
|
+
}
|
|
137
|
+
|
|
130
138
|
export interface ContactCardCreateParams {
|
|
131
139
|
/**
|
|
132
140
|
* First name for the contact card. Required.
|
|
@@ -150,14 +158,6 @@ export interface ContactCardCreateParams {
|
|
|
150
158
|
last_name?: string;
|
|
151
159
|
}
|
|
152
160
|
|
|
153
|
-
export interface ContactCardRetrieveParams {
|
|
154
|
-
/**
|
|
155
|
-
* E.164 phone number to filter by. If omitted, all my cards for the partner are
|
|
156
|
-
* returned.
|
|
157
|
-
*/
|
|
158
|
-
phone_number?: string;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
161
|
export interface ContactCardUpdateParams {
|
|
162
162
|
/**
|
|
163
163
|
* Query param: E.164 phone number of the contact card to update
|
|
@@ -184,8 +184,8 @@ export declare namespace ContactCard {
|
|
|
184
184
|
export {
|
|
185
185
|
type SetContactCard as SetContactCard,
|
|
186
186
|
type ContactCardRetrieveResponse as ContactCardRetrieveResponse,
|
|
187
|
-
type ContactCardCreateParams as ContactCardCreateParams,
|
|
188
187
|
type ContactCardRetrieveParams as ContactCardRetrieveParams,
|
|
188
|
+
type ContactCardCreateParams as ContactCardCreateParams,
|
|
189
189
|
type ContactCardUpdateParams as ContactCardUpdateParams,
|
|
190
190
|
};
|
|
191
191
|
}
|
package/src/resources/index.ts
CHANGED
|
@@ -27,8 +27,8 @@ export {
|
|
|
27
27
|
type ChatLeaveChatResponse,
|
|
28
28
|
type ChatSendVoicememoResponse,
|
|
29
29
|
type ChatCreateParams,
|
|
30
|
-
type ChatUpdateParams,
|
|
31
30
|
type ChatListChatsParams,
|
|
31
|
+
type ChatUpdateParams,
|
|
32
32
|
type ChatSendVoicememoParams,
|
|
33
33
|
type ChatsListChatsPagination,
|
|
34
34
|
} from './chats/chats';
|
|
@@ -36,8 +36,8 @@ export {
|
|
|
36
36
|
ContactCard,
|
|
37
37
|
type SetContactCard,
|
|
38
38
|
type ContactCardRetrieveResponse,
|
|
39
|
-
type ContactCardCreateParams,
|
|
40
39
|
type ContactCardRetrieveParams,
|
|
40
|
+
type ContactCardCreateParams,
|
|
41
41
|
type ContactCardUpdateParams,
|
|
42
42
|
} from './contact-card';
|
|
43
43
|
export {
|
|
@@ -46,9 +46,9 @@ export {
|
|
|
46
46
|
type MessageEffect,
|
|
47
47
|
type ReplyTo,
|
|
48
48
|
type MessageAddReactionResponse,
|
|
49
|
-
type MessageUpdateParams,
|
|
50
|
-
type MessageAddReactionParams,
|
|
51
49
|
type MessageListMessagesThreadParams,
|
|
50
|
+
type MessageAddReactionParams,
|
|
51
|
+
type MessageUpdateParams,
|
|
52
52
|
type MessagesListMessagesPagination,
|
|
53
53
|
} from './messages';
|
|
54
54
|
export { PhoneNumbers, type PhoneNumberListResponse } from './phone-numbers';
|
|
@@ -30,36 +30,47 @@ import { path } from '../internal/utils/path';
|
|
|
30
30
|
*/
|
|
31
31
|
export class Messages extends APIResource {
|
|
32
32
|
/**
|
|
33
|
-
* Retrieve
|
|
34
|
-
*
|
|
33
|
+
* Retrieve all messages in a conversation thread. Given any message ID in the
|
|
34
|
+
* thread, returns the originator message and all replies in chronological order.
|
|
35
|
+
*
|
|
36
|
+
* If the message is not part of a thread, returns just that single message.
|
|
37
|
+
*
|
|
38
|
+
* Supports pagination and configurable ordering.
|
|
35
39
|
*
|
|
36
40
|
* @example
|
|
37
41
|
* ```ts
|
|
38
|
-
*
|
|
42
|
+
* // Automatically fetches more pages as needed.
|
|
43
|
+
* for await (const message of client.messages.listMessagesThread(
|
|
39
44
|
* '69a37c7d-af4f-4b5e-af42-e28e98ce873a',
|
|
40
|
-
* )
|
|
45
|
+
* )) {
|
|
46
|
+
* // ...
|
|
47
|
+
* }
|
|
41
48
|
* ```
|
|
42
49
|
*/
|
|
43
|
-
|
|
44
|
-
|
|
50
|
+
listMessagesThread(
|
|
51
|
+
messageID: string,
|
|
52
|
+
query: MessageListMessagesThreadParams | null | undefined = {},
|
|
53
|
+
options?: RequestOptions,
|
|
54
|
+
): PagePromise<MessagesListMessagesPagination, Message> {
|
|
55
|
+
return this._client.getAPIList(path`/v3/messages/${messageID}/thread`, ListMessagesPagination<Message>, {
|
|
56
|
+
query,
|
|
57
|
+
...options,
|
|
58
|
+
});
|
|
45
59
|
}
|
|
46
60
|
|
|
47
61
|
/**
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* **Note:** A message can be edited up to 5 times, and only within 15 minutes of
|
|
51
|
-
* when it was originally sent.
|
|
62
|
+
* Retrieve a specific message by its ID. This endpoint returns the full message
|
|
63
|
+
* details including text, attachments, reactions, and metadata.
|
|
52
64
|
*
|
|
53
65
|
* @example
|
|
54
66
|
* ```ts
|
|
55
|
-
* const message = await client.messages.
|
|
67
|
+
* const message = await client.messages.retrieve(
|
|
56
68
|
* '69a37c7d-af4f-4b5e-af42-e28e98ce873a',
|
|
57
|
-
* { text: 'This is the edited message content' },
|
|
58
69
|
* );
|
|
59
70
|
* ```
|
|
60
71
|
*/
|
|
61
|
-
|
|
62
|
-
return this._client.
|
|
72
|
+
retrieve(messageID: string, options?: RequestOptions): APIPromise<Message> {
|
|
73
|
+
return this._client.get(path`/v3/messages/${messageID}`, options);
|
|
63
74
|
}
|
|
64
75
|
|
|
65
76
|
/**
|
|
@@ -111,32 +122,21 @@ export class Messages extends APIResource {
|
|
|
111
122
|
}
|
|
112
123
|
|
|
113
124
|
/**
|
|
114
|
-
*
|
|
115
|
-
* thread, returns the originator message and all replies in chronological order.
|
|
116
|
-
*
|
|
117
|
-
* If the message is not part of a thread, returns just that single message.
|
|
125
|
+
* Edit the text content of a specific part of a previously sent message.
|
|
118
126
|
*
|
|
119
|
-
*
|
|
127
|
+
* **Note:** A message can be edited up to 5 times, and only within 15 minutes of
|
|
128
|
+
* when it was originally sent.
|
|
120
129
|
*
|
|
121
130
|
* @example
|
|
122
131
|
* ```ts
|
|
123
|
-
*
|
|
124
|
-
* for await (const message of client.messages.listMessagesThread(
|
|
132
|
+
* const message = await client.messages.update(
|
|
125
133
|
* '69a37c7d-af4f-4b5e-af42-e28e98ce873a',
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* }
|
|
134
|
+
* { text: 'This is the edited message content' },
|
|
135
|
+
* );
|
|
129
136
|
* ```
|
|
130
137
|
*/
|
|
131
|
-
|
|
132
|
-
messageID
|
|
133
|
-
query: MessageListMessagesThreadParams | null | undefined = {},
|
|
134
|
-
options?: RequestOptions,
|
|
135
|
-
): PagePromise<MessagesListMessagesPagination, Message> {
|
|
136
|
-
return this._client.getAPIList(path`/v3/messages/${messageID}/thread`, ListMessagesPagination<Message>, {
|
|
137
|
-
query,
|
|
138
|
-
...options,
|
|
139
|
-
});
|
|
138
|
+
update(messageID: string, body: MessageUpdateParams, options?: RequestOptions): APIPromise<Message> {
|
|
139
|
+
return this._client.patch(path`/v3/messages/${messageID}`, { body, ...options });
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
|
|
@@ -274,16 +274,11 @@ export interface MessageAddReactionResponse {
|
|
|
274
274
|
trace_id?: string;
|
|
275
275
|
}
|
|
276
276
|
|
|
277
|
-
export interface
|
|
278
|
-
/**
|
|
279
|
-
* New text content for the message part
|
|
280
|
-
*/
|
|
281
|
-
text: string;
|
|
282
|
-
|
|
277
|
+
export interface MessageListMessagesThreadParams extends ListMessagesPaginationParams {
|
|
283
278
|
/**
|
|
284
|
-
*
|
|
279
|
+
* Sort order for messages (asc = oldest first, desc = newest first)
|
|
285
280
|
*/
|
|
286
|
-
|
|
281
|
+
order?: 'asc' | 'desc';
|
|
287
282
|
}
|
|
288
283
|
|
|
289
284
|
export interface MessageAddReactionParams {
|
|
@@ -312,11 +307,16 @@ export interface MessageAddReactionParams {
|
|
|
312
307
|
part_index?: number;
|
|
313
308
|
}
|
|
314
309
|
|
|
315
|
-
export interface
|
|
310
|
+
export interface MessageUpdateParams {
|
|
316
311
|
/**
|
|
317
|
-
*
|
|
312
|
+
* New text content for the message part
|
|
318
313
|
*/
|
|
319
|
-
|
|
314
|
+
text: string;
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Index of the message part to edit. Defaults to 0.
|
|
318
|
+
*/
|
|
319
|
+
part_index?: number;
|
|
320
320
|
}
|
|
321
321
|
|
|
322
322
|
export declare namespace Messages {
|
|
@@ -326,8 +326,8 @@ export declare namespace Messages {
|
|
|
326
326
|
type ReplyTo as ReplyTo,
|
|
327
327
|
type MessageAddReactionResponse as MessageAddReactionResponse,
|
|
328
328
|
type MessagesListMessagesPagination as MessagesListMessagesPagination,
|
|
329
|
-
type MessageUpdateParams as MessageUpdateParams,
|
|
330
|
-
type MessageAddReactionParams as MessageAddReactionParams,
|
|
331
329
|
type MessageListMessagesThreadParams as MessageListMessagesThreadParams,
|
|
330
|
+
type MessageAddReactionParams as MessageAddReactionParams,
|
|
331
|
+
type MessageUpdateParams as MessageUpdateParams,
|
|
332
332
|
};
|
|
333
333
|
}
|
|
@@ -17,55 +17,82 @@ import { RequestOptions } from '../internal/request-options';
|
|
|
17
17
|
*
|
|
18
18
|
* ## Webhook Headers
|
|
19
19
|
*
|
|
20
|
-
*
|
|
20
|
+
* All webhook requests include two sets of headers. **If you have an existing integration
|
|
21
|
+
* using the `X-Webhook-*` headers, nothing changes** — those headers are still sent on
|
|
22
|
+
* every delivery and work exactly as before. The new `webhook-*` headers follow the
|
|
23
|
+
* [Standard Webhooks](https://github.com/standard-webhooks/standard-webhooks) specification.
|
|
24
|
+
* You can safely ignore them if your current verification code works and you don't want to use this convention.
|
|
25
|
+
*
|
|
26
|
+
* ### Standard Webhooks Headers (Recommended)
|
|
27
|
+
*
|
|
28
|
+
* Used by [our SDK](https://github.com/linq-team/linq-node) and any [Standard Webhooks library](https://github.com/standard-webhooks/standard-webhooks).
|
|
21
29
|
*
|
|
22
30
|
* | Header | Description |
|
|
23
31
|
* |--------|-------------|
|
|
24
|
-
* | `
|
|
25
|
-
* | `
|
|
26
|
-
* | `
|
|
27
|
-
* | `X-Webhook-Signature` | HMAC-SHA256 signature for verification |
|
|
32
|
+
* | `webhook-id` | Unique event identifier (use as idempotency key) |
|
|
33
|
+
* | `webhook-timestamp` | Unix timestamp (seconds) when the webhook was sent |
|
|
34
|
+
* | `webhook-signature` | Standard Webhooks signature (`v1,{base64}` format) |
|
|
28
35
|
*
|
|
29
|
-
*
|
|
36
|
+
* ### Legacy Headers (Deprecated)
|
|
37
|
+
*
|
|
38
|
+
* Still sent on every delivery for backwards compatibility. Existing verification code
|
|
39
|
+
* using these headers continues to work — no changes required.
|
|
30
40
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
41
|
+
* | Header | Description |
|
|
42
|
+
* |--------|-------------|
|
|
43
|
+
* | `X-Webhook-Event` | *(deprecated)* Event type (e.g., `message.sent`) |
|
|
44
|
+
* | `X-Webhook-Subscription-ID` | *(deprecated)* Webhook subscription ID |
|
|
45
|
+
* | `X-Webhook-Timestamp` | *(deprecated)* Unix timestamp (seconds) |
|
|
46
|
+
* | `X-Webhook-Signature` | *(deprecated)* HMAC-SHA256 signature (hex-encoded) |
|
|
33
47
|
*
|
|
34
|
-
*
|
|
48
|
+
* ## Signing Secrets
|
|
35
49
|
*
|
|
36
|
-
*
|
|
50
|
+
* Signing secrets use the Standard Webhooks format: a `whsec_` prefix followed
|
|
51
|
+
* by base64-encoded random bytes (e.g., `whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw7Jxx2Oll+OE=`).
|
|
37
52
|
*
|
|
38
|
-
*
|
|
39
|
-
* {timestamp}.{payload}
|
|
40
|
-
* ```
|
|
53
|
+
* Strip the `whsec_` prefix and base64-decode the remainder to get the raw key bytes.
|
|
41
54
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
55
|
+
* ## Verifying Webhook Signatures
|
|
56
|
+
*
|
|
57
|
+
* Webhooks are signed following the [Standard Webhooks specification](https://github.com/standard-webhooks/standard-webhooks).
|
|
58
|
+
* You can use any [Standard Webhooks library](https://github.com/standard-webhooks/standard-webhooks) to verify
|
|
59
|
+
* signatures, or implement verification manually:
|
|
60
|
+
*
|
|
61
|
+
* **Signed content:** `{webhook-id}.{webhook-timestamp}.{body}`
|
|
45
62
|
*
|
|
46
63
|
* **Verification Steps:**
|
|
47
64
|
*
|
|
48
|
-
* 1. Extract the `
|
|
49
|
-
* 2.
|
|
50
|
-
* 3.
|
|
51
|
-
* 4.
|
|
52
|
-
* 5.
|
|
53
|
-
* 6.
|
|
65
|
+
* 1. Extract the `webhook-id`, `webhook-timestamp`, and `webhook-signature` headers
|
|
66
|
+
* 2. Reject if the timestamp is more than 5 minutes old (replay protection)
|
|
67
|
+
* 3. Get the raw request body bytes (do not parse and re-serialize)
|
|
68
|
+
* 4. Construct signed content: `"{webhook-id}.{webhook-timestamp}.{body}"`
|
|
69
|
+
* 5. Strip the `whsec_` prefix from your secret and base64-decode to get key bytes
|
|
70
|
+
* 6. Compute HMAC-SHA256 using the key bytes over the signed content
|
|
71
|
+
* 7. Base64-encode the result and compare with the value after `v1,` in `webhook-signature`
|
|
72
|
+
* 8. Use constant-time comparison to prevent timing attacks
|
|
54
73
|
*
|
|
55
74
|
* **Example (Python):**
|
|
56
75
|
*
|
|
57
76
|
* ```python
|
|
58
|
-
* import hmac
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
77
|
+
* import base64, hmac, hashlib
|
|
78
|
+
*
|
|
79
|
+
* def verify_webhook(secret, body, headers):
|
|
80
|
+
* msg_id = headers['webhook-id']
|
|
81
|
+
* timestamp = headers['webhook-timestamp']
|
|
82
|
+
* signature = headers['webhook-signature']
|
|
83
|
+
*
|
|
84
|
+
* secret_str = secret.removeprefix('whsec_')
|
|
85
|
+
* key = base64.b64decode(secret_str)
|
|
86
|
+
*
|
|
87
|
+
* signed_content = f"{msg_id}.{timestamp}.{body}"
|
|
88
|
+
* expected = base64.b64encode(
|
|
89
|
+
* hmac.new(key, signed_content.encode(), hashlib.sha256).digest()
|
|
90
|
+
* ).decode()
|
|
91
|
+
*
|
|
92
|
+
* for sig in signature.split(' '):
|
|
93
|
+
* if sig.startswith('v1,') and hmac.compare_digest(expected, sig[3:]):
|
|
94
|
+
* return True
|
|
95
|
+
* return False
|
|
69
96
|
* ```
|
|
70
97
|
*
|
|
71
98
|
* **Example (Node.js):**
|
|
@@ -73,16 +100,28 @@ import { RequestOptions } from '../internal/request-options';
|
|
|
73
100
|
* ```javascript
|
|
74
101
|
* const crypto = require('crypto');
|
|
75
102
|
*
|
|
76
|
-
* function verifyWebhook(
|
|
77
|
-
* const
|
|
103
|
+
* function verifyWebhook(secret, rawBody, headers) {
|
|
104
|
+
* const msgId = headers['webhook-id'];
|
|
105
|
+
* const timestamp = headers['webhook-timestamp'];
|
|
106
|
+
* const signature = headers['webhook-signature'];
|
|
107
|
+
*
|
|
108
|
+
* const secretStr = secret.startsWith('whsec_') ? secret.slice(6) : secret;
|
|
109
|
+
* const keyBytes = Buffer.from(secretStr, 'base64');
|
|
110
|
+
* const signedContent = `${msgId}.${timestamp}.${rawBody}`;
|
|
78
111
|
* const expected = crypto
|
|
79
|
-
* .createHmac('sha256',
|
|
80
|
-
* .update(
|
|
81
|
-
* .digest('
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
112
|
+
* .createHmac('sha256', keyBytes)
|
|
113
|
+
* .update(signedContent)
|
|
114
|
+
* .digest('base64');
|
|
115
|
+
*
|
|
116
|
+
* return signature.split(' ').some(sig => {
|
|
117
|
+
* if (!sig.startsWith('v1,')) return false;
|
|
118
|
+
* try {
|
|
119
|
+
* return crypto.timingSafeEqual(
|
|
120
|
+
* Buffer.from(expected, 'base64'),
|
|
121
|
+
* Buffer.from(sig.slice(3), 'base64')
|
|
122
|
+
* );
|
|
123
|
+
* } catch { return false; }
|
|
124
|
+
* });
|
|
86
125
|
* }
|
|
87
126
|
* ```
|
|
88
127
|
*
|
|
@@ -136,13 +175,15 @@ export type WebhookEventType =
|
|
|
136
175
|
| 'call.ended'
|
|
137
176
|
| 'call.failed'
|
|
138
177
|
| 'call.declined'
|
|
139
|
-
| 'call.no_answer'
|
|
178
|
+
| 'call.no_answer'
|
|
179
|
+
| 'location.sharing.started'
|
|
180
|
+
| 'location.sharing.stopped';
|
|
140
181
|
|
|
141
182
|
export interface WebhookEventListResponse {
|
|
142
183
|
/**
|
|
143
184
|
* URL to the webhook events documentation
|
|
144
185
|
*/
|
|
145
|
-
doc_url: 'https://
|
|
186
|
+
doc_url: 'https://docs.linqapp.com/guides/webhooks/events';
|
|
146
187
|
|
|
147
188
|
/**
|
|
148
189
|
* List of all available webhook event types
|