@rawdash/connector-google-ads 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,131 @@
1
+ <!-- This file is generated from connector metadata by scripts/generate-connector-docs.ts. Do not edit by hand. -->
2
+
3
+ # @rawdash/connector-google-ads
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@rawdash/connector-google-ads)](https://www.npmjs.com/package/@rawdash/connector-google-ads)
6
+ [![license](https://img.shields.io/npm/l/@rawdash/connector-google-ads)](https://github.com/rawdash/rawdash/blob/main/LICENSE)
7
+
8
+ Sync Google Ads campaigns plus daily campaign, ad-group, and keyword performance (impressions, clicks, cost, conversions) via GAQL.
9
+
10
+ ## Install
11
+
12
+ ```sh
13
+ npm install @rawdash/connector-google-ads
14
+ ```
15
+
16
+ ## Authentication
17
+
18
+ OAuth 2.0 refresh token against an account with read access to the Google Ads customer, plus a developer token from the manager account that owns API access.
19
+
20
+ 1. Apply for Google Ads API access from your manager account (Tools → API Center). Copy the developer token - it lives on the manager, not the child account.
21
+ 2. In Google Cloud Console, enable the Google Ads API on a project, create an OAuth 2.0 client ID, and complete the OAuth consent flow for the adwords scope to obtain a refresh token. The official walkthrough is at https://developers.google.com/google-ads/api/docs/oauth/overview.
22
+ 3. Find the Google Ads customer ID at the top of the Ads UI (e.g. 123-456-7890) and store it without dashes (e.g. 1234567890).
23
+ 4. If the OAuth credential authenticates against an MCC that owns the customer, set `loginCustomerId` to the MCC id (digits only). For a direct-access account, omit it.
24
+ 5. Store the client secret, refresh token, and developer token as secrets, then reference them as `clientSecret: secret("GADS_CLIENT_SECRET")`, `refreshToken: secret("GADS_REFRESH_TOKEN")`, and `developerToken: secret("GADS_DEVELOPER_TOKEN")`.
25
+
26
+ ## Configuration
27
+
28
+ | Field | Type | Required | Description |
29
+ | ----------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
30
+ | `customerId` | string | Yes | Google Ads customer ID for the account to sync, digits only (the dashed form 123-456-7890 with the dashes removed). |
31
+ | `loginCustomerId` | string | No | Manager (MCC) account ID, digits only. Set this when the OAuth credential authenticates against an MCC that owns the customer account. |
32
+ | `clientId` | string | Yes | OAuth 2.0 client ID from a Google Cloud project that has the Google Ads API enabled. |
33
+ | `clientSecret` | secret | Yes | OAuth 2.0 client secret paired with the client ID above. |
34
+ | `refreshToken` | secret | Yes | Google OAuth 2.0 refresh token issued for the https://www.googleapis.com/auth/adwords scope. |
35
+ | `developerToken` | secret | Yes | Google Ads API developer token from the manager account that owns API access (Tools → API Center). |
36
+ | `lookbackDays` | number | No | How many calendar days of metric history to fetch on a full sync. Defaults to 90. |
37
+ | `resources` | array | No | Which Google Ads resources to sync. Omit to sync everything; pin a subset to avoid pulling keyword-level metrics on a quota-limited token. |
38
+
39
+ ## Resources
40
+
41
+ - **`google_ads_campaign`** _(entity)_ - Google Ads campaigns with id, name, status, bidding strategy type, and start / end dates.
42
+ - Endpoint: `POST /v18/customers/{customerId}/googleAds:search`
43
+ - `id`: Numeric Google Ads campaign id.
44
+ - `name`: Campaign display name.
45
+ - `status`: Campaign status (ENABLED, PAUSED, REMOVED, UNKNOWN, UNSPECIFIED).
46
+ - `biddingStrategyType`: Bidding strategy in use (e.g. MAXIMIZE_CONVERSIONS, MANUAL_CPC).
47
+ - `startDate`: Campaign start date (YYYY-MM-DD).
48
+ - `endDate`: Campaign end date (YYYY-MM-DD), if set.
49
+ - **`google_ads_campaign_metrics`** _(metric)_ - Daily campaign performance - impressions, clicks, cost, conversions, and conversion value per (date, campaignId).
50
+ - Endpoint: `POST /v18/customers/{customerId}/googleAds:search`
51
+ - Unit: cost
52
+ - Granularity: day
53
+ - Dimensions: `date`, `campaignId`, `campaignName`, `impressions`, `clicks`, `cost`, `costMicros`, `conversions`, `conversionsValue`
54
+ - Sample value is `cost` (account currency units). All other fields are mirrored in attributes for filtering and ratio metrics (CPA = cost / conversions, ROAS = conversionsValue / cost).
55
+ - **`google_ads_ad_group_metrics`** _(metric)_ - Daily ad-group performance - impressions, clicks, cost, and conversions per (date, adGroupId).
56
+ - Endpoint: `POST /v18/customers/{customerId}/googleAds:search`
57
+ - Unit: cost
58
+ - Granularity: day
59
+ - Dimensions: `date`, `adGroupId`, `adGroupName`, `campaignId`, `impressions`, `clicks`, `cost`, `costMicros`, `conversions`
60
+ - **`google_ads_keyword_metrics`** _(metric)_ - Daily keyword performance - impressions, clicks, cost, and historical quality score per (date, criterionId).
61
+ - Endpoint: `POST /v18/customers/{customerId}/googleAds:search`
62
+ - Unit: cost
63
+ - Granularity: day
64
+ - Dimensions: `date`, `criterionId`, `keywordText`, `matchType`, `adGroupId`, `impressions`, `clicks`, `cost`, `costMicros`, `qualityScore`
65
+ - Driven by `keyword_view`; the cost / impression columns roll up to the criterion-day pair.
66
+
67
+ ## Example
68
+
69
+ ```ts
70
+ import {
71
+ defineConfig,
72
+ defineDashboard,
73
+ defineMetric,
74
+ secret,
75
+ } from '@rawdash/core';
76
+
77
+ const googleAds = {
78
+ name: 'googleAds',
79
+ connectorId: 'google-ads',
80
+ config: {
81
+ customerId: '1234567890',
82
+ clientId: '1234567890-abcdef.apps.googleusercontent.com',
83
+ clientSecret: secret('GADS_CLIENT_SECRET'),
84
+ refreshToken: secret('GADS_REFRESH_TOKEN'),
85
+ developerToken: secret('GADS_DEVELOPER_TOKEN'),
86
+ lookbackDays: 90,
87
+ },
88
+ };
89
+
90
+ export default defineConfig({
91
+ connectors: [googleAds],
92
+ dashboards: {
93
+ paid: defineDashboard({
94
+ widgets: {
95
+ spend_30d: {
96
+ kind: 'timeseries',
97
+ title: 'Ad spend (last 30 days)',
98
+ window: '30d',
99
+ metric: defineMetric({
100
+ connector: googleAds,
101
+ shape: 'metric',
102
+ name: 'google_ads_campaign_metrics',
103
+ fn: 'sum',
104
+ }),
105
+ },
106
+ },
107
+ }),
108
+ },
109
+ });
110
+ ```
111
+
112
+ ## Rate limits
113
+
114
+ Google Ads API basic-access tokens get a 15,000 operations / day quota per developer token; the connector treats 429 (RESOURCE_EXHAUSTED) as a transient error and the host backs off.
115
+
116
+ ## Limitations
117
+
118
+ - Cost values are stored in account currency units (cost_micros ÷ 1,000,000); the original micro-precision integer is also exposed in attributes.
119
+ - Keyword metrics use the historical (per-day) quality score from `metrics.historical_quality_score`; criteria with no impressions on a day will report a null quality score.
120
+ - Incremental syncs trail the last 3 days because Google Ads can attribute conversions to a click up to 3 days after the event.
121
+ - Audience-, asset-, and recommendation-level reporting are out of scope; this connector covers campaign / ad-group / keyword performance only.
122
+
123
+ ## Links
124
+
125
+ - [Rawdash docs](https://rawdash.dev/docs/connectors/)
126
+ - [Google Ads API docs](https://developers.google.com/google-ads/api/docs/start)
127
+ - [GitHub](https://github.com/rawdash/rawdash)
128
+
129
+ ## License
130
+
131
+ Apache-2.0
@@ -0,0 +1,498 @@
1
+ import { BaseConnector, ConnectorContext, SyncOptions, StorageHandle, SyncResult, ConnectorDoc } from '@rawdash/core';
2
+ import { z } from 'zod';
3
+
4
+ declare const configFields: z.ZodObject<{
5
+ customerId: z.ZodString;
6
+ loginCustomerId: z.ZodOptional<z.ZodString>;
7
+ clientId: z.ZodString;
8
+ clientSecret: z.ZodObject<{
9
+ $secret: z.ZodString;
10
+ }, z.core.$strip>;
11
+ refreshToken: z.ZodObject<{
12
+ $secret: z.ZodString;
13
+ }, z.core.$strip>;
14
+ developerToken: z.ZodObject<{
15
+ $secret: z.ZodString;
16
+ }, z.core.$strip>;
17
+ lookbackDays: z.ZodOptional<z.ZodNumber>;
18
+ resources: z.ZodOptional<z.ZodArray<z.ZodEnum<{
19
+ campaigns: "campaigns";
20
+ campaign_metrics: "campaign_metrics";
21
+ ad_group_metrics: "ad_group_metrics";
22
+ keyword_metrics: "keyword_metrics";
23
+ }>>>;
24
+ }, z.core.$strip>;
25
+ declare const doc: ConnectorDoc;
26
+ interface GoogleAdsSettings {
27
+ customerId: string;
28
+ loginCustomerId?: string;
29
+ lookbackDays?: number;
30
+ resources?: readonly GoogleAdsResource[];
31
+ }
32
+ declare const googleAdsCredentials: {
33
+ clientId: {
34
+ description: string;
35
+ auth: "required";
36
+ };
37
+ clientSecret: {
38
+ description: string;
39
+ auth: "required";
40
+ };
41
+ refreshToken: {
42
+ description: string;
43
+ auth: "required";
44
+ };
45
+ developerToken: {
46
+ description: string;
47
+ auth: "required";
48
+ };
49
+ };
50
+ type GoogleAdsCredentials = typeof googleAdsCredentials;
51
+ declare const PHASE_ORDER: readonly ["campaigns", "campaign_metrics", "ad_group_metrics", "keyword_metrics"];
52
+ type GoogleAdsPhase = (typeof PHASE_ORDER)[number];
53
+ type GoogleAdsResource = GoogleAdsPhase;
54
+ declare const campaignRowSchema: z.ZodObject<{
55
+ campaign: z.ZodObject<{
56
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
57
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
58
+ status: z.ZodOptional<z.ZodNullable<z.ZodString>>;
59
+ biddingStrategyType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
60
+ startDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
61
+ endDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
62
+ resourceName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
63
+ }, z.core.$strip>;
64
+ }, z.core.$strip>;
65
+ declare const campaignMetricRowSchema: z.ZodObject<{
66
+ segments: z.ZodObject<{
67
+ date: z.ZodString;
68
+ }, z.core.$strip>;
69
+ campaign: z.ZodObject<{
70
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
71
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
72
+ resourceName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
73
+ }, z.core.$strip>;
74
+ metrics: z.ZodObject<{
75
+ impressions: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
76
+ clicks: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
77
+ costMicros: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
78
+ conversions: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
79
+ conversionsValue: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
80
+ historicalQualityScore: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
81
+ }, z.core.$strip>;
82
+ }, z.core.$strip>;
83
+ declare const adGroupMetricRowSchema: z.ZodObject<{
84
+ segments: z.ZodObject<{
85
+ date: z.ZodString;
86
+ }, z.core.$strip>;
87
+ campaign: z.ZodOptional<z.ZodNullable<z.ZodObject<{
88
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
89
+ }, z.core.$strip>>>;
90
+ adGroup: z.ZodObject<{
91
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
92
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
93
+ resourceName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
94
+ }, z.core.$strip>;
95
+ metrics: z.ZodObject<{
96
+ impressions: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
97
+ clicks: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
98
+ costMicros: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
99
+ conversions: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
100
+ conversionsValue: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
101
+ historicalQualityScore: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
102
+ }, z.core.$strip>;
103
+ }, z.core.$strip>;
104
+ declare const keywordMetricRowSchema: z.ZodObject<{
105
+ segments: z.ZodObject<{
106
+ date: z.ZodString;
107
+ }, z.core.$strip>;
108
+ adGroup: z.ZodOptional<z.ZodNullable<z.ZodObject<{
109
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
110
+ }, z.core.$strip>>>;
111
+ adGroupCriterion: z.ZodObject<{
112
+ criterionId: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
113
+ keyword: z.ZodOptional<z.ZodNullable<z.ZodObject<{
114
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
115
+ matchType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
116
+ }, z.core.$strip>>>;
117
+ resourceName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
118
+ }, z.core.$strip>;
119
+ metrics: z.ZodObject<{
120
+ impressions: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
121
+ clicks: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
122
+ costMicros: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
123
+ conversions: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
124
+ conversionsValue: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
125
+ historicalQualityScore: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
126
+ }, z.core.$strip>;
127
+ }, z.core.$strip>;
128
+ type CampaignRow = z.infer<typeof campaignRowSchema>;
129
+ type CampaignMetricRow = z.infer<typeof campaignMetricRowSchema>;
130
+ type AdGroupMetricRow = z.infer<typeof adGroupMetricRowSchema>;
131
+ type KeywordMetricRow = z.infer<typeof keywordMetricRowSchema>;
132
+ interface DateRange {
133
+ startDate: string;
134
+ endDate: string;
135
+ }
136
+ declare function getDateRange(options: SyncOptions, lookbackDays: number, now?: number): DateRange;
137
+ declare function campaignToEntity(row: CampaignRow): {
138
+ type: string;
139
+ id: string;
140
+ attributes: Record<string, string | number | null>;
141
+ updated_at: number;
142
+ };
143
+ declare function campaignMetricRowToSample(row: CampaignMetricRow): {
144
+ name: string;
145
+ ts: number;
146
+ value: number;
147
+ attributes: Record<string, string | number | null>;
148
+ };
149
+ declare function adGroupMetricRowToSample(row: AdGroupMetricRow): {
150
+ name: string;
151
+ ts: number;
152
+ value: number;
153
+ attributes: Record<string, string | number | null>;
154
+ };
155
+ declare function keywordMetricRowToSample(row: KeywordMetricRow): {
156
+ name: string;
157
+ ts: number;
158
+ value: number;
159
+ attributes: Record<string, string | number | null>;
160
+ };
161
+ declare class GoogleAdsConnector extends BaseConnector<GoogleAdsSettings, GoogleAdsCredentials> {
162
+ static readonly id = "google-ads";
163
+ static readonly resources: {
164
+ readonly google_ads_campaign: {
165
+ readonly shape: "entity";
166
+ readonly description: "Google Ads campaigns with id, name, status, bidding strategy type, and start / end dates.";
167
+ readonly endpoint: "POST /v18/customers/{customerId}/googleAds:search";
168
+ readonly fields: [{
169
+ readonly name: "id";
170
+ readonly description: "Numeric Google Ads campaign id.";
171
+ }, {
172
+ readonly name: "name";
173
+ readonly description: "Campaign display name.";
174
+ }, {
175
+ readonly name: "status";
176
+ readonly description: "Campaign status (ENABLED, PAUSED, REMOVED, UNKNOWN, UNSPECIFIED).";
177
+ }, {
178
+ readonly name: "biddingStrategyType";
179
+ readonly description: "Bidding strategy in use (e.g. MAXIMIZE_CONVERSIONS, MANUAL_CPC).";
180
+ }, {
181
+ readonly name: "startDate";
182
+ readonly description: "Campaign start date (YYYY-MM-DD).";
183
+ }, {
184
+ readonly name: "endDate";
185
+ readonly description: "Campaign end date (YYYY-MM-DD), if set.";
186
+ }];
187
+ readonly responses: {
188
+ readonly oauth_token: z.ZodObject<{
189
+ access_token: z.ZodString;
190
+ expires_in: z.ZodOptional<z.ZodNumber>;
191
+ }, z.core.$strip>;
192
+ readonly campaigns: z.ZodArray<z.ZodObject<{
193
+ campaign: z.ZodObject<{
194
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
195
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
196
+ status: z.ZodOptional<z.ZodNullable<z.ZodString>>;
197
+ biddingStrategyType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
198
+ startDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
199
+ endDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
200
+ resourceName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
201
+ }, z.core.$strip>;
202
+ }, z.core.$strip>>;
203
+ };
204
+ };
205
+ readonly google_ads_campaign_metrics: {
206
+ readonly shape: "metric";
207
+ readonly description: "Daily campaign performance - impressions, clicks, cost, conversions, and conversion value per (date, campaignId).";
208
+ readonly endpoint: "POST /v18/customers/{customerId}/googleAds:search";
209
+ readonly unit: "cost";
210
+ readonly granularity: "day";
211
+ readonly dimensions: [{
212
+ readonly name: "date";
213
+ readonly description: "Calendar day of the metric sample.";
214
+ }, {
215
+ readonly name: "campaignId";
216
+ readonly description: "Numeric Google Ads campaign id.";
217
+ }, {
218
+ readonly name: "campaignName";
219
+ readonly description: "Campaign display name at sync time.";
220
+ }, {
221
+ readonly name: "impressions";
222
+ readonly description: "Ad impressions served on the day.";
223
+ }, {
224
+ readonly name: "clicks";
225
+ readonly description: "Clicks recorded on the day.";
226
+ }, {
227
+ readonly name: "cost";
228
+ readonly description: "Cost in account currency units (cost_micros ÷ 1,000,000).";
229
+ }, {
230
+ readonly name: "costMicros";
231
+ readonly description: "Raw cost in micros, as returned by the API.";
232
+ }, {
233
+ readonly name: "conversions";
234
+ readonly description: "Counted conversions attributed to the day.";
235
+ }, {
236
+ readonly name: "conversionsValue";
237
+ readonly description: "Total value of conversions for the day.";
238
+ }];
239
+ readonly notes: "Sample value is `cost` (account currency units). All other fields are mirrored in attributes for filtering and ratio metrics (CPA = cost / conversions, ROAS = conversionsValue / cost).";
240
+ readonly responses: {
241
+ readonly campaign_metrics: z.ZodArray<z.ZodObject<{
242
+ segments: z.ZodObject<{
243
+ date: z.ZodString;
244
+ }, z.core.$strip>;
245
+ campaign: z.ZodObject<{
246
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
247
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
248
+ resourceName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
249
+ }, z.core.$strip>;
250
+ metrics: z.ZodObject<{
251
+ impressions: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
252
+ clicks: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
253
+ costMicros: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
254
+ conversions: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
255
+ conversionsValue: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
256
+ historicalQualityScore: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
257
+ }, z.core.$strip>;
258
+ }, z.core.$strip>>;
259
+ };
260
+ };
261
+ readonly google_ads_ad_group_metrics: {
262
+ readonly shape: "metric";
263
+ readonly description: "Daily ad-group performance - impressions, clicks, cost, and conversions per (date, adGroupId).";
264
+ readonly endpoint: "POST /v18/customers/{customerId}/googleAds:search";
265
+ readonly unit: "cost";
266
+ readonly granularity: "day";
267
+ readonly dimensions: [{
268
+ readonly name: "date";
269
+ readonly description: "Calendar day of the metric sample.";
270
+ }, {
271
+ readonly name: "adGroupId";
272
+ readonly description: "Numeric Google Ads ad-group id.";
273
+ }, {
274
+ readonly name: "adGroupName";
275
+ readonly description: "Ad-group display name at sync time.";
276
+ }, {
277
+ readonly name: "campaignId";
278
+ readonly description: "Parent campaign id.";
279
+ }, {
280
+ readonly name: "impressions";
281
+ readonly description: "Ad impressions served on the day.";
282
+ }, {
283
+ readonly name: "clicks";
284
+ readonly description: "Clicks recorded on the day.";
285
+ }, {
286
+ readonly name: "cost";
287
+ readonly description: "Cost in account currency units.";
288
+ }, {
289
+ readonly name: "costMicros";
290
+ readonly description: "Raw cost in micros, as returned by the API.";
291
+ }, {
292
+ readonly name: "conversions";
293
+ readonly description: "Counted conversions attributed to the day.";
294
+ }];
295
+ readonly responses: {
296
+ readonly ad_group_metrics: z.ZodArray<z.ZodObject<{
297
+ segments: z.ZodObject<{
298
+ date: z.ZodString;
299
+ }, z.core.$strip>;
300
+ campaign: z.ZodOptional<z.ZodNullable<z.ZodObject<{
301
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
302
+ }, z.core.$strip>>>;
303
+ adGroup: z.ZodObject<{
304
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
305
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
306
+ resourceName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
307
+ }, z.core.$strip>;
308
+ metrics: z.ZodObject<{
309
+ impressions: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
310
+ clicks: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
311
+ costMicros: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
312
+ conversions: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
313
+ conversionsValue: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
314
+ historicalQualityScore: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
315
+ }, z.core.$strip>;
316
+ }, z.core.$strip>>;
317
+ };
318
+ };
319
+ readonly google_ads_keyword_metrics: {
320
+ readonly shape: "metric";
321
+ readonly description: "Daily keyword performance - impressions, clicks, cost, and historical quality score per (date, criterionId).";
322
+ readonly endpoint: "POST /v18/customers/{customerId}/googleAds:search";
323
+ readonly unit: "cost";
324
+ readonly granularity: "day";
325
+ readonly dimensions: [{
326
+ readonly name: "date";
327
+ readonly description: "Calendar day of the metric sample.";
328
+ }, {
329
+ readonly name: "criterionId";
330
+ readonly description: "Numeric keyword (ad-group criterion) id.";
331
+ }, {
332
+ readonly name: "keywordText";
333
+ readonly description: "Keyword text.";
334
+ }, {
335
+ readonly name: "matchType";
336
+ readonly description: "Match type (EXACT, PHRASE, BROAD, …).";
337
+ }, {
338
+ readonly name: "adGroupId";
339
+ readonly description: "Parent ad-group id.";
340
+ }, {
341
+ readonly name: "impressions";
342
+ readonly description: "Ad impressions served on the day.";
343
+ }, {
344
+ readonly name: "clicks";
345
+ readonly description: "Clicks recorded on the day.";
346
+ }, {
347
+ readonly name: "cost";
348
+ readonly description: "Cost in account currency units.";
349
+ }, {
350
+ readonly name: "costMicros";
351
+ readonly description: "Raw cost in micros, as returned by the API.";
352
+ }, {
353
+ readonly name: "qualityScore";
354
+ readonly description: "Historical quality score for the day (1-10), null when no impressions.";
355
+ }];
356
+ readonly notes: "Driven by `keyword_view`; the cost / impression columns roll up to the criterion-day pair.";
357
+ readonly responses: {
358
+ readonly keyword_metrics: z.ZodArray<z.ZodObject<{
359
+ segments: z.ZodObject<{
360
+ date: z.ZodString;
361
+ }, z.core.$strip>;
362
+ adGroup: z.ZodOptional<z.ZodNullable<z.ZodObject<{
363
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
364
+ }, z.core.$strip>>>;
365
+ adGroupCriterion: z.ZodObject<{
366
+ criterionId: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
367
+ keyword: z.ZodOptional<z.ZodNullable<z.ZodObject<{
368
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
369
+ matchType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
370
+ }, z.core.$strip>>>;
371
+ resourceName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
372
+ }, z.core.$strip>;
373
+ metrics: z.ZodObject<{
374
+ impressions: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
375
+ clicks: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
376
+ costMicros: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
377
+ conversions: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
378
+ conversionsValue: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
379
+ historicalQualityScore: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
380
+ }, z.core.$strip>;
381
+ }, z.core.$strip>>;
382
+ };
383
+ };
384
+ };
385
+ static readonly schemas: {
386
+ readonly oauth_token: z.ZodObject<{
387
+ access_token: z.ZodString;
388
+ expires_in: z.ZodOptional<z.ZodNumber>;
389
+ }, z.core.$strip>;
390
+ readonly campaigns: z.ZodArray<z.ZodObject<{
391
+ campaign: z.ZodObject<{
392
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
393
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
394
+ status: z.ZodOptional<z.ZodNullable<z.ZodString>>;
395
+ biddingStrategyType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
396
+ startDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
397
+ endDate: z.ZodOptional<z.ZodNullable<z.ZodString>>;
398
+ resourceName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
399
+ }, z.core.$strip>;
400
+ }, z.core.$strip>>;
401
+ } & {
402
+ readonly campaign_metrics: z.ZodArray<z.ZodObject<{
403
+ segments: z.ZodObject<{
404
+ date: z.ZodString;
405
+ }, z.core.$strip>;
406
+ campaign: z.ZodObject<{
407
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
408
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
409
+ resourceName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
410
+ }, z.core.$strip>;
411
+ metrics: z.ZodObject<{
412
+ impressions: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
413
+ clicks: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
414
+ costMicros: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
415
+ conversions: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
416
+ conversionsValue: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
417
+ historicalQualityScore: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
418
+ }, z.core.$strip>;
419
+ }, z.core.$strip>>;
420
+ } & {
421
+ readonly ad_group_metrics: z.ZodArray<z.ZodObject<{
422
+ segments: z.ZodObject<{
423
+ date: z.ZodString;
424
+ }, z.core.$strip>;
425
+ campaign: z.ZodOptional<z.ZodNullable<z.ZodObject<{
426
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
427
+ }, z.core.$strip>>>;
428
+ adGroup: z.ZodObject<{
429
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
430
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
431
+ resourceName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
432
+ }, z.core.$strip>;
433
+ metrics: z.ZodObject<{
434
+ impressions: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
435
+ clicks: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
436
+ costMicros: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
437
+ conversions: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
438
+ conversionsValue: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
439
+ historicalQualityScore: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
440
+ }, z.core.$strip>;
441
+ }, z.core.$strip>>;
442
+ } & {
443
+ readonly keyword_metrics: z.ZodArray<z.ZodObject<{
444
+ segments: z.ZodObject<{
445
+ date: z.ZodString;
446
+ }, z.core.$strip>;
447
+ adGroup: z.ZodOptional<z.ZodNullable<z.ZodObject<{
448
+ id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
449
+ }, z.core.$strip>>>;
450
+ adGroupCriterion: z.ZodObject<{
451
+ criterionId: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
452
+ keyword: z.ZodOptional<z.ZodNullable<z.ZodObject<{
453
+ text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
454
+ matchType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
455
+ }, z.core.$strip>>>;
456
+ resourceName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
457
+ }, z.core.$strip>;
458
+ metrics: z.ZodObject<{
459
+ impressions: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
460
+ clicks: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
461
+ costMicros: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
462
+ conversions: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
463
+ conversionsValue: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
464
+ historicalQualityScore: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
465
+ }, z.core.$strip>;
466
+ }, z.core.$strip>>;
467
+ } & Readonly<Record<string, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>>;
468
+ static create(input: unknown, ctx?: ConnectorContext): GoogleAdsConnector;
469
+ readonly id = "google-ads";
470
+ readonly credentials: {
471
+ clientId: {
472
+ description: string;
473
+ auth: "required";
474
+ };
475
+ clientSecret: {
476
+ description: string;
477
+ auth: "required";
478
+ };
479
+ refreshToken: {
480
+ description: string;
481
+ auth: "required";
482
+ };
483
+ developerToken: {
484
+ description: string;
485
+ auth: "required";
486
+ };
487
+ };
488
+ private cachedToken;
489
+ private fetchAccessToken;
490
+ private getAccessToken;
491
+ private buildHeaders;
492
+ private searchPage;
493
+ private writePhase;
494
+ private clearScopeOnFirstPage;
495
+ sync(options: SyncOptions, storage: StorageHandle, signal?: AbortSignal): Promise<SyncResult>;
496
+ }
497
+
498
+ export { GoogleAdsConnector, type GoogleAdsResource, type GoogleAdsSettings, adGroupMetricRowToSample, campaignMetricRowToSample, campaignToEntity, configFields, GoogleAdsConnector as default, doc, getDateRange, keywordMetricRowToSample };