@medalsocial/sdk 1.4.0 → 1.6.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/README.md +178 -2
- package/dist/openapi/medal-social.openapi.json +1180 -21
- package/dist/src/index.d.mts +886 -187
- package/dist/src/index.d.ts +886 -187
- package/dist/src/index.js +360 -13
- package/dist/src/index.js.map +1 -1
- package/dist/src/index.mjs +354 -13
- package/dist/src/index.mjs.map +1 -1
- package/dist/src/openapi.generated.d.mts +597 -0
- package/dist/src/openapi.generated.d.ts +597 -0
- package/dist/src/openapi.generated.js.map +1 -1
- package/openapi/medal-social.openapi.yaml +700 -0
- package/package.json +1 -1
- package/skills/resources/SKILL.md +3 -2
package/dist/src/index.d.mts
CHANGED
|
@@ -1,5 +1,524 @@
|
|
|
1
1
|
export { components as OpenApiComponents, operations as OpenApiOperations, paths as OpenApiPaths } from './openapi.generated.mjs';
|
|
2
2
|
|
|
3
|
+
/** Successful API response wrapper */
|
|
4
|
+
interface ApiResponse<T> {
|
|
5
|
+
data: T;
|
|
6
|
+
}
|
|
7
|
+
/** Paginated API response */
|
|
8
|
+
interface PaginatedResponse<T> {
|
|
9
|
+
data: T[];
|
|
10
|
+
pagination: {
|
|
11
|
+
has_more: boolean;
|
|
12
|
+
next_cursor: string | null;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/** API error thrown by the client */
|
|
16
|
+
declare class MedalApiError extends Error {
|
|
17
|
+
readonly status: number;
|
|
18
|
+
readonly code: string;
|
|
19
|
+
readonly details?: unknown;
|
|
20
|
+
constructor(status: number, code: string, message: string, details?: unknown);
|
|
21
|
+
}
|
|
22
|
+
/** Pagination options for list endpoints */
|
|
23
|
+
interface PaginationOptions {
|
|
24
|
+
limit?: number;
|
|
25
|
+
cursor?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Lifecycle status of a hosted connect link. */
|
|
29
|
+
type ConnectLinkStatus = "pending" | "consumed" | "expired" | "revoked";
|
|
30
|
+
/** Lifecycle state of a channel connection. */
|
|
31
|
+
type ChannelConnectionState = "connecting" | "active" | "disconnected" | "disabled";
|
|
32
|
+
/** Input for minting a hosted connect link. */
|
|
33
|
+
interface CreateConnectLinkInput {
|
|
34
|
+
/** Channel type to connect (e.g. `telegram_inbox`). */
|
|
35
|
+
channel_type: string;
|
|
36
|
+
/** Display label shown on the hosted connect page (max 100 characters). */
|
|
37
|
+
label?: string;
|
|
38
|
+
/** URL the hosted page redirects to after a successful connect — must be https. */
|
|
39
|
+
redirect_url?: string;
|
|
40
|
+
}
|
|
41
|
+
/** Result of minting a connect link (HTTP 201). */
|
|
42
|
+
interface ConnectLinkCreateResult {
|
|
43
|
+
id: string;
|
|
44
|
+
/**
|
|
45
|
+
* The single-use hosted connect URL containing the one-time link token.
|
|
46
|
+
* **Present ONLY in the live create response** — an idempotent replay
|
|
47
|
+
* (retrying with the same `Idempotency-Key`) returns the link WITHOUT `url`.
|
|
48
|
+
* If you lose it, revoke the link and mint a new one; the token can never
|
|
49
|
+
* be retrieved again.
|
|
50
|
+
*/
|
|
51
|
+
url?: string;
|
|
52
|
+
channel_type: string;
|
|
53
|
+
label: string | null;
|
|
54
|
+
status: ConnectLinkStatus;
|
|
55
|
+
/** Unix timestamp in milliseconds when the link expires. */
|
|
56
|
+
expires_at: number;
|
|
57
|
+
}
|
|
58
|
+
/** A hosted connect link (list view — tokens are never returned). */
|
|
59
|
+
interface ConnectLink {
|
|
60
|
+
id: string;
|
|
61
|
+
channel_type: string;
|
|
62
|
+
label: string | null;
|
|
63
|
+
status: ConnectLinkStatus;
|
|
64
|
+
/** Stable ref of the connection created by consuming this link, or `null`. */
|
|
65
|
+
consumed_connection_ref: string | null;
|
|
66
|
+
/** Unix timestamp in milliseconds. */
|
|
67
|
+
expires_at: number;
|
|
68
|
+
/** Unix timestamp in milliseconds. */
|
|
69
|
+
created_at: number;
|
|
70
|
+
}
|
|
71
|
+
/** Filters and cursor pagination for listing connect links. */
|
|
72
|
+
interface ListConnectLinksOptions extends PaginationOptions {
|
|
73
|
+
channel_type?: string;
|
|
74
|
+
status?: ConnectLinkStatus;
|
|
75
|
+
}
|
|
76
|
+
/** Result of revoking a connect link. */
|
|
77
|
+
interface ConnectLinkRevokeResult {
|
|
78
|
+
id: string;
|
|
79
|
+
status: "revoked";
|
|
80
|
+
}
|
|
81
|
+
/** A channel connection attached to the workspace (generic, channel-agnostic shape). */
|
|
82
|
+
interface ChannelConnection {
|
|
83
|
+
id: string;
|
|
84
|
+
channel_type: string;
|
|
85
|
+
label: string | null;
|
|
86
|
+
state: ChannelConnectionState;
|
|
87
|
+
/** Privacy-preserving identity handle (e.g. a masked phone number). */
|
|
88
|
+
masked_identity: string;
|
|
89
|
+
/** Unix timestamp in milliseconds, or `null` if never active. */
|
|
90
|
+
last_activity_at: number | null;
|
|
91
|
+
/** Linked helpdesk channel connection ID, or `null`. */
|
|
92
|
+
helpdesk_connection_id: string | null;
|
|
93
|
+
}
|
|
94
|
+
/** Result of disconnecting a channel connection. */
|
|
95
|
+
interface ChannelConnectionDisconnectResult {
|
|
96
|
+
id: string;
|
|
97
|
+
state: "disconnected";
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Lifecycle status of a helpdesk conversation. */
|
|
101
|
+
type ConversationStatus = "open" | "snoozed" | "closed";
|
|
102
|
+
/** Who authored a helpdesk message. */
|
|
103
|
+
type MessageAuthorType = "visitor" | "operator" | "ai" | "system";
|
|
104
|
+
/** Kind of helpdesk message. `note` is operator-internal and never delivered to the customer. */
|
|
105
|
+
type HelpdeskMessageType = "chat" | "email" | "note";
|
|
106
|
+
/** A helpdesk conversation across any connected channel (widget, email, social DMs, …). */
|
|
107
|
+
interface Conversation {
|
|
108
|
+
id: string;
|
|
109
|
+
/** Channel type, e.g. 'widget', 'instagram', 'messenger', 'whatsapp', 'email'. */
|
|
110
|
+
channel: string;
|
|
111
|
+
channel_connection_id: string | null;
|
|
112
|
+
status: ConversationStatus;
|
|
113
|
+
subject: string | null;
|
|
114
|
+
assignee_user_id: string | null;
|
|
115
|
+
contact_id: string | null;
|
|
116
|
+
visitor_name: string | null;
|
|
117
|
+
visitor_email: string | null;
|
|
118
|
+
external_conversation_id: string | null;
|
|
119
|
+
channel_account_id: string | null;
|
|
120
|
+
message_count: number;
|
|
121
|
+
unread_for_operator: number;
|
|
122
|
+
/** Unix timestamp in milliseconds. */
|
|
123
|
+
last_message_at: number;
|
|
124
|
+
last_message_preview: string | null;
|
|
125
|
+
last_message_author_type: MessageAuthorType | null;
|
|
126
|
+
/** Unix timestamp in milliseconds. */
|
|
127
|
+
created_at: number;
|
|
128
|
+
/** Unix timestamp in milliseconds. */
|
|
129
|
+
updated_at: number;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Outbound delivery state of a helpdesk message.
|
|
133
|
+
*
|
|
134
|
+
* - `pending` — queued for the channel, not handed off yet.
|
|
135
|
+
* - `sent` — handed to the channel provider, no confirmation yet.
|
|
136
|
+
* - `delivered` — the channel confirmed delivery to the customer.
|
|
137
|
+
* - `failed` — delivery failed; see `delivery_error` on the message.
|
|
138
|
+
*/
|
|
139
|
+
type MessageDeliveryStatus = "pending" | "sent" | "delivered" | "failed";
|
|
140
|
+
/** A single message inside a helpdesk conversation. */
|
|
141
|
+
interface ConversationMessage {
|
|
142
|
+
id: string;
|
|
143
|
+
conversation_id: string;
|
|
144
|
+
author_type: MessageAuthorType;
|
|
145
|
+
message_type: HelpdeskMessageType;
|
|
146
|
+
author_user_id: string | null;
|
|
147
|
+
author_name: string | null;
|
|
148
|
+
body: string;
|
|
149
|
+
/**
|
|
150
|
+
* Outbound delivery state, or `null` for inbound messages and internal
|
|
151
|
+
* notes — neither is ever sent to a channel, so neither has delivery state.
|
|
152
|
+
*
|
|
153
|
+
* **A `201` from `helpdesk.replies.create` means the reply was ACCEPTED, not
|
|
154
|
+
* delivered.** The channel hand-off happens asynchronously afterwards: poll
|
|
155
|
+
* this field (or subscribe to the `helpdesk.message_delivery_updated`
|
|
156
|
+
* webhook event, which carries the same values) to learn whether the message
|
|
157
|
+
* actually reached the customer.
|
|
158
|
+
*/
|
|
159
|
+
delivery_status: MessageDeliveryStatus | null;
|
|
160
|
+
/**
|
|
161
|
+
* Last send error for a `failed` outbound message, or `null` when there is
|
|
162
|
+
* no error to report (including on inbound messages and internal notes).
|
|
163
|
+
*/
|
|
164
|
+
delivery_error: string | null;
|
|
165
|
+
/** Unix timestamp in milliseconds. */
|
|
166
|
+
created_at: number;
|
|
167
|
+
}
|
|
168
|
+
/** Filters for listing/searching helpdesk conversations. */
|
|
169
|
+
interface ListConversationsOptions extends PaginationOptions {
|
|
170
|
+
status?: ConversationStatus;
|
|
171
|
+
/** Only conversations assigned to this user. */
|
|
172
|
+
assignee_user_id?: string;
|
|
173
|
+
/** Match against visitor name/email. */
|
|
174
|
+
requester?: string;
|
|
175
|
+
/** Free-text search query. */
|
|
176
|
+
query?: string;
|
|
177
|
+
/** Only conversations on these channels (serialized as CSV). */
|
|
178
|
+
channels?: string[];
|
|
179
|
+
}
|
|
180
|
+
/** Input for updating a conversation's status and/or assignee. At least one field is required. */
|
|
181
|
+
interface UpdateConversationInput {
|
|
182
|
+
status?: ConversationStatus;
|
|
183
|
+
/** User ID to assign, or `null` to unassign. */
|
|
184
|
+
assignee_user_id?: string | null;
|
|
185
|
+
}
|
|
186
|
+
/** Result of a conversation update. */
|
|
187
|
+
interface ConversationUpdateResult {
|
|
188
|
+
id: string;
|
|
189
|
+
status: ConversationStatus;
|
|
190
|
+
assignee_user_id: string | null;
|
|
191
|
+
}
|
|
192
|
+
/** Input for sending an operator reply (or internal note) into a conversation. */
|
|
193
|
+
interface CreateReplyInput {
|
|
194
|
+
conversation_id: string;
|
|
195
|
+
/** Message body (max 20,000 characters). */
|
|
196
|
+
body: string;
|
|
197
|
+
/** `note` = operator-internal note (not delivered to the customer). Default `chat`. */
|
|
198
|
+
message_type?: "chat" | "note";
|
|
199
|
+
/** Agent display name for bridged replies (shown in widget + inbox). */
|
|
200
|
+
author_name?: string;
|
|
201
|
+
}
|
|
202
|
+
/** Result returned after creating a reply (HTTP 201). */
|
|
203
|
+
interface ReplyCreateResult {
|
|
204
|
+
id: string;
|
|
205
|
+
conversation_id: string;
|
|
206
|
+
status: string;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/** A webhook endpoint registered in the workspace. */
|
|
210
|
+
interface WebhookEndpoint {
|
|
211
|
+
id: string;
|
|
212
|
+
name: string;
|
|
213
|
+
/** Destination URL (must be https). */
|
|
214
|
+
url: string;
|
|
215
|
+
enabled: boolean;
|
|
216
|
+
/** Subscribed event types. Empty array = all events. */
|
|
217
|
+
event_types: string[];
|
|
218
|
+
/** Channel-type filter (e.g. ['widget', 'whatsapp']), or `null` for all channels. */
|
|
219
|
+
channels: string[] | null;
|
|
220
|
+
/** Channel-connection filter, or `null` for all connections. */
|
|
221
|
+
channel_connection_ids: string[] | null;
|
|
222
|
+
/** Last 4 characters of the signing secret, for identification. */
|
|
223
|
+
secret_last4: string;
|
|
224
|
+
consecutive_failures: number;
|
|
225
|
+
/** Unix timestamps in milliseconds, or `null` if never. */
|
|
226
|
+
last_delivery_at: number | null;
|
|
227
|
+
last_success_at: number | null;
|
|
228
|
+
last_error_at: number | null;
|
|
229
|
+
last_error: string | null;
|
|
230
|
+
created_at: number;
|
|
231
|
+
updated_at: number;
|
|
232
|
+
/**
|
|
233
|
+
* Full signing secret (`whsec_…`) — present ONLY in the `create` response.
|
|
234
|
+
* It is returned exactly once and can never be retrieved again. Store it
|
|
235
|
+
* securely immediately; you need it to verify delivery signatures.
|
|
236
|
+
*/
|
|
237
|
+
secret?: string;
|
|
238
|
+
}
|
|
239
|
+
/** Input for creating a webhook endpoint. */
|
|
240
|
+
interface CreateWebhookInput {
|
|
241
|
+
/** Display name (max 100 characters). */
|
|
242
|
+
name: string;
|
|
243
|
+
/** Destination URL — must be https. */
|
|
244
|
+
url: string;
|
|
245
|
+
/** Event types to subscribe to (e.g. 'helpdesk.message_received'). Empty = all. */
|
|
246
|
+
event_types: string[];
|
|
247
|
+
/** Restrict to these channel types (e.g. ['widget', 'whatsapp']). */
|
|
248
|
+
channels?: string[];
|
|
249
|
+
/** Restrict to these channel connection IDs. */
|
|
250
|
+
channel_connection_ids?: string[];
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Input for updating a webhook endpoint. Only provided fields change.
|
|
254
|
+
* Pass `null` for `channels` or `channel_connection_ids` to CLEAR an existing
|
|
255
|
+
* filter (deliver for all channels / all accounts again); omitting the field
|
|
256
|
+
* leaves the current filter unchanged.
|
|
257
|
+
*/
|
|
258
|
+
interface UpdateWebhookInput {
|
|
259
|
+
name?: string;
|
|
260
|
+
url?: string;
|
|
261
|
+
event_types?: string[];
|
|
262
|
+
channels?: string[] | null;
|
|
263
|
+
channel_connection_ids?: string[] | null;
|
|
264
|
+
enabled?: boolean;
|
|
265
|
+
}
|
|
266
|
+
/** Result of deleting a webhook endpoint. */
|
|
267
|
+
interface WebhookDeleteResult {
|
|
268
|
+
id: string;
|
|
269
|
+
status: string;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* A delivery attempt record for a webhook endpoint.
|
|
273
|
+
*
|
|
274
|
+
* `id` is the same value sent as the `X-Medal-Delivery-Id` and
|
|
275
|
+
* `Idempotency-Key` headers on the outbound request, so you can join your own
|
|
276
|
+
* receiving log to this listing exactly.
|
|
277
|
+
*
|
|
278
|
+
* **Deliveries never carry payload bodies.** The event payload can contain
|
|
279
|
+
* customer PII, so it is not returned here — use the correlation fields below
|
|
280
|
+
* to look the subject up through the regular API instead.
|
|
281
|
+
*
|
|
282
|
+
* All correlation fields (`resource_id`, `conversation_id`, `message_id`,
|
|
283
|
+
* `connection_ref`, `channel`, `channel_connection_id`) are derived from the
|
|
284
|
+
* stored event and **fail closed to `null`** whenever no canonical event
|
|
285
|
+
* exists for the delivery — e.g. `test.ping` deliveries, or events that have
|
|
286
|
+
* aged out of retention. Always null-check before using them.
|
|
287
|
+
*/
|
|
288
|
+
interface WebhookDelivery {
|
|
289
|
+
id: string;
|
|
290
|
+
event_type: string;
|
|
291
|
+
/**
|
|
292
|
+
* Primary subject id of the announced event (a message id for message
|
|
293
|
+
* events, a connection id for channel lifecycle events, …), or `null`.
|
|
294
|
+
*/
|
|
295
|
+
resource_id: string | null;
|
|
296
|
+
/** Helpdesk conversation the event belongs to, or `null`. */
|
|
297
|
+
conversation_id: string | null;
|
|
298
|
+
/** Helpdesk message the event belongs to, or `null`. */
|
|
299
|
+
message_id: string | null;
|
|
300
|
+
/** Opaque connection reference carried by the event, or `null`. */
|
|
301
|
+
connection_ref: string | null;
|
|
302
|
+
/** Channel type (e.g. `telegram_inbox`, `widget`), or `null`. */
|
|
303
|
+
channel: string | null;
|
|
304
|
+
/** Channel connection the event belongs to, or `null`. */
|
|
305
|
+
channel_connection_id: string | null;
|
|
306
|
+
status: "pending" | "delivered" | "dead_letter";
|
|
307
|
+
attempt_count: number;
|
|
308
|
+
/** Unix timestamp in milliseconds of the next retry, or `null`. */
|
|
309
|
+
next_attempt_at: number | null;
|
|
310
|
+
response_status: number | null;
|
|
311
|
+
duration_ms: number | null;
|
|
312
|
+
last_error: string | null;
|
|
313
|
+
/** Unix timestamp in milliseconds, or `null` if not delivered. */
|
|
314
|
+
delivered_at: number | null;
|
|
315
|
+
created_at: number;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Options for listing recent deliveries.
|
|
319
|
+
*
|
|
320
|
+
* This endpoint is **not** cursor-paginated — it returns the most recent
|
|
321
|
+
* deliveries only, capped by `limit`. There is no `cursor` parameter; to keep
|
|
322
|
+
* a durable record, ingest deliveries as they arrive (or poll and de-duplicate
|
|
323
|
+
* on the delivery `id`).
|
|
324
|
+
*/
|
|
325
|
+
interface ListDeliveriesOptions {
|
|
326
|
+
limit?: number;
|
|
327
|
+
}
|
|
328
|
+
/** Result returned after queuing a test delivery (HTTP 202). */
|
|
329
|
+
interface WebhookTestResult {
|
|
330
|
+
delivery_id: string;
|
|
331
|
+
status: string;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Capability confirmation types.
|
|
336
|
+
*
|
|
337
|
+
* Medal's confirmable write routes require BOTH an `Idempotency-Key` and an
|
|
338
|
+
* `X-Capability-Confirmation` token whenever the calling credential holds the
|
|
339
|
+
* capability scope *directly* — which is the case for every correctly-scoped
|
|
340
|
+
* partner key and OAuth grant. (API keys carrying only legacy scopes are
|
|
341
|
+
* exempt.) The token is minted by `POST /api/v1/capability-confirmations` and
|
|
342
|
+
* is bound to the workspace, the auth subject, the HTTP method + path, the
|
|
343
|
+
* capability's required scopes, and the idempotency key.
|
|
344
|
+
*/
|
|
345
|
+
/**
|
|
346
|
+
* Confirmable capability ids backing the write routes this SDK exposes.
|
|
347
|
+
*
|
|
348
|
+
* Mirrors the server-side capability registry. Each id maps to exactly one
|
|
349
|
+
* method + path template — see {@link CAPABILITY_ROUTES}.
|
|
350
|
+
*/
|
|
351
|
+
declare const CAPABILITY_IDS: readonly ["channel.connect_link.create.execute", "channel.connect_link.revoke.execute", "channel.connection.disconnect.execute", "helpdesk.conversation.reply.execute", "helpdesk.conversation.update.execute", "helpdesk.webhook.create.execute", "helpdesk.webhook.update.execute", "helpdesk.webhook.delete.execute"];
|
|
352
|
+
/** A confirmable capability id backing an SDK write route. */
|
|
353
|
+
type CapabilityId = (typeof CAPABILITY_IDS)[number];
|
|
354
|
+
/** The API route a capability confirms, as registered server-side. */
|
|
355
|
+
interface CapabilityRoute {
|
|
356
|
+
method: "POST" | "PATCH" | "DELETE";
|
|
357
|
+
/** Path template; `{id}` is filled from `path_params.id`. */
|
|
358
|
+
path_template: string;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Method + path template for each confirmable capability.
|
|
362
|
+
*
|
|
363
|
+
* The server resolves the same mapping from its capability registry — this
|
|
364
|
+
* copy exists so the SDK can build human-readable previews and supply
|
|
365
|
+
* `path_params` without a round trip.
|
|
366
|
+
*/
|
|
367
|
+
declare const CAPABILITY_ROUTES: Record<CapabilityId, CapabilityRoute>;
|
|
368
|
+
/** Primitive accepted as a capability path parameter value. */
|
|
369
|
+
type CapabilityPathParamValue = string | number | boolean;
|
|
370
|
+
/** Input for `POST /api/v1/capability-confirmations`. */
|
|
371
|
+
interface IssueCapabilityConfirmationInput {
|
|
372
|
+
/**
|
|
373
|
+
* Capability to confirm. Unknown ids are rejected with
|
|
374
|
+
* `CAPABILITY_NOT_FOUND`; read-only or non-confirmable capabilities with
|
|
375
|
+
* `CAPABILITY_NOT_CONFIRMABLE`.
|
|
376
|
+
*/
|
|
377
|
+
capability_id: CapabilityId | (string & {});
|
|
378
|
+
/**
|
|
379
|
+
* Concrete `/api/v1/...` path the token should be bound to. Optional when
|
|
380
|
+
* the capability has exactly one API target (all capabilities in
|
|
381
|
+
* {@link CAPABILITY_ROUTES} do); required when it has several. Must match a
|
|
382
|
+
* path built from the capability's own templates.
|
|
383
|
+
*/
|
|
384
|
+
api_path?: string;
|
|
385
|
+
/** Values for the capability path template's parameters, e.g. `{ id: 'wh_1' }`. */
|
|
386
|
+
path_params?: Record<string, CapabilityPathParamValue>;
|
|
387
|
+
/**
|
|
388
|
+
* The exact `Idempotency-Key` you will send on the confirmed write. The
|
|
389
|
+
* token is bound to it — a mismatch is rejected. Required for every
|
|
390
|
+
* capability in {@link CAPABILITY_ROUTES}.
|
|
391
|
+
*/
|
|
392
|
+
idempotency_key?: string;
|
|
393
|
+
/**
|
|
394
|
+
* Human-readable description of the action being approved (1–4000 chars).
|
|
395
|
+
* This is the text your user saw and approved, and it is retained for audit.
|
|
396
|
+
*/
|
|
397
|
+
preview_summary: string;
|
|
398
|
+
/**
|
|
399
|
+
* Must be `true`.
|
|
400
|
+
*
|
|
401
|
+
* **This asserts that a human on your side approved this specific action.**
|
|
402
|
+
* Do not send it to rubber-stamp unattended writes — it is the audit record
|
|
403
|
+
* that a person, not a script, authorised the change.
|
|
404
|
+
*/
|
|
405
|
+
user_approved: true;
|
|
406
|
+
}
|
|
407
|
+
/** A minted capability confirmation token. */
|
|
408
|
+
interface CapabilityConfirmation {
|
|
409
|
+
/** Send this as the `X-Capability-Confirmation` header on the write. */
|
|
410
|
+
confirmation_token: string;
|
|
411
|
+
token_type: "medal_capability_confirmation";
|
|
412
|
+
capability_id: string;
|
|
413
|
+
/** HTTP method the token is bound to. */
|
|
414
|
+
method: string;
|
|
415
|
+
/** Concrete API path the token is bound to. */
|
|
416
|
+
path: string;
|
|
417
|
+
/** Capability scopes the token was minted against. */
|
|
418
|
+
required_scopes: string[];
|
|
419
|
+
/** Idempotency key the token is bound to, or `null` if it was minted unbound. */
|
|
420
|
+
idempotency_key: string | null;
|
|
421
|
+
/** Lifetime in seconds (60–900). */
|
|
422
|
+
expires_in: number;
|
|
423
|
+
/** ISO-8601 expiry timestamp. */
|
|
424
|
+
expires_at: string;
|
|
425
|
+
/** Echo of the submitted `preview_summary`. */
|
|
426
|
+
preview_summary: string;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Request body type for each confirmable capability.
|
|
430
|
+
*
|
|
431
|
+
* `undefined` for routes that take no request body (the `DELETE` routes).
|
|
432
|
+
*/
|
|
433
|
+
interface CapabilityWriteBodies {
|
|
434
|
+
"channel.connect_link.create.execute": CreateConnectLinkInput;
|
|
435
|
+
"channel.connect_link.revoke.execute": undefined;
|
|
436
|
+
"channel.connection.disconnect.execute": undefined;
|
|
437
|
+
"helpdesk.conversation.reply.execute": CreateReplyInput;
|
|
438
|
+
"helpdesk.conversation.update.execute": UpdateConversationInput;
|
|
439
|
+
"helpdesk.webhook.create.execute": CreateWebhookInput;
|
|
440
|
+
"helpdesk.webhook.update.execute": UpdateWebhookInput;
|
|
441
|
+
"helpdesk.webhook.delete.execute": undefined;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* A capability paired with the request body for that exact route.
|
|
445
|
+
*
|
|
446
|
+
* Modelled as a discriminated union rather than two independent parameters so
|
|
447
|
+
* the pair cannot be decoupled: passing a `helpdesk.conversation.reply.execute`
|
|
448
|
+
* id alongside a webhook payload is a compile error, even when the id's static
|
|
449
|
+
* type is the full {@link CapabilityId} union.
|
|
450
|
+
*/
|
|
451
|
+
type CapabilityWriteRequest = {
|
|
452
|
+
[K in CapabilityId]: {
|
|
453
|
+
/** Capability about to be confirmed. */
|
|
454
|
+
capabilityId: K;
|
|
455
|
+
/** The request body of the pending write, or `undefined` for `DELETE` routes. */
|
|
456
|
+
body: CapabilityWriteBodies[K];
|
|
457
|
+
};
|
|
458
|
+
}[CapabilityId];
|
|
459
|
+
/** Fields common to every {@link AutoConfirmContext} variant. */
|
|
460
|
+
interface AutoConfirmContextBase {
|
|
461
|
+
/** HTTP method of the write. */
|
|
462
|
+
method: string;
|
|
463
|
+
/** Resolved API path of the write (path params substituted + encoded). */
|
|
464
|
+
path: string;
|
|
465
|
+
/** Path parameters used to resolve `path`, if any. */
|
|
466
|
+
pathParams?: Record<string, CapabilityPathParamValue>;
|
|
467
|
+
/** Idempotency key that will be bound to the token and sent on the write. */
|
|
468
|
+
idempotencyKey: string;
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Context handed to an {@link AutoConfirmOptions.previewSummary} callback.
|
|
472
|
+
*
|
|
473
|
+
* A discriminated union on `capabilityId` — narrow on it to get the exact
|
|
474
|
+
* `body` type for that route:
|
|
475
|
+
*
|
|
476
|
+
* ```ts
|
|
477
|
+
* previewSummary: (ctx) => {
|
|
478
|
+
* if (ctx.capabilityId === 'helpdesk.conversation.reply.execute') {
|
|
479
|
+
* // ctx.body is CreateReplyInput here
|
|
480
|
+
* return `Reply to ${ctx.body.conversation_id}: ${ctx.body.body}`;
|
|
481
|
+
* }
|
|
482
|
+
* return `${ctx.method} ${ctx.path}`;
|
|
483
|
+
* }
|
|
484
|
+
* ```
|
|
485
|
+
*
|
|
486
|
+
* `body` is the **exact object you passed to the SDK method**, by reference
|
|
487
|
+
* and unmodified — it is your own payload, so there is nothing to redact and
|
|
488
|
+
* nothing crosses a tenant boundary. Treat it as read-only: mutating it from
|
|
489
|
+
* the callback would change what is actually sent.
|
|
490
|
+
*/
|
|
491
|
+
type AutoConfirmContext = AutoConfirmContextBase & CapabilityWriteRequest;
|
|
492
|
+
/**
|
|
493
|
+
* Opt-in auto-confirmation.
|
|
494
|
+
*
|
|
495
|
+
* When configured, the SDK mints an idempotency key and a confirmation token
|
|
496
|
+
* for you before each confirmable write, then attaches both headers.
|
|
497
|
+
*
|
|
498
|
+
* **This is not a bypass.** Every minted token carries
|
|
499
|
+
* `user_approved: true`, which asserts that *your own user* approved that
|
|
500
|
+
* specific action — the `preview_summary` you return is the audit record of
|
|
501
|
+
* what they approved. Only enable this on a code path where a human really did
|
|
502
|
+
* approve the write. Never wire it into unattended automation.
|
|
503
|
+
*/
|
|
504
|
+
interface AutoConfirmOptions {
|
|
505
|
+
/**
|
|
506
|
+
* Build the `preview_summary` for the pending write. Must return a
|
|
507
|
+
* non-empty string describing what the user approved; returning blank text
|
|
508
|
+
* throws instead of asserting an approval that has no description.
|
|
509
|
+
*
|
|
510
|
+
* The context includes the pending request `body`, so the summary can name
|
|
511
|
+
* the specific action rather than the route — narrow on
|
|
512
|
+
* `context.capabilityId` to get the exact payload type. Prefer a
|
|
513
|
+
* payload-aware summary: `"Reply to conv_1: 'Refund issued'"` is an audit
|
|
514
|
+
* record, `"POST /api/v1/helpdesk/replies"` is not.
|
|
515
|
+
*
|
|
516
|
+
* The server caps `preview_summary` at 4000 characters, so summarise the
|
|
517
|
+
* payload rather than serialising it wholesale.
|
|
518
|
+
*/
|
|
519
|
+
previewSummary: (context: AutoConfirmContext) => string;
|
|
520
|
+
}
|
|
521
|
+
|
|
3
522
|
/** Configuration for the low-level HTTP client. */
|
|
4
523
|
interface ClientConfig {
|
|
5
524
|
baseUrl: string;
|
|
@@ -25,7 +544,22 @@ interface RequestOptions {
|
|
|
25
544
|
* `POST /api/v1/capability-confirmations`. API keys with legacy scopes do
|
|
26
545
|
* not need it.
|
|
27
546
|
*/
|
|
28
|
-
capabilityConfirmation?: string;
|
|
547
|
+
capabilityConfirmation?: string;
|
|
548
|
+
/**
|
|
549
|
+
* Opt in to (or out of) automatic capability confirmation for this call.
|
|
550
|
+
*
|
|
551
|
+
* Supply `{ previewSummary }` to have the SDK mint the idempotency key and
|
|
552
|
+
* the `X-Capability-Confirmation` token itself; pass `false` to suppress a
|
|
553
|
+
* client-level `autoConfirmCapabilities` default. Defaults to the client
|
|
554
|
+
* setting, which itself defaults to OFF.
|
|
555
|
+
*
|
|
556
|
+
* Auto-confirmation sends `user_approved: true` on your behalf, asserting
|
|
557
|
+
* that a human on your side approved this exact action — only use it where
|
|
558
|
+
* that is true.
|
|
559
|
+
*
|
|
560
|
+
* Ignored on routes that do not require a capability confirmation.
|
|
561
|
+
*/
|
|
562
|
+
autoConfirm?: AutoConfirmOptions | false;
|
|
29
563
|
}
|
|
30
564
|
/**
|
|
31
565
|
* Low-level HTTP client used by all resource classes.
|
|
@@ -48,29 +582,139 @@ declare class BaseClient {
|
|
|
48
582
|
private request;
|
|
49
583
|
}
|
|
50
584
|
|
|
51
|
-
/**
|
|
52
|
-
|
|
53
|
-
|
|
585
|
+
/**
|
|
586
|
+
* Mint short-lived capability confirmation tokens.
|
|
587
|
+
*
|
|
588
|
+
* Medal's confirmable write routes (connect links, channel connections,
|
|
589
|
+
* helpdesk replies/updates, webhook endpoint writes) require BOTH an
|
|
590
|
+
* `Idempotency-Key` and an `X-Capability-Confirmation` header when the calling
|
|
591
|
+
* credential holds the capability scope *directly* — which is the case for
|
|
592
|
+
* every correctly-scoped partner key. This resource issues that header value.
|
|
593
|
+
*
|
|
594
|
+
* @example Explicit flow
|
|
595
|
+
* ```ts
|
|
596
|
+
* const idempotencyKey = crypto.randomUUID();
|
|
597
|
+
* const { data: confirmation } = await medal.capabilityConfirmations.create({
|
|
598
|
+
* capability_id: 'channel.connect_link.create.execute',
|
|
599
|
+
* idempotency_key: idempotencyKey,
|
|
600
|
+
* preview_summary: 'Mint a Telegram connect link for Acme Support',
|
|
601
|
+
* user_approved: true, // a human on your side approved this exact action
|
|
602
|
+
* });
|
|
603
|
+
*
|
|
604
|
+
* await medal.channels.connectLinks.create(
|
|
605
|
+
* { channel_type: 'telegram_inbox', label: 'Acme Support' },
|
|
606
|
+
* { idempotencyKey, capabilityConfirmation: confirmation.confirmation_token },
|
|
607
|
+
* );
|
|
608
|
+
* ```
|
|
609
|
+
*/
|
|
610
|
+
declare class CapabilityConfirmations {
|
|
611
|
+
private client;
|
|
612
|
+
constructor(client: BaseClient);
|
|
613
|
+
/**
|
|
614
|
+
* Issue a confirmation token for one pending write.
|
|
615
|
+
*
|
|
616
|
+
* The token is bound to the workspace, the auth subject, the capability's
|
|
617
|
+
* method + path, its required scopes, and `idempotency_key` — so it is
|
|
618
|
+
* usable exactly once, for exactly the write it describes, and expires
|
|
619
|
+
* within 15 minutes.
|
|
620
|
+
*
|
|
621
|
+
* Setting `user_approved: true` asserts that a human on your side approved
|
|
622
|
+
* this specific action. `preview_summary` is what they approved, and is
|
|
623
|
+
* retained for audit — write it for a human reader, not a log parser.
|
|
624
|
+
*/
|
|
625
|
+
create(input: IssueCapabilityConfirmationInput): Promise<ApiResponse<CapabilityConfirmation>>;
|
|
54
626
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Resolves the `Idempotency-Key` + `X-Capability-Confirmation` pair required
|
|
630
|
+
* by confirmable write routes.
|
|
631
|
+
*
|
|
632
|
+
* Auto-confirmation is OFF unless the integrator opts in — either globally via
|
|
633
|
+
* the `Medal` constructor's `autoConfirmCapabilities`, or per call via
|
|
634
|
+
* `{ autoConfirm: { previewSummary } }`. When it is off this is a pass-through:
|
|
635
|
+
* whatever headers the caller supplied are what gets sent.
|
|
636
|
+
*/
|
|
637
|
+
declare class CapabilityConfirmer {
|
|
638
|
+
private confirmations;
|
|
639
|
+
private defaults?;
|
|
640
|
+
constructor(confirmations: CapabilityConfirmations, defaults?: AutoConfirmOptions | undefined);
|
|
641
|
+
/**
|
|
642
|
+
* Return the request options to use for a confirmable write, minting the
|
|
643
|
+
* idempotency key and confirmation token first when auto-confirm is active.
|
|
644
|
+
*
|
|
645
|
+
* `body` is the pending request payload (`undefined` for `DELETE` routes).
|
|
646
|
+
* It is handed to the `previewSummary` callback by reference so the summary
|
|
647
|
+
* can describe the specific action, not just the route — it is the caller's
|
|
648
|
+
* own payload, so it is passed through unmodified and unredacted.
|
|
649
|
+
*/
|
|
650
|
+
prepare(request: CapabilityWriteRequest, pathParams?: Record<string, CapabilityPathParamValue>, options?: RequestOptions): Promise<RequestOptions | undefined>;
|
|
62
651
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
constructor(
|
|
652
|
+
|
|
653
|
+
/** Mint, list, and revoke hosted connect links. */
|
|
654
|
+
declare class ChannelConnectLinks {
|
|
655
|
+
private client;
|
|
656
|
+
private confirmer;
|
|
657
|
+
constructor(client: BaseClient, confirmer: CapabilityConfirmer);
|
|
658
|
+
/**
|
|
659
|
+
* Mint a single-use hosted connect link. Returns HTTP 201.
|
|
660
|
+
*
|
|
661
|
+
* **The response's `data.url` contains the one-time link token EXACTLY
|
|
662
|
+
* ONCE.** Send it to the person who should connect their account — an
|
|
663
|
+
* idempotent replay (same `Idempotency-Key`) returns the link WITHOUT
|
|
664
|
+
* `url`, so store it immediately (or revoke and mint a new link if lost).
|
|
665
|
+
*
|
|
666
|
+
* Requires the `channel.connect.manage` scope; OAuth callers additionally
|
|
667
|
+
* need the workspace `admin` role.
|
|
668
|
+
*/
|
|
669
|
+
create(input: CreateConnectLinkInput, options?: RequestOptions): Promise<ApiResponse<ConnectLinkCreateResult>>;
|
|
670
|
+
/**
|
|
671
|
+
* List the workspace's connect links (tokens are never returned), newest
|
|
672
|
+
* first, with cursor-based pagination.
|
|
673
|
+
*
|
|
674
|
+
* `limit` defaults to 50 server-side and is capped at 100. Follow
|
|
675
|
+
* `pagination.next_cursor` while `pagination.has_more` is true.
|
|
676
|
+
*
|
|
677
|
+
* The `channel_type` / `status` filters are applied **within** each page,
|
|
678
|
+
* so a page may hold fewer than `limit` items while `has_more` is still
|
|
679
|
+
* true — drive the loop off `has_more`, never off the item count.
|
|
680
|
+
*/
|
|
681
|
+
list(options?: ListConnectLinksOptions): Promise<PaginatedResponse<ConnectLink>>;
|
|
682
|
+
/** Revoke a pending connect link so it can no longer be consumed. */
|
|
683
|
+
revoke(id: string, options?: RequestOptions): Promise<ApiResponse<ConnectLinkRevokeResult>>;
|
|
69
684
|
}
|
|
70
|
-
/**
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
685
|
+
/** List and disconnect the workspace's channel connections. */
|
|
686
|
+
declare class ChannelConnections {
|
|
687
|
+
private client;
|
|
688
|
+
private confirmer;
|
|
689
|
+
constructor(client: BaseClient, confirmer: CapabilityConfirmer);
|
|
690
|
+
/**
|
|
691
|
+
* List the workspace's channel connections (generic, channel-agnostic
|
|
692
|
+
* shape), newest first, with cursor-based pagination.
|
|
693
|
+
*
|
|
694
|
+
* `limit` defaults to 50 server-side and is capped at 100. Follow
|
|
695
|
+
* `pagination.next_cursor` while `pagination.has_more` is true. Rows that
|
|
696
|
+
* are not projectable as connections are dropped within the page, so a page
|
|
697
|
+
* may hold fewer than `limit` items while `has_more` is still true — drive
|
|
698
|
+
* the loop off `has_more`, never off the item count.
|
|
699
|
+
*/
|
|
700
|
+
list(options?: PaginationOptions): Promise<PaginatedResponse<ChannelConnection>>;
|
|
701
|
+
/**
|
|
702
|
+
* Disconnect a connected channel account (best-effort platform logout, then
|
|
703
|
+
* local revoke). Emits a `helpdesk.channel_disconnected` webhook event with
|
|
704
|
+
* `reason: "api_disconnect"` if the account was previously connected.
|
|
705
|
+
*/
|
|
706
|
+
disconnect(id: string, options?: RequestOptions): Promise<ApiResponse<ChannelConnectionDisconnectResult>>;
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* Partner channel connect — mint hosted connect links that let an external
|
|
710
|
+
* person (no Medal account required) attach a channel account (e.g.
|
|
711
|
+
* `telegram_inbox`) to the workspace's helpdesk, and manage the resulting
|
|
712
|
+
* connections.
|
|
713
|
+
*/
|
|
714
|
+
declare class Channels {
|
|
715
|
+
readonly connectLinks: ChannelConnectLinks;
|
|
716
|
+
readonly connections: ChannelConnections;
|
|
717
|
+
constructor(client: BaseClient, confirmer?: CapabilityConfirmer);
|
|
74
718
|
}
|
|
75
719
|
|
|
76
720
|
/** A contact in the workspace CRM. */
|
|
@@ -532,94 +1176,11 @@ declare class Gdpr {
|
|
|
532
1176
|
}>;
|
|
533
1177
|
}
|
|
534
1178
|
|
|
535
|
-
/** Lifecycle status of a helpdesk conversation. */
|
|
536
|
-
type ConversationStatus = "open" | "snoozed" | "closed";
|
|
537
|
-
/** Who authored a helpdesk message. */
|
|
538
|
-
type MessageAuthorType = "visitor" | "operator" | "ai" | "system";
|
|
539
|
-
/** Kind of helpdesk message. `note` is operator-internal and never delivered to the customer. */
|
|
540
|
-
type HelpdeskMessageType = "chat" | "email" | "note";
|
|
541
|
-
/** A helpdesk conversation across any connected channel (widget, email, social DMs, …). */
|
|
542
|
-
interface Conversation {
|
|
543
|
-
id: string;
|
|
544
|
-
/** Channel type, e.g. 'widget', 'instagram', 'messenger', 'whatsapp', 'email'. */
|
|
545
|
-
channel: string;
|
|
546
|
-
channel_connection_id: string | null;
|
|
547
|
-
status: ConversationStatus;
|
|
548
|
-
subject: string | null;
|
|
549
|
-
assignee_user_id: string | null;
|
|
550
|
-
contact_id: string | null;
|
|
551
|
-
visitor_name: string | null;
|
|
552
|
-
visitor_email: string | null;
|
|
553
|
-
external_conversation_id: string | null;
|
|
554
|
-
channel_account_id: string | null;
|
|
555
|
-
message_count: number;
|
|
556
|
-
unread_for_operator: number;
|
|
557
|
-
/** Unix timestamp in milliseconds. */
|
|
558
|
-
last_message_at: number;
|
|
559
|
-
last_message_preview: string | null;
|
|
560
|
-
last_message_author_type: MessageAuthorType | null;
|
|
561
|
-
/** Unix timestamp in milliseconds. */
|
|
562
|
-
created_at: number;
|
|
563
|
-
/** Unix timestamp in milliseconds. */
|
|
564
|
-
updated_at: number;
|
|
565
|
-
}
|
|
566
|
-
/** A single message inside a helpdesk conversation. */
|
|
567
|
-
interface ConversationMessage {
|
|
568
|
-
id: string;
|
|
569
|
-
conversation_id: string;
|
|
570
|
-
author_type: MessageAuthorType;
|
|
571
|
-
message_type: HelpdeskMessageType;
|
|
572
|
-
author_user_id: string | null;
|
|
573
|
-
author_name: string | null;
|
|
574
|
-
body: string;
|
|
575
|
-
/** Unix timestamp in milliseconds. */
|
|
576
|
-
created_at: number;
|
|
577
|
-
}
|
|
578
|
-
/** Filters for listing/searching helpdesk conversations. */
|
|
579
|
-
interface ListConversationsOptions extends PaginationOptions {
|
|
580
|
-
status?: ConversationStatus;
|
|
581
|
-
/** Only conversations assigned to this user. */
|
|
582
|
-
assignee_user_id?: string;
|
|
583
|
-
/** Match against visitor name/email. */
|
|
584
|
-
requester?: string;
|
|
585
|
-
/** Free-text search query. */
|
|
586
|
-
query?: string;
|
|
587
|
-
/** Only conversations on these channels (serialized as CSV). */
|
|
588
|
-
channels?: string[];
|
|
589
|
-
}
|
|
590
|
-
/** Input for updating a conversation's status and/or assignee. At least one field is required. */
|
|
591
|
-
interface UpdateConversationInput {
|
|
592
|
-
status?: ConversationStatus;
|
|
593
|
-
/** User ID to assign, or `null` to unassign. */
|
|
594
|
-
assignee_user_id?: string | null;
|
|
595
|
-
}
|
|
596
|
-
/** Result of a conversation update. */
|
|
597
|
-
interface ConversationUpdateResult {
|
|
598
|
-
id: string;
|
|
599
|
-
status: ConversationStatus;
|
|
600
|
-
assignee_user_id: string | null;
|
|
601
|
-
}
|
|
602
|
-
/** Input for sending an operator reply (or internal note) into a conversation. */
|
|
603
|
-
interface CreateReplyInput {
|
|
604
|
-
conversation_id: string;
|
|
605
|
-
/** Message body (max 20,000 characters). */
|
|
606
|
-
body: string;
|
|
607
|
-
/** `note` = operator-internal note (not delivered to the customer). Default `chat`. */
|
|
608
|
-
message_type?: "chat" | "note";
|
|
609
|
-
/** Agent display name for bridged replies (shown in widget + inbox). */
|
|
610
|
-
author_name?: string;
|
|
611
|
-
}
|
|
612
|
-
/** Result returned after creating a reply (HTTP 201). */
|
|
613
|
-
interface ReplyCreateResult {
|
|
614
|
-
id: string;
|
|
615
|
-
conversation_id: string;
|
|
616
|
-
status: string;
|
|
617
|
-
}
|
|
618
|
-
|
|
619
1179
|
/** Browse and manage helpdesk conversations. */
|
|
620
1180
|
declare class HelpdeskConversations {
|
|
621
1181
|
private client;
|
|
622
|
-
|
|
1182
|
+
private confirmer;
|
|
1183
|
+
constructor(client: BaseClient, confirmer: CapabilityConfirmer);
|
|
623
1184
|
/** List/search conversations with cursor-based pagination and optional filters. */
|
|
624
1185
|
list(options?: ListConversationsOptions): Promise<PaginatedResponse<Conversation>>;
|
|
625
1186
|
/** Get a conversation by ID. */
|
|
@@ -632,7 +1193,8 @@ declare class HelpdeskConversations {
|
|
|
632
1193
|
/** Send operator replies (or internal notes) into conversations. */
|
|
633
1194
|
declare class HelpdeskReplies {
|
|
634
1195
|
private client;
|
|
635
|
-
|
|
1196
|
+
private confirmer;
|
|
1197
|
+
constructor(client: BaseClient, confirmer: CapabilityConfirmer);
|
|
636
1198
|
/**
|
|
637
1199
|
* Send an operator reply or internal note. Returns HTTP 201.
|
|
638
1200
|
*
|
|
@@ -645,7 +1207,7 @@ declare class HelpdeskReplies {
|
|
|
645
1207
|
declare class Helpdesk {
|
|
646
1208
|
readonly conversations: HelpdeskConversations;
|
|
647
1209
|
readonly replies: HelpdeskReplies;
|
|
648
|
-
constructor(client: BaseClient);
|
|
1210
|
+
constructor(client: BaseClient, confirmer?: CapabilityConfirmer);
|
|
649
1211
|
}
|
|
650
1212
|
|
|
651
1213
|
/** A post in the workspace (list view). */
|
|
@@ -754,97 +1316,168 @@ declare class Posts {
|
|
|
754
1316
|
channels(): Promise<ApiResponse<Channel[]>>;
|
|
755
1317
|
}
|
|
756
1318
|
|
|
757
|
-
/**
|
|
758
|
-
interface
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
/**
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
event_types: string[];
|
|
766
|
-
/** Channel-type filter (e.g. ['widget', 'whatsapp']), or `null` for all channels. */
|
|
767
|
-
channels: string[] | null;
|
|
768
|
-
/** Channel-connection filter, or `null` for all connections. */
|
|
769
|
-
channel_connection_ids: string[] | null;
|
|
770
|
-
/** Last 4 characters of the signing secret, for identification. */
|
|
771
|
-
secret_last4: string;
|
|
772
|
-
consecutive_failures: number;
|
|
773
|
-
/** Unix timestamps in milliseconds, or `null` if never. */
|
|
774
|
-
last_delivery_at: number | null;
|
|
775
|
-
last_success_at: number | null;
|
|
776
|
-
last_error_at: number | null;
|
|
777
|
-
last_error: string | null;
|
|
778
|
-
created_at: number;
|
|
779
|
-
updated_at: number;
|
|
780
|
-
/**
|
|
781
|
-
* Full signing secret (`whsec_…`) — present ONLY in the `create` response.
|
|
782
|
-
* It is returned exactly once and can never be retrieved again. Store it
|
|
783
|
-
* securely immediately; you need it to verify delivery signatures.
|
|
784
|
-
*/
|
|
785
|
-
secret?: string;
|
|
1319
|
+
/** Input for creating a scan — provide exactly ONE of `url`, `orgnr`, or `name`. */
|
|
1320
|
+
interface ScanCreateInput {
|
|
1321
|
+
/** Website URL to scan directly (https is assumed when the scheme is missing). */
|
|
1322
|
+
url?: string;
|
|
1323
|
+
/** 9-digit Norwegian organisation number — resolved via the public registry. */
|
|
1324
|
+
orgnr?: string;
|
|
1325
|
+
/** Company name — resolved to the best registry match before scanning. */
|
|
1326
|
+
name?: string;
|
|
786
1327
|
}
|
|
787
|
-
/**
|
|
788
|
-
interface
|
|
789
|
-
|
|
1328
|
+
/** Reference returned when a scan job is queued (HTTP 202). */
|
|
1329
|
+
interface ScanCreateResult {
|
|
1330
|
+
id: string;
|
|
1331
|
+
status: "pending" | string;
|
|
1332
|
+
message?: string;
|
|
1333
|
+
}
|
|
1334
|
+
/** Lifecycle of an asynchronous scan job. */
|
|
1335
|
+
type ScanStatus = "pending" | "running" | "done" | "failed";
|
|
1336
|
+
/** A company-registry search hit from `scan.companies()`. */
|
|
1337
|
+
interface ScanCompany {
|
|
1338
|
+
orgnr: string;
|
|
790
1339
|
name: string;
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
1340
|
+
org_form: string | null;
|
|
1341
|
+
industry: string | null;
|
|
1342
|
+
city: string | null;
|
|
1343
|
+
website: string | null;
|
|
1344
|
+
}
|
|
1345
|
+
/** Nettskår sub-scores (0–100); null = the axis could not be measured. */
|
|
1346
|
+
interface ScanSubScores {
|
|
1347
|
+
fart: number | null;
|
|
1348
|
+
google: number | null;
|
|
1349
|
+
ai: number | null;
|
|
1350
|
+
trygghet: number | null;
|
|
1351
|
+
omdomme: number | null;
|
|
799
1352
|
}
|
|
800
1353
|
/**
|
|
801
|
-
*
|
|
802
|
-
*
|
|
803
|
-
*
|
|
804
|
-
* leaves the current filter unchanged.
|
|
1354
|
+
* The versioned scan findings payload. Shapes within are additive per
|
|
1355
|
+
* `version`; string unions stay open (`| string`) so new detections never
|
|
1356
|
+
* break consumers.
|
|
805
1357
|
*/
|
|
806
|
-
interface
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
1358
|
+
interface ScanResultPayload {
|
|
1359
|
+
version: number;
|
|
1360
|
+
/** Weighted composite score (0–100); null when nothing could be measured. */
|
|
1361
|
+
nettskaar: number | null;
|
|
1362
|
+
subScores: ScanSubScores;
|
|
1363
|
+
registry?: {
|
|
1364
|
+
orgnr: string;
|
|
1365
|
+
navn: string;
|
|
1366
|
+
organisasjonsform?: string;
|
|
1367
|
+
naeringBeskrivelse?: string;
|
|
1368
|
+
antallAnsatte?: number;
|
|
1369
|
+
poststed?: string;
|
|
1370
|
+
};
|
|
1371
|
+
signals: {
|
|
1372
|
+
version: number;
|
|
1373
|
+
tech: string[];
|
|
1374
|
+
pixels: string[];
|
|
1375
|
+
consent: string[];
|
|
1376
|
+
commerce: string[];
|
|
1377
|
+
marketing?: string[];
|
|
1378
|
+
social: Record<string, string | undefined>;
|
|
1379
|
+
emailProvider?: string;
|
|
1380
|
+
unreachable?: boolean;
|
|
1381
|
+
inconclusive?: boolean;
|
|
1382
|
+
dnsPending?: boolean;
|
|
1383
|
+
};
|
|
1384
|
+
pagespeed?: {
|
|
1385
|
+
mobileScore?: number;
|
|
1386
|
+
lcpMs?: number;
|
|
1387
|
+
cls?: number;
|
|
1388
|
+
inpMs?: number;
|
|
1389
|
+
error?: string;
|
|
1390
|
+
};
|
|
1391
|
+
seo: {
|
|
1392
|
+
titleLength: number;
|
|
1393
|
+
metaDescriptionLength: number;
|
|
1394
|
+
h1Count: number;
|
|
1395
|
+
hasOg: boolean;
|
|
1396
|
+
hasCanonical: boolean;
|
|
1397
|
+
hreflangCount: number;
|
|
1398
|
+
hasViewport: boolean;
|
|
1399
|
+
};
|
|
1400
|
+
ai: {
|
|
1401
|
+
/** null = llms.txt could not be checked (unknown), false = confirmed absent. */
|
|
1402
|
+
llmsTxtFound: boolean | null;
|
|
1403
|
+
/** null = robots.txt could not be read (unknown, not "none blocked"). */
|
|
1404
|
+
blockedBots: string[] | null;
|
|
1405
|
+
jsonLdTypes: string[];
|
|
1406
|
+
faqFound: boolean;
|
|
1407
|
+
};
|
|
1408
|
+
gdpr: {
|
|
1409
|
+
/**
|
|
1410
|
+
* true = tracking pixels load with no consent platform; false = clean or
|
|
1411
|
+
* a consent platform is present; null = unknown (unreachable / JS-only).
|
|
1412
|
+
*/
|
|
1413
|
+
trackingBeforeConsent: boolean | null;
|
|
1414
|
+
cmp: string | null;
|
|
1415
|
+
privacyPageFound: boolean;
|
|
1416
|
+
};
|
|
1417
|
+
mailAuth: {
|
|
1418
|
+
spf: "ok" | "missing" | "unknown" | string;
|
|
1419
|
+
dmarc: "ok" | "missing" | "unknown" | string;
|
|
1420
|
+
dmarcPolicy?: string;
|
|
1421
|
+
};
|
|
1422
|
+
httpsOk: boolean;
|
|
818
1423
|
}
|
|
819
|
-
/** A
|
|
820
|
-
interface
|
|
1424
|
+
/** A scan job as returned by `scan.get()`. */
|
|
1425
|
+
interface ScanJob {
|
|
821
1426
|
id: string;
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
/**
|
|
831
|
-
|
|
832
|
-
created_at:
|
|
1427
|
+
status: ScanStatus | string;
|
|
1428
|
+
input: ScanCreateInput;
|
|
1429
|
+
resolved: {
|
|
1430
|
+
orgnr?: string;
|
|
1431
|
+
companyName?: string;
|
|
1432
|
+
websiteUrl?: string;
|
|
1433
|
+
} | null;
|
|
1434
|
+
result: ScanResultPayload | null;
|
|
1435
|
+
/** Public-safe failure code (`company_not_found`, `no_website`, …). */
|
|
1436
|
+
error: string | null;
|
|
1437
|
+
created_at: string | null;
|
|
1438
|
+
finished_at: string | null;
|
|
833
1439
|
}
|
|
834
|
-
/** Options for
|
|
835
|
-
interface
|
|
836
|
-
|
|
1440
|
+
/** Options for `scan.waitForResult()`. */
|
|
1441
|
+
interface WaitForScanOptions {
|
|
1442
|
+
/** Poll interval in milliseconds. Default 2500. */
|
|
1443
|
+
intervalMs?: number;
|
|
1444
|
+
/** Give up after this long. Default 120000 (scans normally finish in ~30 s). */
|
|
1445
|
+
timeoutMs?: number;
|
|
837
1446
|
}
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
1447
|
+
|
|
1448
|
+
/**
|
|
1449
|
+
* Company & website scans (Nettsjekk) — score a Norwegian company's web
|
|
1450
|
+
* presence (performance, SEO, GDPR consent, AI visibility, mail auth) from a
|
|
1451
|
+
* URL, an organisation number, or a company name.
|
|
1452
|
+
*/
|
|
1453
|
+
declare class Scan {
|
|
1454
|
+
private client;
|
|
1455
|
+
constructor(client: BaseClient);
|
|
1456
|
+
/**
|
|
1457
|
+
* Queue a scan. Provide exactly one of `url`, `orgnr`, or `name`.
|
|
1458
|
+
* Runs asynchronously — poll with `get()` or use `waitForResult()`.
|
|
1459
|
+
*
|
|
1460
|
+
* @throws Error before any request when zero or several selectors are set —
|
|
1461
|
+
* the server would reject the body anyway; failing locally is clearer.
|
|
1462
|
+
*/
|
|
1463
|
+
create(input: ScanCreateInput): Promise<ApiResponse<ScanCreateResult>>;
|
|
1464
|
+
/** Get a scan job's status and, once done, its findings payload. */
|
|
1465
|
+
get(id: string): Promise<ApiResponse<ScanJob>>;
|
|
1466
|
+
/** Search the Norwegian company registry by name (typeahead, top 5 hits). */
|
|
1467
|
+
companies(q: string): Promise<ApiResponse<ScanCompany[]>>;
|
|
1468
|
+
/**
|
|
1469
|
+
* Poll a scan until it settles. Resolves with the job for both `done` and
|
|
1470
|
+
* `failed` (check `job.error`); throws only when the deadline passes while
|
|
1471
|
+
* the scan is still pending/running.
|
|
1472
|
+
*/
|
|
1473
|
+
waitForResult(id: string, options?: WaitForScanOptions): Promise<ScanJob>;
|
|
842
1474
|
}
|
|
843
1475
|
|
|
844
1476
|
/** Manage webhook endpoints and inspect their deliveries. */
|
|
845
1477
|
declare class Webhooks {
|
|
846
1478
|
private client;
|
|
847
|
-
|
|
1479
|
+
private confirmer;
|
|
1480
|
+
constructor(client: BaseClient, confirmer?: CapabilityConfirmer);
|
|
848
1481
|
/** List all webhook endpoints in the workspace. */
|
|
849
1482
|
list(): Promise<ApiResponse<WebhookEndpoint[]>>;
|
|
850
1483
|
/**
|
|
@@ -997,6 +1630,38 @@ interface MessageDeliveryUpdatedEvent extends WebhookEventBase {
|
|
|
997
1630
|
message: WebhookMessageSnapshot;
|
|
998
1631
|
};
|
|
999
1632
|
}
|
|
1633
|
+
/**
|
|
1634
|
+
* Fields present in the `data` of channel lifecycle events. Unlike message
|
|
1635
|
+
* events there is no conversation snapshot — the payload is channel-generic.
|
|
1636
|
+
* `channel` / `channelConnectionId` sit at the top level so endpoint channel
|
|
1637
|
+
* filters match exactly like message events.
|
|
1638
|
+
*/
|
|
1639
|
+
interface WebhookChannelLifecycleData {
|
|
1640
|
+
/** Helpdesk channel type (e.g. `telegram`), or `null` for non-helpdesk channels. */
|
|
1641
|
+
channel: string | null;
|
|
1642
|
+
channelConnectionId: string | null;
|
|
1643
|
+
/** Connector channel type (e.g. `telegram_inbox`). */
|
|
1644
|
+
channel_type: string;
|
|
1645
|
+
/** Adapter-defined stable connection ref (matches `consumed_connection_ref` on the connect link). */
|
|
1646
|
+
connection_ref: string;
|
|
1647
|
+
label: string | null;
|
|
1648
|
+
masked_identity: string | null;
|
|
1649
|
+
}
|
|
1650
|
+
/** A channel account was connected to the workspace (e.g. via a partner connect link). */
|
|
1651
|
+
interface ChannelConnectedEvent extends WebhookEventBase {
|
|
1652
|
+
type: "helpdesk.channel_connected";
|
|
1653
|
+
data: WebhookChannelLifecycleData;
|
|
1654
|
+
}
|
|
1655
|
+
/** Why a channel account was disconnected. */
|
|
1656
|
+
type ChannelDisconnectReason = "api_disconnect" | "user_revoked" | "member_disconnect";
|
|
1657
|
+
/** A previously connected channel account was removed from the workspace. */
|
|
1658
|
+
interface ChannelDisconnectedEvent extends WebhookEventBase {
|
|
1659
|
+
type: "helpdesk.channel_disconnected";
|
|
1660
|
+
data: WebhookChannelLifecycleData & {
|
|
1661
|
+
/** Why the account went away. */
|
|
1662
|
+
reason?: ChannelDisconnectReason;
|
|
1663
|
+
};
|
|
1664
|
+
}
|
|
1000
1665
|
/** A `test.ping` delivery queued via `medal.webhooks.test(id)`. Carries sample data. */
|
|
1001
1666
|
interface TestPingEvent extends WebhookEventBase {
|
|
1002
1667
|
type: "test.ping";
|
|
@@ -1017,7 +1682,7 @@ interface TestPingEvent extends WebhookEventBase {
|
|
|
1017
1682
|
* }
|
|
1018
1683
|
* ```
|
|
1019
1684
|
*/
|
|
1020
|
-
type WebhookEvent = ConversationCreatedEvent | ConversationAssignedEvent | ConversationStatusChangedEvent | MessageReceivedEvent | MessageSentEvent | MessageDeliveryUpdatedEvent | TestPingEvent;
|
|
1685
|
+
type WebhookEvent = ConversationCreatedEvent | ConversationAssignedEvent | ConversationStatusChangedEvent | MessageReceivedEvent | MessageSentEvent | MessageDeliveryUpdatedEvent | ChannelConnectedEvent | ChannelDisconnectedEvent | TestPingEvent;
|
|
1021
1686
|
/** Machine-readable reason a webhook verification failed. */
|
|
1022
1687
|
type WebhookVerificationErrorCode = "malformed_header" | "timestamp_out_of_tolerance" | "invalid_signature" | "invalid_payload";
|
|
1023
1688
|
/** Thrown by {@link verifyWebhookSignature} when a delivery cannot be authenticated. */
|
|
@@ -1077,6 +1742,37 @@ interface MedalOptions {
|
|
|
1077
1742
|
* OAuth tokens can access multiple workspaces, so you must specify which one.
|
|
1078
1743
|
*/
|
|
1079
1744
|
workspaceId?: string;
|
|
1745
|
+
/**
|
|
1746
|
+
* Opt in to automatic capability confirmation for confirmable writes.
|
|
1747
|
+
* **Defaults to OFF.**
|
|
1748
|
+
*
|
|
1749
|
+
* Medal's confirmable write routes (connect links, channel connections,
|
|
1750
|
+
* helpdesk replies/updates, webhook endpoint writes) require BOTH an
|
|
1751
|
+
* `Idempotency-Key` and an `X-Capability-Confirmation` token whenever the
|
|
1752
|
+
* credential holds the capability scope directly — which is the case for
|
|
1753
|
+
* every correctly-scoped partner key. With this option set, the SDK mints
|
|
1754
|
+
* both for you before each such write instead of making you hand-roll
|
|
1755
|
+
* `POST /api/v1/capability-confirmations`.
|
|
1756
|
+
*
|
|
1757
|
+
* **Read before enabling:** each minted token carries `user_approved: true`,
|
|
1758
|
+
* which asserts to Medal that *a human on your side approved that specific
|
|
1759
|
+
* action*, and the `previewSummary` you return is retained as the audit
|
|
1760
|
+
* record of what they approved. Enable it only on code paths where that is
|
|
1761
|
+
* genuinely true — never to rubber-stamp unattended writes. Pass
|
|
1762
|
+
* `{ autoConfirm: false }` on an individual call to opt out again, or use
|
|
1763
|
+
* `medal.capabilityConfirmations.create(...)` for full manual control.
|
|
1764
|
+
*
|
|
1765
|
+
* @example
|
|
1766
|
+
* ```ts
|
|
1767
|
+
* const medal = new Medal('medal_xxx', {
|
|
1768
|
+
* autoConfirmCapabilities: {
|
|
1769
|
+
* previewSummary: (ctx) =>
|
|
1770
|
+
* `${operator.email} approved ${ctx.method} ${ctx.path}`,
|
|
1771
|
+
* },
|
|
1772
|
+
* });
|
|
1773
|
+
* ```
|
|
1774
|
+
*/
|
|
1775
|
+
autoConfirmCapabilities?: AutoConfirmOptions;
|
|
1080
1776
|
}
|
|
1081
1777
|
/**
|
|
1082
1778
|
* Medal Social SDK client.
|
|
@@ -1125,12 +1821,15 @@ interface MedalOptions {
|
|
|
1125
1821
|
* ```
|
|
1126
1822
|
*/
|
|
1127
1823
|
declare class Medal {
|
|
1824
|
+
readonly capabilityConfirmations: CapabilityConfirmations;
|
|
1825
|
+
readonly channels: Channels;
|
|
1128
1826
|
readonly emails: Emails;
|
|
1129
1827
|
readonly contacts: Contacts;
|
|
1130
1828
|
readonly deals: Deals;
|
|
1131
1829
|
readonly gdpr: Gdpr;
|
|
1132
1830
|
readonly helpdesk: Helpdesk;
|
|
1133
1831
|
readonly posts: Posts;
|
|
1832
|
+
readonly scan: Scan;
|
|
1134
1833
|
readonly webhooks: Webhooks;
|
|
1135
1834
|
readonly workspaces: Workspaces;
|
|
1136
1835
|
constructor(token: string, options?: MedalOptions);
|
|
@@ -1139,4 +1838,4 @@ declare class Medal {
|
|
|
1139
1838
|
/** Convenience factory — equivalent to `new Medal(apiKey, options)`. */
|
|
1140
1839
|
declare function createMedalClient(apiKey: string, options?: MedalOptions): Medal;
|
|
1141
1840
|
|
|
1142
|
-
export { type Activity, type AddNoteInput, type ApiResponse, BaseClient, type BatchSendInput, type BatchSendResult, type BatchSendSummary, type Channel, type ConsentRecord, type ConsentResult, type ConsentType, type Contact, type ContactConsents, type ContactCreateResult, type ContactNoteResult, type ContactRemoveResult, type ContactStatus, type ContactUpdateResult, Contacts, type Conversation, type ConversationAssignedEvent, type ConversationCreatedEvent, type ConversationMessage, type ConversationStatus, type ConversationStatusChangedEvent, type ConversationUpdateResult, type CookieCategoryConsent, type CookieConsentInput, type CreateContactInput, type CreateDealInput, type CreatePostInput, type CreateReplyInput, type CreateWebhookInput, DEFAULT_WEBHOOK_TOLERANCE_MS, type Deal, type DealCreateResult, type DealRemoveResult, type DealStatus, type DealUpdateResult, Deals, type EmailSend, type EmailSendResult, type EmailStatus, type EmailTemplate, type EmailTemplateDetail, Emails, Gdpr, type GdprExport, type GetTemplateOptions, Helpdesk, type HelpdeskMessageType, type ImportContactInput, type ImportContactsResult, type ListContactsOptions, type ListConversationsOptions, type ListDealsOptions, type ListDeliveriesOptions, type ListPostsOptions, Medal, MedalApiError, type MedalOptions, type MessageAuthorType, type MessageDeliveryUpdatedEvent, type MessageReceivedEvent, type MessageSentEvent, type PaginatedResponse, type PaginationOptions, type Post, type PostDetail, type PostType, type PostVariant, Posts, type PublishResult, type RecordConsentInput, type ReplyCreateResult, type RequestOptions, type SchedulePostInput, type ScheduleResult, type SendEmailInput, type TestPingEvent, type UpdateContactInput, type UpdateConversationInput, type UpdateDealInput, type UpdatePostInput, type UpdateWebhookInput, type VerifyWebhookSignatureInput, type WebhookConversationSnapshot, type WebhookDeleteResult, type WebhookDelivery, type WebhookEndpoint, type WebhookEvent, type WebhookMessageSnapshot, type WebhookTestResult, WebhookVerificationError, type WebhookVerificationErrorCode, Webhooks, type Workspace, Workspaces, createMedalClient, Medal as default, verifyWebhookSignature };
|
|
1841
|
+
export { type Activity, type AddNoteInput, type ApiResponse, type AutoConfirmContext, type AutoConfirmOptions, BaseClient, type BatchSendInput, type BatchSendResult, type BatchSendSummary, CAPABILITY_IDS, CAPABILITY_ROUTES, type CapabilityConfirmation, CapabilityConfirmations, CapabilityConfirmer, type CapabilityId, type CapabilityPathParamValue, type CapabilityRoute, type CapabilityWriteBodies, type CapabilityWriteRequest, type Channel, type ChannelConnectedEvent, type ChannelConnection, type ChannelConnectionDisconnectResult, type ChannelConnectionState, type ChannelDisconnectReason, type ChannelDisconnectedEvent, Channels, type ConnectLink, type ConnectLinkCreateResult, type ConnectLinkRevokeResult, type ConnectLinkStatus, type ConsentRecord, type ConsentResult, type ConsentType, type Contact, type ContactConsents, type ContactCreateResult, type ContactNoteResult, type ContactRemoveResult, type ContactStatus, type ContactUpdateResult, Contacts, type Conversation, type ConversationAssignedEvent, type ConversationCreatedEvent, type ConversationMessage, type ConversationStatus, type ConversationStatusChangedEvent, type ConversationUpdateResult, type CookieCategoryConsent, type CookieConsentInput, type CreateConnectLinkInput, type CreateContactInput, type CreateDealInput, type CreatePostInput, type CreateReplyInput, type CreateWebhookInput, DEFAULT_WEBHOOK_TOLERANCE_MS, type Deal, type DealCreateResult, type DealRemoveResult, type DealStatus, type DealUpdateResult, Deals, type EmailSend, type EmailSendResult, type EmailStatus, type EmailTemplate, type EmailTemplateDetail, Emails, Gdpr, type GdprExport, type GetTemplateOptions, Helpdesk, type HelpdeskMessageType, type ImportContactInput, type ImportContactsResult, type IssueCapabilityConfirmationInput, type ListConnectLinksOptions, type ListContactsOptions, type ListConversationsOptions, type ListDealsOptions, type ListDeliveriesOptions, type ListPostsOptions, Medal, MedalApiError, type MedalOptions, type MessageAuthorType, type MessageDeliveryStatus, type MessageDeliveryUpdatedEvent, type MessageReceivedEvent, type MessageSentEvent, type PaginatedResponse, type PaginationOptions, type Post, type PostDetail, type PostType, type PostVariant, Posts, type PublishResult, type RecordConsentInput, type ReplyCreateResult, type RequestOptions, Scan, type ScanCompany, type ScanCreateInput, type ScanCreateResult, type ScanJob, type ScanResultPayload, type ScanStatus, type ScanSubScores, type SchedulePostInput, type ScheduleResult, type SendEmailInput, type TestPingEvent, type UpdateContactInput, type UpdateConversationInput, type UpdateDealInput, type UpdatePostInput, type UpdateWebhookInput, type VerifyWebhookSignatureInput, type WaitForScanOptions, type WebhookChannelLifecycleData, type WebhookConversationSnapshot, type WebhookDeleteResult, type WebhookDelivery, type WebhookEndpoint, type WebhookEvent, type WebhookMessageSnapshot, type WebhookTestResult, WebhookVerificationError, type WebhookVerificationErrorCode, Webhooks, type Workspace, Workspaces, createMedalClient, Medal as default, verifyWebhookSignature };
|