import { calendlyRequest, calendlyResourceUri } from './client.ts'
import { mapInvitee } from './models.ts'
import type {
CalendlyAuthInput,
CalendlyInviteeSummary,
DryRunResult,
JsonRecord,
} from './types.ts'
import {
compactRecord,
optionalString,
optionalStringArray,
requireRecord,
requireString,
} from './types.ts'
import { requireAuthMode } from './auth.ts'
export type CreateInviteeInput = CalendlyAuthInput & {
/** Event type uuid or URI. */
eventType: string
/** UTC ISO start time. */
startTime: string
invitee: {
name: string
email: string
timezone?: string
}
eventGuests?: Array<string>
confirm?: boolean
dryRun?: boolean
}
/**
* Create a Calendly invitee (book a time). Requires `confirm: true`, or use
* `dryRun: true`. Calendly may require a paid plan for `POST /invitees`.
* @example
* import createInvitee from 'kody:@kody/calendly/create-invitee'
* const preview = await createInvitee({
* eventType: 'AAAAAAAAAAAAAAAA',
* startTime: '2026-06-01T16:00:00Z',
* invitee: { name: 'Ada', email: 'ada@example.com', timezone: 'America/Denver' },
* dryRun: true,
* })
*/
export async function createInvitee(
input: CreateInviteeInput,
): Promise<
CalendlyInviteeSummary | DryRunResult<{ method: string; path: string; body: JsonRecord }>
> {
const invitee = requireRecord(input.invitee, 'invitee')
const body = compactRecord({
event_type: calendlyResourceUri('event_types', requireString(input.eventType, 'eventType')),
start_time: requireString(input.startTime, 'startTime'),
invitee: compactRecord({
name: requireString(invitee.name, 'invitee.name'),
email: requireString(invitee.email, 'invitee.email'),
timezone: optionalString(invitee.timezone, 'invitee.timezone'),
}),
event_guests: optionalStringArray(input.eventGuests, 'eventGuests'),
})
if (input.dryRun) {
return { dryRun: true, wouldCall: { method: 'POST', path: '/invitees', body } }
}
if (input.confirm !== true) {
throw new Error(
'Creating a Calendly invitee requires confirm: true after explicit user approval, or dryRun: true.',
)
}
const result = await calendlyRequest<unknown>({
...input,
operation: 'scheduledEvents.write',
method: 'POST',
path: '/invitees',
body,
})
return mapInvitee(result.data)
}
/**
* Create a Calendly invitee (book a time). Requires `confirm: true`, or use `dryRun: true`.
* @example
* import createInvitee from 'kody:@kody/calendly/create-invitee'
* const preview = await createInvitee({
* eventType: 'AAA',
* startTime: '2026-06-01T16:00:00Z',
* invitee: { name: 'Ada', email: 'ada@example.com' },
* dryRun: true,
* })
*/
export default async function createInviteeEntrypoint(
params: Partial<CreateInviteeInput> & Record<string, unknown> = {},
) {
const input = requireRecord(params, 'create-invitee')
const invitee = requireRecord(input.invitee, 'invitee')
return createInvitee({
eventType: requireString(input.eventType, 'eventType'),
startTime: requireString(input.startTime, 'startTime'),
invitee: {
name: requireString(invitee.name, 'invitee.name'),
email: requireString(invitee.email, 'invitee.email'),
timezone: optionalString(invitee.timezone, 'invitee.timezone'),
},
eventGuests: optionalStringArray(input.eventGuests, 'eventGuests'),
integrationName: optionalString(input.integrationName, 'integrationName'),
integration: optionalString(input.integration, 'integration'),
account: optionalString(input.account, 'account'),
secretName: optionalString(input.secretName, 'secretName'),
auth: requireAuthMode(input.auth),
confirm: input.confirm === true,
dryRun: input.dryRun === true,
})
}