@proteos/sdk 0.49.0 → 0.51.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.
@@ -2,41 +2,59 @@ import type { ProteosClient } from '../client.js'
2
2
  import type {
3
3
  AcceptMistranscribedTermRequest,
4
4
  AgentListener,
5
+ ApplySendingLimitPresetRequest,
5
6
  AttachContactAddressRequest,
7
+ AttachConversationBriefRequest,
6
8
  BlockContactRequest,
9
+ CallTokenResponse,
10
+ ChannelAction,
11
+ ChannelEvent,
7
12
  Connection,
13
+ ConnectorCatalogEntry,
8
14
  Contact,
9
15
  ContactAddress,
10
16
  ContactErasureRequest,
11
17
  ContactGroup,
12
18
  ContactMergeProposal,
19
+ ContactRecordLink,
13
20
  Conversation,
21
+ ConversationBrief,
14
22
  ConversationFilter,
15
23
  ConversationFilterEvent,
16
24
  ConversationType,
17
25
  CreateAgentListenerRequest,
18
26
  CreateConnectionRequest,
19
27
  CreateContactGroupRequest,
20
- CreateContactRequest,
21
- ContactRecordLink,
22
28
  CreateContactRecordLinkRequest,
23
- ListContactRecordLinksQuery,
29
+ CreateContactRequest,
30
+ CreateConversationBriefRequest,
24
31
  CreateConversationFilterRequest,
25
32
  CreateConversationTypeRequest,
26
33
  CreateGlossaryTermRequest,
34
+ CreateSendingRuleRequest,
27
35
  CreateToneProfileSetupRequest,
28
36
  CreateTranscriptionRequest,
29
37
  DeleteConnectionQuery,
30
38
  DispatchMeetingBotRequest,
39
+ EmailDomainStatus,
40
+ EmailHealth,
41
+ EmailSender,
42
+ EmailSuppression,
43
+ EmailSuppressionKind,
44
+ GetConnectionHealthQuery,
31
45
  GlossaryTerm,
32
46
  InstallConnectionRequest,
33
47
  InstallConnectionResponse,
34
48
  ListAgentListenersQuery,
49
+ ListChannelActionsQuery,
50
+ ListChannelEventsQuery,
35
51
  ListConnectionsQuery,
36
52
  ListContactAddressesQuery,
37
53
  ListContactGroupsQuery,
38
54
  ListContactMergeProposalsQuery,
55
+ ListContactRecordLinksQuery,
39
56
  ListContactsQuery,
57
+ ListConversationBriefsQuery,
40
58
  ListConversationFilterEventsQuery,
41
59
  ListConversationFiltersQuery,
42
60
  ListConversationsQuery,
@@ -47,22 +65,29 @@ import type {
47
65
  ListReactionsResponse,
48
66
  ListResponse,
49
67
  ListRoomsQuery,
68
+ ListSendingLimitPresetsQuery,
69
+ ListSendingRulesQuery,
50
70
  ListToneProfileSetupsQuery,
51
71
  ListToneProfilesQuery,
52
72
  ListTranscriptionsQuery,
53
- CallTokenResponse,
54
73
  MaterializeTranscriptionRequest,
55
- MintCallTokenRequest,
56
- PhoneNumber,
57
- UpdatePhoneNumberRequest,
58
74
  MergeContactsRequest,
59
75
  Message,
76
+ MintCallTokenRequest,
60
77
  MistranscribedTerm,
78
+ PerformChannelActionRequest,
79
+ PhoneNumber,
61
80
  Reaction,
62
81
  RecordPermissionEventRequest,
63
82
  ResolveToneProfileQuery,
83
+ RespondChannelActionRequest,
64
84
  Room,
85
+ SendEligibility,
86
+ SendEligibilityRequest,
87
+ SendingLimitPreset,
88
+ SendingRule,
65
89
  SendMessageRequest,
90
+ SetDefaultSenderRequest,
66
91
  SyncConnectionRequest,
67
92
  ToneProfile,
68
93
  ToneProfileSetup,
@@ -72,11 +97,14 @@ import type {
72
97
  UpdateConnectionRequest,
73
98
  UpdateContactGroupRequest,
74
99
  UpdateContactRequest,
100
+ UpdateConversationBriefRequest,
75
101
  UpdateConversationFilterRequest,
76
102
  UpdateConversationRequest,
77
103
  UpdateConversationTypeRequest,
78
104
  UpdateDraftRequest,
79
105
  UpdateGlossaryTermRequest,
106
+ UpdatePhoneNumberRequest,
107
+ UpdateSendingRuleRequest,
80
108
  UpdateTranscriptionRequest,
81
109
  } from './types.js'
82
110
  import { type VoiceService, VoiceServiceImpl } from './voice.js'
@@ -102,6 +130,14 @@ export class ConversationClient {
102
130
  readonly agentListeners: AgentListenerService
103
131
  /** Ingest-time filter rules (drop-with-audit) + their event trail. */
104
132
  readonly conversationFilters: ConversationFilterService
133
+ /** Outbound send constraints: windows, connection limits, frequency caps + presets. */
134
+ readonly sendingRules: SendingRuleService
135
+ /**
136
+ * Channel actions: acts performed through a connection that are neither a
137
+ * message nor a reaction — LinkedIn invitations, profile visits, InMail.
138
+ */
139
+ readonly channelActions: ChannelActionService
140
+ readonly channelEvents: ChannelEventService
105
141
  /** Per-org glossary: custom vocabulary that boosts transcription accuracy. */
106
142
  readonly glossaryTerms: GlossaryTermService
107
143
  /** Conversation taxonomy: the types the pre-summary classifier assigns. */
@@ -118,6 +154,8 @@ export class ConversationClient {
118
154
  /** Realtime speech-to-text (dictation) — moved here from agent-service. */
119
155
  readonly voice: VoiceService
120
156
  readonly calls: CallService
157
+ /** Conversation briefs: guidance prepared ahead of a conversation (call, meeting) with a contact. */
158
+ readonly conversationBriefs: ConversationBriefService
121
159
 
122
160
  constructor(client: ProteosClient) {
123
161
  this.connections = new ConnectionServiceImpl(client)
@@ -126,6 +164,9 @@ export class ConversationClient {
126
164
  this.messages = new MessageServiceImpl(client)
127
165
  this.agentListeners = new AgentListenerServiceImpl(client)
128
166
  this.conversationFilters = new ConversationFilterServiceImpl(client)
167
+ this.sendingRules = new SendingRuleServiceImpl(client)
168
+ this.channelActions = new ChannelActionServiceImpl(client)
169
+ this.channelEvents = new ChannelEventServiceImpl(client)
129
170
  this.glossaryTerms = new GlossaryTermServiceImpl(client)
130
171
  this.conversationTypes = new ConversationTypeServiceImpl(client)
131
172
  this.contactGroups = new ContactGroupServiceImpl(client)
@@ -135,6 +176,7 @@ export class ConversationClient {
135
176
  this.meetings = new MeetingServiceImpl(client)
136
177
  this.voice = new VoiceServiceImpl(client)
137
178
  this.calls = new CallServiceImpl(client)
179
+ this.conversationBriefs = new ConversationBriefServiceImpl(client)
138
180
  }
139
181
  }
140
182
 
@@ -223,6 +265,33 @@ export interface ConnectionService {
223
265
  ): Promise<ListResponse<ContactAddress>>
224
266
  /** Search a connection's addressable VENUES (Slack channels) for the compose picker. */
225
267
  listRooms(connectionId: string, query?: ListRoomsQuery): Promise<ListResponse<Room>>
268
+ /**
269
+ * Deliverability of a sending-platform connection (SendGrid): rates from
270
+ * the channel_event ledger + the provider's snapshot (engagement quality,
271
+ * counters, suppression counts, domain/sender state, dedicated IPs).
272
+ * `email_provider_not_supported` on mailbox connectors.
273
+ */
274
+ getHealth(connectionId: string, query?: GetConnectionHealthQuery): Promise<EmailHealth>
275
+ /** Ask the provider to re-check the sending domain's DNS. */
276
+ validateDomain(connectionId: string): Promise<EmailDomainStatus>
277
+ /** Re-send the single-sender verification mail (no-op on an authenticated domain). */
278
+ resendSenderVerification(connectionId: string): Promise<void>
279
+ /** Read one provider suppression list live. */
280
+ listSuppressions(connectionId: string, kind: EmailSuppressionKind): Promise<EmailSuppression[]>
281
+ /** Take an address off one provider suppression list (a false positive). */
282
+ removeSuppression(connectionId: string, kind: EmailSuppressionKind, email: string): Promise<void>
283
+ /** Start / stop the provider's automated warmup on a dedicated IP. */
284
+ setIpWarmup(connectionId: string, ip: string, isEnabled: boolean): Promise<void>
285
+ /** The runtime connector catalog: what is wired in this environment + install modes. */
286
+ listConnectors(): Promise<ConnectorCatalogEntry[]>
287
+ /**
288
+ * The sender directory of a domain-authenticated email connection: every
289
+ * email contact address on its domain (colleagues + shared mailboxes), the
290
+ * default flagged. Empty on connections without a sender domain.
291
+ */
292
+ listSenders(connectionId: string): Promise<EmailSender[]>
293
+ /** Pin the connection's fallback sender; returns the refreshed directory. */
294
+ setDefaultSender(connectionId: string, request: SetDefaultSenderRequest): Promise<EmailSender[]>
226
295
  }
227
296
 
228
297
  class ConnectionServiceImpl implements ConnectionService {
@@ -293,13 +362,97 @@ class ConnectionServiceImpl implements ConnectionService {
293
362
  query,
294
363
  )
295
364
  }
365
+
366
+ getHealth(connectionId: string, query: GetConnectionHealthQuery = {}): Promise<EmailHealth> {
367
+ return this.client.requestWithQuery(
368
+ 'GET',
369
+ `${CONVERSATION_BASE_PATH}/connections/${encodeURIComponent(connectionId)}/health`,
370
+ query,
371
+ )
372
+ }
373
+
374
+ validateDomain(connectionId: string): Promise<EmailDomainStatus> {
375
+ return this.client.request(
376
+ 'POST',
377
+ `${CONVERSATION_BASE_PATH}/connections/${encodeURIComponent(connectionId)}/domain/validate`,
378
+ )
379
+ }
380
+
381
+ resendSenderVerification(connectionId: string): Promise<void> {
382
+ return this.client.request(
383
+ 'POST',
384
+ `${CONVERSATION_BASE_PATH}/connections/${encodeURIComponent(connectionId)}/sender/verify`,
385
+ )
386
+ }
387
+
388
+ async listSuppressions(
389
+ connectionId: string,
390
+ kind: EmailSuppressionKind,
391
+ ): Promise<EmailSuppression[]> {
392
+ const response: { data: EmailSuppression[] } = await this.client.requestWithQuery(
393
+ 'GET',
394
+ `${CONVERSATION_BASE_PATH}/connections/${encodeURIComponent(connectionId)}/suppressions`,
395
+ { kind },
396
+ )
397
+ return response.data
398
+ }
399
+
400
+ removeSuppression(
401
+ connectionId: string,
402
+ kind: EmailSuppressionKind,
403
+ email: string,
404
+ ): Promise<void> {
405
+ return this.client.request(
406
+ 'DELETE',
407
+ `${CONVERSATION_BASE_PATH}/connections/${encodeURIComponent(connectionId)}/suppressions/${encodeURIComponent(kind)}/${encodeURIComponent(email)}`,
408
+ )
409
+ }
410
+
411
+ setIpWarmup(connectionId: string, ip: string, isEnabled: boolean): Promise<void> {
412
+ return this.client.request(
413
+ isEnabled ? 'POST' : 'DELETE',
414
+ `${CONVERSATION_BASE_PATH}/connections/${encodeURIComponent(connectionId)}/ip-warmup/${encodeURIComponent(ip)}`,
415
+ )
416
+ }
417
+
418
+ async listConnectors(): Promise<ConnectorCatalogEntry[]> {
419
+ const response: { data: ConnectorCatalogEntry[] } = await this.client.request(
420
+ 'GET',
421
+ `${CONVERSATION_BASE_PATH}/connectors`,
422
+ )
423
+ return response.data
424
+ }
425
+
426
+ async listSenders(connectionId: string): Promise<EmailSender[]> {
427
+ const response: { data: EmailSender[] } = await this.client.request(
428
+ 'GET',
429
+ `${CONVERSATION_BASE_PATH}/connections/${encodeURIComponent(connectionId)}/senders`,
430
+ )
431
+ return response.data
432
+ }
433
+
434
+ async setDefaultSender(
435
+ connectionId: string,
436
+ request: SetDefaultSenderRequest,
437
+ ): Promise<EmailSender[]> {
438
+ const response: { data: EmailSender[] } = await this.client.request(
439
+ 'PUT',
440
+ `${CONVERSATION_BASE_PATH}/connections/${encodeURIComponent(connectionId)}/senders/default`,
441
+ request,
442
+ )
443
+ return response.data
444
+ }
296
445
  }
297
446
 
298
447
  /** The person-level identity layer: contacts, addresses, merges, permissions, erasure. */
299
448
  export interface ContactService {
300
449
  list(query?: ListContactsQuery): Promise<ListResponse<Contact>>
301
450
  get(id: string): Promise<Contact>
302
- /** Manually mint a contact (sync dedup — 409 contact_address_taken on any owned address). */
451
+ /**
452
+ * Manually mint a contact (sync dedup — 409 contact_address_taken on any
453
+ * owned address), or with `platform_user_id` ensure a colleague's bound
454
+ * contact and attach the addresses to it.
455
+ */
303
456
  create(request: CreateContactRequest): Promise<Contact>
304
457
  update(id: string, request: UpdateContactRequest): Promise<Contact>
305
458
  attachAddress(contactId: string, request: AttachContactAddressRequest): Promise<Contact>
@@ -369,7 +522,9 @@ class ContactServiceImpl implements ContactService {
369
522
  return this.client.request('POST', `${CONVERSATION_BASE_PATH}/contact-record-links`, request)
370
523
  }
371
524
 
372
- listRecordLinks(query: ListContactRecordLinksQuery = {}): Promise<ListResponse<ContactRecordLink>> {
525
+ listRecordLinks(
526
+ query: ListContactRecordLinksQuery = {},
527
+ ): Promise<ListResponse<ContactRecordLink>> {
373
528
  return this.client.requestWithQuery(
374
529
  'GET',
375
530
  `${CONVERSATION_BASE_PATH}/contact-record-links`,
@@ -549,6 +704,12 @@ export interface MessageService {
549
704
  /** One message with its read-time projections (reactions, attachments). */
550
705
  get(messageId: string): Promise<Message>
551
706
  send(request: SendMessageRequest): Promise<Message>
707
+ /**
708
+ * Dry-run of the sending gate: same addressing as send, no content, nothing
709
+ * minted. Answers whether the send may go out now and, when held, the
710
+ * earliest instant it may (`earliest_allowed_at`).
711
+ */
712
+ checkSendEligibility(request: SendEligibilityRequest): Promise<SendEligibility>
552
713
  /**
553
714
  * Store an outbound message for human review (status=draft) — same request
554
715
  * shape as send, nothing reaches the connector until sendDraft. Originate
@@ -600,6 +761,14 @@ class MessageServiceImpl implements MessageService {
600
761
  return this.client.request('POST', `${CONVERSATION_BASE_PATH}/messages/send`, request)
601
762
  }
602
763
 
764
+ checkSendEligibility(request: SendEligibilityRequest): Promise<SendEligibility> {
765
+ return this.client.request(
766
+ 'POST',
767
+ `${CONVERSATION_BASE_PATH}/messages/send-eligibility`,
768
+ request,
769
+ )
770
+ }
771
+
603
772
  draft(request: SendMessageRequest): Promise<Message> {
604
773
  return this.client.request('POST', `${CONVERSATION_BASE_PATH}/messages/draft`, request)
605
774
  }
@@ -1136,7 +1305,10 @@ export interface CallService {
1136
1305
  request: UpdatePhoneNumberRequest,
1137
1306
  ): Promise<{ data: PhoneNumber[] }>
1138
1307
  /** Point one number at the platform. Returns the refreshed list. */
1139
- connectPhoneNumber(connectionId: string, numberExternalId: string): Promise<{ data: PhoneNumber[] }>
1308
+ connectPhoneNumber(
1309
+ connectionId: string,
1310
+ numberExternalId: string,
1311
+ ): Promise<{ data: PhoneNumber[] }>
1140
1312
  /** Release one number (restores its previous handler). Returns the refreshed list. */
1141
1313
  disconnectPhoneNumber(
1142
1314
  connectionId: string,
@@ -1199,3 +1371,238 @@ export type {
1199
1371
  VoiceService,
1200
1372
  VoiceTranscriptionStream,
1201
1373
  } from './voice.js'
1374
+
1375
+ /**
1376
+ * Conversation briefs — guidance prepared ahead of a conversation ("talk to
1377
+ * these people about this"; the conversation sibling of message drafts).
1378
+ * Binding is explicit: the softphone carries the brief id into the call, or
1379
+ * `attach` names the conversation. Any number of briefs may be open for the
1380
+ * same people. Edits/attach on a non-open brief fail 409
1381
+ * `conversation_brief_not_editable`; a conversation already carrying a brief
1382
+ * refuses another (409 `conversation_brief_already_attached`).
1383
+ */
1384
+ export interface ConversationBriefService {
1385
+ list(query?: ListConversationBriefsQuery): Promise<ListResponse<ConversationBrief>>
1386
+ get(id: string): Promise<ConversationBrief>
1387
+ create(request: CreateConversationBriefRequest): Promise<ConversationBrief>
1388
+ update(id: string, request: UpdateConversationBriefRequest): Promise<ConversationBrief>
1389
+ /** Decline an open brief (prepared → discarded, terminal). */
1390
+ discard(id: string): Promise<ConversationBrief>
1391
+ /** Bind an open brief to a conversation explicitly (prepared → used). */
1392
+ attach(id: string, request: AttachConversationBriefRequest): Promise<ConversationBrief>
1393
+ delete(id: string): Promise<void>
1394
+ }
1395
+
1396
+ class ConversationBriefServiceImpl implements ConversationBriefService {
1397
+ constructor(private readonly client: ProteosClient) {}
1398
+
1399
+ list(query: ListConversationBriefsQuery = {}): Promise<ListResponse<ConversationBrief>> {
1400
+ return this.client.requestWithQuery(
1401
+ 'GET',
1402
+ `${CONVERSATION_BASE_PATH}/conversation-briefs`,
1403
+ query,
1404
+ )
1405
+ }
1406
+
1407
+ get(id: string): Promise<ConversationBrief> {
1408
+ return this.client.request(
1409
+ 'GET',
1410
+ `${CONVERSATION_BASE_PATH}/conversation-briefs/${encodeURIComponent(id)}`,
1411
+ )
1412
+ }
1413
+
1414
+ create(request: CreateConversationBriefRequest): Promise<ConversationBrief> {
1415
+ return this.client.request('POST', `${CONVERSATION_BASE_PATH}/conversation-briefs`, request)
1416
+ }
1417
+
1418
+ update(id: string, request: UpdateConversationBriefRequest): Promise<ConversationBrief> {
1419
+ return this.client.request(
1420
+ 'PATCH',
1421
+ `${CONVERSATION_BASE_PATH}/conversation-briefs/${encodeURIComponent(id)}`,
1422
+ request,
1423
+ )
1424
+ }
1425
+
1426
+ discard(id: string): Promise<ConversationBrief> {
1427
+ return this.client.request(
1428
+ 'POST',
1429
+ `${CONVERSATION_BASE_PATH}/conversation-briefs/${encodeURIComponent(id)}/discard`,
1430
+ )
1431
+ }
1432
+
1433
+ attach(id: string, request: AttachConversationBriefRequest): Promise<ConversationBrief> {
1434
+ return this.client.request(
1435
+ 'POST',
1436
+ `${CONVERSATION_BASE_PATH}/conversation-briefs/${encodeURIComponent(id)}/attach`,
1437
+ request,
1438
+ )
1439
+ }
1440
+
1441
+ async delete(id: string): Promise<void> {
1442
+ await this.client.request(
1443
+ 'DELETE',
1444
+ `${CONVERSATION_BASE_PATH}/conversation-briefs/${encodeURIComponent(id)}`,
1445
+ )
1446
+ }
1447
+ }
1448
+
1449
+ /**
1450
+ * Sending rules — outbound send constraints (windows, connection limits,
1451
+ * frequency caps), the static limit-preset catalog and its apply expansion.
1452
+ * A denied send/reply/sendDraft fails with a ProteosError whose `details`
1453
+ * carry `earliest_allowed_at` (429) or the blocked contact (403).
1454
+ */
1455
+ export interface SendingRuleService {
1456
+ list(query?: ListSendingRulesQuery): Promise<ListResponse<SendingRule>>
1457
+ get(id: string): Promise<SendingRule>
1458
+ create(request: CreateSendingRuleRequest): Promise<SendingRule>
1459
+ update(id: string, request: UpdateSendingRuleRequest): Promise<SendingRule>
1460
+ delete(id: string): Promise<void>
1461
+ /** The static preset catalog, optionally narrowed to one connector. */
1462
+ listPresets(query?: ListSendingLimitPresetsQuery): Promise<{ data: SendingLimitPreset[] }>
1463
+ /**
1464
+ * Expand a preset into limit rules linked to the given connections,
1465
+ * replacing the limit rules they were linked to before.
1466
+ */
1467
+ applyPreset(request: ApplySendingLimitPresetRequest): Promise<{ data: SendingRule[] }>
1468
+ }
1469
+
1470
+ class SendingRuleServiceImpl implements SendingRuleService {
1471
+ constructor(private readonly client: ProteosClient) {}
1472
+
1473
+ list(query: ListSendingRulesQuery = {}): Promise<ListResponse<SendingRule>> {
1474
+ return this.client.requestWithQuery('GET', `${CONVERSATION_BASE_PATH}/sending-rules`, query)
1475
+ }
1476
+
1477
+ get(id: string): Promise<SendingRule> {
1478
+ return this.client.request(
1479
+ 'GET',
1480
+ `${CONVERSATION_BASE_PATH}/sending-rules/${encodeURIComponent(id)}`,
1481
+ )
1482
+ }
1483
+
1484
+ create(request: CreateSendingRuleRequest): Promise<SendingRule> {
1485
+ return this.client.request('POST', `${CONVERSATION_BASE_PATH}/sending-rules`, request)
1486
+ }
1487
+
1488
+ update(id: string, request: UpdateSendingRuleRequest): Promise<SendingRule> {
1489
+ return this.client.request(
1490
+ 'PATCH',
1491
+ `${CONVERSATION_BASE_PATH}/sending-rules/${encodeURIComponent(id)}`,
1492
+ request,
1493
+ )
1494
+ }
1495
+
1496
+ async delete(id: string): Promise<void> {
1497
+ await this.client.request(
1498
+ 'DELETE',
1499
+ `${CONVERSATION_BASE_PATH}/sending-rules/${encodeURIComponent(id)}`,
1500
+ )
1501
+ }
1502
+
1503
+ listPresets(query: ListSendingLimitPresetsQuery = {}): Promise<{ data: SendingLimitPreset[] }> {
1504
+ return this.client.requestWithQuery(
1505
+ 'GET',
1506
+ `${CONVERSATION_BASE_PATH}/sending-rules/presets`,
1507
+ query,
1508
+ )
1509
+ }
1510
+
1511
+ applyPreset(request: ApplySendingLimitPresetRequest): Promise<{ data: SendingRule[] }> {
1512
+ return this.client.request(
1513
+ 'POST',
1514
+ `${CONVERSATION_BASE_PATH}/sending-rules/apply-preset`,
1515
+ request,
1516
+ )
1517
+ }
1518
+ }
1519
+
1520
+ /**
1521
+ * Channel actions — the ledger of acts performed through a connection that
1522
+ * are neither a message nor a reaction (LinkedIn invitations, profile visits,
1523
+ * InMail). A denied perform fails like a denied send (ProteosError with
1524
+ * `details.earliest_allowed_at`); a provider refusal carries its own code
1525
+ * (already_connected, already_invited_recently, invitation_already_received,
1526
+ * connection_limit_reached, insufficient_inmail_credits, inmail_not_allowed,
1527
+ * not_connected_with_recipient). An invitation is pre-flighted with one silent
1528
+ * profile read before anything is sent, so those refusals never mint a
1529
+ * phantom act.
1530
+ */
1531
+ export interface ChannelActionService {
1532
+ list(query?: ListChannelActionsQuery): Promise<ListResponse<ChannelAction>>
1533
+ get(id: string): Promise<ChannelAction>
1534
+ /** Performs one act; resolves to the row in its post-perform status. */
1535
+ perform(request: PerformChannelActionRequest): Promise<ChannelAction>
1536
+ /** Withdraws a performed outbound act (an invitation). */
1537
+ cancel(id: string): Promise<ChannelAction>
1538
+ /** Answers an inbound act (a received invitation). */
1539
+ respond(id: string, request: RespondChannelActionRequest): Promise<ChannelAction>
1540
+ }
1541
+
1542
+ class ChannelActionServiceImpl implements ChannelActionService {
1543
+ constructor(private readonly client: ProteosClient) {}
1544
+
1545
+ list(query: ListChannelActionsQuery = {}): Promise<ListResponse<ChannelAction>> {
1546
+ return this.client.requestWithQuery('GET', `${CONVERSATION_BASE_PATH}/channel-actions`, query)
1547
+ }
1548
+
1549
+ get(id: string): Promise<ChannelAction> {
1550
+ return this.client.request(
1551
+ 'GET',
1552
+ `${CONVERSATION_BASE_PATH}/channel-actions/${encodeURIComponent(id)}`,
1553
+ )
1554
+ }
1555
+
1556
+ perform(request: PerformChannelActionRequest): Promise<ChannelAction> {
1557
+ return this.client.request('POST', `${CONVERSATION_BASE_PATH}/channel-actions`, request)
1558
+ }
1559
+
1560
+ cancel(id: string): Promise<ChannelAction> {
1561
+ return this.client.request(
1562
+ 'POST',
1563
+ `${CONVERSATION_BASE_PATH}/channel-actions/${encodeURIComponent(id)}/cancel`,
1564
+ )
1565
+ }
1566
+
1567
+ respond(id: string, request: RespondChannelActionRequest): Promise<ChannelAction> {
1568
+ return this.client.request(
1569
+ 'POST',
1570
+ `${CONVERSATION_BASE_PATH}/channel-actions/${encodeURIComponent(id)}/respond`,
1571
+ request,
1572
+ )
1573
+ }
1574
+ }
1575
+
1576
+ /**
1577
+ * The channel_event ledger — provider-observed delivery / engagement events
1578
+ * about outbound messages (delivered, bounced, opened, clicked,
1579
+ * spam_reported, unsubscribed, …). Read-only: rows are appended by webhook
1580
+ * ingest. `listByMessage` is the per-message history, oldest first.
1581
+ */
1582
+ export interface ChannelEventService {
1583
+ list(query?: ListChannelEventsQuery): Promise<ListResponse<ChannelEvent>>
1584
+ get(id: string): Promise<ChannelEvent>
1585
+ listByMessage(messageId: string): Promise<ListResponse<ChannelEvent>>
1586
+ }
1587
+
1588
+ class ChannelEventServiceImpl implements ChannelEventService {
1589
+ constructor(private readonly client: ProteosClient) {}
1590
+
1591
+ list(query: ListChannelEventsQuery = {}): Promise<ListResponse<ChannelEvent>> {
1592
+ return this.client.requestWithQuery('GET', `${CONVERSATION_BASE_PATH}/channel-events`, query)
1593
+ }
1594
+
1595
+ get(id: string): Promise<ChannelEvent> {
1596
+ return this.client.request(
1597
+ 'GET',
1598
+ `${CONVERSATION_BASE_PATH}/channel-events/${encodeURIComponent(id)}`,
1599
+ )
1600
+ }
1601
+
1602
+ listByMessage(messageId: string): Promise<ListResponse<ChannelEvent>> {
1603
+ return this.client.request(
1604
+ 'GET',
1605
+ `${CONVERSATION_BASE_PATH}/messages/${encodeURIComponent(messageId)}/events`,
1606
+ )
1607
+ }
1608
+ }