ab-ecosystem-cpass 0.1.0 → 1.0.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.
Files changed (97) hide show
  1. package/README.md +127 -25
  2. package/dist/client.d.ts +56 -1
  3. package/dist/client.js +76 -30
  4. package/dist/client.js.map +1 -1
  5. package/dist/http.d.ts +8 -0
  6. package/dist/http.js +10 -3
  7. package/dist/http.js.map +1 -1
  8. package/dist/index.d.ts +16 -1
  9. package/dist/index.js +35 -2
  10. package/dist/index.js.map +1 -1
  11. package/dist/resources/audience/contact-notes.d.ts +51 -0
  12. package/dist/resources/audience/contact-notes.js +70 -0
  13. package/dist/resources/audience/contact-notes.js.map +1 -0
  14. package/dist/resources/audience/contact-tags.d.ts +43 -0
  15. package/dist/resources/audience/contact-tags.js +60 -0
  16. package/dist/resources/audience/contact-tags.js.map +1 -0
  17. package/dist/resources/audience/contacts.d.ts +76 -0
  18. package/dist/resources/audience/contacts.js +103 -0
  19. package/dist/resources/audience/contacts.js.map +1 -0
  20. package/dist/resources/audience/crm-triggers.d.ts +67 -0
  21. package/dist/resources/audience/crm-triggers.js +86 -0
  22. package/dist/resources/audience/crm-triggers.js.map +1 -0
  23. package/dist/resources/audience/custom-fields.d.ts +54 -0
  24. package/dist/resources/audience/custom-fields.js +71 -0
  25. package/dist/resources/audience/custom-fields.js.map +1 -0
  26. package/dist/resources/audience/export-history.d.ts +52 -0
  27. package/dist/resources/audience/export-history.js +67 -0
  28. package/dist/resources/audience/export-history.js.map +1 -0
  29. package/dist/resources/audience/import-history.d.ts +51 -0
  30. package/dist/resources/audience/import-history.js +66 -0
  31. package/dist/resources/audience/import-history.js.map +1 -0
  32. package/dist/resources/audience/segments.d.ts +49 -0
  33. package/dist/resources/audience/segments.js +66 -0
  34. package/dist/resources/audience/segments.js.map +1 -0
  35. package/dist/resources/audience/webhooks.d.ts +68 -0
  36. package/dist/resources/audience/webhooks.js +83 -0
  37. package/dist/resources/audience/webhooks.js.map +1 -0
  38. package/dist/resources/channels/activity.d.ts +25 -0
  39. package/dist/resources/channels/activity.js +34 -0
  40. package/dist/resources/channels/activity.js.map +1 -0
  41. package/dist/resources/channels/billing.d.ts +46 -0
  42. package/dist/resources/channels/billing.js +59 -0
  43. package/dist/resources/channels/billing.js.map +1 -0
  44. package/dist/resources/channels/channels.d.ts +115 -0
  45. package/dist/resources/channels/channels.js +129 -0
  46. package/dist/resources/channels/channels.js.map +1 -0
  47. package/dist/resources/channels/templates.d.ts +90 -0
  48. package/dist/resources/channels/templates.js +109 -0
  49. package/dist/resources/channels/templates.js.map +1 -0
  50. package/dist/resources/channels/wallet.d.ts +25 -0
  51. package/dist/resources/channels/wallet.js +34 -0
  52. package/dist/resources/channels/wallet.js.map +1 -0
  53. package/dist/resources/channels/webhooks.d.ts +60 -0
  54. package/dist/resources/channels/webhooks.js +79 -0
  55. package/dist/resources/channels/webhooks.js.map +1 -0
  56. package/dist/resources/paths.d.ts +12 -0
  57. package/dist/resources/paths.js +17 -0
  58. package/dist/resources/paths.js.map +1 -0
  59. package/dist/types/audience.d.ts +512 -0
  60. package/dist/types/audience.js +3 -0
  61. package/dist/types/audience.js.map +1 -0
  62. package/dist/types/channels.d.ts +383 -0
  63. package/dist/types/channels.js +22 -0
  64. package/dist/types/channels.js.map +1 -0
  65. package/dist/types/common.d.ts +55 -0
  66. package/dist/types/common.js +8 -0
  67. package/dist/types/common.js.map +1 -0
  68. package/dist/types/contact-filter.d.ts +55 -0
  69. package/dist/types/contact-filter.js +11 -0
  70. package/dist/types/contact-filter.js.map +1 -0
  71. package/dist/types/index.d.ts +4 -0
  72. package/dist/types/index.js +21 -0
  73. package/dist/types/index.js.map +1 -0
  74. package/docs/audience/contact-notes.md +129 -0
  75. package/docs/audience/contact-tags.md +109 -0
  76. package/docs/audience/contacts.md +227 -0
  77. package/docs/audience/crm-triggers.md +240 -0
  78. package/docs/audience/custom-fields.md +174 -0
  79. package/docs/audience/exports.md +163 -0
  80. package/docs/audience/imports.md +161 -0
  81. package/docs/audience/segments.md +120 -0
  82. package/docs/audience/webhooks.md +167 -0
  83. package/docs/channels/activity.md +68 -0
  84. package/docs/channels/billing.md +112 -0
  85. package/docs/channels/channel-props.md +290 -0
  86. package/docs/channels/channels.md +199 -0
  87. package/docs/channels/templates.md +224 -0
  88. package/docs/channels/wallet.md +67 -0
  89. package/docs/channels/webhooks.md +152 -0
  90. package/docs/contact-filter.md +157 -0
  91. package/package.json +7 -3
  92. package/dist/resources/channels.d.ts +0 -10
  93. package/dist/resources/channels.js +0 -19
  94. package/dist/resources/channels.js.map +0 -1
  95. package/dist/types.d.ts +0 -70
  96. package/dist/types.js +0 -7
  97. package/dist/types.js.map +0 -1
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ChannelWebhooks = void 0;
4
+ const paths_1 = require("../paths");
5
+ const base = (channelId) => `${paths_1.CHANNELS}/${(0, paths_1.seg)(channelId)}/webhooks`;
6
+ /**
7
+ * Channel webhooks: where a channel's message traffic is delivered.
8
+ *
9
+ * These carry conversation events -- `incoming`, `sent`, `delivered`, `read`,
10
+ * `failed` -- plus the account-level notices Meta sends about templates, the
11
+ * phone number and the WABA. Distinct from `crm.webhooks`, which carries
12
+ * contact changes from the audience module.
13
+ *
14
+ * Each webhook subscribes to a set of events; several webhooks may watch the
15
+ * same channel, and each gets its own copy.
16
+ *
17
+ * `meta` on a stored webhook is an audit trail -- who created or last changed
18
+ * it and from where -- filled in by the service from the caller's identity and
19
+ * IP. It is never accepted on a write.
20
+ */
21
+ class ChannelWebhooks {
22
+ http;
23
+ constructor(http) {
24
+ this.http = http;
25
+ }
26
+ /**
27
+ * `GET /v1/channels/:channelId/webhooks` -- offset paginated. `search`
28
+ * matches the title and the URL; `active` and `event` are quick filters,
29
+ * where `event` finds the webhooks subscribed to that one event.
30
+ *
31
+ * Scope: `channels:read`.
32
+ */
33
+ list(channelId, query = {}) {
34
+ return this.http.request('GET', base(channelId), { query });
35
+ }
36
+ /**
37
+ * `GET /v1/channels/:channelId/webhooks/:id`.
38
+ *
39
+ * Scope: `channels:read`.
40
+ */
41
+ get(channelId, id) {
42
+ return this.http.request('GET', `${base(channelId)}/${(0, paths_1.seg)(id)}`);
43
+ }
44
+ /**
45
+ * `POST /v1/channels/:channelId/webhooks` -- 201 with the created webhook.
46
+ *
47
+ * Only `url` and `events` are required; the title defaults to
48
+ * `'CRM Channel Webhook'` and the webhook starts active. Webhooks created
49
+ * through the API are recorded with `meta.source: 'API'`.
50
+ *
51
+ * Scope: `channels:write`.
52
+ */
53
+ create(channelId, input) {
54
+ return this.http.request('POST', base(channelId), { body: input });
55
+ }
56
+ /**
57
+ * `PATCH /v1/channels/:channelId/webhooks/:id` -- a partial update; at least
58
+ * one field is required. `events` replaces the subscription list rather than
59
+ * adding to it. Pause delivery with `{ active: false }`.
60
+ *
61
+ * Scope: `channels:write`.
62
+ */
63
+ update(channelId, id, input) {
64
+ return this.http.request('PATCH', `${base(channelId)}/${(0, paths_1.seg)(id)}`, {
65
+ body: input,
66
+ });
67
+ }
68
+ /**
69
+ * `DELETE /v1/channels/:channelId/webhooks/:id` -- 204. Delivery stops
70
+ * immediately.
71
+ *
72
+ * Scope: `channels:write`.
73
+ */
74
+ delete(channelId, id) {
75
+ return this.http.request('DELETE', `${base(channelId)}/${(0, paths_1.seg)(id)}`);
76
+ }
77
+ }
78
+ exports.ChannelWebhooks = ChannelWebhooks;
79
+ //# sourceMappingURL=webhooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../../../src/resources/channels/webhooks.ts"],"names":[],"mappings":";;;AAQA,oCAAyC;AAEzC,MAAM,IAAI,GAAG,CAAC,SAAiB,EAAE,EAAE,CAAC,GAAG,gBAAQ,IAAI,IAAA,WAAG,EAAC,SAAS,CAAC,WAAW,CAAC;AAE7E;;;;;;;;;;;;;;GAcG;AACH,MAAa,eAAe;IACG;IAA7B,YAA6B,IAAgB;QAAhB,SAAI,GAAJ,IAAI,CAAY;IAAG,CAAC;IAEjD;;;;;;OAMG;IACH,IAAI,CAAC,SAAiB,EAAE,QAA2C,EAAE;QACnE,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAA4B,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACzF,CAAC;IAED;;;;OAIG;IACH,GAAG,CAAC,SAAiB,EAAE,EAAU;QAC/B,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAiB,KAAK,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,IAAA,WAAG,EAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACnF,CAAC;IAED;;;;;;;;OAQG;IACH,MAAM,CAAC,SAAiB,EAAE,KAAgC;QACxD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAiB,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACrF,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,SAAiB,EAAE,EAAU,EAAE,KAAgC;QACpE,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAiB,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,IAAA,WAAG,EAAC,EAAE,CAAC,EAAE,EAAE;YACjF,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,SAAiB,EAAE,EAAU;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAO,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,IAAA,WAAG,EAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC5E,CAAC;CACF;AA1DD,0CA0DC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Where each service sits behind the gateway.
3
+ *
4
+ * The gateway mounts its router at `/v1` and proxies `/audience/*` to the
5
+ * audience service and `/channels/*` to the channels service, stripping the
6
+ * prefix on the way through. So `/v1/audience/contacts` reaches the audience
7
+ * service as `/contacts`.
8
+ */
9
+ export declare const AUDIENCE = "/v1/audience";
10
+ export declare const CHANNELS = "/v1/channels";
11
+ /** Path segments are escaped: an id from a caller must not be able to add one. */
12
+ export declare const seg: (value: string) => string;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.seg = exports.CHANNELS = exports.AUDIENCE = void 0;
4
+ /**
5
+ * Where each service sits behind the gateway.
6
+ *
7
+ * The gateway mounts its router at `/v1` and proxies `/audience/*` to the
8
+ * audience service and `/channels/*` to the channels service, stripping the
9
+ * prefix on the way through. So `/v1/audience/contacts` reaches the audience
10
+ * service as `/contacts`.
11
+ */
12
+ exports.AUDIENCE = '/v1/audience';
13
+ exports.CHANNELS = '/v1/channels';
14
+ /** Path segments are escaped: an id from a caller must not be able to add one. */
15
+ const seg = (value) => encodeURIComponent(String(value));
16
+ exports.seg = seg;
17
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/resources/paths.ts"],"names":[],"mappings":";;;AAAA;;;;;;;GAOG;AACU,QAAA,QAAQ,GAAG,cAAc,CAAC;AAC1B,QAAA,QAAQ,GAAG,cAAc,CAAC;AAEvC,kFAAkF;AAC3E,MAAM,GAAG,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAAnE,QAAA,GAAG,OAAgE"}
@@ -0,0 +1,512 @@
1
+ /**
2
+ * Audience service types: contacts and everything hanging off them.
3
+ * Mirrors `packages/contracts/src/audience/*`.
4
+ */
5
+ import type { ContactFilter, ContactFilterEntry } from './contact-filter';
6
+ import type { IsoDate, JsonObject, ListQuery, ObjectId, PageQuery } from './common';
7
+ /** A label a contact can carry. */
8
+ export interface ContactTag {
9
+ id: string;
10
+ name: string;
11
+ icon: string;
12
+ color: string;
13
+ }
14
+ export interface CreateContactTagInput {
15
+ /** Trimmed, 1..120 characters. */
16
+ name: string;
17
+ /** Icon name or emoji, up to 120 characters. Default `''`. */
18
+ icon?: string;
19
+ /** Free-form so the palette can evolve; only length is checked (32). Default `''`. */
20
+ color?: string;
21
+ }
22
+ export type UpdateContactTagInput = Partial<CreateContactTagInput>;
23
+ /** `search` matches the tag name. */
24
+ export type ListContactTagsQuery = ListQuery;
25
+ export type ContactStatus = 'live' | 'trashed';
26
+ export type ContactPrivacyStatus = 'open' | 'locked';
27
+ export type ContactChannel = 'whatsapp' | 'facebook' | 'instagram' | 'telegram' | 'email' | 'rcs' | 'webchat';
28
+ /** One channel identity of a contact. Server-owned: never sent on a write. */
29
+ export interface ContactProfile {
30
+ id: string;
31
+ channel: ContactChannel;
32
+ /** Phone number, handle or address, depending on the channel. */
33
+ identifier: string;
34
+ name: string;
35
+ profile_pic: string;
36
+ extra: JsonObject;
37
+ }
38
+ export interface ContactName {
39
+ /** Up to 20 characters. */
40
+ salutation: string;
41
+ /** Up to 120 characters. */
42
+ first_name: string;
43
+ /** Up to 120 characters. */
44
+ last_name: string;
45
+ }
46
+ /** Which directions of traffic are blocked for this contact. */
47
+ export interface ContactBlocked {
48
+ incoming: boolean;
49
+ outgoing: boolean;
50
+ bot: boolean;
51
+ api: boolean;
52
+ }
53
+ export interface ContactChatMetadata {
54
+ new: boolean;
55
+ archived: boolean;
56
+ unread: number;
57
+ /** Seconds to pause automation for. */
58
+ pause_duration: number;
59
+ marked_as_unread: boolean;
60
+ closed: boolean;
61
+ marked_as_done: boolean;
62
+ blocked: ContactBlocked;
63
+ }
64
+ export interface ContactLeadSource {
65
+ type?: string;
66
+ module?: string;
67
+ id: string | null;
68
+ }
69
+ export interface Contact {
70
+ id: string;
71
+ name: ContactName;
72
+ /** Channel identities, keyed by channel. Server-owned. */
73
+ profile: Record<string, ContactProfile>;
74
+ /** Custom field values, keyed by field slug. */
75
+ custom_field_hash: JsonObject;
76
+ chat_metadata: ContactChatMetadata;
77
+ order?: string;
78
+ /** Unix seconds. Server-owned. */
79
+ last_seen: number;
80
+ /** Unix seconds of the last inbound customer message. Server-owned. */
81
+ last_icm_timestamp: number;
82
+ /** Server-owned. */
83
+ last_interaction_props: JsonObject;
84
+ agent: string | null;
85
+ team: string | null;
86
+ lead_source: ContactLeadSource;
87
+ status: ContactStatus;
88
+ privacy_status: ContactPrivacyStatus;
89
+ /** Resolved tag documents, not ids. */
90
+ tags: ContactTag[];
91
+ createdAt: IsoDate;
92
+ updatedAt: IsoDate;
93
+ }
94
+ /**
95
+ * Everything a caller may set. The server-owned paths (`profile`, `last_seen`,
96
+ * `last_icm_timestamp`, `last_interaction_props`) are deliberately absent.
97
+ */
98
+ export interface CreateContactInput {
99
+ name?: Partial<ContactName>;
100
+ order?: string;
101
+ /** Contact tag ids. Default `[]`. */
102
+ tags?: ObjectId[];
103
+ agent?: ObjectId | null;
104
+ team?: ObjectId | null;
105
+ lead_source?: {
106
+ type?: string;
107
+ module?: string;
108
+ id?: ObjectId | null;
109
+ };
110
+ status?: ContactStatus;
111
+ privacy_status?: ContactPrivacyStatus;
112
+ /** Values keyed by custom field slug. */
113
+ custom_field_hash?: JsonObject;
114
+ chat_metadata?: Partial<Omit<ContactChatMetadata, 'blocked'>> & {
115
+ blocked?: Partial<ContactBlocked>;
116
+ };
117
+ }
118
+ export type UpdateContactInput = Partial<CreateContactInput>;
119
+ /**
120
+ * `search` matches the first and last name, plus the name and identifier of
121
+ * every channel identity. `segment` names a saved filter; `filter` carries
122
+ * ad-hoc conditions. Sending both narrows the segment by the conditions.
123
+ */
124
+ export interface ListContactsQuery extends ListQuery {
125
+ /** A contact tag id. */
126
+ tag?: ObjectId;
127
+ agent?: ObjectId;
128
+ /** Default `'live'`; pass `'trashed'` to read the trash. */
129
+ status?: ContactStatus;
130
+ /** A segment's id or its name; ids are tried first when the value looks like one. */
131
+ segment?: string;
132
+ /** Serialised to JSON by the SDK before it goes on the query string. */
133
+ filter?: ContactFilter;
134
+ }
135
+ /**
136
+ * `delete` is two-stage: the first call trashes the contact, a second one on an
137
+ * already-trashed contact destroys it. The body says which happened, since the
138
+ * status code (200 either way) does not.
139
+ */
140
+ export interface ContactDeleteResult {
141
+ id: string;
142
+ status: 'trashed' | 'deleted';
143
+ }
144
+ export interface ContactNoteAttachment {
145
+ type?: string;
146
+ size?: string;
147
+ url: string;
148
+ mime?: string;
149
+ file_name?: string;
150
+ }
151
+ export interface ContactNote {
152
+ id: string;
153
+ /** The contact the note hangs off. */
154
+ contact: string;
155
+ note: string;
156
+ attachments: ContactNoteAttachment[];
157
+ /** Ids of team members mentioned in the note. */
158
+ mentions: string[];
159
+ createdAt: IsoDate;
160
+ updatedAt: IsoDate;
161
+ }
162
+ export interface CreateContactNoteInput {
163
+ /** 1..5000 characters. */
164
+ note: string;
165
+ /** Default `[]`. */
166
+ attachments?: ContactNoteAttachment[];
167
+ /** Team member ids. Default `[]`. */
168
+ mentions?: ObjectId[];
169
+ }
170
+ export type UpdateContactNoteInput = Partial<CreateContactNoteInput>;
171
+ /** Cursor paginated -- notes are appended, so an offset would shift under you. */
172
+ export type ListContactNotesQuery = PageQuery;
173
+ export type CustomFieldType = 'text' | 'url' | 'email' | 'date' | 'phone' | 'number' | 'decimal' | 'amount' | 'address' | 'location' | 'country' | 'language' | 'attachment' | 'periodic_time' | 'percent' | 'timezone' | 'textarea' | 'checkbox' | 'dropdown' | 'timestamp' | 'dial_code' | 'multi_select';
174
+ /** `system` fields are provisioned by the platform, `user` ones by tenants. */
175
+ export type CustomFieldSource = 'system' | 'user';
176
+ export type CustomFieldTeamAccess = 'restricted' | 'open_to_all';
177
+ export interface CustomField {
178
+ id: string;
179
+ /** Machine name, unique per account. Usable in place of the id on every route. */
180
+ slug: string;
181
+ name?: string;
182
+ caption?: string;
183
+ /** Who owns the field, not its data type -- that is `dataType`. */
184
+ type: CustomFieldSource;
185
+ dataType?: CustomFieldType;
186
+ /** Default value, shaped by `dataType`. */
187
+ default: JsonObject;
188
+ /** Type-specific configuration: dropdown options, number precision, and so on. */
189
+ props: JsonObject;
190
+ required: boolean;
191
+ displayInPanel: boolean;
192
+ showInSidebar: boolean;
193
+ showAsLabel: boolean;
194
+ isBoard: boolean;
195
+ teamAccess: CustomFieldTeamAccess;
196
+ createdAt: IsoDate;
197
+ updatedAt: IsoDate;
198
+ }
199
+ export interface CreateCustomFieldInput {
200
+ /**
201
+ * snake_case, `^[a-z][a-z0-9_]{0,63}$`, and not one of the reserved names --
202
+ * contact document paths (`name`, `tags`, `status`, ...), channel keys
203
+ * (`whatsapp`, `email`, ...) or built-in filter fields (`system_last_seen`,
204
+ * `system_identifier`, ...). Immutable: `update` cannot change it.
205
+ */
206
+ slug: string;
207
+ /** 1..120 characters. */
208
+ name: string;
209
+ /** Up to 240 characters. */
210
+ caption?: string;
211
+ dataType: CustomFieldType;
212
+ /** Default `{}`. */
213
+ default?: JsonObject;
214
+ /** Type-specific configuration. Default `{}`. */
215
+ props?: JsonObject;
216
+ /** Default `false`. */
217
+ required?: boolean;
218
+ /** Default `false`. */
219
+ displayInPanel?: boolean;
220
+ /** Default `false`. */
221
+ showInSidebar?: boolean;
222
+ /** Default `false`. */
223
+ showAsLabel?: boolean;
224
+ /** Default `false`. */
225
+ isBoard?: boolean;
226
+ /** Default `'open_to_all'`. */
227
+ teamAccess?: CustomFieldTeamAccess;
228
+ }
229
+ /** Everything but the slug, which a field keeps for life. */
230
+ export type UpdateCustomFieldInput = Partial<Omit<CreateCustomFieldInput, 'slug'>>;
231
+ /** `search` matches the slug, the label and the caption. */
232
+ export interface ListCustomFieldsQuery extends ListQuery {
233
+ /** Quick filter: the field's data type. */
234
+ dataType?: CustomFieldType;
235
+ /** Quick filter: platform-provisioned or tenant-created. */
236
+ type?: CustomFieldSource;
237
+ teamAccess?: CustomFieldTeamAccess;
238
+ }
239
+ /**
240
+ * A saved contact filter. Nothing is materialised: a segment holds no contact
241
+ * ids, and covers whatever its conditions match the next time it is run.
242
+ */
243
+ export interface Segment {
244
+ id: string;
245
+ name: string;
246
+ description?: string;
247
+ filter: ContactFilter;
248
+ createdAt: IsoDate;
249
+ updatedAt: IsoDate;
250
+ }
251
+ export interface CreateSegmentInput {
252
+ /** Trimmed, 1..120 characters. */
253
+ name: string;
254
+ /** Trimmed, up to 500 characters. */
255
+ description?: string;
256
+ /** Rejected on write if the conditions do not parse, rather than when first run. */
257
+ filter: ContactFilter;
258
+ }
259
+ export type UpdateSegmentInput = Partial<CreateSegmentInput>;
260
+ /** `search` matches the segment name and description. */
261
+ export type ListSegmentsQuery = ListQuery;
262
+ /** The only module triggers watch today. */
263
+ export type CrmTriggerModule = 'contact';
264
+ /**
265
+ * `event` triggers run off a contact change. `time` triggers are scheduled, and
266
+ * are stored and served but not yet dispatched -- nothing schedules them.
267
+ */
268
+ export type CrmTriggerType = 'event' | 'time';
269
+ /**
270
+ * What happened to the contact. `edited` and `modified` are both any-change; the
271
+ * rest are narrower readings of the same update, decided by which paths moved.
272
+ */
273
+ export type CrmTriggerEvent = 'agent_assigned' | 'agent_deassigned' | 'created' | 'edited' | 'modified' | 'deleted' | 'marked_as_done' | 'marked_as_closed' | 'marked_as_archived' | 'blocked';
274
+ /**
275
+ * Narrows an event to the fields it touched. `any` fires on every change,
276
+ * `any_of_selected` needs one of `fields` to have moved, `all` needs all of
277
+ * them. Events with no change set -- a creation, a deletion -- pass regardless.
278
+ */
279
+ export interface CrmTriggerWhen {
280
+ /** Default `'any'`. */
281
+ condition?: 'any' | 'any_of_selected' | 'all';
282
+ /** Dotted contact paths: `name.first_name`, `chat_metadata.closed`. Default `[]`. */
283
+ fields?: string[];
284
+ }
285
+ export type CrmTriggerHttpMethod = 'POST' | 'PUT' | 'PATCH' | 'GET';
286
+ /** Webhook is the only action the schema defines. */
287
+ export interface CrmTriggerAction {
288
+ /** Default `'webhook'`. */
289
+ type?: 'webhook';
290
+ config: {
291
+ url: string;
292
+ /** Default `'POST'`. */
293
+ method?: CrmTriggerHttpMethod;
294
+ /** Sent alongside the contact payload. Default `{}`. */
295
+ headers?: Record<string, string>;
296
+ };
297
+ }
298
+ export interface CrmTrigger {
299
+ id: string;
300
+ name: string;
301
+ active: boolean;
302
+ module: CrmTriggerModule;
303
+ type: CrmTriggerType;
304
+ trigger: CrmTriggerEvent;
305
+ when: Required<CrmTriggerWhen>;
306
+ /**
307
+ * The same conditions `contacts.list({ filter })` speaks, flat rather than
308
+ * wrapped: the changed contact has to match them for the trigger to fire.
309
+ */
310
+ filters: ContactFilterEntry[];
311
+ action: CrmTriggerAction;
312
+ createdAt: IsoDate;
313
+ updatedAt: IsoDate;
314
+ }
315
+ export interface CreateCrmTriggerInput {
316
+ /** Trimmed, 1..120 characters. */
317
+ name: string;
318
+ /** Default `true`. */
319
+ active?: boolean;
320
+ /** Default `'contact'`. */
321
+ module?: CrmTriggerModule;
322
+ /** Default `'event'`. */
323
+ type?: CrmTriggerType;
324
+ /** Default `'edited'`. */
325
+ trigger?: CrmTriggerEvent;
326
+ /** Default `{ condition: 'any', fields: [] }`. */
327
+ when?: CrmTriggerWhen;
328
+ /** At most 50 conditions. Default `[]`, which fires on every matching event. */
329
+ filters?: ContactFilterEntry[];
330
+ action: CrmTriggerAction;
331
+ }
332
+ export type UpdateCrmTriggerInput = Partial<CreateCrmTriggerInput>;
333
+ /** `search` matches the trigger name. */
334
+ export interface ListCrmTriggersQuery extends ListQuery {
335
+ /** Quick filter: the contact event the trigger watches. */
336
+ trigger?: CrmTriggerEvent;
337
+ type?: CrmTriggerType;
338
+ active?: boolean;
339
+ }
340
+ export type CrmTriggerLogStatus = 'success' | 'fail';
341
+ /**
342
+ * One dispatch attempt. Logs are written by the dispatcher, never by a caller,
343
+ * and the collection expires them after 30 days.
344
+ */
345
+ export interface CrmTriggerLog {
346
+ id: string;
347
+ /** Id of the trigger that fired. */
348
+ trigger: string;
349
+ event: CrmTriggerEvent;
350
+ status: CrmTriggerLogStatus;
351
+ payload: {
352
+ url?: string;
353
+ body?: unknown;
354
+ };
355
+ /** Whatever came back: status and body, or the error that stopped the call. */
356
+ response?: unknown;
357
+ /** When the log row is removed. */
358
+ expiryDate: IsoDate;
359
+ createdAt: IsoDate;
360
+ updatedAt: IsoDate;
361
+ }
362
+ export interface ListCrmTriggerLogsQuery extends ListQuery {
363
+ /** Quick filter: one trigger's history. */
364
+ trigger?: ObjectId;
365
+ event?: CrmTriggerEvent;
366
+ status?: CrmTriggerLogStatus;
367
+ }
368
+ /** Import and export history share one lifecycle, and a row starts out `pending`. */
369
+ export type HistoryStatus = 'pending' | 'processing' | 'completed' | 'failed';
370
+ /** What a history row moved: contacts, or datastore records. */
371
+ export type HistoryModule = 'contact' | 'datastore';
372
+ /**
373
+ * `extra` is an untyped column on both schemas. The SDK carries it through
374
+ * verbatim, so anything an older writer left there survives a round trip.
375
+ * A failed import puts its reason in `extra.error`.
376
+ */
377
+ export type HistoryExtra = JsonObject;
378
+ /**
379
+ * Everything the worker needs to read the file. The stored column is untyped,
380
+ * so the keys the platform acts on are named and anything else is passed
381
+ * through rather than dropped.
382
+ */
383
+ export interface ImportConfig {
384
+ /** Column header -> contact field. Default `{}`. */
385
+ mapping?: Record<string, string>;
386
+ /** What to do with a row matching an existing contact. Default `'skip'`. */
387
+ duplicateStrategy?: 'skip' | 'update';
388
+ /** Anything else a caller or an older writer put here. */
389
+ [key: string]: unknown;
390
+ }
391
+ /** Counted by the worker as it walks the file; `new` + `duplicate` = `success`. */
392
+ export interface ImportStatistics {
393
+ total: number;
394
+ success: number;
395
+ failed: number;
396
+ /** Rows that created a contact. */
397
+ new: number;
398
+ /** Rows that matched one that already existed. */
399
+ duplicate: number;
400
+ }
401
+ export interface ImportHistory {
402
+ id: string;
403
+ /** The team member who started it; rows written before members existed carry none. */
404
+ member?: string;
405
+ module: HistoryModule;
406
+ /** Storage key of the uploaded file. */
407
+ file: string;
408
+ title: string;
409
+ status: HistoryStatus;
410
+ config: ImportConfig;
411
+ extra: HistoryExtra;
412
+ statistics: ImportStatistics;
413
+ createdAt: IsoDate;
414
+ updatedAt: IsoDate;
415
+ }
416
+ export interface CreateImportHistoryInput {
417
+ /** Default `'contact'`. */
418
+ module?: HistoryModule;
419
+ /** Storage key of the uploaded file, 1..1024 characters. The worker resolves it. */
420
+ file: string;
421
+ /** Trimmed, 1..200 characters. */
422
+ title: string;
423
+ /** Default `{}`, which means an empty mapping and `duplicateStrategy: 'skip'`. */
424
+ config?: ImportConfig;
425
+ /** Default `{}`. */
426
+ extra?: HistoryExtra;
427
+ }
428
+ /** `search` matches the title. */
429
+ export interface ListImportHistoryQuery extends ListQuery {
430
+ module?: HistoryModule;
431
+ status?: HistoryStatus;
432
+ }
433
+ /**
434
+ * What to write out. Sending both a segment and a filter narrows the segment,
435
+ * the same way `contacts.list` reads the pair.
436
+ */
437
+ export interface ExportConfig {
438
+ /** A saved segment's id or its name. */
439
+ segment?: string;
440
+ filter?: ContactFilter;
441
+ /** Columns to write; empty means the worker's default set. Default `[]`. */
442
+ fields?: string[];
443
+ /** Anything else a caller or an older writer put here. */
444
+ [key: string]: unknown;
445
+ }
446
+ export interface ExportHistory {
447
+ id: string;
448
+ /** The team member who started it; rows written before members existed carry none. */
449
+ member?: string;
450
+ module: HistoryModule;
451
+ /** Storage key of the finished file; absent until the worker has written one. */
452
+ file?: string;
453
+ title: string;
454
+ /** Rows written. `0` until the export completes. */
455
+ count: number;
456
+ status: HistoryStatus;
457
+ /** Why it failed, when it did. */
458
+ error?: string;
459
+ config: ExportConfig;
460
+ extra: HistoryExtra;
461
+ createdAt: IsoDate;
462
+ updatedAt: IsoDate;
463
+ }
464
+ export interface CreateExportHistoryInput {
465
+ /** Default `'contact'`. */
466
+ module?: HistoryModule;
467
+ /** Trimmed, 1..200 characters. */
468
+ title: string;
469
+ /** Default `{}`, which exports every contact with the worker's default columns. */
470
+ config?: ExportConfig;
471
+ /** Default `{}`. */
472
+ extra?: HistoryExtra;
473
+ }
474
+ /** `search` matches the title. */
475
+ export interface ListExportHistoryQuery extends ListQuery {
476
+ module?: HistoryModule;
477
+ status?: HistoryStatus;
478
+ }
479
+ export type WebhookEventType = 'contact.created' | 'contact.updated' | 'contact.deleted';
480
+ export interface Webhook {
481
+ id: string;
482
+ url: string;
483
+ events: WebhookEventType[];
484
+ enabled: boolean;
485
+ /** Consecutive delivery failures. */
486
+ failureCount: number;
487
+ lastDeliveredAt?: IsoDate;
488
+ createdAt: IsoDate;
489
+ updatedAt: IsoDate;
490
+ }
491
+ export interface CreateWebhookInput {
492
+ /** Must be a valid absolute URL. */
493
+ url: string;
494
+ /** At least one event. */
495
+ events: WebhookEventType[];
496
+ /** Default `true`. */
497
+ enabled?: boolean;
498
+ }
499
+ export type UpdateWebhookInput = Partial<CreateWebhookInput>;
500
+ /** Cursor paginated. */
501
+ export interface ListWebhooksQuery extends PageQuery {
502
+ enabled?: boolean;
503
+ }
504
+ /** The body the platform POSTs to a registered webhook URL. */
505
+ export interface WebhookEnvelope {
506
+ /** Delivery id, stable across retries of the same event. */
507
+ id: string;
508
+ type: string;
509
+ tenantId: string;
510
+ createdAt: IsoDate;
511
+ data: unknown;
512
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=audience.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audience.js","sourceRoot":"","sources":["../../src/types/audience.ts"],"names":[],"mappings":""}