import {z} from 'zod' export type GoogleAdsSearchads360V23CommonDateRange = {endDate?: string | undefined, startDate?: string | undefined}; export type GoogleAdsSearchads360V23ServicesCampaignDuration = {dateRange?: GoogleAdsSearchads360V23CommonDateRange | undefined, durationInDays?: number | undefined}; export type GoogleAdsSearchads360V23ServicesFrequencyCap = {impressions?: number | undefined, timeUnit?: ('UNSPECIFIED' | 'UNKNOWN' | 'DAY' | 'WEEK' | 'MONTH') | undefined}; export type GoogleAdsSearchads360V23ServicesEffectiveFrequencyLimit = {effectiveFrequencyBreakdownLimit?: number | undefined}; export type GoogleAdsSearchads360V23ServicesForecastMetricOptions = {includeCoview?: boolean | undefined}; export type GoogleAdsSearchads360V23ServicesSurfaceTargeting = {surfaces?: (Array<'UNSPECIFIED' | 'UNKNOWN' | 'DISCOVER_FEED' | 'GMAIL' | 'IN_FEED' | 'IN_STREAM_BUMPER' | 'IN_STREAM_NON_SKIPPABLE' | 'IN_STREAM_SKIPPABLE' | 'SHORTS'>) | undefined}; export type GoogleAdsSearchads360V23ServicesTargetFrequencySettings = {targetFrequency?: number | undefined, timeUnit?: ('UNSPECIFIED' | 'UNKNOWN' | 'WEEKLY' | 'MONTHLY') | undefined}; export type GoogleAdsSearchads360V23ServicesYouTubeSelectSettings = {lineupId?: unknown | undefined}; export type GoogleAdsSearchads360V23ServicesAdvancedProductTargeting = {surfaceTargetingSettings?: GoogleAdsSearchads360V23ServicesSurfaceTargeting | undefined, targetFrequencySettings?: GoogleAdsSearchads360V23ServicesTargetFrequencySettings | undefined, youtubeSelectSettings?: GoogleAdsSearchads360V23ServicesYouTubeSelectSettings | undefined}; export type GoogleAdsSearchads360V23ServicesPlannedProduct = {advancedProductTargeting?: GoogleAdsSearchads360V23ServicesAdvancedProductTargeting | undefined, budgetMicros?: unknown | undefined, conversionRate?: number | undefined, plannableProductCode?: string | undefined}; export type GoogleAdsSearchads360V23CommonAdditionalApplicationInfo = {applicationId?: string | undefined, applicationInstance?: ('UNSPECIFIED' | 'UNKNOWN' | 'DEVELOPMENT_AND_TESTING' | 'PRODUCTION') | undefined}; export type GoogleAdsSearchads360V23CommonUserInterestInfo = {userInterestCategory?: string | undefined}; export type GoogleAdsSearchads360V23CommonUserListInfo = {userList?: string | undefined}; export type GoogleAdsSearchads360V23ServicesAudienceTargeting = {userInterest?: Array | undefined, userLists?: Array | undefined}; export type GoogleAdsSearchads360V23CommonDeviceInfo = {type?: ('UNSPECIFIED' | 'UNKNOWN' | 'MOBILE' | 'TABLET' | 'DESKTOP' | 'CONNECTED_TV' | 'OTHER') | undefined}; export type GoogleAdsSearchads360V23CommonGenderInfo = {type?: ('UNSPECIFIED' | 'UNKNOWN' | 'MALE' | 'FEMALE' | 'UNDETERMINED') | undefined}; export type GoogleAdsSearchads360V23ServicesTargeting = {ageRange?: ('UNSPECIFIED' | 'UNKNOWN' | 'AGE_RANGE_18_24' | 'AGE_RANGE_18_34' | 'AGE_RANGE_18_44' | 'AGE_RANGE_18_49' | 'AGE_RANGE_18_54' | 'AGE_RANGE_18_64' | 'AGE_RANGE_18_65_UP' | 'AGE_RANGE_21_34' | 'AGE_RANGE_25_34' | 'AGE_RANGE_25_44' | 'AGE_RANGE_25_49' | 'AGE_RANGE_25_54' | 'AGE_RANGE_25_64' | 'AGE_RANGE_25_65_UP' | 'AGE_RANGE_35_44' | 'AGE_RANGE_35_49' | 'AGE_RANGE_35_54' | 'AGE_RANGE_35_64' | 'AGE_RANGE_35_65_UP' | 'AGE_RANGE_45_54' | 'AGE_RANGE_45_64' | 'AGE_RANGE_45_65_UP' | 'AGE_RANGE_50_65_UP' | 'AGE_RANGE_55_64' | 'AGE_RANGE_55_65_UP' | 'AGE_RANGE_65_UP') | undefined, audienceTargeting?: GoogleAdsSearchads360V23ServicesAudienceTargeting | undefined, devices?: Array | undefined, genders?: Array | undefined, network?: ('UNSPECIFIED' | 'UNKNOWN' | 'YOUTUBE' | 'GOOGLE_VIDEO_PARTNERS' | 'YOUTUBE_AND_GOOGLE_VIDEO_PARTNERS') | undefined, plannableLocationId?: string | undefined, plannableLocationIds?: Array | undefined}; export type GoogleAdsSearchads360V23ServicesGenerateReachForecastRequest = {campaignDuration?: GoogleAdsSearchads360V23ServicesCampaignDuration | undefined, cookieFrequencyCap?: number | undefined, cookieFrequencyCapSetting?: GoogleAdsSearchads360V23ServicesFrequencyCap | undefined, currencyCode?: string | undefined, customerReachGroup?: string | undefined, effectiveFrequencyLimit?: GoogleAdsSearchads360V23ServicesEffectiveFrequencyLimit | undefined, forecastMetricOptions?: GoogleAdsSearchads360V23ServicesForecastMetricOptions | undefined, minEffectiveFrequency?: number | undefined, plannedProducts?: Array | undefined, reachApplicationInfo?: GoogleAdsSearchads360V23CommonAdditionalApplicationInfo | undefined, targeting?: GoogleAdsSearchads360V23ServicesTargeting | undefined}; export type CreateApiV23CustomersCustomersIdGenerateReachForecastArgs = {customersId: string, body: GoogleAdsSearchads360V23ServicesGenerateReachForecastRequest}; export type CreateApiV23CustomersCustomersIdGenerateReachForecastOptions = {baseUrl?: string | undefined, Oauth2?: string | undefined, Oauth2c?: string | undefined, fetch?: typeof fetch | undefined}; export const googleAdsSearchads360V23ServicesOnTargetAudienceMetrics = z.object({censusAudienceSize: z.string().optional(), youtubeAudienceSize: z.string().optional()}); export const googleAdsSearchads360V23ServicesEffectiveFrequencyBreakdown = z.object({effectiveCoviewReach: z.string().optional(), effectiveFrequency: z.number().int().optional(), onTargetEffectiveCoviewReach: z.string().optional(), onTargetReach: z.string().optional(), totalReach: z.string().optional()}); export const googleAdsSearchads360V23ServicesForecast = z.object({conversions: z.number().optional(), effectiveFrequencyBreakdowns: z.array(googleAdsSearchads360V23ServicesEffectiveFrequencyBreakdown).optional(), onTargetCoviewImpressions: z.string().optional(), onTargetCoviewReach: z.string().optional(), onTargetImpressions: z.string().optional(), onTargetReach: z.string().optional(), totalCoviewImpressions: z.string().optional(), totalCoviewReach: z.string().optional(), totalImpressions: z.string().optional(), totalReach: z.string().optional(), trueviewViews: z.string().optional(), viewableImpressions: z.string().optional()}); export const googleAdsSearchads360V23ServicesPlannedProductForecast = z.object({averageFrequency: z.number().optional(), conversions: z.number().optional(), onTargetCoviewImpressions: z.string().optional(), onTargetCoviewReach: z.string().optional(), onTargetImpressions: z.string().optional(), onTargetReach: z.string().optional(), totalCoviewImpressions: z.string().optional(), totalCoviewReach: z.string().optional(), totalImpressions: z.string().optional(), totalReach: z.string().optional(), trueviewViews: z.string().optional(), viewableImpressions: z.string().optional()}); export const googleAdsSearchads360V23ServicesPlannedProductReachForecast = z.object({costMicros: z.string().optional(), plannableProductCode: z.string().optional(), plannedProductForecast: googleAdsSearchads360V23ServicesPlannedProductForecast.optional()}); export const googleAdsSearchads360V23ServicesReachForecast = z.object({costMicros: z.string().optional(), forecast: googleAdsSearchads360V23ServicesForecast.optional(), plannedProductReachForecasts: z.array(googleAdsSearchads360V23ServicesPlannedProductReachForecast).optional()}); export const googleAdsSearchads360V23ServicesReachCurve = z.object({reachForecasts: z.array(googleAdsSearchads360V23ServicesReachForecast).optional()}); export const googleAdsSearchads360V23ServicesGenerateReachForecastResponse = z.object({onTargetAudienceMetrics: googleAdsSearchads360V23ServicesOnTargetAudienceMetrics.optional(), reachCurve: googleAdsSearchads360V23ServicesReachCurve.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 }; /** * Generates a reach forecast for a given targeting / product mix. List of thrown errors: [AuthenticationError]() [AuthorizationError]() [FieldError]() [HeaderError]() [InternalError]() [QuotaError]() [RangeError]() [ReachPlanError]() [RequestError]() * * POST /v23/customers/{customersId}:generateReachForecast */ export const createApiV23CustomersCustomersIdGenerateReachForecast = async (args: CreateApiV23CustomersCustomersIdGenerateReachForecastArgs, options?: CreateApiV23CustomersCustomersIdGenerateReachForecastOptions) => { const {baseUrl = "https://searchads360.googleapis.com", fetch: fetchFn = fetch, Oauth2, Oauth2c} = 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}`) if (Oauth2c !== undefined) headers.set('authorization', `Bearer ${Oauth2c}`) const url = `${baseUrl.replace(/\/+$/, '')}/v23/customers/${encodeURIComponent(String(args.customersId))}:generateReachForecast${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(googleAdsSearchads360V23ServicesGenerateReachForecastResponse, await res.json()) };