import {z} from 'zod' export type AutomationStageTrigger = {type: 'stage', stage: string}; export type AutomationSegmentTrigger = {type: 'segment', conditions: Array>, frequency?: ('everyTime' | 'once') | undefined}; export type AutomationReplyTrigger = {type: 'reply', stages?: Array | undefined, frequency?: ('everyTime' | 'once') | undefined, audience?: ('anyone' | 'relatedContacts') | undefined, reopenArchived?: boolean | undefined}; export type AutomationTrigger = AutomationStageTrigger | AutomationSegmentTrigger | AutomationReplyTrigger; export type AutomationTiming = {mode: 'now', useBusinessHours?: boolean | undefined} | {mode: 'after', amount: number, unit: 'minutes' | 'hours' | 'days' | 'months', anchor?: string | undefined, timeOfDay?: number | undefined, useBusinessHours?: boolean | undefined} | {mode: 'dayOfWeek', day: 'sunday' | 'monday' | 'tuesday' | 'wednesday' | 'thursday' | 'friday' | 'saturday', timeOfDay: number} | {mode: 'daysOfWeek', days: Array, timeOfDay: number} | {mode: 'dayOfMonth', day: number, timeOfDay: number} | {mode: 'dateRange', startDay: number, endDay: number, timeOfDay: number} | {mode: 'everyXDays', interval: number, startImmediately?: boolean | undefined, timeOfDay?: number | undefined}; export type AutomationRecipient = {type: 'assignee'} | {type: 'relatedContacts'} | {type: 'contactTypes', contactTypeIds: Array} | {type: 'specific', addresses: Array} | {type: 'field', fieldUuid: string}; export type AutomationAction = {type: 'email', inbox: string, templateId: string, to: AutomationRecipient, cc?: Array | undefined, deliveryMode?: ('multiple' | 'single') | undefined, fallback?: {inbox: string, templateId: string} | undefined} | {type: 'sms', inbox: string, templateId: string, to: AutomationRecipient, fallback?: {inbox: string, templateId: string} | undefined} | {type: 'task', source: 'template' | 'manual', templateId?: string | undefined, tasks?: (Array<{title: string, description?: string | undefined, userId?: string | undefined, dueInDays?: number | undefined, dueFrom?: string | undefined}>) | undefined, fieldUuid?: string | undefined, useBusinessDays?: boolean | undefined} | {type: 'assign', mode: 'user' | 'team' | 'roundRobin' | 'contactField', userId?: string | undefined, teamId?: string | undefined, contactFieldUuid?: string | undefined, onlyIfUnassigned?: boolean | undefined} | {type: 'update_fields', fields: Array<{fieldUuid: string, value: unknown}>} | {type: 'stage', stage: string} | {type: 'due_date', from?: string | undefined, days?: number | undefined, useBusinessDays?: boolean | undefined} | {type: 'notify', userIds?: Array | undefined, teamIds?: Array | undefined, fieldUuids?: Array | undefined, notifyCardCreator?: boolean | undefined, message?: string | undefined} | {type: 'archive'} | {type: 'archive_convos'} | {type: 'webhook', url: string}; export type CreateAutomationRequest = {title: string, trigger: AutomationTrigger, timing?: AutomationTiming | undefined, actions: Array}; export type CreateApiApiBoardBoardIdConfigurationAutomationsArgs = {boardId: string, body: CreateAutomationRequest}; export type CreateApiApiBoardBoardIdConfigurationAutomationsOptions = {baseUrl?: string | undefined, ApiKeyHeader?: string | undefined, fetch?: typeof fetch | undefined}; export const createApiApiBoardBoardIdConfigurationAutomationsResponse = z.object({data: z.object({uuid: z.string().optional(), title: z.string().optional(), archived: z.boolean().optional(), triggerOn: z.string().optional(), timingMode: z.string().optional(), description: z.string().optional(), actions: z.array(z.object({})).optional()}).optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Create an automation * * POST /api/board/{boardId}/configuration/automations * * Also accepts auth: PartnerBearer */ export const createApiApiBoardBoardIdConfigurationAutomations = async (args: CreateApiApiBoardBoardIdConfigurationAutomationsArgs, options?: CreateApiApiBoardBoardIdConfigurationAutomationsOptions) => { const {baseUrl = "https://core-api.getaptly.com", fetch: fetchFn = fetch, ApiKeyHeader} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (ApiKeyHeader !== undefined) headers.set("x-token", ApiKeyHeader) const url = `${baseUrl.replace(/\/+$/, '')}/api/board/${encodeURIComponent(String(args.boardId))}/configuration/automations${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(createApiApiBoardBoardIdConfigurationAutomationsResponse, await res.json()) };