import { RESEND_EVENT_DEFINITION_SCHEMA, RESEND_EVENT_DEFINITION_WIRE_SCHEMA, RESEND_EVENT_SEND_RESPONSE_SCHEMA, RESEND_EVENT_DELETE_RESPONSE_SCHEMA, RESEND_EVENT_MUTATION_RESPONSE_SCHEMA, RESEND_EVENT_VALUE_TYPE_SCHEMA, resendListSchema, resendListWireSchema, } from "@automate.ax/integration-contracts/resend" import * as z from "zod" import { defineAction } from "../../automation/actions" import { getResendApi, RESEND_FULL_ACCESS_ACCOUNT_OPTIONS } from "./lib" const RESEND_ACCOUNT = "resend" const EVENT_SCHEMA = z .record(z.string().min(1), RESEND_EVENT_VALUE_TYPE_SCHEMA) .nullable() const EVENT_NAME_SCHEMA = z .string() .min(1) .refine((name) => !name.startsWith("resend:"), { message: 'Custom event names cannot start with the reserved "resend:" prefix.', }) const EVENT_LIST_SCHEMA = resendListSchema(RESEND_EVENT_DEFINITION_SCHEMA) const EVENT_LIST_WIRE_SCHEMA = resendListWireSchema( RESEND_EVENT_DEFINITION_WIRE_SCHEMA, ) /** Creates a custom-event definition for Resend Automations. */ export const createResendCustomEventDefinition = defineAction( "Create Resend custom event definition", ) .describe("Creates a named custom event and optional flat payload schema.") .account(RESEND_ACCOUNT, RESEND_FULL_ACCESS_ACCOUNT_OPTIONS) .input( z.object({ name: EVENT_NAME_SCHEMA, schema: EVENT_SCHEMA.optional(), }), ) .output(RESEND_EVENT_MUTATION_RESPONSE_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler( async ({ account, input }) => await getResendApi(account).call("/events", { body: input, httpMethod: "POST", responseSchema: RESEND_EVENT_MUTATION_RESPONSE_SCHEMA, }), ) /** Lists custom-event definitions for Resend Automations. */ export const listResendCustomEventDefinitions = defineAction( "List Resend custom event definitions", ) .describe("Lists custom-event definitions with cursor pagination.") .account(RESEND_ACCOUNT, RESEND_FULL_ACCESS_ACCOUNT_OPTIONS) .input( z .object({ after: z.string().min(1).optional(), before: z.string().min(1).optional(), limit: z.number().int().min(1).max(100).prefault(20), }) .refine(({ after, before }) => !(after && before), { message: "after and before cannot be used together.", }), ) .output(EVENT_LIST_SCHEMA) .retry({ replaySafety: "safe" }) .handler( async ({ account, input }) => await getResendApi(account).call("/events", { query: input, responseSchema: EVENT_LIST_WIRE_SCHEMA, }), ) /** Retrieves a custom-event definition by ID or exact name. */ export const getResendCustomEventDefinition = defineAction( "Get Resend custom event definition", ) .describe("Retrieves a custom-event definition by ID or exact name.") .account(RESEND_ACCOUNT, RESEND_FULL_ACCESS_ACCOUNT_OPTIONS) .input(z.object({ event: z.string().min(1) })) .output(RESEND_EVENT_DEFINITION_SCHEMA) .retry({ replaySafety: "safe" }) .handler( async ({ account, input }) => await getResendApi(account).call( `/events/${encodeURIComponent(input.event)}`, { responseSchema: RESEND_EVENT_DEFINITION_WIRE_SCHEMA }, ), ) /** Replaces or clears a Resend custom-event payload schema. */ export const updateResendCustomEventDefinition = defineAction( "Update Resend custom event definition", ) .describe("Replaces or clears a custom event's flat payload schema.") .account(RESEND_ACCOUNT, RESEND_FULL_ACCESS_ACCOUNT_OPTIONS) .input( z.object({ event: z.string().min(1), schema: EVENT_SCHEMA, }), ) .output(RESEND_EVENT_MUTATION_RESPONSE_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler( async ({ account, input }) => await getResendApi(account).call( `/events/${encodeURIComponent(input.event)}`, { body: { schema: input.schema }, httpMethod: "PATCH", responseSchema: RESEND_EVENT_MUTATION_RESPONSE_SCHEMA, }, ), ) /** Permanently deletes a Resend custom-event definition. */ export const deleteResendCustomEventDefinition = defineAction( "Delete Resend custom event definition", ) .describe("Permanently deletes a custom-event definition by ID or name.") .account(RESEND_ACCOUNT, RESEND_FULL_ACCESS_ACCOUNT_OPTIONS) .input(z.object({ event: z.string().min(1) })) .output(RESEND_EVENT_DELETE_RESPONSE_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler( async ({ account, input }) => await getResendApi(account).call( `/events/${encodeURIComponent(input.event)}`, { httpMethod: "DELETE", responseSchema: RESEND_EVENT_DELETE_RESPONSE_SCHEMA, }, ), ) /** Sends a custom event to Resend for one identified contact. */ export const sendResendCustomEvent = defineAction("Send Resend custom event") .describe("Sends a named custom event and optional payload for one contact.") .account(RESEND_ACCOUNT, RESEND_FULL_ACCESS_ACCOUNT_OPTIONS) .input( z .object({ contactId: z.string().min(1).optional(), email: z.email().optional(), event: EVENT_NAME_SCHEMA, payload: z.record(z.string().min(1), z.json()).optional(), }) .refine(({ contactId, email }) => Boolean(contactId) !== Boolean(email), { message: "Provide exactly one of contactId or email.", }), ) .output(RESEND_EVENT_SEND_RESPONSE_SCHEMA) .retry({ replaySafety: "unsafe" }) .handler( async ({ account, input }) => await getResendApi(account).call("/events/send", { body: { ...(input.contactId && { contact_id: input.contactId }), ...(input.email && { email: input.email }), event: input.event, ...(input.payload && { payload: input.payload }), }, httpMethod: "POST", responseSchema: RESEND_EVENT_SEND_RESPONSE_SCHEMA, }), )