import {z} from 'zod' export type BidOptionsAgeBucketMultipliers = {'18-24'?: number | undefined, '25-34'?: number | undefined, '35-44'?: number | undefined, '45-49'?: number | undefined, '50-54'?: number | undefined, '55-64'?: number | undefined, '65+'?: number | undefined}; export type BidOptionsAppTypeMultipliers = {android_mobile?: number | undefined, android_tablet?: number | undefined, ipad?: number | undefined, iphone?: number | undefined, web?: number | undefined, web_mobile?: number | undefined}; export type BidOptionsAudienceMultipliers = {audience_id: string, multiplier: number}; export type BidOptionsGenderMultipliers = {female?: number | undefined, male?: number | undefined}; export type BidOptionsPlacementMultipliers = {browse?: number | undefined, related_pins?: number | undefined, search?: number | undefined}; export type ScheduleBidMultipliers = {age_bucket_multipliers?: BidOptionsAgeBucketMultipliers | undefined, app_type_multipliers?: BidOptionsAppTypeMultipliers | undefined, audience_multipliers?: Array | undefined, gender_multipliers?: BidOptionsGenderMultipliers | undefined, placement_multipliers?: BidOptionsPlacementMultipliers | undefined}; export type EntityId = string; export type AdAccountEntityType = 'ADVERTISER' | 'CAMPAIGN' | 'AD_GROUP' | 'AD'; export type ScheduleAction = 'INCREASE_BY_VALUE' | 'INCREASE_BY_PERCENT'; export type ScheduleStatus = 'DRAFT' | 'CREATED' | 'SCHEDULED' | 'ACTIVE' | 'COMPLETED' | 'FAILED' | 'CANCELED'; export type ScheduleType = 'CAMPAIGN_BUDGET_CHANGE' | 'CAMPAIGN_BID_MULTIPLIERS'; export type ScheduleCreate = {delta_value?: (string | ScheduleBidMultipliers) | undefined, end_timestamp?: number | undefined, entity_id: EntityId, entity_type?: AdAccountEntityType | undefined, name?: string | undefined, schedule_action?: ScheduleAction | undefined, schedule_status?: ScheduleStatus | undefined, schedule_type?: ScheduleType | undefined, start_timestamp?: number | undefined}; export type CreateApiAdAccountsAdAccountIdSchedulesArgs = {ad_account_id: string, body: Array}; export type CreateApiAdAccountsAdAccountIdSchedulesOptions = {baseUrl?: string | undefined, pinterestOauth2?: string | undefined, fetch?: typeof fetch | undefined}; export const bidOptionsAgeBucketMultipliers = z.object({"18-24": z.number().optional(), "25-34": z.number().optional(), "35-44": z.number().optional(), "45-49": z.number().optional(), "50-54": z.number().optional(), "55-64": z.number().optional(), "65+": z.number().optional()}); export const bidOptionsAppTypeMultipliers = z.object({android_mobile: z.number().optional(), android_tablet: z.number().optional(), ipad: z.number().optional(), iphone: z.number().optional(), web: z.number().optional(), web_mobile: z.number().optional()}); export const bidOptionsAudienceMultipliers = z.object({audience_id: z.string(), multiplier: z.number()}); export const bidOptionsGenderMultipliers = z.object({female: z.number().optional(), male: z.number().optional()}); export const bidOptionsPlacementMultipliers = z.object({browse: z.number().optional(), related_pins: z.number().optional(), search: z.number().optional()}); export const scheduleBidMultipliers = z.object({age_bucket_multipliers: bidOptionsAgeBucketMultipliers.optional(), app_type_multipliers: bidOptionsAppTypeMultipliers.optional(), audience_multipliers: z.array(bidOptionsAudienceMultipliers).optional(), gender_multipliers: bidOptionsGenderMultipliers.optional(), placement_multipliers: bidOptionsPlacementMultipliers.optional()}); export const entityId = z.string(); export const adAccountEntityType = z.enum(["ADVERTISER", "CAMPAIGN", "AD_GROUP", "AD"]); export const scheduleAction = z.enum(["INCREASE_BY_VALUE", "INCREASE_BY_PERCENT"]); export const scheduleStatus = z.enum(["DRAFT", "CREATED", "SCHEDULED", "ACTIVE", "COMPLETED", "FAILED", "CANCELED"]); export const scheduleType = z.enum(["CAMPAIGN_BUDGET_CHANGE", "CAMPAIGN_BID_MULTIPLIERS"]); export const schedule = z.object({delta_value: z.union([z.string(), scheduleBidMultipliers]).optional(), end_timestamp: z.number().int().optional(), entity_id: entityId, entity_type: adAccountEntityType.optional(), name: z.string().optional(), schedule_action: scheduleAction.optional(), schedule_id: z.string(), schedule_status: scheduleStatus.optional(), schedule_type: scheduleType.optional(), start_timestamp: z.number().int().optional()}); export const pinterestLibError = z.object({code: z.number().int(), message: z.string()}); export const createApiAdAccountsAdAccountIdSchedulesResponse = z.array(z.object({data: z.union([schedule, z.object({id: z.string().max(18), schedule_id: z.string(), exceptions: pinterestLibError})])})); 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 schedules * * POST /ad_accounts/{ad_account_id}/schedules */ export const createApiAdAccountsAdAccountIdSchedules = async (args: CreateApiAdAccountsAdAccountIdSchedulesArgs, options?: CreateApiAdAccountsAdAccountIdSchedulesOptions) => { const {baseUrl = "https://api.pinterest.com/v5", fetch: fetchFn = fetch, pinterestOauth2} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (pinterestOauth2 !== undefined) headers.set('authorization', `Bearer ${pinterestOauth2}`) const url = `${baseUrl.replace(/\/+$/, '')}/ad_accounts/${encodeURIComponent(String(args.ad_account_id))}/schedules${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(createApiAdAccountsAdAccountIdSchedulesResponse, await res.json()) };