@proteos/sdk 0.28.0 → 0.29.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/index.cjs +31 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +110 -1
- package/dist/index.d.ts +110 -1
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/conversation/index.ts +55 -0
- package/src/conversation/types.ts +120 -0
- package/src/index.ts +18 -0
package/package.json
CHANGED
|
@@ -30,6 +30,12 @@ import type {
|
|
|
30
30
|
BlockContactRequest,
|
|
31
31
|
Contact,
|
|
32
32
|
ContactAddress,
|
|
33
|
+
ConversationFilter,
|
|
34
|
+
ConversationFilterEvent,
|
|
35
|
+
CreateConversationFilterRequest,
|
|
36
|
+
ListConversationFilterEventsQuery,
|
|
37
|
+
ListConversationFiltersQuery,
|
|
38
|
+
UpdateConversationFilterRequest,
|
|
33
39
|
ContactErasureRequest,
|
|
34
40
|
ContactMergeProposal,
|
|
35
41
|
MergeContactsRequest,
|
|
@@ -64,6 +70,8 @@ export class ConversationClient {
|
|
|
64
70
|
readonly contacts: ContactService
|
|
65
71
|
readonly messages: MessageService
|
|
66
72
|
readonly agentListeners: AgentListenerService
|
|
73
|
+
/** Ingest-time filter rules (drop-with-audit) + their event trail. */
|
|
74
|
+
readonly conversationFilters: ConversationFilterService
|
|
67
75
|
/** Per-org glossary: custom vocabulary that boosts transcription accuracy. */
|
|
68
76
|
readonly glossaryTerms: GlossaryTermService
|
|
69
77
|
readonly transcriptions: TranscriptionService
|
|
@@ -78,6 +86,7 @@ export class ConversationClient {
|
|
|
78
86
|
this.contacts = new ContactServiceImpl(client)
|
|
79
87
|
this.messages = new MessageServiceImpl(client)
|
|
80
88
|
this.agentListeners = new AgentListenerServiceImpl(client)
|
|
89
|
+
this.conversationFilters = new ConversationFilterServiceImpl(client)
|
|
81
90
|
this.glossaryTerms = new GlossaryTermServiceImpl(client)
|
|
82
91
|
this.transcriptions = new TranscriptionServiceImpl(client)
|
|
83
92
|
this.meetings = new MeetingServiceImpl(client)
|
|
@@ -429,6 +438,52 @@ class AgentListenerServiceImpl implements AgentListenerService {
|
|
|
429
438
|
}
|
|
430
439
|
}
|
|
431
440
|
|
|
441
|
+
/**
|
|
442
|
+
* Ingest-time conversation filters: block/allow rules that drop matching
|
|
443
|
+
* inbound messages before persistence, scoped globally or per connection.
|
|
444
|
+
* listEvents pages a rule's drop-audit trail (who got dropped, when, why).
|
|
445
|
+
*/
|
|
446
|
+
export interface ConversationFilterService {
|
|
447
|
+
list(query?: ListConversationFiltersQuery): Promise<ListResponse<ConversationFilter>>
|
|
448
|
+
get(id: string): Promise<ConversationFilter>
|
|
449
|
+
create(request: CreateConversationFilterRequest): Promise<ConversationFilter>
|
|
450
|
+
update(id: string, request: UpdateConversationFilterRequest): Promise<ConversationFilter>
|
|
451
|
+
delete(id: string): Promise<void>
|
|
452
|
+
listEvents(id: string, query?: ListConversationFilterEventsQuery): Promise<ListResponse<ConversationFilterEvent>>
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
class ConversationFilterServiceImpl implements ConversationFilterService {
|
|
456
|
+
constructor(private readonly client: ProteosClient) {}
|
|
457
|
+
|
|
458
|
+
list(query: ListConversationFiltersQuery = {}): Promise<ListResponse<ConversationFilter>> {
|
|
459
|
+
return this.client.requestWithQuery('GET', `${CONVERSATION_BASE_PATH}/conversation-filters`, query)
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
get(id: string): Promise<ConversationFilter> {
|
|
463
|
+
return this.client.request('GET', `${CONVERSATION_BASE_PATH}/conversation-filters/${encodeURIComponent(id)}`)
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
create(request: CreateConversationFilterRequest): Promise<ConversationFilter> {
|
|
467
|
+
return this.client.request('POST', `${CONVERSATION_BASE_PATH}/conversation-filters`, request)
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
update(id: string, request: UpdateConversationFilterRequest): Promise<ConversationFilter> {
|
|
471
|
+
return this.client.request('PATCH', `${CONVERSATION_BASE_PATH}/conversation-filters/${encodeURIComponent(id)}`, request)
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
async delete(id: string): Promise<void> {
|
|
475
|
+
await this.client.request('DELETE', `${CONVERSATION_BASE_PATH}/conversation-filters/${encodeURIComponent(id)}`)
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
listEvents(id: string, query: ListConversationFilterEventsQuery = {}): Promise<ListResponse<ConversationFilterEvent>> {
|
|
479
|
+
return this.client.requestWithQuery(
|
|
480
|
+
'GET',
|
|
481
|
+
`${CONVERSATION_BASE_PATH}/conversation-filters/${encodeURIComponent(id)}/events`,
|
|
482
|
+
query,
|
|
483
|
+
)
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
432
487
|
/**
|
|
433
488
|
* Per-org glossary: custom-vocabulary terms that boost transcription accuracy.
|
|
434
489
|
* A term feeds the transcription provider's keyterm prompting; `priority` ranks
|
|
@@ -566,6 +566,126 @@ export interface ListAgentListenersQuery extends PaginationQuery {
|
|
|
566
566
|
is_enabled?: boolean
|
|
567
567
|
}
|
|
568
568
|
|
|
569
|
+
/**
|
|
570
|
+
* Conversation filters: ingest-time rules that drop matching inbound messages
|
|
571
|
+
* BEFORE persistence (no message, no contact — only a content-free audit
|
|
572
|
+
* event). Scope-first evaluation: connection-scoped rules are final when one
|
|
573
|
+
* matches; global rules apply otherwise. Specificity within a scope:
|
|
574
|
+
* address > domain > role_based > automated > internal_conversations > all,
|
|
575
|
+
* allow beats block within a class.
|
|
576
|
+
*/
|
|
577
|
+
export type ConversationFilterType =
|
|
578
|
+
| 'address'
|
|
579
|
+
| 'domain'
|
|
580
|
+
| 'role_based'
|
|
581
|
+
| 'automated'
|
|
582
|
+
| 'internal_conversations'
|
|
583
|
+
| 'all'
|
|
584
|
+
export type ConversationFilterAction = 'block' | 'allow'
|
|
585
|
+
/** Which side of the message address/domain rules test (default: sender). */
|
|
586
|
+
export type FilterMatchOn = 'sender' | 'any_participant'
|
|
587
|
+
/** Deterministic machine-mail header signals the automated filter matches. */
|
|
588
|
+
export type AutomatedSignal =
|
|
589
|
+
| 'auto_submitted'
|
|
590
|
+
| 'bulk'
|
|
591
|
+
| 'mailing_list'
|
|
592
|
+
| 'bounce'
|
|
593
|
+
| 'auto_response_suppress'
|
|
594
|
+
|
|
595
|
+
/** Exact canonical address (lowercased email / E.164 phone / provider id), any channel kind. */
|
|
596
|
+
export interface AddressFilterConfig {
|
|
597
|
+
kind: ContactAddressKind
|
|
598
|
+
value: string
|
|
599
|
+
match_on?: FilterMatchOn
|
|
600
|
+
}
|
|
601
|
+
/** Equals on the parsed email domain (lowercase, no leading '@'). */
|
|
602
|
+
export interface DomainFilterConfig {
|
|
603
|
+
domain: string
|
|
604
|
+
match_on?: FilterMatchOn
|
|
605
|
+
}
|
|
606
|
+
/** Sender local-part is a role mailbox; empty prefixes = the built-in set. Email-only. */
|
|
607
|
+
export interface RoleBasedFilterConfig {
|
|
608
|
+
prefixes?: string[]
|
|
609
|
+
}
|
|
610
|
+
/** Header-signal machine-mail detection; empty signals = all. Email-only. */
|
|
611
|
+
export interface AutomatedFilterConfig {
|
|
612
|
+
signals?: AutomatedSignal[]
|
|
613
|
+
}
|
|
614
|
+
/** Drops only when sender AND every recipient are on these domains. Always block. */
|
|
615
|
+
export interface InternalConversationsFilterConfig {
|
|
616
|
+
domains: string[]
|
|
617
|
+
}
|
|
618
|
+
/** Matches every message (empty config) — the scope-control primitive. */
|
|
619
|
+
export type AllFilterConfig = Record<string, never>
|
|
620
|
+
|
|
621
|
+
export type ConversationFilterConfig =
|
|
622
|
+
| AddressFilterConfig
|
|
623
|
+
| DomainFilterConfig
|
|
624
|
+
| RoleBasedFilterConfig
|
|
625
|
+
| AutomatedFilterConfig
|
|
626
|
+
| InternalConversationsFilterConfig
|
|
627
|
+
| AllFilterConfig
|
|
628
|
+
|
|
629
|
+
export interface ConversationFilter {
|
|
630
|
+
id: string
|
|
631
|
+
org_id: string
|
|
632
|
+
/** Empty = global (org-wide); set = scoped to that connection. */
|
|
633
|
+
connection_id: string
|
|
634
|
+
filter_type: ConversationFilterType
|
|
635
|
+
action: ConversationFilterAction
|
|
636
|
+
filter_config?: ConversationFilterConfig
|
|
637
|
+
is_enabled: boolean
|
|
638
|
+
/** Read-only rollup: messages this rule dropped in the last 30 days. */
|
|
639
|
+
recent_event_count?: number
|
|
640
|
+
created_at: string
|
|
641
|
+
created_by: UserRef
|
|
642
|
+
updated_at: string
|
|
643
|
+
updated_by: UserRef
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/** One drop-audit entry (content-free: routing/identity facts only). */
|
|
647
|
+
export interface ConversationFilterEvent {
|
|
648
|
+
id: string
|
|
649
|
+
org_id: string
|
|
650
|
+
connection_id: string
|
|
651
|
+
conversation_filter_id: string
|
|
652
|
+
filter_type: ConversationFilterType
|
|
653
|
+
reason: string
|
|
654
|
+
sender_kind?: ContactAddressKind
|
|
655
|
+
sender_value?: string
|
|
656
|
+
external_message_id?: string
|
|
657
|
+
occurred_at: string
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
export interface CreateConversationFilterRequest {
|
|
661
|
+
connection_id?: string
|
|
662
|
+
filter_type: ConversationFilterType
|
|
663
|
+
action: ConversationFilterAction
|
|
664
|
+
filter_config?: Record<string, unknown>
|
|
665
|
+
is_enabled?: boolean
|
|
666
|
+
/** Opts past the own-domain guard (self_domain_block). */
|
|
667
|
+
is_self_domain_acknowledged?: boolean
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
export interface UpdateConversationFilterRequest {
|
|
671
|
+
/** filter_type and filter_config must be sent together. */
|
|
672
|
+
filter_type?: ConversationFilterType
|
|
673
|
+
action?: ConversationFilterAction
|
|
674
|
+
filter_config?: Record<string, unknown>
|
|
675
|
+
is_enabled?: boolean
|
|
676
|
+
is_self_domain_acknowledged?: boolean
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
export interface ListConversationFiltersQuery extends PaginationQuery {
|
|
680
|
+
/** Omit = all; '' = global-only; an id = that connection's rules. */
|
|
681
|
+
connection_id?: string
|
|
682
|
+
filter_type?: ConversationFilterType
|
|
683
|
+
action?: ConversationFilterAction
|
|
684
|
+
is_enabled?: boolean
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
export type ListConversationFilterEventsQuery = PaginationQuery
|
|
688
|
+
|
|
569
689
|
/**
|
|
570
690
|
* Discriminates a send target: a person's contact address or a venue. The
|
|
571
691
|
* server also accepts the legacy 'participant' value as an alias for
|
package/src/index.ts
CHANGED
|
@@ -237,6 +237,24 @@ export type {
|
|
|
237
237
|
ContactRef,
|
|
238
238
|
ContactSource,
|
|
239
239
|
ContactStatus,
|
|
240
|
+
AddressFilterConfig,
|
|
241
|
+
AllFilterConfig,
|
|
242
|
+
AutomatedFilterConfig,
|
|
243
|
+
AutomatedSignal,
|
|
244
|
+
ConversationFilter,
|
|
245
|
+
ConversationFilterAction,
|
|
246
|
+
ConversationFilterConfig,
|
|
247
|
+
ConversationFilterEvent,
|
|
248
|
+
ConversationFilterService,
|
|
249
|
+
ConversationFilterType,
|
|
250
|
+
CreateConversationFilterRequest,
|
|
251
|
+
DomainFilterConfig,
|
|
252
|
+
FilterMatchOn,
|
|
253
|
+
InternalConversationsFilterConfig,
|
|
254
|
+
ListConversationFilterEventsQuery,
|
|
255
|
+
ListConversationFiltersQuery,
|
|
256
|
+
RoleBasedFilterConfig,
|
|
257
|
+
UpdateConversationFilterRequest,
|
|
240
258
|
ErasureRequestStatus,
|
|
241
259
|
MergeContactsRequest,
|
|
242
260
|
MergeProposalStatus,
|