import { CLOSEBOT_ID_SCHEMA, CLOSEBOT_SOURCE_CALENDAR_SCHEMA, CLOSEBOT_SOURCE_CHANNEL_SCHEMA, CLOSEBOT_SOURCE_FIELDS_SCHEMA, CLOSEBOT_SOURCE_OWNER_SCHEMA, CLOSEBOT_SOURCE_PAGE_SCHEMA, CLOSEBOT_SOURCE_SCHEMA, CLOSEBOT_SOURCE_TAG_SCHEMA, } from "@automate.ax/integration-contracts/closebot" import * as z from "zod" import { defineAction } from "../../../automation/actions" import { CLOSEBOT_ACCOUNT, getCloseBotApi, hasCloseBotUpdate } from "./lib" const AVAILABILITY_INPUT_SCHEMA = z.object({ dayOfWeekUtc: z.string().trim().min(1), duration: z.string().trim().min(1), startTimeUtc: z.string().trim().min(1), }) /** Lists CloseBot sources with pagination, search, and ordering. */ export const listCloseBotSources = defineAction("List CloseBot sources") .describe("Lists sources with pagination, search, category, and ordering.") .account(CLOSEBOT_ACCOUNT) .input( z.object({ category: z.string().trim().min(1).optional(), forceTokenRefresh: z.boolean().prefault(false), order: z.string().trim().min(1).prefault("+id"), page: z.number().int().nonnegative().prefault(0), pageSize: z.number().int().positive().max(100).prefault(20), query: z.string().optional(), }), ) .output(CLOSEBOT_SOURCE_PAGE_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getCloseBotApi(account.secret).request("agency/source", { query: input, responseSchema: CLOSEBOT_SOURCE_PAGE_SCHEMA, }), ) /** Retrieves one CloseBot source. */ export const getCloseBotSource = defineAction("Get CloseBot source") .describe("Retrieves one CloseBot source by ID.") .account(CLOSEBOT_ACCOUNT) .input(z.object({ sourceId: CLOSEBOT_ID_SCHEMA })) .output(CLOSEBOT_SOURCE_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getCloseBotApi(account.secret).request( `agency/source/${encodeURIComponent(input.sourceId)}`, { responseSchema: CLOSEBOT_SOURCE_SCHEMA }, ), ) /** Deletes one CloseBot source and its associated data. */ export const deleteCloseBotSource = defineAction("Delete CloseBot source") .describe("Deletes a source and its associated CloseBot data.") .account(CLOSEBOT_ACCOUNT) .input(z.object({ sourceId: CLOSEBOT_ID_SCHEMA })) .output(z.null()) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => getCloseBotApi(account.secret).request( `agency/source/${encodeURIComponent(input.sourceId)}`, { method: "DELETE", responseSchema: z.null() }, ), ) /** Updates operational settings for one CloseBot source. */ export const updateCloseBotSource = defineAction("Update CloseBot source") .describe("Updates source messaging, access, availability, and web settings.") .account(CLOSEBOT_ACCOUNT) .input( z .object({ accountsWithAccess: CLOSEBOT_ID_SCHEMA.array().nullable().optional(), autoShutoff: z.boolean().nullable().optional(), botRespondWindows: AVAILABILITY_INPUT_SCHEMA.extend({ channel: z.string().trim().min(1), }) .array() .nullable() .optional(), doNotRespondWindows: z .object({ end: z.date(), start: z.date() }) .array() .nullable() .optional(), gracefulGoodbye: z.boolean().nullable().optional(), hubSpotOwnerId: z.string().trim().min(1).nullable().optional(), isAvailabilityContactTimezone: z.boolean().nullable().optional(), isBotRespondWindowsQuietHours: z.boolean().nullable().optional(), markConversationsAsUnread: z.boolean().nullable().optional(), name: z.string().trim().min(1).nullable().optional(), respondToReactions: z.boolean().nullable().optional(), respondWindows: AVAILABILITY_INPUT_SCHEMA.array().nullable().optional(), scriptDomainAllowList: z .string() .trim() .min(1) .array() .nullable() .optional(), sourceId: CLOSEBOT_ID_SCHEMA, summarizeAttachments: z.boolean().nullable().optional(), timezone: z.string().trim().min(1).nullable().optional(), webhookCallback: z.url().nullable().optional(), }) .refine( (input) => hasCloseBotUpdate(input, ["sourceId"]), "Provide a source field to update.", ), ) .output(CLOSEBOT_SOURCE_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler(async ({ account, input }) => { const { sourceId, ...body } = input return getCloseBotApi(account.secret).request( `agency/source/${encodeURIComponent(sourceId)}`, { body, method: "PUT", responseSchema: CLOSEBOT_SOURCE_SCHEMA }, ) }) /** Lists calendars available to a CloseBot source. */ export const listCloseBotSourceCalendars = defineAction( "List CloseBot source calendars", ) .describe("Lists calendars available to one source.") .account(CLOSEBOT_ACCOUNT) .input(z.object({ sourceId: CLOSEBOT_ID_SCHEMA })) .output(CLOSEBOT_SOURCE_CALENDAR_SCHEMA.array()) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getCloseBotApi(account.secret).request( `agency/source/${encodeURIComponent(input.sourceId)}/calendars`, { responseSchema: CLOSEBOT_SOURCE_CALENDAR_SCHEMA.array() }, ), ) /** Lists messaging channels available to a CloseBot source. */ export const listCloseBotSourceChannels = defineAction( "List CloseBot source channels", ) .describe("Lists messaging channels available to one source.") .account(CLOSEBOT_ACCOUNT) .input(z.object({ sourceId: CLOSEBOT_ID_SCHEMA })) .output(CLOSEBOT_SOURCE_CHANNEL_SCHEMA.array()) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getCloseBotApi(account.secret).request( `agency/source/${encodeURIComponent(input.sourceId)}/channels`, { responseSchema: CLOSEBOT_SOURCE_CHANNEL_SCHEMA.array() }, ), ) /** Lists contact, location, and custom fields for a CloseBot source. */ export const listCloseBotSourceFields = defineAction( "List CloseBot source fields", ) .describe("Lists contact, location, and custom fields for one source.") .account(CLOSEBOT_ACCOUNT) .input(z.object({ sourceId: CLOSEBOT_ID_SCHEMA })) .output(CLOSEBOT_SOURCE_FIELDS_SCHEMA) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getCloseBotApi(account.secret).request( `agency/source/${encodeURIComponent(input.sourceId)}/fields`, { responseSchema: CLOSEBOT_SOURCE_FIELDS_SCHEMA }, ), ) /** Lists contact tags available to a CloseBot source. */ export const listCloseBotSourceTags = defineAction("List CloseBot source tags") .describe("Lists contact tags available to one source.") .account(CLOSEBOT_ACCOUNT) .input(z.object({ sourceId: CLOSEBOT_ID_SCHEMA })) .output(CLOSEBOT_SOURCE_TAG_SCHEMA.array()) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getCloseBotApi(account.secret).request( `agency/source/${encodeURIComponent(input.sourceId)}/tags`, { responseSchema: CLOSEBOT_SOURCE_TAG_SCHEMA.array() }, ), ) /** Lists HubSpot owners available to a CloseBot source. */ export const listCloseBotSourceOwners = defineAction( "List CloseBot source owners", ) .describe("Lists HubSpot owners available to one source.") .account(CLOSEBOT_ACCOUNT) .input(z.object({ sourceId: CLOSEBOT_ID_SCHEMA })) .output(CLOSEBOT_SOURCE_OWNER_SCHEMA.array()) .retry({ replaySafety: "safe" }) .handler(async ({ account, input }) => getCloseBotApi(account.secret).request( `agency/source/${encodeURIComponent(input.sourceId)}/owners`, { responseSchema: CLOSEBOT_SOURCE_OWNER_SCHEMA.array() }, ), )