import {z} from 'zod' export type CallersInfoRequest = {callerId?: string | undefined, name?: string | undefined}; export type CalledNumberInfo = {phoneNumber?: string | undefined}; export type TimeInterval = {from?: string | undefined, to?: string | undefined}; export type WeeklyScheduleInfo = {monday?: Array | undefined, tuesday?: Array | undefined, wednesday?: Array | undefined, thursday?: Array | undefined, friday?: Array | undefined, saturday?: Array | undefined, sunday?: Array | undefined}; export type RangesInfo = {from?: string | undefined, to?: string | undefined}; export type ScheduleInfo = {weeklyRanges?: WeeklyScheduleInfo | undefined, ranges?: Array | undefined, ref?: ('BusinessHours' | 'AfterHours') | undefined}; export type CreateAnsweringRuleForwardingNumberInfo = {id?: string | undefined, uri?: string | undefined, phoneNumber?: string | undefined, label?: string | undefined, type?: ('Home' | 'Mobile' | 'Work' | 'PhoneLine' | 'Outage' | 'Other' | 'BusinessMobilePhone' | 'ExternalCarrier' | 'ExtensionApps') | undefined}; export type ForwardingRuleInfo = {index?: number | undefined, ringCount?: number | undefined, enabled?: boolean | undefined, forwardingNumbers?: Array | undefined}; export type ForwardingInfo = {notifyMySoftPhones?: boolean | undefined, notifyAdminSoftPhones?: boolean | undefined, softPhonesRingCount?: number | undefined, softPhonesAlwaysRing?: boolean | undefined, ringingMode?: ('Sequentially' | 'Simultaneously') | undefined, rules?: Array | undefined, softPhonesPositionTop?: boolean | undefined, mobileTimeout?: boolean | undefined}; export type UnconditionalForwardingInfo = {phoneNumber?: string | undefined, action?: ('HoldTimeExpiration' | 'MaxCallers' | 'NoAnswer') | undefined}; export type TransferExtensionInfo = {id?: string | undefined, uri?: string | undefined, name?: string | undefined, extensionNumber?: string | undefined}; export type TransferInfo = {extension?: TransferExtensionInfo | undefined, action?: ('HoldTimeExpiration' | 'MaxCallers' | 'NoAnswer') | undefined}; export type FixedOrderAgentsExtensionInfo = {id?: string | undefined, uri?: string | undefined, extensionNumber?: string | undefined, name?: string | undefined}; export type FixedOrderAgents = {extension?: FixedOrderAgentsExtensionInfo | undefined, index?: number | undefined}; export type QueueInfo = {transferMode?: ('Rotating' | 'Simultaneous' | 'FixedOrder') | undefined, transfer?: Array | undefined, noAnswerAction?: ('WaitPrimaryMembers' | 'WaitPrimaryAndOverflowMembers' | 'Voicemail' | 'TransferToExtension' | 'UnconditionalForwarding') | undefined, fixedOrderAgents?: Array | undefined, holdAudioInterruptionMode?: ('Never' | 'WhenMusicEnds' | 'Periodically') | undefined, holdAudioInterruptionPeriod?: number | undefined, holdTimeExpirationAction?: ('TransferToExtension' | 'UnconditionalForwarding' | 'Voicemail') | undefined, agentTimeout?: number | undefined, wrapUpTime?: number | undefined, holdTime?: number | undefined, maxCallers?: number | undefined, maxCallersAction?: ('Voicemail' | 'Announcement' | 'TransferToExtension' | 'UnconditionalForwarding') | undefined, unconditionalForwarding?: Array | undefined}; export type TransferredExtension = {id?: string | undefined, uri?: string | undefined}; export type TransferredExtensionInfo = {extension?: TransferredExtension | undefined}; export type RecipientInfo = {uri?: string | undefined, id?: string | undefined}; export type VoicemailInfo = {enabled?: boolean | undefined, recipient?: RecipientInfo | undefined}; export type MissedCallExtensionInfoExternalNumber = {phoneNumber?: string | undefined}; export type MissedCallExtensionInfo = {id?: string | undefined, externalNumber?: MissedCallExtensionInfoExternalNumber | undefined}; export type MissedCallInfo = {actionType?: ('PlayGreetingAndDisconnect' | 'ConnectToExtension' | 'ConnectToExternalNumber') | undefined, extension?: MissedCallExtensionInfo | undefined}; export type GreetingTypeEnum = 'Introductory' | 'Announcement' | 'AutomaticRecording' | 'BlockedCallersAll' | 'BlockedCallersSpecific' | 'BlockedNoCallerId' | 'BlockedPayPhones' | 'ConnectingMessage' | 'ConnectingAudio' | 'StartRecording' | 'StopRecording' | 'Voicemail' | 'Unavailable' | 'InterruptPrompt' | 'HoldMusic' | 'Company'; export type PresetInfo = {uri?: string | undefined, id?: string | undefined, name?: string | undefined}; export type CustomGreetingInfoRequest = {id?: string | undefined}; export type GreetingInfo = {type?: GreetingTypeEnum | undefined, preset?: PresetInfo | undefined, custom?: CustomGreetingInfoRequest | undefined}; export type CreateAnsweringRuleRequest = {enabled?: boolean | undefined, type: string, name: string, callers?: Array | undefined, calledNumbers?: Array | undefined, schedule?: ScheduleInfo | undefined, callHandlingAction?: ('ForwardCalls' | 'UnconditionalForwarding' | 'AgentQueue' | 'TransferToExtension' | 'TakeMessagesOnly' | 'PlayAnnouncementOnly' | 'SharedLines') | undefined, forwarding?: ForwardingInfo | undefined, unconditionalForwarding?: UnconditionalForwardingInfo | undefined, queue?: QueueInfo | undefined, transfer?: TransferredExtensionInfo | undefined, voicemail?: VoicemailInfo | undefined, missedCall?: MissedCallInfo | undefined, greetings?: Array | undefined, screening?: ('Off' | 'NoCallerId' | 'UnknownCallerId' | 'Always') | undefined}; export type CreateApiRestapiV10AccountAccountIdExtensionExtensionIdAnsweringRuleArgs = {accountId: string, extensionId: string, body: CreateAnsweringRuleRequest}; export type CreateApiRestapiV10AccountAccountIdExtensionExtensionIdAnsweringRuleOptions = {baseUrl?: string | undefined, OAuth2?: string | undefined, fetch?: typeof fetch | undefined}; export const timeInterval = z.object({from: z.string().optional(), to: z.string().optional()}); export const weeklyScheduleInfo = z.object({monday: z.array(timeInterval).optional(), tuesday: z.array(timeInterval).optional(), wednesday: z.array(timeInterval).optional(), thursday: z.array(timeInterval).optional(), friday: z.array(timeInterval).optional(), saturday: z.array(timeInterval).optional(), sunday: z.array(timeInterval).optional()}); export const rangesInfo = z.object({from: z.string().optional(), to: z.string().optional()}); export const scheduleInfo = z.object({weeklyRanges: weeklyScheduleInfo.optional(), ranges: z.array(rangesInfo).optional(), ref: z.enum(["BusinessHours", "AfterHours"]).optional()}); export const calledNumberInfo = z.object({phoneNumber: z.string().optional()}); export const callersInfo = z.object({callerId: z.string().optional(), name: z.string().optional()}); export const createAnsweringRuleForwardingNumberInfo = z.object({id: z.string().optional(), uri: z.string().optional(), phoneNumber: z.string().optional(), label: z.string().optional(), type: z.enum(["Home", "Mobile", "Work", "PhoneLine", "Outage", "Other", "BusinessMobilePhone", "ExternalCarrier", "ExtensionApps"]).optional()}); export const forwardingRuleInfo = z.object({index: z.number().int().optional(), ringCount: z.number().int().optional(), enabled: z.boolean().optional(), forwardingNumbers: z.array(createAnsweringRuleForwardingNumberInfo).optional()}); export const forwardingInfo = z.object({notifyMySoftPhones: z.boolean().optional(), notifyAdminSoftPhones: z.boolean().optional(), softPhonesRingCount: z.number().int().optional(), softPhonesAlwaysRing: z.boolean().optional(), ringingMode: z.enum(["Sequentially", "Simultaneously"]).optional(), rules: z.array(forwardingRuleInfo).optional(), softPhonesPositionTop: z.boolean().optional(), mobileTimeout: z.boolean().optional()}); export const unconditionalForwardingInfo = z.object({phoneNumber: z.string().optional(), action: z.enum(["HoldTimeExpiration", "MaxCallers", "NoAnswer"]).optional()}); export const transferExtensionInfo = z.object({id: z.string().optional(), uri: z.string().optional(), name: z.string().optional(), extensionNumber: z.string().optional()}); export const transferInfo = z.object({extension: transferExtensionInfo.optional(), action: z.enum(["HoldTimeExpiration", "MaxCallers", "NoAnswer"]).optional()}); export const fixedOrderAgentsExtensionInfo = z.object({id: z.string().optional(), uri: z.string().optional(), extensionNumber: z.string().optional(), name: z.string().optional()}); export const fixedOrderAgents = z.object({extension: fixedOrderAgentsExtensionInfo.optional(), index: z.number().int().optional()}); export const queueInfo = z.object({transferMode: z.enum(["Rotating", "Simultaneous", "FixedOrder"]).optional(), transfer: z.array(transferInfo).optional(), noAnswerAction: z.enum(["WaitPrimaryMembers", "WaitPrimaryAndOverflowMembers", "Voicemail", "TransferToExtension", "UnconditionalForwarding"]).optional(), fixedOrderAgents: z.array(fixedOrderAgents).optional(), holdAudioInterruptionMode: z.enum(["Never", "WhenMusicEnds", "Periodically"]).optional(), holdAudioInterruptionPeriod: z.number().int().optional(), holdTimeExpirationAction: z.enum(["TransferToExtension", "UnconditionalForwarding", "Voicemail"]).optional(), agentTimeout: z.number().int().optional(), wrapUpTime: z.number().int().gte(0).lte(300).optional(), holdTime: z.number().int().optional(), maxCallers: z.number().int().lte(25).optional(), maxCallersAction: z.enum(["Voicemail", "Announcement", "TransferToExtension", "UnconditionalForwarding"]).optional(), unconditionalForwarding: z.array(unconditionalForwardingInfo).optional()}); export const transferredExtension = z.object({id: z.string().optional(), uri: z.string().optional()}); export const transferredExtensionInfo = z.object({extension: transferredExtension.optional()}); export const recipientInfo = z.object({uri: z.string().optional(), id: z.string().optional()}); export const voicemailInfo = z.object({enabled: z.boolean().optional(), recipient: recipientInfo.optional()}); export const greetingTypeEnum = z.enum(["Introductory", "Announcement", "AutomaticRecording", "BlockedCallersAll", "BlockedCallersSpecific", "BlockedNoCallerId", "BlockedPayPhones", "ConnectingMessage", "ConnectingAudio", "StartRecording", "StopRecording", "Voicemail", "Unavailable", "InterruptPrompt", "HoldMusic", "Company"]); export const presetInfo = z.object({uri: z.string().optional(), id: z.string().optional(), name: z.string().optional()}); export const customGreetingInfoRequest = z.object({id: z.string().optional()}); export const greetingInfo = z.object({type: greetingTypeEnum.optional(), preset: presetInfo.optional(), custom: customGreetingInfoRequest.optional()}); export const sharedLinesInfo = z.object({timeout: z.number().int().gte(10).lte(80).optional()}); export const customAnsweringRuleInfo = z.object({uri: z.string().optional(), id: z.string().optional(), type: z.enum(["BusinessHours", "AfterHours", "Custom"]).optional(), name: z.string().optional(), enabled: z.boolean().optional(), schedule: scheduleInfo.optional(), calledNumbers: z.array(calledNumberInfo).optional(), callers: z.array(callersInfo).optional(), callHandlingAction: z.enum(["ForwardCalls", "UnconditionalForwarding", "AgentQueue", "TransferToExtension", "TakeMessagesOnly", "PlayAnnouncementOnly", "SharedLines"]).optional(), forwarding: forwardingInfo.optional(), unconditionalForwarding: unconditionalForwardingInfo.optional(), queue: queueInfo.optional(), transfer: transferredExtensionInfo.optional(), voicemail: voicemailInfo.optional(), greetings: z.array(greetingInfo).optional(), screening: z.enum(["Off", "NoCallerId", "UnknownCallerId", "Always"]).optional(), sharedLines: sharedLinesInfo.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 Call Handling Rule * * POST /restapi/v1.0/account/{accountId}/extension/{extensionId}/answering-rule */ export const createApiRestapiV10AccountAccountIdExtensionExtensionIdAnsweringRule = async (args: CreateApiRestapiV10AccountAccountIdExtensionExtensionIdAnsweringRuleArgs, options?: CreateApiRestapiV10AccountAccountIdExtensionExtensionIdAnsweringRuleOptions) => { const {baseUrl = "https://platform.ringcentral.com", fetch: fetchFn = fetch, OAuth2} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (OAuth2 !== undefined) headers.set('authorization', `Bearer ${OAuth2}`) const url = `${baseUrl.replace(/\/+$/, '')}/restapi/v1.0/account/${encodeURIComponent(String(args.accountId))}/extension/${encodeURIComponent(String(args.extensionId))}/answering-rule${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(customAnsweringRuleInfo, await res.json()) };