@automate.ax/integration-contracts 0.139.1 → 0.141.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.
@@ -0,0 +1,157 @@
1
+ import { isEncodable, type Encodable } from "@automate.ax/codec"
2
+ import * as z from "zod"
3
+
4
+ const CLOSEBOT_API_ORIGIN = "https://api.closebot.com/"
5
+
6
+ const CLOSEBOT_SECRET_SCHEMA = z.object({
7
+ apiKey: z.string().trim().min(1),
8
+ })
9
+
10
+ export const CLOSEBOT_VALUE_SCHEMA = z.custom<Encodable>(isEncodable, {
11
+ message: "Expected a codec-safe CloseBot value.",
12
+ })
13
+
14
+ export const CLOSEBOT_RESPONSE_SCHEMA = z.union([
15
+ CLOSEBOT_VALUE_SCHEMA,
16
+ z.undefined().transform(() => null),
17
+ ])
18
+
19
+ interface CloseBotRequestOptions<TSchema extends z.ZodType> {
20
+ body?: Encodable | FormData
21
+ method?: "DELETE" | "GET" | "PATCH" | "POST" | "PUT"
22
+ query?: Record<
23
+ string,
24
+ | boolean
25
+ | Date
26
+ | number
27
+ | string
28
+ | (boolean | Date | number | string)[]
29
+ | null
30
+ | undefined
31
+ >
32
+ responseSchema: TSchema
33
+ }
34
+
35
+ /** Error returned by a rejected CloseBot API request. */
36
+ export class CloseBotApiError extends Error {
37
+ readonly details: Encodable
38
+ readonly retryAfter?: string
39
+ readonly status: number
40
+
41
+ /**
42
+ * Creates an error from a rejected CloseBot response.
43
+ *
44
+ * @param status - HTTP response status.
45
+ * @param details - Codec-safe response details.
46
+ * @param retryAfter - Raw provider retry timing, when present.
47
+ */
48
+ constructor(status: number, details: Encodable, retryAfter?: string) {
49
+ super(`CloseBot API request failed (${status}).`)
50
+ this.name = "CloseBotApiError"
51
+ this.details = details
52
+ this.retryAfter = retryAfter
53
+ this.status = status
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Creates an authenticated CloseBot REST API client.
59
+ *
60
+ * @param secret - Stored CloseBot API key.
61
+ */
62
+ export function getCloseBotApi(secret: unknown) {
63
+ const { apiKey } = CLOSEBOT_SECRET_SCHEMA.parse(secret)
64
+ const root = new URL(CLOSEBOT_API_ORIGIN)
65
+
66
+ return {
67
+ /**
68
+ * Sends one JSON request to a CloseBot API path.
69
+ *
70
+ * @param path - Relative path below the CloseBot API origin.
71
+ * @param options - Request method, query, body, and response schema.
72
+ */
73
+ async request<TSchema extends z.ZodType>(
74
+ path: string,
75
+ options: CloseBotRequestOptions<TSchema>,
76
+ ): Promise<z.output<TSchema>> {
77
+ const normalizedPath = path.replace(/^\/+/, "")
78
+ if (
79
+ !normalizedPath ||
80
+ normalizedPath.includes("://") ||
81
+ normalizedPath.includes("\\")
82
+ ) {
83
+ throw new TypeError("CloseBot API paths must be relative.")
84
+ }
85
+
86
+ const url = new URL(normalizedPath, root)
87
+ if (url.origin !== root.origin) {
88
+ throw new TypeError(
89
+ "CloseBot API paths must remain on api.closebot.com.",
90
+ )
91
+ }
92
+ for (const [key, value] of Object.entries(options.query ?? {})) {
93
+ if (value == null) continue
94
+ if (Array.isArray(value)) {
95
+ for (const item of value)
96
+ url.searchParams.append(key, queryValue(item))
97
+ } else {
98
+ url.searchParams.set(key, queryValue(value))
99
+ }
100
+ }
101
+
102
+ const headers = new Headers({
103
+ Accept: "application/json",
104
+ "X-CB-KEY": apiKey,
105
+ })
106
+ if (options.body !== undefined && !(options.body instanceof FormData)) {
107
+ headers.set("Content-Type", "application/json")
108
+ }
109
+
110
+ const response = await fetch(url, {
111
+ body:
112
+ options.body === undefined
113
+ ? undefined
114
+ : options.body instanceof FormData
115
+ ? options.body
116
+ : JSON.stringify(options.body),
117
+ headers,
118
+ method: options.method ?? "GET",
119
+ redirect: "error",
120
+ })
121
+ const text = await response.text()
122
+ const parsed = CLOSEBOT_RESPONSE_SCHEMA.safeParse(
123
+ text ? parseJson(text) : null,
124
+ )
125
+ if (!response.ok || !parsed.success) {
126
+ throw new CloseBotApiError(
127
+ response.status,
128
+ parsed.success ? parsed.data : { response: text },
129
+ response.headers.get("Retry-After") ?? undefined,
130
+ )
131
+ }
132
+ return options.responseSchema.parse(parsed.data)
133
+ },
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Parses a response while retaining non-JSON provider diagnostics.
139
+ *
140
+ * @param value - Raw response body.
141
+ */
142
+ function parseJson(value: string): unknown {
143
+ try {
144
+ return JSON.parse(value)
145
+ } catch {
146
+ return value
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Serializes one supported query value.
152
+ *
153
+ * @param value - Public query value.
154
+ */
155
+ function queryValue(value: boolean | Date | number | string) {
156
+ return value instanceof Date ? value.toISOString() : String(value)
157
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./api"
2
+ export * from "./schemas"
@@ -0,0 +1,517 @@
1
+ import * as z from "zod"
2
+
3
+ export const CLOSEBOT_ID_SCHEMA = z.string().trim().min(1)
4
+
5
+ export const CLOSEBOT_DATE_SCHEMA = z
6
+ .union([z.date(), z.iso.datetime({ offset: true })])
7
+ .transform((value) => (value instanceof Date ? value : new Date(value)))
8
+
9
+ const OPTIONAL_STRING = z.string().nullable().optional()
10
+ const OPTIONAL_BOOLEAN = z.boolean().optional()
11
+ const OPTIONAL_INTEGER = z.number().int().optional()
12
+ const OPTIONAL_DATE = CLOSEBOT_DATE_SCHEMA.nullable().optional()
13
+
14
+ export const CLOSEBOT_AGENCY_MEMBER_SCHEMA = z.object({
15
+ accountId: OPTIONAL_STRING,
16
+ authId: OPTIONAL_STRING,
17
+ email: OPTIONAL_STRING,
18
+ name: OPTIONAL_STRING,
19
+ role: OPTIONAL_STRING,
20
+ status: OPTIONAL_STRING,
21
+ })
22
+
23
+ export const CLOSEBOT_AGENCY_SCHEMA = z.object({
24
+ betaTester: OPTIONAL_BOOLEAN,
25
+ id: OPTIONAL_STRING,
26
+ members: CLOSEBOT_AGENCY_MEMBER_SCHEMA.array().nullable().optional(),
27
+ name: OPTIONAL_STRING,
28
+ })
29
+
30
+ export const CLOSEBOT_FOLLOW_UP_SEQUENCE_SCHEMA = z.object({
31
+ duration: OPTIONAL_INTEGER,
32
+ order: OPTIONAL_INTEGER,
33
+ unit: OPTIONAL_STRING,
34
+ })
35
+
36
+ export const CLOSEBOT_FOLLOW_UP_STATE_SCHEMA = z.object({
37
+ extraPrompt: OPTIONAL_STRING,
38
+ id: OPTIONAL_INTEGER,
39
+ isDefault: OPTIONAL_BOOLEAN,
40
+ name: OPTIONAL_STRING,
41
+ order: OPTIONAL_INTEGER,
42
+ repeatFinal: OPTIONAL_BOOLEAN,
43
+ sequences: CLOSEBOT_FOLLOW_UP_SEQUENCE_SCHEMA.array().nullable().optional(),
44
+ })
45
+
46
+ export const CLOSEBOT_TAG_SCHEMA = z.object({
47
+ approveDeny: OPTIONAL_BOOLEAN,
48
+ id: OPTIONAL_STRING,
49
+ name: OPTIONAL_STRING,
50
+ })
51
+
52
+ export const CLOSEBOT_TAG_FILTER_SCHEMA = z.object({
53
+ groups: z
54
+ .object({
55
+ operator: OPTIONAL_STRING,
56
+ rules: z
57
+ .object({
58
+ condition: OPTIONAL_STRING,
59
+ tagId: OPTIONAL_STRING,
60
+ tagName: OPTIONAL_STRING,
61
+ })
62
+ .array()
63
+ .nullable()
64
+ .optional(),
65
+ })
66
+ .array()
67
+ .nullable()
68
+ .optional(),
69
+ operator: OPTIONAL_STRING,
70
+ })
71
+
72
+ export const CLOSEBOT_CHANNEL_RULES_SCHEMA = z.object({
73
+ channels: z
74
+ .object({
75
+ channel: OPTIONAL_STRING,
76
+ rules: z
77
+ .object({ operator: OPTIONAL_STRING, value: OPTIONAL_STRING })
78
+ .array()
79
+ .nullable()
80
+ .optional(),
81
+ type: OPTIONAL_STRING,
82
+ })
83
+ .array()
84
+ .nullable()
85
+ .optional(),
86
+ })
87
+
88
+ export const CLOSEBOT_BOT_SOURCE_SCHEMA = z.object({
89
+ category: OPTIONAL_STRING,
90
+ channelList: z.string().array().nullable().optional(),
91
+ channelRules: CLOSEBOT_CHANNEL_RULES_SCHEMA.optional(),
92
+ enabled: OPTIONAL_BOOLEAN,
93
+ flowVariableValues: z.record(z.string(), z.string()).nullable().optional(),
94
+ id: OPTIONAL_STRING,
95
+ key: OPTIONAL_STRING,
96
+ name: OPTIONAL_STRING,
97
+ personaNameOverride: OPTIONAL_STRING,
98
+ tagFilterConfig: CLOSEBOT_TAG_FILTER_SCHEMA.optional(),
99
+ tags: CLOSEBOT_TAG_SCHEMA.array().nullable().optional(),
100
+ })
101
+
102
+ export const CLOSEBOT_BOT_VERSION_SCHEMA = z.object({
103
+ modifiedAt: CLOSEBOT_DATE_SCHEMA.optional(),
104
+ modifiedBy: OPTIONAL_STRING,
105
+ name: OPTIONAL_STRING,
106
+ published: OPTIONAL_BOOLEAN,
107
+ version: OPTIONAL_STRING,
108
+ })
109
+
110
+ export const CLOSEBOT_PERSONA_SPLIT_TEST_SOURCE_RESULT_SCHEMA = z.object({
111
+ averageLeadScore: z.number().optional(),
112
+ responseCount: OPTIONAL_INTEGER,
113
+ sourceId: OPTIONAL_STRING,
114
+ sourceName: OPTIONAL_STRING,
115
+ totalInstances: OPTIONAL_INTEGER,
116
+ })
117
+
118
+ export const CLOSEBOT_PERSONA_SPLIT_TEST_RESULTS_SCHEMA = z.object({
119
+ averageLeadScore: z.number().optional(),
120
+ computedAt: CLOSEBOT_DATE_SCHEMA.optional(),
121
+ personaId: OPTIONAL_STRING,
122
+ personaName: OPTIONAL_STRING,
123
+ responseCount: OPTIONAL_INTEGER,
124
+ sources: CLOSEBOT_PERSONA_SPLIT_TEST_SOURCE_RESULT_SCHEMA.array()
125
+ .nullable()
126
+ .optional(),
127
+ splitWeight: OPTIONAL_INTEGER,
128
+ totalInstances: OPTIONAL_INTEGER,
129
+ })
130
+
131
+ export const CLOSEBOT_PERSONA_SPLIT_TEST_SCHEMA = z.object({
132
+ endedAt: OPTIONAL_DATE,
133
+ id: OPTIONAL_STRING,
134
+ isActive: OPTIONAL_BOOLEAN,
135
+ personas: z
136
+ .object({
137
+ order: OPTIONAL_INTEGER,
138
+ personaId: OPTIONAL_STRING,
139
+ results: CLOSEBOT_PERSONA_SPLIT_TEST_RESULTS_SCHEMA.optional(),
140
+ weight: OPTIONAL_INTEGER,
141
+ })
142
+ .array()
143
+ .nullable()
144
+ .optional(),
145
+ startedAt: OPTIONAL_DATE,
146
+ })
147
+
148
+ export const CLOSEBOT_BOT_TEMPLATE_SCHEMA = z.object({
149
+ description: OPTIONAL_STRING,
150
+ id: OPTIONAL_STRING,
151
+ industry: OPTIONAL_STRING,
152
+ level: OPTIONAL_STRING,
153
+ name: OPTIONAL_STRING,
154
+ previewUrl: OPTIONAL_STRING,
155
+ tags: z.string().array().nullable().optional(),
156
+ tier: OPTIONAL_STRING,
157
+ videoUrl: OPTIONAL_STRING,
158
+ })
159
+
160
+ export const CLOSEBOT_FOLDER_SCHEMA = z.object({
161
+ bots: z.string().array().nullable(),
162
+ children: z.string().array().nullable(),
163
+ id: z.string().nullable(),
164
+ name: z.string().nullable(),
165
+ personas: z.string().array().nullable(),
166
+ })
167
+
168
+ export const CLOSEBOT_FOLDER_CREATED_SCHEMA = z.object({
169
+ id: z.string().nullable(),
170
+ })
171
+
172
+ export const CLOSEBOT_BOT_SCHEMA = z.object({
173
+ category: OPTIONAL_STRING,
174
+ favorited: OPTIONAL_BOOLEAN,
175
+ folderId: OPTIONAL_STRING,
176
+ followUpActive: OPTIONAL_BOOLEAN,
177
+ followUpExtraPrompt: OPTIONAL_STRING,
178
+ followUpRepeat: OPTIONAL_BOOLEAN,
179
+ followUpSequences: CLOSEBOT_FOLLOW_UP_SEQUENCE_SCHEMA.array()
180
+ .nullable()
181
+ .optional(),
182
+ followUpStates: CLOSEBOT_FOLLOW_UP_STATE_SCHEMA.array().nullable().optional(),
183
+ followUpVarianceMinutes: OPTIONAL_INTEGER,
184
+ id: OPTIONAL_STRING,
185
+ locked: OPTIONAL_BOOLEAN,
186
+ modifiedAt: OPTIONAL_STRING,
187
+ modifiedBy: OPTIONAL_STRING,
188
+ name: OPTIONAL_STRING,
189
+ personaIds: z.string().array().nullable().optional(),
190
+ personaSplitTest: CLOSEBOT_PERSONA_SPLIT_TEST_SCHEMA.optional(),
191
+ personaWeights: z.record(z.string(), z.number().int()).nullable().optional(),
192
+ reschedulingEnabled: OPTIONAL_BOOLEAN,
193
+ smartFollowUp: OPTIONAL_BOOLEAN,
194
+ sources: CLOSEBOT_BOT_SOURCE_SCHEMA.array().nullable().optional(),
195
+ tools: z
196
+ .object({
197
+ enabled: OPTIONAL_BOOLEAN,
198
+ id: OPTIONAL_STRING,
199
+ options: z.object({}).optional(),
200
+ type: OPTIONAL_STRING,
201
+ })
202
+ .array()
203
+ .nullable()
204
+ .optional(),
205
+ versions: CLOSEBOT_BOT_VERSION_SCHEMA.array().nullable().optional(),
206
+ })
207
+
208
+ export const CLOSEBOT_PUBLISH_BOT_RESULT_SCHEMA = z.object({
209
+ message: z.json().optional(),
210
+ version: OPTIONAL_STRING,
211
+ })
212
+
213
+ export const CLOSEBOT_LEAD_FIELD_SCHEMA = z.object({
214
+ aiProduced: OPTIONAL_BOOLEAN,
215
+ field: OPTIONAL_STRING,
216
+ name: OPTIONAL_STRING,
217
+ value: OPTIONAL_STRING,
218
+ })
219
+
220
+ export const CLOSEBOT_BOT_INSTANCE_SCHEMA = z.object({
221
+ botId: OPTIONAL_STRING,
222
+ botVersion: OPTIONAL_STRING,
223
+ followUpTime: OPTIONAL_DATE,
224
+ followUpTimezone: OPTIONAL_STRING,
225
+ followUpTimezoneKind: OPTIONAL_STRING,
226
+ isSmartFollowUpTime: OPTIONAL_BOOLEAN,
227
+ scheduleRespondTime: OPTIONAL_DATE,
228
+ })
229
+
230
+ export const CLOSEBOT_LEAD_SCHEMA = z.object({
231
+ contactId: OPTIONAL_STRING,
232
+ fields: CLOSEBOT_LEAD_FIELD_SCHEMA.array().nullable().optional(),
233
+ id: OPTIONAL_STRING,
234
+ instances: CLOSEBOT_BOT_INSTANCE_SCHEMA.array().nullable().optional(),
235
+ lastMessage: OPTIONAL_STRING,
236
+ lastMessageBotId: OPTIONAL_STRING,
237
+ lastMessageDirection: OPTIONAL_STRING,
238
+ lastMessageIsNote: OPTIONAL_BOOLEAN,
239
+ lastMessageTime: OPTIONAL_DATE,
240
+ mentionedMe: OPTIONAL_BOOLEAN,
241
+ mimicSourceId: OPTIONAL_STRING,
242
+ mostRecentFailureReason: OPTIONAL_STRING,
243
+ name: OPTIONAL_STRING,
244
+ score: z.number().int().nullable().optional(),
245
+ source: z.object({ id: OPTIONAL_STRING, name: OPTIONAL_STRING }).optional(),
246
+ starred: OPTIONAL_BOOLEAN,
247
+ tags: z.string().array().nullable().optional(),
248
+ unread: OPTIONAL_BOOLEAN,
249
+ wontRespondUntil: OPTIONAL_DATE,
250
+ })
251
+
252
+ export const CLOSEBOT_LEAD_PAGE_SCHEMA = z.object({
253
+ mentionsTotal: z.number().int().nullable().optional(),
254
+ page: z.number().int(),
255
+ pageSize: z.number().int(),
256
+ results: CLOSEBOT_LEAD_SCHEMA.array().nullable(),
257
+ starredTotal: z.number().int().nullable().optional(),
258
+ total: z.number().int(),
259
+ })
260
+
261
+ export const CLOSEBOT_LEAD_SEARCH_RESULT_SCHEMA = z.object({
262
+ leads: CLOSEBOT_LEAD_SCHEMA.array().nullable(),
263
+ mentionsTotal: z.number().int().nullable().optional(),
264
+ starredTotal: z.number().int().nullable().optional(),
265
+ total: z.number().int(),
266
+ })
267
+
268
+ export const CLOSEBOT_LEAD_AI_STATUS_SCHEMA = z.object({
269
+ applicable: OPTIONAL_BOOLEAN,
270
+ enabled: OPTIONAL_BOOLEAN,
271
+ reason: OPTIONAL_STRING,
272
+ })
273
+
274
+ export const CLOSEBOT_LEAD_HISTORY_EVENT_SCHEMA = z.object({
275
+ actionKey: OPTIONAL_STRING,
276
+ domain: OPTIONAL_STRING,
277
+ eventType: OPTIONAL_STRING,
278
+ id: OPTIONAL_STRING,
279
+ path: OPTIONAL_STRING,
280
+ points: z.number().int().nullable().optional(),
281
+ title: OPTIONAL_STRING,
282
+ triggerType: OPTIONAL_STRING,
283
+ url: OPTIONAL_STRING,
284
+ visitedAt: CLOSEBOT_DATE_SCHEMA.optional(),
285
+ })
286
+
287
+ export const CLOSEBOT_NOTE_RESULT_SCHEMA = z.object({
288
+ aiVisible: z.boolean(),
289
+ noteId: z.string().nullable(),
290
+ })
291
+
292
+ export const CLOSEBOT_SCHEDULED_MESSAGE_SCHEMA = z.object({
293
+ body: OPTIONAL_STRING,
294
+ botId: OPTIONAL_STRING,
295
+ cancelOnReply: z.boolean(),
296
+ channel: OPTIONAL_STRING,
297
+ createdAt: CLOSEBOT_DATE_SCHEMA,
298
+ createdByAccountId: z.string().nullable(),
299
+ createdByIconUrl: OPTIONAL_STRING,
300
+ createdByName: OPTIONAL_STRING,
301
+ id: z.string().nullable(),
302
+ kind: z.string().nullable(),
303
+ leadId: z.string().nullable(),
304
+ sendAt: CLOSEBOT_DATE_SCHEMA,
305
+ sentMessageId: OPTIONAL_STRING,
306
+ sourceId: OPTIONAL_STRING,
307
+ status: z.string().nullable(),
308
+ statusReason: OPTIONAL_STRING,
309
+ })
310
+
311
+ export const CLOSEBOT_SEND_MESSAGE_RESULT_SCHEMA = z.object({
312
+ messageId: z.string().nullable(),
313
+ })
314
+
315
+ export const CLOSEBOT_SOURCE_AVAILABILITY_SCHEMA = z.object({
316
+ dayOfWeekUtc: OPTIONAL_STRING,
317
+ duration: OPTIONAL_STRING,
318
+ startTimeUtc: OPTIONAL_STRING,
319
+ })
320
+
321
+ export const CLOSEBOT_BOT_SOURCE_AVAILABILITY_SCHEMA =
322
+ CLOSEBOT_SOURCE_AVAILABILITY_SCHEMA.extend({ channel: OPTIONAL_STRING })
323
+
324
+ export const CLOSEBOT_DO_NOT_RESPOND_WINDOW_SCHEMA = z.object({
325
+ end: CLOSEBOT_DATE_SCHEMA.optional(),
326
+ start: CLOSEBOT_DATE_SCHEMA.optional(),
327
+ })
328
+
329
+ export const CLOSEBOT_SOURCE_SCHEMA = z.object({
330
+ accountsWithAccess: z.string().array().nullable().optional(),
331
+ address: OPTIONAL_STRING,
332
+ agencyId: OPTIONAL_STRING,
333
+ autoShutoff: OPTIONAL_BOOLEAN,
334
+ botRespondWindows: CLOSEBOT_BOT_SOURCE_AVAILABILITY_SCHEMA.array()
335
+ .nullable()
336
+ .optional(),
337
+ bots: z
338
+ .object({
339
+ botName: OPTIONAL_STRING,
340
+ channelRules: CLOSEBOT_CHANNEL_RULES_SCHEMA.optional(),
341
+ channels: z.string().array().nullable().optional(),
342
+ enabled: OPTIONAL_BOOLEAN,
343
+ id: OPTIONAL_STRING,
344
+ personaNameOverride: OPTIONAL_STRING,
345
+ tagFilterConfig: CLOSEBOT_TAG_FILTER_SCHEMA.optional(),
346
+ tags: CLOSEBOT_TAG_SCHEMA.array().nullable().optional(),
347
+ })
348
+ .array()
349
+ .nullable()
350
+ .optional(),
351
+ category: OPTIONAL_STRING,
352
+ connected: OPTIONAL_BOOLEAN,
353
+ doNotRespondWindows: CLOSEBOT_DO_NOT_RESPOND_WINDOW_SCHEMA.array()
354
+ .nullable()
355
+ .optional(),
356
+ gracefulGoodbye: OPTIONAL_BOOLEAN,
357
+ hubSpotOwnerId: OPTIONAL_STRING,
358
+ isAvailabilityContactTimezone: OPTIONAL_BOOLEAN,
359
+ isBotRespondWindowsQuietHours: OPTIONAL_BOOLEAN,
360
+ key: OPTIONAL_STRING,
361
+ markConversationAsUnread: OPTIONAL_BOOLEAN,
362
+ name: OPTIONAL_STRING,
363
+ respondToReactions: OPTIONAL_BOOLEAN,
364
+ respondWindows: CLOSEBOT_SOURCE_AVAILABILITY_SCHEMA.array()
365
+ .nullable()
366
+ .optional(),
367
+ scriptDomainAllowList: z.string().array().nullable().optional(),
368
+ scriptInstalled: OPTIONAL_BOOLEAN,
369
+ scriptLastSeenAt: OPTIONAL_DATE,
370
+ scriptLastSeenDomain: OPTIONAL_STRING,
371
+ scriptLastSeenEndpoint: OPTIONAL_STRING,
372
+ sourceId: OPTIONAL_STRING,
373
+ summarizeAttachments: OPTIONAL_BOOLEAN,
374
+ timezone: OPTIONAL_STRING,
375
+ webhookCallback: OPTIONAL_STRING,
376
+ })
377
+
378
+ export const CLOSEBOT_SOURCE_PAGE_SCHEMA = z.object({
379
+ page: z.number().int(),
380
+ pageSize: z.number().int(),
381
+ results: CLOSEBOT_SOURCE_SCHEMA.array().nullable(),
382
+ total: z.number().int(),
383
+ })
384
+
385
+ export const CLOSEBOT_SOURCE_CALENDAR_SCHEMA = z.object({
386
+ id: OPTIONAL_STRING,
387
+ name: OPTIONAL_STRING,
388
+ })
389
+
390
+ export const CLOSEBOT_SOURCE_CHANNEL_SCHEMA = z.object({
391
+ filterType: OPTIONAL_STRING,
392
+ id: OPTIONAL_STRING,
393
+ name: OPTIONAL_STRING,
394
+ source: OPTIONAL_STRING,
395
+ })
396
+
397
+ export const CLOSEBOT_SOURCE_FIELD_SCHEMA = z.object({
398
+ dataType: OPTIONAL_STRING,
399
+ fieldKey: OPTIONAL_STRING,
400
+ name: OPTIONAL_STRING,
401
+ })
402
+
403
+ export const CLOSEBOT_SOURCE_FIELDS_SCHEMA = z.object({
404
+ contact: CLOSEBOT_SOURCE_FIELD_SCHEMA.array().nullable().optional(),
405
+ customValue: CLOSEBOT_SOURCE_FIELD_SCHEMA.array().nullable().optional(),
406
+ location: CLOSEBOT_SOURCE_FIELD_SCHEMA.array().nullable().optional(),
407
+ })
408
+
409
+ export const CLOSEBOT_SOURCE_TAG_SCHEMA = z.object({
410
+ id: OPTIONAL_STRING,
411
+ name: OPTIONAL_STRING,
412
+ })
413
+
414
+ export const CLOSEBOT_SOURCE_OWNER_SCHEMA = z.object({
415
+ email: OPTIONAL_STRING,
416
+ firstName: OPTIONAL_STRING,
417
+ lastName: OPTIONAL_STRING,
418
+ ownerId: OPTIONAL_STRING,
419
+ })
420
+
421
+ export const CLOSEBOT_LIBRARY_FILE_SOURCE_SCHEMA = z.object({
422
+ category: OPTIONAL_STRING,
423
+ id: OPTIONAL_STRING,
424
+ name: OPTIONAL_STRING,
425
+ })
426
+
427
+ export const CLOSEBOT_LIBRARY_FILE_SCHEMA = z.object({
428
+ accountId: OPTIONAL_STRING,
429
+ estimatedFileSize: z.number().int().optional(),
430
+ externalItemId: OPTIONAL_STRING,
431
+ externalLibraryResourceSyncId: OPTIONAL_STRING,
432
+ externalProvider: OPTIONAL_STRING,
433
+ externalResourceId: OPTIONAL_STRING,
434
+ externalResourceName: OPTIONAL_STRING,
435
+ externalResourceType: OPTIONAL_STRING,
436
+ faviconUrl: OPTIONAL_STRING,
437
+ fileId: OPTIONAL_STRING,
438
+ fileName: OPTIONAL_STRING,
439
+ fileSize: z.number().int().optional(),
440
+ fileStatus: OPTIONAL_STRING,
441
+ fileType: OPTIONAL_STRING,
442
+ lastModified: CLOSEBOT_DATE_SCHEMA.optional(),
443
+ lastUse: OPTIONAL_DATE,
444
+ sources: CLOSEBOT_LIBRARY_FILE_SOURCE_SCHEMA.array().nullable().optional(),
445
+ uri: OPTIONAL_STRING,
446
+ uses: z.number().int().nullable().optional(),
447
+ })
448
+
449
+ export const CLOSEBOT_LIBRARY_FILE_PREVIEW_SCHEMA = z.object({
450
+ chunks: z
451
+ .object({ chunkIndex: OPTIONAL_INTEGER, content: OPTIONAL_STRING })
452
+ .array()
453
+ .nullable()
454
+ .optional(),
455
+ content: OPTIONAL_STRING,
456
+ errorMessage: OPTIONAL_STRING,
457
+ fileId: OPTIONAL_STRING,
458
+ fileName: OPTIONAL_STRING,
459
+ fileSize: z.number().int().optional(),
460
+ fileStatus: OPTIONAL_STRING,
461
+ fileType: OPTIONAL_STRING,
462
+ lastModified: CLOSEBOT_DATE_SCHEMA.optional(),
463
+ previewSource: OPTIONAL_STRING,
464
+ })
465
+
466
+ export const CLOSEBOT_WEB_SCRAPE_PAGE_SCHEMA = z.object({
467
+ enabled: OPTIONAL_BOOLEAN,
468
+ url: OPTIONAL_STRING,
469
+ })
470
+
471
+ export const CLOSEBOT_BOT_VARIABLE_SCHEMA = z.object({
472
+ id: z.string().nullable(),
473
+ name: z.string().nullable(),
474
+ value: z.string().nullable(),
475
+ })
476
+
477
+ export const CLOSEBOT_PERSONA_SCHEMA = z.object({
478
+ agencyId: OPTIONAL_STRING,
479
+ aiProviderPreferences: z.string().array().nullable().optional(),
480
+ botIds: z.string().array().nullable().optional(),
481
+ bots: z
482
+ .object({ id: OPTIONAL_STRING, name: OPTIONAL_STRING })
483
+ .array()
484
+ .nullable()
485
+ .optional(),
486
+ breakupLargeMessagePercent: OPTIONAL_INTEGER,
487
+ color: OPTIONAL_STRING,
488
+ default: OPTIONAL_BOOLEAN,
489
+ description: OPTIONAL_STRING,
490
+ favorited: OPTIONAL_BOOLEAN,
491
+ folderId: OPTIONAL_STRING,
492
+ howToRespond: OPTIONAL_STRING,
493
+ id: OPTIONAL_STRING,
494
+ imageUri: OPTIONAL_STRING,
495
+ modifiedAt: OPTIONAL_STRING,
496
+ modifiedBy: OPTIONAL_STRING,
497
+ personaName: OPTIONAL_STRING,
498
+ responseDelay: OPTIONAL_INTEGER,
499
+ responseTime: OPTIONAL_STRING,
500
+ typoPercent: OPTIONAL_INTEGER,
501
+ voiceStyles: OPTIONAL_STRING,
502
+ })
503
+
504
+ export const CLOSEBOT_SMART_FAQ_STATE_SCHEMA = z.union([
505
+ z.literal(0),
506
+ z.literal(1),
507
+ ])
508
+
509
+ export const CLOSEBOT_SMART_FAQ_SCHEMA = z.object({
510
+ agencyId: OPTIONAL_STRING,
511
+ answer: OPTIONAL_STRING,
512
+ id: OPTIONAL_STRING,
513
+ leadIds: z.string().array().nullable().optional(),
514
+ question: OPTIONAL_STRING,
515
+ sourceId: OPTIONAL_STRING,
516
+ state: CLOSEBOT_SMART_FAQ_STATE_SCHEMA.optional(),
517
+ })