@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.
- package/dist/{chunk-TDG5QFZ5.js → chunk-IRFFXJMB.js} +66 -4
- package/dist/chunk-IRFFXJMB.js.map +1 -0
- package/dist/{chunk-OD7GPJAW.cjs → chunk-RKFXHDVU.cjs} +67 -3
- package/dist/chunk-RKFXHDVU.cjs.map +1 -0
- package/dist/index.cjs +456 -98
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1036 -9
- package/dist/index.d.ts +1036 -9
- package/dist/index.js +353 -5
- package/dist/index.js.map +1 -1
- package/dist/meta/index.cjs +65 -57
- package/dist/meta/index.d.cts +1 -1
- package/dist/meta/index.d.ts +1 -1
- package/dist/meta/index.js +1 -1
- package/dist/{types-COxVBT4w.d.cts → types-C9flkAj-.d.cts} +208 -7
- package/dist/{types-COxVBT4w.d.ts → types-C9flkAj-.d.ts} +208 -7
- package/package.json +1 -1
- package/src/auth/index.ts +40 -11
- package/src/auth/me.ts +13 -1
- package/src/auth/platform-entities.ts +17 -0
- package/src/auth/profiles.ts +82 -0
- package/src/auth/types.ts +87 -0
- package/src/auth/user-profile-assignments.ts +41 -0
- package/src/auth/users.ts +37 -0
- package/src/conversation/index.ts +417 -10
- package/src/conversation/types.ts +731 -3
- package/src/errors.ts +20 -3
- package/src/index.ts +104 -17
- package/src/meta/app-configurations.ts +100 -0
- package/src/meta/index.ts +28 -10
- package/src/meta/types.ts +94 -4
- package/src/workflow/types.ts +13 -0
- package/dist/chunk-OD7GPJAW.cjs.map +0 -1
- package/dist/chunk-TDG5QFZ5.js.map +0 -1
|
@@ -56,6 +56,7 @@ export type ConnectorKey =
|
|
|
56
56
|
| 'twilio-phone'
|
|
57
57
|
| 'aircall'
|
|
58
58
|
| 'webhook-cti'
|
|
59
|
+
| 'sendgrid'
|
|
59
60
|
|
|
60
61
|
/**
|
|
61
62
|
* Telephony lifecycle of one phone call, carried in the call conversation's
|
|
@@ -290,6 +291,14 @@ export interface Connection {
|
|
|
290
291
|
supports_reactions: boolean
|
|
291
292
|
/** The capability descriptor; absent when unsupported. */
|
|
292
293
|
reactions?: ReactionCapability
|
|
294
|
+
/**
|
|
295
|
+
* Computed on read like reactions: the channel actions the connector
|
|
296
|
+
* performs through this connection (invitation, profile_visit, inmail, …).
|
|
297
|
+
* A separate list from reactions — a reaction toggles an edge on a
|
|
298
|
+
* message, an action is a performed act with its own lifecycle. Absent
|
|
299
|
+
* when the connector performs none.
|
|
300
|
+
*/
|
|
301
|
+
actions?: ChannelActionCapability[]
|
|
293
302
|
/**
|
|
294
303
|
* Computed on read like supports_reactions: who operates the integration
|
|
295
304
|
* (native | unipile). Absent when the connector is not registered in this
|
|
@@ -457,6 +466,12 @@ export interface Message {
|
|
|
457
466
|
*/
|
|
458
467
|
child_conversation_id?: string
|
|
459
468
|
child_messages_total?: number
|
|
469
|
+
/**
|
|
470
|
+
* Provider-side outcome + engagement projection of an OUTBOUND message on
|
|
471
|
+
* a sending platform (folded from the channel_event ledger); absent on
|
|
472
|
+
* channels that report nothing and on inbound rows.
|
|
473
|
+
*/
|
|
474
|
+
delivery?: MessageDelivery
|
|
460
475
|
metadata: Record<string, unknown>
|
|
461
476
|
error: string
|
|
462
477
|
created_at: string
|
|
@@ -465,6 +480,31 @@ export interface Message {
|
|
|
465
480
|
updated_by: UserRef
|
|
466
481
|
}
|
|
467
482
|
|
|
483
|
+
/**
|
|
484
|
+
* Provider-side outcome of an outbound message — a separate axis from
|
|
485
|
+
* MessageStatus (the message stays `sent` at the platform level once the
|
|
486
|
+
* provider accepted it): sent → delivered | deferred | bounced | dropped.
|
|
487
|
+
*/
|
|
488
|
+
export type MessageDeliveryStatus = 'sent' | 'delivered' | 'deferred' | 'bounced' | 'dropped'
|
|
489
|
+
|
|
490
|
+
/** The read-side fold of a message's channel events. */
|
|
491
|
+
export interface MessageDelivery {
|
|
492
|
+
status: MessageDeliveryStatus
|
|
493
|
+
delivered_at?: string
|
|
494
|
+
bounced_at?: string
|
|
495
|
+
dropped_at?: string
|
|
496
|
+
/** First HUMAN open / click; totals count every event (machine opens excluded). */
|
|
497
|
+
opened_at?: string
|
|
498
|
+
opens_total?: number
|
|
499
|
+
clicked_at?: string
|
|
500
|
+
clicks_total?: number
|
|
501
|
+
spam_reported_at?: string
|
|
502
|
+
unsubscribed_at?: string
|
|
503
|
+
/** Latest bounce / drop / deferral text. */
|
|
504
|
+
reason?: string
|
|
505
|
+
last_event_at?: string
|
|
506
|
+
}
|
|
507
|
+
|
|
468
508
|
/**
|
|
469
509
|
* Per-trigger configuration, discriminated by the sibling trigger_type: channel
|
|
470
510
|
* carries external_channel_id, keyword carries phrases, always/mention carry
|
|
@@ -623,6 +663,15 @@ export interface SendMessageRequest {
|
|
|
623
663
|
* `unsupported_content`.
|
|
624
664
|
*/
|
|
625
665
|
attachments?: FileRef[]
|
|
666
|
+
/**
|
|
667
|
+
* Overrides the sending identity on a sending-platform email connection: a
|
|
668
|
+
* contact address id on the connection's sender domain
|
|
669
|
+
* (`connections.listSenders`). Without it: the conversation's pinned sender
|
|
670
|
+
* → the acting user's own address on the domain → the connection's default.
|
|
671
|
+
* Off-domain ids fail with `sender_not_found`; connections without a sender
|
|
672
|
+
* domain refuse it with `sender_domain_not_available`.
|
|
673
|
+
*/
|
|
674
|
+
sender_address_id?: string
|
|
626
675
|
}
|
|
627
676
|
|
|
628
677
|
/**
|
|
@@ -991,6 +1040,8 @@ export interface ListConversationsQuery extends PaginationQuery {
|
|
|
991
1040
|
/** Threads whose roster contains this external party — the person stream. */
|
|
992
1041
|
/** Contact stream: threads whose roster contains the resolved person. */
|
|
993
1042
|
contact_id?: string
|
|
1043
|
+
/** "Sent as" stream: threads pinned to one sending identity (a contact address id). */
|
|
1044
|
+
sender_address_id?: string
|
|
994
1045
|
/** Opt into the root/latest message projection on each row. */
|
|
995
1046
|
include?: 'messages_summary'
|
|
996
1047
|
}
|
|
@@ -1189,7 +1240,19 @@ export type ContactSource = 'sync' | 'ingest' | 'manual' | 'merge'
|
|
|
1189
1240
|
export type ContactStatus = 'active' | 'merged' | 'archived' | 'erased'
|
|
1190
1241
|
export type ConsentStatus = 'unknown' | 'opted_in' | 'opted_out'
|
|
1191
1242
|
export type PermissionEventType = 'opt_in' | 'opt_out' | 'block' | 'unblock'
|
|
1192
|
-
|
|
1243
|
+
/**
|
|
1244
|
+
* Where a permission event came from. `provider` = the sending platform
|
|
1245
|
+
* observed it (its unsubscribe link, a spam complaint relayed by the mailbox
|
|
1246
|
+
* provider, a hard bounce); `link_click` stays for OUR unsubscribe links.
|
|
1247
|
+
*/
|
|
1248
|
+
export type PermissionEventSource =
|
|
1249
|
+
| 'manual'
|
|
1250
|
+
| 'import'
|
|
1251
|
+
| 'link_click'
|
|
1252
|
+
| 'reply'
|
|
1253
|
+
| 'api'
|
|
1254
|
+
| 'system'
|
|
1255
|
+
| 'provider'
|
|
1193
1256
|
export type MergeProposalStatus = 'proposed' | 'approved' | 'rejected' | 'superseded'
|
|
1194
1257
|
export type ErasureRequestStatus = 'requested' | 'completed'
|
|
1195
1258
|
export type RoomSource = 'sync' | 'ingest'
|
|
@@ -1220,6 +1283,14 @@ export interface Contact {
|
|
|
1220
1283
|
/** Merge tombstone redirect (set when status is 'merged'). */
|
|
1221
1284
|
merged_into_contact_id?: string
|
|
1222
1285
|
source: ContactSource
|
|
1286
|
+
/** IANA zone name (Europe/Berlin); absent = unknown. Filled from directory sweeps while empty. */
|
|
1287
|
+
timezone?: string
|
|
1288
|
+
/**
|
|
1289
|
+
* BCP-47 language tag with optional region (de, de-CH, pt-BR); absent =
|
|
1290
|
+
* unknown. Named locale, not language: the region carries formatting
|
|
1291
|
+
* conventions on top of the language.
|
|
1292
|
+
*/
|
|
1293
|
+
locale?: string
|
|
1223
1294
|
/** ContactGroup membership (one group per contact); absent = unassigned. */
|
|
1224
1295
|
group_key?: string
|
|
1225
1296
|
/**
|
|
@@ -1341,12 +1412,22 @@ export interface ListContactsQuery extends PaginationQuery {
|
|
|
1341
1412
|
status?: ContactStatus
|
|
1342
1413
|
/** Members of one contact group (drives group-member lists). */
|
|
1343
1414
|
group_key?: string
|
|
1415
|
+
/**
|
|
1416
|
+
* The contact bound to one platform user (at most one active contact per
|
|
1417
|
+
* user per org); `'me'` resolves to the caller — a client's way to its own
|
|
1418
|
+
* contact.
|
|
1419
|
+
*/
|
|
1420
|
+
platform_user_id?: string
|
|
1344
1421
|
}
|
|
1345
1422
|
|
|
1346
1423
|
export interface UpdateContactRequest {
|
|
1347
1424
|
name?: string
|
|
1348
1425
|
status?: 'active' | 'archived'
|
|
1349
1426
|
has_legal_hold?: boolean
|
|
1427
|
+
/** IANA zone name; normalized server-side, 400 contact_timezone_invalid when unparseable; '' clears. */
|
|
1428
|
+
timezone?: string
|
|
1429
|
+
/** BCP-47 language tag; normalized server-side, 400 contact_locale_invalid when unparseable; '' clears. */
|
|
1430
|
+
locale?: string
|
|
1350
1431
|
/**
|
|
1351
1432
|
* Assigns the contact to a contact group ('' clears). A PATCH assignment is
|
|
1352
1433
|
* stamped group_source='manual' — tone synthesis never overrides it.
|
|
@@ -1360,8 +1441,22 @@ export interface UpdateContactRequest {
|
|
|
1360
1441
|
* rejects the create with 409 contact_address_taken.
|
|
1361
1442
|
*/
|
|
1362
1443
|
export interface CreateContactRequest {
|
|
1363
|
-
name
|
|
1364
|
-
|
|
1444
|
+
/** Required without platform_user_id; with it, fills an empty name only. */
|
|
1445
|
+
name?: string
|
|
1446
|
+
/** Required (≥1) without platform_user_id; with it, attached to the colleague's contact. */
|
|
1447
|
+
addresses?: AttachContactAddressRequest[]
|
|
1448
|
+
/**
|
|
1449
|
+
* Colleague mode: ensure the contact bound to this platform user (created
|
|
1450
|
+
* from the account directory, or the existing one — every colleague has
|
|
1451
|
+
* exactly one) and attach the addresses to it. 200 when it already
|
|
1452
|
+
* existed, 201 when created; 404 `platform_user_not_found`, 409
|
|
1453
|
+
* `contact_platform_user_conflict`.
|
|
1454
|
+
*/
|
|
1455
|
+
platform_user_id?: string
|
|
1456
|
+
/** IANA zone name; optional, validated as on update. */
|
|
1457
|
+
timezone?: string
|
|
1458
|
+
/** BCP-47 language tag; optional, validated as on update. */
|
|
1459
|
+
locale?: string
|
|
1365
1460
|
}
|
|
1366
1461
|
|
|
1367
1462
|
export interface AttachContactAddressRequest {
|
|
@@ -1610,3 +1705,636 @@ export interface DispatchMeetingBotRequest {
|
|
|
1610
1705
|
*/
|
|
1611
1706
|
language?: string
|
|
1612
1707
|
}
|
|
1708
|
+
|
|
1709
|
+
// ── Sending rules ─────────────────────────────────────────────────────────────
|
|
1710
|
+
|
|
1711
|
+
/**
|
|
1712
|
+
* Discriminates a sending rule: window (WHEN sending is allowed, recipient-
|
|
1713
|
+
* local weekday ranges), limit (HOW MUCH one connection may send per rolling
|
|
1714
|
+
* period), frequency_cap (HOW OFTEN one contact may be contacted per rolling
|
|
1715
|
+
* period).
|
|
1716
|
+
*/
|
|
1717
|
+
export type SendingRuleType = 'window' | 'limit' | 'frequency_cap' | 'warmup'
|
|
1718
|
+
/** Rolling lookback ("last 24 hours from now") — never a calendar day. */
|
|
1719
|
+
export type SendingPeriod = 'rolling_24h' | 'rolling_7d' | 'rolling_30d'
|
|
1720
|
+
/**
|
|
1721
|
+
* ONE kind of act performed through a channel connection — shared by a
|
|
1722
|
+
* limit's `action` (what it counts), a channel action's `action_type` (what
|
|
1723
|
+
* was performed) and the eligibility check. `message` is the plain send
|
|
1724
|
+
* (valid on a limit, never on a channel action row).
|
|
1725
|
+
*/
|
|
1726
|
+
export type ChannelActionType = 'message' | 'invitation' | 'inmail' | 'profile_visit'
|
|
1727
|
+
export type Weekday =
|
|
1728
|
+
| 'monday'
|
|
1729
|
+
| 'tuesday'
|
|
1730
|
+
| 'wednesday'
|
|
1731
|
+
| 'thursday'
|
|
1732
|
+
| 'friday'
|
|
1733
|
+
| 'saturday'
|
|
1734
|
+
| 'sunday'
|
|
1735
|
+
|
|
1736
|
+
/** One open range on one weekday, "HH:MM" wall-clock, from < until, same day. */
|
|
1737
|
+
export interface WindowDay {
|
|
1738
|
+
day: Weekday
|
|
1739
|
+
from: string
|
|
1740
|
+
until: string
|
|
1741
|
+
}
|
|
1742
|
+
export interface WindowRuleConfig {
|
|
1743
|
+
days: WindowDay[]
|
|
1744
|
+
/** IANA zone used for contacts without a timezone. */
|
|
1745
|
+
fallback_timezone: string
|
|
1746
|
+
}
|
|
1747
|
+
export interface LimitRuleConfig {
|
|
1748
|
+
action: ChannelActionType
|
|
1749
|
+
max_count: number
|
|
1750
|
+
period: SendingPeriod
|
|
1751
|
+
/** Minimum spacing between consecutive sends; 0/absent = none. */
|
|
1752
|
+
min_gap_seconds?: number
|
|
1753
|
+
}
|
|
1754
|
+
export interface FrequencyCapRuleConfig {
|
|
1755
|
+
max_count: number
|
|
1756
|
+
period: SendingPeriod
|
|
1757
|
+
}
|
|
1758
|
+
/**
|
|
1759
|
+
* A limit that RAMPS: `start_count` acts of `action` per rolling `period` on
|
|
1760
|
+
* the day the warmup started, growing by `daily_increase` (a count, or a
|
|
1761
|
+
* percent of the previous day's allowance when `is_increase_percent`) every
|
|
1762
|
+
* UTC calendar day until `max_count`, after which it behaves as a plain
|
|
1763
|
+
* limit. `started_at` may be omitted on create — the server stamps now.
|
|
1764
|
+
*/
|
|
1765
|
+
export interface WarmupRuleConfig {
|
|
1766
|
+
action: ChannelActionType
|
|
1767
|
+
start_count: number
|
|
1768
|
+
daily_increase: number
|
|
1769
|
+
is_increase_percent?: boolean
|
|
1770
|
+
max_count: number
|
|
1771
|
+
period: SendingPeriod
|
|
1772
|
+
started_at: string
|
|
1773
|
+
}
|
|
1774
|
+
export type SendingRuleConfig =
|
|
1775
|
+
| WindowRuleConfig
|
|
1776
|
+
| LimitRuleConfig
|
|
1777
|
+
| FrequencyCapRuleConfig
|
|
1778
|
+
| WarmupRuleConfig
|
|
1779
|
+
|
|
1780
|
+
/**
|
|
1781
|
+
* One outbound send constraint, defined once and LINKED to any number of
|
|
1782
|
+
* connections and/or channels (both empty = org-wide). Per rule type the most
|
|
1783
|
+
* specific tier wins at send time: names the connection > names the channel >
|
|
1784
|
+
* org-wide. Replies skip the rule when `is_reply_exempt`.
|
|
1785
|
+
*/
|
|
1786
|
+
// ── Conversation briefs ──────────────────────────────────────────────────────────────
|
|
1787
|
+
|
|
1788
|
+
/**
|
|
1789
|
+
* Lifecycle of a conversation brief: `prepared` (open — editable, waiting for its
|
|
1790
|
+
* call), `used` (attached to a call conversation; terminal), `discarded`
|
|
1791
|
+
* (declined without a call; terminal).
|
|
1792
|
+
*/
|
|
1793
|
+
export type ConversationBriefStatus = 'prepared' | 'used' | 'discarded'
|
|
1794
|
+
|
|
1795
|
+
/**
|
|
1796
|
+
* Guidance prepared AHEAD of a conversation — "talk to these people about
|
|
1797
|
+
* this" — the conversation sibling of a draft message. Binding to a
|
|
1798
|
+
* conversation is always explicit: the softphone carries the brief id into
|
|
1799
|
+
* the call (attached at call start), or `attach` names the conversation.
|
|
1800
|
+
* Nothing matches by contact or number, and any number of briefs may be open
|
|
1801
|
+
* for the same people at once. Records that want a brief (an activity) store
|
|
1802
|
+
* its id; every UI surface renders from the id.
|
|
1803
|
+
*/
|
|
1804
|
+
export interface ConversationBrief {
|
|
1805
|
+
id: string
|
|
1806
|
+
org_id: string
|
|
1807
|
+
/** Human label ("Renewal call with Dana"); may be empty. */
|
|
1808
|
+
subject: string
|
|
1809
|
+
/** The people the conversation is with (≥ 1, deduplicated, sorted). */
|
|
1810
|
+
contact_ids: string[]
|
|
1811
|
+
/** How the conversation should happen (phone opens the softphone); absent = unspecified. */
|
|
1812
|
+
channel?: Channel
|
|
1813
|
+
/** ConversationType key the conversation is meant to be; stamped on attach. */
|
|
1814
|
+
type_key?: string
|
|
1815
|
+
/** The conversation the brief was used on; absent until used. */
|
|
1816
|
+
conversation_id?: string
|
|
1817
|
+
status: ConversationBriefStatus
|
|
1818
|
+
/** Guidance text (markdown allowed). */
|
|
1819
|
+
content: string
|
|
1820
|
+
used_at?: string
|
|
1821
|
+
created_at: string
|
|
1822
|
+
created_by: UserRef
|
|
1823
|
+
updated_at: string
|
|
1824
|
+
updated_by: UserRef
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
export interface CreateConversationBriefRequest {
|
|
1828
|
+
subject?: string
|
|
1829
|
+
/** The people the conversation is with (≥ 1). */
|
|
1830
|
+
contact_ids: string[]
|
|
1831
|
+
/** Must be a known channel when set. */
|
|
1832
|
+
channel?: Channel
|
|
1833
|
+
/** Must name an existing conversation type when set. */
|
|
1834
|
+
type_key?: string
|
|
1835
|
+
content: string
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
/** PATCH semantics — absent fields keep their value. Only open briefs. */
|
|
1839
|
+
export interface UpdateConversationBriefRequest {
|
|
1840
|
+
subject?: string
|
|
1841
|
+
/** Replaces the set wholesale. */
|
|
1842
|
+
contact_ids?: string[]
|
|
1843
|
+
/** Empty string clears the channel. */
|
|
1844
|
+
channel?: Channel | ''
|
|
1845
|
+
content?: string
|
|
1846
|
+
type_key?: string
|
|
1847
|
+
}
|
|
1848
|
+
|
|
1849
|
+
/** Binds an open brief to a conversation explicitly. */
|
|
1850
|
+
export interface AttachConversationBriefRequest {
|
|
1851
|
+
conversation_id: string
|
|
1852
|
+
}
|
|
1853
|
+
|
|
1854
|
+
export interface ListConversationBriefsQuery extends PaginationQuery {
|
|
1855
|
+
/** Briefs naming this person. */
|
|
1856
|
+
contact_id?: string
|
|
1857
|
+
conversation_id?: string
|
|
1858
|
+
channel?: Channel
|
|
1859
|
+
type_key?: string
|
|
1860
|
+
status?: ConversationBriefStatus
|
|
1861
|
+
sort_by?: string
|
|
1862
|
+
sort?: 'asc' | 'desc'
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
export interface SendingRule {
|
|
1866
|
+
id: string
|
|
1867
|
+
org_id: string
|
|
1868
|
+
name: string
|
|
1869
|
+
connection_ids: string[]
|
|
1870
|
+
channels: Channel[]
|
|
1871
|
+
rule_type: SendingRuleType
|
|
1872
|
+
rule_config?: SendingRuleConfig
|
|
1873
|
+
is_enabled: boolean
|
|
1874
|
+
is_reply_exempt: boolean
|
|
1875
|
+
created_at: string
|
|
1876
|
+
created_by: UserRef
|
|
1877
|
+
updated_at: string
|
|
1878
|
+
updated_by: UserRef
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1881
|
+
export interface CreateSendingRuleRequest {
|
|
1882
|
+
name?: string
|
|
1883
|
+
connection_ids?: string[]
|
|
1884
|
+
channels?: Channel[]
|
|
1885
|
+
rule_type: SendingRuleType
|
|
1886
|
+
rule_config: Record<string, unknown>
|
|
1887
|
+
/** Defaults to true. */
|
|
1888
|
+
is_enabled?: boolean
|
|
1889
|
+
/** Defaults per type: window + frequency_cap true, limit false. */
|
|
1890
|
+
is_reply_exempt?: boolean
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
export interface UpdateSendingRuleRequest {
|
|
1894
|
+
name?: string
|
|
1895
|
+
/** Replaces the stored links wholesale when present. */
|
|
1896
|
+
connection_ids?: string[]
|
|
1897
|
+
channels?: Channel[]
|
|
1898
|
+
/** rule_type and rule_config must be sent together. */
|
|
1899
|
+
rule_type?: SendingRuleType
|
|
1900
|
+
rule_config?: Record<string, unknown>
|
|
1901
|
+
is_enabled?: boolean
|
|
1902
|
+
is_reply_exempt?: boolean
|
|
1903
|
+
}
|
|
1904
|
+
|
|
1905
|
+
export interface ListSendingRulesQuery extends PaginationQuery {
|
|
1906
|
+
/** Rules LINKED to this connection. */
|
|
1907
|
+
connection_id?: string
|
|
1908
|
+
channel?: Channel
|
|
1909
|
+
rule_type?: SendingRuleType
|
|
1910
|
+
is_enabled?: boolean
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
/** A recommended limit bundle for one class of sender account (static catalog). */
|
|
1914
|
+
export interface SendingLimitPreset {
|
|
1915
|
+
key: string
|
|
1916
|
+
name: string
|
|
1917
|
+
description: string
|
|
1918
|
+
connector_keys: ConnectorKey[]
|
|
1919
|
+
is_recommended: boolean
|
|
1920
|
+
rules: (
|
|
1921
|
+
| { rule_type: 'limit'; rule_config: LimitRuleConfig }
|
|
1922
|
+
| { rule_type: 'warmup'; rule_config: WarmupRuleConfig }
|
|
1923
|
+
)[]
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
export interface ListSendingLimitPresetsQuery {
|
|
1927
|
+
connector_key?: ConnectorKey
|
|
1928
|
+
}
|
|
1929
|
+
|
|
1930
|
+
export interface ApplySendingLimitPresetRequest {
|
|
1931
|
+
connection_ids: string[]
|
|
1932
|
+
preset_key: string
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
/** Dry-run twin of SendMessageRequest: addressing only, nothing minted. */
|
|
1936
|
+
export interface SendEligibilityRequest {
|
|
1937
|
+
conversation_id?: string
|
|
1938
|
+
reply_to_message_id?: string
|
|
1939
|
+
connection_id?: string
|
|
1940
|
+
to?: SendRecipient[]
|
|
1941
|
+
cc?: SendRecipient[]
|
|
1942
|
+
bcc?: SendRecipient[]
|
|
1943
|
+
/**
|
|
1944
|
+
* Widens the check to a channel action (invitation, profile_visit, inmail):
|
|
1945
|
+
* originate mode only, the first `to` recipient is the target. Absent =
|
|
1946
|
+
* message.
|
|
1947
|
+
*/
|
|
1948
|
+
action_type?: ChannelActionType
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
/**
|
|
1952
|
+
* "May this send go out now?" — `reason` is the error code a real send would
|
|
1953
|
+
* fail with (sending_window_closed | sending_limit_reached |
|
|
1954
|
+
* frequency_cap_reached | contact_blocked | contact_opted_out);
|
|
1955
|
+
* `earliest_allowed_at` is set for the temporal three.
|
|
1956
|
+
*/
|
|
1957
|
+
export interface SendEligibility {
|
|
1958
|
+
is_allowed: boolean
|
|
1959
|
+
reason?: string
|
|
1960
|
+
rule_id?: string
|
|
1961
|
+
rule_type?: SendingRuleType
|
|
1962
|
+
earliest_allowed_at?: string
|
|
1963
|
+
contact_id?: string
|
|
1964
|
+
contact_address_id?: string
|
|
1965
|
+
}
|
|
1966
|
+
|
|
1967
|
+
// ── Connector catalog ─────────────────────────────────────────────────────────
|
|
1968
|
+
|
|
1969
|
+
/**
|
|
1970
|
+
* One connector WIRED in this deployment (registry membership decides
|
|
1971
|
+
* availability). `install_modes` lists the install variants the environment
|
|
1972
|
+
* supports for a direct-install connector (a sending platform's own_account /
|
|
1973
|
+
* managed); empty for OAuth / install-free connectors.
|
|
1974
|
+
*/
|
|
1975
|
+
/**
|
|
1976
|
+
* ONE sending identity of a domain-authenticated email connection: an email
|
|
1977
|
+
* contact address on the connection's sender domain. A personal sender belongs
|
|
1978
|
+
* to a colleague's contact (`platform_user` set); a shared mailbox (sales@) to
|
|
1979
|
+
* a role contact without one. Computed from the contact directory on read.
|
|
1980
|
+
*/
|
|
1981
|
+
export interface EmailSender {
|
|
1982
|
+
contact_address_id: string
|
|
1983
|
+
contact_id: string
|
|
1984
|
+
from_email: string
|
|
1985
|
+
from_name: string
|
|
1986
|
+
platform_user?: UserRef
|
|
1987
|
+
/** The connection's fallback sender when neither the thread nor the user pins one. */
|
|
1988
|
+
is_default: boolean
|
|
1989
|
+
}
|
|
1990
|
+
|
|
1991
|
+
/** Pins a connection's default sender (an address on its sender domain). */
|
|
1992
|
+
export interface SetDefaultSenderRequest {
|
|
1993
|
+
contact_address_id: string
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
export interface ConnectorCatalogEntry {
|
|
1997
|
+
key: ConnectorKey
|
|
1998
|
+
channel: Channel
|
|
1999
|
+
provider: ConnectorProvider
|
|
2000
|
+
install_modes: string[]
|
|
2001
|
+
}
|
|
2002
|
+
|
|
2003
|
+
// ── Email deliverability (sending-platform connections) ──────────────────────
|
|
2004
|
+
|
|
2005
|
+
/** One of a sending platform's suppression lists. */
|
|
2006
|
+
export type EmailSuppressionKind =
|
|
2007
|
+
| 'bounces'
|
|
2008
|
+
| 'blocks'
|
|
2009
|
+
| 'spam_reports'
|
|
2010
|
+
| 'invalid_emails'
|
|
2011
|
+
| 'unsubscribes'
|
|
2012
|
+
|
|
2013
|
+
/**
|
|
2014
|
+
* Ledger rollup over the last `days` days: DISTINCT messages per event type
|
|
2015
|
+
* (machine opens excluded). Rates are fractions (0–1): delivery / bounce /
|
|
2016
|
+
* hard-bounce over sent, open / click / spam / unsubscribe over delivered.
|
|
2017
|
+
*/
|
|
2018
|
+
export interface EmailHealthWindow {
|
|
2019
|
+
days: number
|
|
2020
|
+
sent: number
|
|
2021
|
+
delivered: number
|
|
2022
|
+
deferred: number
|
|
2023
|
+
bounced: number
|
|
2024
|
+
hard_bounced: number
|
|
2025
|
+
dropped: number
|
|
2026
|
+
opened: number
|
|
2027
|
+
clicked: number
|
|
2028
|
+
spam_reported: number
|
|
2029
|
+
unsubscribed: number
|
|
2030
|
+
delivery_rate: number
|
|
2031
|
+
bounce_rate: number
|
|
2032
|
+
hard_bounce_rate: number
|
|
2033
|
+
open_rate: number
|
|
2034
|
+
click_rate: number
|
|
2035
|
+
spam_rate: number
|
|
2036
|
+
unsubscribe_rate: number
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
/** The provider's composite sender-quality score (1–5, computed daily). */
|
|
2040
|
+
export interface EmailEngagementQuality {
|
|
2041
|
+
date: string
|
|
2042
|
+
score: number
|
|
2043
|
+
bounce_classification: number
|
|
2044
|
+
bounce_rate: number
|
|
2045
|
+
engagement_recency: number
|
|
2046
|
+
open_rate: number
|
|
2047
|
+
spam_rate: number
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
/** The provider's own counters for this connection's traffic (its category). */
|
|
2051
|
+
export interface EmailProviderStats {
|
|
2052
|
+
days: number
|
|
2053
|
+
requests: number
|
|
2054
|
+
processed: number
|
|
2055
|
+
delivered: number
|
|
2056
|
+
deferred: number
|
|
2057
|
+
bounces: number
|
|
2058
|
+
blocks: number
|
|
2059
|
+
bounce_drops: number
|
|
2060
|
+
invalid_emails: number
|
|
2061
|
+
opens: number
|
|
2062
|
+
unique_opens: number
|
|
2063
|
+
clicks: number
|
|
2064
|
+
unique_clicks: number
|
|
2065
|
+
spam_reports: number
|
|
2066
|
+
spam_report_drops: number
|
|
2067
|
+
unsubscribes: number
|
|
2068
|
+
unsubscribe_drops: number
|
|
2069
|
+
}
|
|
2070
|
+
|
|
2071
|
+
export interface EmailSuppressionCounts {
|
|
2072
|
+
bounces: number
|
|
2073
|
+
blocks: number
|
|
2074
|
+
spam_reports: number
|
|
2075
|
+
invalid_emails: number
|
|
2076
|
+
unsubscribes: number
|
|
2077
|
+
/** A list hit the page cap — the count is a floor. */
|
|
2078
|
+
is_approximate?: boolean
|
|
2079
|
+
}
|
|
2080
|
+
|
|
2081
|
+
export interface EmailDnsRecord {
|
|
2082
|
+
host: string
|
|
2083
|
+
type: string
|
|
2084
|
+
data: string
|
|
2085
|
+
is_valid: boolean
|
|
2086
|
+
reason?: string
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
export interface EmailDomainStatus {
|
|
2090
|
+
domain: string
|
|
2091
|
+
is_valid: boolean
|
|
2092
|
+
dns: EmailDnsRecord[]
|
|
2093
|
+
}
|
|
2094
|
+
|
|
2095
|
+
export interface EmailSenderStatus {
|
|
2096
|
+
from_email: string
|
|
2097
|
+
/** authenticated_domain | single_sender */
|
|
2098
|
+
mode: string
|
|
2099
|
+
is_verified: boolean
|
|
2100
|
+
}
|
|
2101
|
+
|
|
2102
|
+
/** One dedicated IP of the account with its warmup state. */
|
|
2103
|
+
export interface EmailIp {
|
|
2104
|
+
ip: string
|
|
2105
|
+
is_warming_up: boolean
|
|
2106
|
+
warmup_started_at?: string
|
|
2107
|
+
pools: string[]
|
|
2108
|
+
}
|
|
2109
|
+
|
|
2110
|
+
/**
|
|
2111
|
+
* The provider's account-level snapshot (refreshed daily by the connector's
|
|
2112
|
+
* sweep, or on demand with `refresh`). Every section is optional — a plan
|
|
2113
|
+
* without the feature or a failed pull leaves it absent and adds a warning.
|
|
2114
|
+
*/
|
|
2115
|
+
export interface EmailProviderHealth {
|
|
2116
|
+
engagement_quality?: EmailEngagementQuality
|
|
2117
|
+
stats?: EmailProviderStats
|
|
2118
|
+
suppressions?: EmailSuppressionCounts
|
|
2119
|
+
domain?: EmailDomainStatus
|
|
2120
|
+
sender?: EmailSenderStatus
|
|
2121
|
+
ips: EmailIp[]
|
|
2122
|
+
warnings?: string[]
|
|
2123
|
+
refreshed_at: string
|
|
2124
|
+
}
|
|
2125
|
+
|
|
2126
|
+
/** GET /connections/:id/health — ledger windows + the provider snapshot. */
|
|
2127
|
+
export interface EmailHealth {
|
|
2128
|
+
connection_id: string
|
|
2129
|
+
windows: EmailHealthWindow[]
|
|
2130
|
+
provider?: EmailProviderHealth
|
|
2131
|
+
}
|
|
2132
|
+
|
|
2133
|
+
export interface GetConnectionHealthQuery {
|
|
2134
|
+
/** Force a live provider pull (slow — several provider calls). */
|
|
2135
|
+
refresh?: boolean
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2138
|
+
/** One address on a provider suppression list. */
|
|
2139
|
+
export interface EmailSuppression {
|
|
2140
|
+
kind: EmailSuppressionKind
|
|
2141
|
+
email: string
|
|
2142
|
+
reason?: string
|
|
2143
|
+
status?: string
|
|
2144
|
+
created_at: string
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
// ── Channel events ────────────────────────────────────────────────────────────
|
|
2148
|
+
|
|
2149
|
+
/**
|
|
2150
|
+
* ONE provider-observed occurrence about an outbound message on a sending
|
|
2151
|
+
* platform: the delivery lifecycle (processed → delivered | deferred |
|
|
2152
|
+
* bounced | dropped) and engagement (opened, clicked, spam_reported,
|
|
2153
|
+
* unsubscribed, resubscribed). Provider vocabularies map onto these inside
|
|
2154
|
+
* the connector.
|
|
2155
|
+
*/
|
|
2156
|
+
export type ChannelEventType =
|
|
2157
|
+
| 'processed'
|
|
2158
|
+
| 'delivered'
|
|
2159
|
+
| 'deferred'
|
|
2160
|
+
| 'bounced'
|
|
2161
|
+
| 'dropped'
|
|
2162
|
+
| 'opened'
|
|
2163
|
+
| 'clicked'
|
|
2164
|
+
| 'spam_reported'
|
|
2165
|
+
| 'unsubscribed'
|
|
2166
|
+
| 'resubscribed'
|
|
2167
|
+
|
|
2168
|
+
/** hard = the address is gone (suppressed); soft = this attempt was refused. */
|
|
2169
|
+
export type BounceKind = 'hard' | 'soft'
|
|
2170
|
+
|
|
2171
|
+
/** The provider's category of a bounce / block. */
|
|
2172
|
+
export type BounceClassification =
|
|
2173
|
+
| 'invalid_address'
|
|
2174
|
+
| 'technical_failure'
|
|
2175
|
+
| 'content'
|
|
2176
|
+
| 'reputation'
|
|
2177
|
+
| 'volume'
|
|
2178
|
+
| 'mailbox_unavailable'
|
|
2179
|
+
| 'unclassified'
|
|
2180
|
+
|
|
2181
|
+
/**
|
|
2182
|
+
* One row of the channel_event ledger — the sibling of channel actions (acts
|
|
2183
|
+
* WE perform) and reactions (edges): something the provider or the recipient
|
|
2184
|
+
* did that we record. Append-only, deduped on the provider's event id.
|
|
2185
|
+
* Message.delivery and provider-sourced contact permission events derive
|
|
2186
|
+
* from it.
|
|
2187
|
+
*/
|
|
2188
|
+
export interface ChannelEvent {
|
|
2189
|
+
id: string
|
|
2190
|
+
org_id: string
|
|
2191
|
+
connection_id: string
|
|
2192
|
+
connector_key: ConnectorKey
|
|
2193
|
+
channel: Channel
|
|
2194
|
+
/** The message the event is about; absent when unresolvable. */
|
|
2195
|
+
message_id?: string
|
|
2196
|
+
conversation_id?: string
|
|
2197
|
+
contact_id?: string
|
|
2198
|
+
contact_address_id?: string
|
|
2199
|
+
/** The provider's recipient (lowercased email). */
|
|
2200
|
+
recipient_address: string
|
|
2201
|
+
event_type: ChannelEventType
|
|
2202
|
+
external_event_id: string
|
|
2203
|
+
external_message_id?: string
|
|
2204
|
+
occurred_at: string
|
|
2205
|
+
/** Bounce / deferral / drop text (the SMTP response, the drop reason). */
|
|
2206
|
+
reason?: string
|
|
2207
|
+
response?: string
|
|
2208
|
+
bounce_kind?: BounceKind
|
|
2209
|
+
bounce_classification?: BounceClassification
|
|
2210
|
+
/** The clicked link (clicked events). */
|
|
2211
|
+
url?: string
|
|
2212
|
+
/** An opened event a mail client's privacy proxy generated, not the person. */
|
|
2213
|
+
is_machine_open?: boolean
|
|
2214
|
+
metadata: Record<string, unknown>
|
|
2215
|
+
created_at: string
|
|
2216
|
+
created_by: UserRef
|
|
2217
|
+
}
|
|
2218
|
+
|
|
2219
|
+
export interface ListChannelEventsQuery extends PaginationQuery {
|
|
2220
|
+
connection_id?: string
|
|
2221
|
+
message_id?: string
|
|
2222
|
+
conversation_id?: string
|
|
2223
|
+
contact_id?: string
|
|
2224
|
+
event_type?: ChannelEventType
|
|
2225
|
+
/** ISO instants bounding occurred_at (from inclusive, until exclusive). */
|
|
2226
|
+
from?: string
|
|
2227
|
+
until?: string
|
|
2228
|
+
sort_by?: string
|
|
2229
|
+
sort?: 'asc' | 'desc'
|
|
2230
|
+
}
|
|
2231
|
+
|
|
2232
|
+
// ── Channel actions ───────────────────────────────────────────────────────────
|
|
2233
|
+
|
|
2234
|
+
/**
|
|
2235
|
+
* Lifecycle of a channel action. Execution: pending → performed | failed.
|
|
2236
|
+
* Outcome (invitations): performed → accepted | declined | withdrawn |
|
|
2237
|
+
* expired; an inbound received invitation starts pending and ends
|
|
2238
|
+
* accepted | declined | expired.
|
|
2239
|
+
*/
|
|
2240
|
+
export type ChannelActionStatus =
|
|
2241
|
+
| 'pending'
|
|
2242
|
+
| 'performed'
|
|
2243
|
+
| 'failed'
|
|
2244
|
+
| 'accepted'
|
|
2245
|
+
| 'declined'
|
|
2246
|
+
| 'withdrawn'
|
|
2247
|
+
| 'expired'
|
|
2248
|
+
/** Our answer to an inbound channel action (a received invitation). */
|
|
2249
|
+
export type ChannelActionResponse = 'accept' | 'decline'
|
|
2250
|
+
/** What an action type acts on: a person on the channel, or an external object. */
|
|
2251
|
+
export type ChannelActionTargetKind = 'contact-address' | 'external'
|
|
2252
|
+
|
|
2253
|
+
/**
|
|
2254
|
+
* One action type a connector performs, projected onto `connection.actions`.
|
|
2255
|
+
*/
|
|
2256
|
+
export interface ChannelActionCapability {
|
|
2257
|
+
action_type: ChannelActionType
|
|
2258
|
+
target_kind: ChannelActionTargetKind
|
|
2259
|
+
/** The act can be withdrawn after performing (an invitation). */
|
|
2260
|
+
is_cancelable: boolean
|
|
2261
|
+
/** An inbound act of this type can be answered (accept / decline). */
|
|
2262
|
+
is_respondable: boolean
|
|
2263
|
+
/** Performing also sends a message that lands as a Message + Conversation (InMail). */
|
|
2264
|
+
is_message_minting: boolean
|
|
2265
|
+
/** Bound of the free-text note the act carries (LinkedIn invitation: 300). */
|
|
2266
|
+
max_note_length?: number
|
|
2267
|
+
}
|
|
2268
|
+
|
|
2269
|
+
export interface InvitationParams {
|
|
2270
|
+
note?: string
|
|
2271
|
+
email?: string
|
|
2272
|
+
}
|
|
2273
|
+
export type ProfileVisitParams = Record<string, never>
|
|
2274
|
+
export interface InmailParams {
|
|
2275
|
+
subject?: string
|
|
2276
|
+
content: ContentBlock[]
|
|
2277
|
+
}
|
|
2278
|
+
export type ChannelActionParams = InvitationParams | ProfileVisitParams | InmailParams
|
|
2279
|
+
|
|
2280
|
+
/**
|
|
2281
|
+
* One act performed through a channel connection that is neither a message
|
|
2282
|
+
* nor a reaction — a LinkedIn invitation, a profile visit, an InMail (which
|
|
2283
|
+
* ALSO mints a message, see message_id). A LEDGER row: appended, transitioned
|
|
2284
|
+
* along its lifecycle, never toggled. `direction` outbound = we acted;
|
|
2285
|
+
* inbound = someone acted on us (a received invitation you may answer).
|
|
2286
|
+
* `created_by` is the performer on outbound rows (user or agent), the system
|
|
2287
|
+
* on ingested inbound rows; `updated_by` who accepted / declined / withdrew.
|
|
2288
|
+
*/
|
|
2289
|
+
export interface ChannelAction {
|
|
2290
|
+
id: string
|
|
2291
|
+
org_id: string
|
|
2292
|
+
connection_id: string
|
|
2293
|
+
connector_key: ConnectorKey
|
|
2294
|
+
channel: Channel
|
|
2295
|
+
action_type: ChannelActionType
|
|
2296
|
+
direction: MessageDirection
|
|
2297
|
+
status: ChannelActionStatus
|
|
2298
|
+
contact_id?: string
|
|
2299
|
+
contact_address_id?: string
|
|
2300
|
+
/** The provider-side identity acted on (a LinkedIn member id). */
|
|
2301
|
+
target_external_id: string
|
|
2302
|
+
contact: ContactRef
|
|
2303
|
+
/** An InMail's minted message; an invitation's note-chat once accepted. */
|
|
2304
|
+
message_id?: string
|
|
2305
|
+
conversation_id?: string
|
|
2306
|
+
params?: ChannelActionParams
|
|
2307
|
+
/** The provider handle (Unipile invitation id) — cancel / respond key. */
|
|
2308
|
+
external_action_id?: string
|
|
2309
|
+
error?: string
|
|
2310
|
+
occurred_at: string
|
|
2311
|
+
resolved_at?: string
|
|
2312
|
+
/** Provider enrichment: invitation usage %, network_distance, … */
|
|
2313
|
+
metadata: Record<string, unknown>
|
|
2314
|
+
created_at: string
|
|
2315
|
+
created_by: UserRef
|
|
2316
|
+
updated_at: string
|
|
2317
|
+
updated_by: UserRef
|
|
2318
|
+
}
|
|
2319
|
+
|
|
2320
|
+
/** Performs one act. `target` is the person acted on (kind contact-address + the connector-side external id). */
|
|
2321
|
+
export interface PerformChannelActionRequest {
|
|
2322
|
+
connection_id: string
|
|
2323
|
+
action_type: ChannelActionType
|
|
2324
|
+
target: SendRecipient
|
|
2325
|
+
/** Per-type input: invitation {note?, email?}; profile_visit {}; inmail {subject?, content}. */
|
|
2326
|
+
params?: Record<string, unknown>
|
|
2327
|
+
}
|
|
2328
|
+
|
|
2329
|
+
export interface RespondChannelActionRequest {
|
|
2330
|
+
response: ChannelActionResponse
|
|
2331
|
+
}
|
|
2332
|
+
|
|
2333
|
+
export interface ListChannelActionsQuery extends PaginationQuery {
|
|
2334
|
+
channel?: Channel
|
|
2335
|
+
connection_id?: string
|
|
2336
|
+
action_type?: ChannelActionType
|
|
2337
|
+
direction?: MessageDirection
|
|
2338
|
+
status?: ChannelActionStatus
|
|
2339
|
+
contact_id?: string
|
|
2340
|
+
}
|