Skip to content

Commit bb56cc3

Browse files
bazarnovefimmatytsin
authored andcommitted
🎉 Source Google Ads: add new stream Campaign Budget (airbytehq#28078)
1 parent 53c49b0 commit bb56cc3

File tree

10 files changed

+212
-2
lines changed

10 files changed

+212
-2
lines changed

airbyte-integrations/connectors/source-google-ads/acceptance-test-config.yml

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ acceptance_tests:
6060
ad_groups: ["4651612872", "segments.date"]
6161
accounts: ["4651612872", "segments.date"]
6262
campaigns: ["4651612872", "segments.date"]
63+
campaign_budget: ["4651612872", "segments.date"]
6364
user_location_report: ["4651612872", "segments.date"]
6465
ad_group_ad_report: ["4651612872", "segments.date"]
6566
display_keyword_performance_report: ["4651612872", "segments.date"]

airbyte-integrations/connectors/source-google-ads/integration_tests/abnormal_state.json

+7
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,12 @@
8989
"stream_state": { "4651612872": { "segments.date": "2222-01-01" }},
9090
"stream_descriptor": { "name": "display_keyword_performance_report" }
9191
}
92+
},
93+
{
94+
"type": "STREAM",
95+
"stream": {
96+
"stream_state": { "4651612872": { "segments.date": "2222-01-01" }},
97+
"stream_descriptor": { "name": "campaign_budget" }
98+
}
9299
}
93100
]

airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl

+3
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,6 @@
8686
{"stream":"ad_groups","data":{"ad_group.ad_rotation_mode":"UNSPECIFIED","ad_group.base_ad_group":"customers/4651612872/adGroups/137051662444","ad_group.campaign":"customers/4651612872/campaigns/16820250687","ad_group.cpc_bid_micros":10000,"ad_group.cpm_bid_micros":10000,"ad_group.cpv_bid_micros":0,"ad_group.display_custom_bid_dimension":"UNSPECIFIED","ad_group.effective_target_cpa_micros":0,"ad_group.effective_target_cpa_source":"UNSPECIFIED","ad_group.effective_target_roas":0.0,"ad_group.effective_target_roas_source":"UNSPECIFIED","ad_group.excluded_parent_asset_field_types":[],"ad_group.optimized_targeting_enabled":false,"ad_group.final_url_suffix":"","ad_group.id":137051662444,"ad_group.labels":[],"ad_group.name":"Группа объявлений 1","ad_group.percent_cpc_bid_micros":0,"ad_group.resource_name":"customers/4651612872/adGroups/137051662444","ad_group.status":"ENABLED","ad_group.target_cpa_micros":0,"ad_group.target_cpm_micros":10000,"ad_group.target_roas":0.0,"ad_group.targeting_setting.target_restrictions":["targeting_dimension: AUDIENCE\nbid_only: true\n","targeting_dimension: AGE_RANGE\nbid_only: true\n","targeting_dimension: GENDER\nbid_only: true\n","targeting_dimension: PARENTAL_STATUS\nbid_only: true\n","targeting_dimension: INCOME_RANGE\nbid_only: true\n"],"ad_group.tracking_url_template":"","ad_group.type":"SEARCH_STANDARD","ad_group.url_custom_parameters":[],"segments.date":"2022-04-10"},"emitted_at":1679577823329}
8787
{"stream": "audience", "data": {"audience.description": "", "audience.dimensions": ["audience_segments {\n segments {\n custom_audience {\n custom_audience: \"customers/4651612872/customAudiences/523469909\"\n }\n }\n}\n"], "audience.exclusion_dimension": "", "audience.id": 47792633, "audience.name": "Audience name 1", "audience.resource_name": "customers/4651612872/audiences/47792633", "audience.status": "ENABLED"}, "emitted_at": 1688510825339}
8888
{"stream": "user_interest", "data": {"user_interest.availabilities": ["channel {\n availability_mode: CHANNEL_TYPE_AND_ALL_SUBTYPES\n advertising_channel_type: SEARCH\n include_default_channel_sub_type: true\n}\nlocale {\n availability_mode: ALL_LOCALES\n}\n", "channel {\n availability_mode: CHANNEL_TYPE_AND_ALL_SUBTYPES\n advertising_channel_type: DISPLAY\n include_default_channel_sub_type: true\n}\nlocale {\n availability_mode: ALL_LOCALES\n}\n", "channel {\n availability_mode: CHANNEL_TYPE_AND_ALL_SUBTYPES\n advertising_channel_type: SHOPPING\n include_default_channel_sub_type: true\n}\nlocale {\n availability_mode: ALL_LOCALES\n}\n", "channel {\n availability_mode: CHANNEL_TYPE_AND_ALL_SUBTYPES\n advertising_channel_type: DISCOVERY\n include_default_channel_sub_type: true\n}\nlocale {\n availability_mode: ALL_LOCALES\n}\n", "channel {\n availability_mode: CHANNEL_TYPE_AND_SUBSET_SUBTYPES\n advertising_channel_type: VIDEO\n advertising_channel_sub_type: VIDEO_SEQUENCE\n advertising_channel_sub_type: VIDEO_OUTSTREAM\n advertising_channel_sub_type: VIDEO_ACTION\n advertising_channel_sub_type: VIDEO_NON_SKIPPABLE\n advertising_channel_sub_type: VIDEO_REACH_TARGET_FREQUENCY\n include_default_channel_sub_type: true\n}\nlocale {\n availability_mode: ALL_LOCALES\n}\n"], "user_interest.launched_to_all": false, "user_interest.name": "Cloud Services Power Users", "user_interest.resource_name": "customers/4651612872/userInterests/92931", "user_interest.taxonomy_type": "AFFINITY", "user_interest.user_interest_id": 92931, "user_interest.user_interest_parent": "customers/4651612872/userInterests/92507"}, "emitted_at": 1688510842265}
89+
{"stream": "campaign_budget", "data": {"campaign_budget.aligned_bidding_strategy_id": 0, "campaign_budget.amount_micros": 750000, "campaign_budget.delivery_method": ["STANDARD"], "campaign_budget.explicitly_shared": false, "campaign_budget.has_recommended_budget": false, "campaign_budget.id": 10695604507, "campaign_budget.name": "Website traffic-Search-15", "campaign_budget.period": ["DAILY"], "campaign_budget.recommended_budget_amount_micros": 0, "campaign_budget.recommended_budget_estimated_change_weekly_clicks": 0, "campaign_budget.recommended_budget_estimated_change_weekly_cost_micros": 0, "campaign_budget.recommended_budget_estimated_change_weekly_interactions": 0, "campaign_budget.recommended_budget_estimated_change_weekly_views": 0, "campaign_budget.reference_count": 1, "campaign_budget.resource_name": "customers/4651612872/campaignBudgets/10695604507", "campaign_budget.status": ["ENABLED"], "campaign_budget.total_amount_micros": 0, "campaign_budget.type": ["STANDARD"], "segments.date": "2022-04-08", "segments.budget_campaign_association_status.campaign": "customers/4651612872/campaigns/16820250687", "segments.budget_campaign_association_status.status": ["ENABLED"], "metrics.all_conversions": 0.0, "metrics.all_conversions_from_interactions_rate": 0.0, "metrics.all_conversions_value": 0.0, "metrics.average_cost": 0.0, "metrics.average_cpc": 0.0, "metrics.average_cpe": 0.0, "metrics.average_cpm": 0.0, "metrics.average_cpv": 0.0, "metrics.clicks": 0, "metrics.conversions": 0.0, "metrics.conversions_from_interactions_rate": 0.0, "metrics.conversions_value": 0.0, "metrics.cost_micros": 0, "metrics.cost_per_all_conversions": 0.0, "metrics.cost_per_conversion": 0.0, "metrics.cross_device_conversions": 0.0, "metrics.ctr": 0.0, "metrics.engagement_rate": 0.0, "metrics.engagements": 0, "metrics.impressions": 2, "metrics.interaction_event_types": [], "metrics.interaction_rate": 0.0, "metrics.interactions": 0, "metrics.value_per_all_conversions": 0.0, "metrics.value_per_conversion": 0.0, "metrics.video_view_rate": 0.0, "metrics.video_views": 0, "metrics.view_through_conversions": 0}, "emitted_at": 1688986481805}
90+
{"stream": "campaign_budget", "data": {"campaign_budget.aligned_bidding_strategy_id": 0, "campaign_budget.amount_micros": 750000, "campaign_budget.delivery_method": ["STANDARD"], "campaign_budget.explicitly_shared": false, "campaign_budget.has_recommended_budget": false, "campaign_budget.id": 10695604507, "campaign_budget.name": "Website traffic-Search-15", "campaign_budget.period": ["DAILY"], "campaign_budget.recommended_budget_amount_micros": 0, "campaign_budget.recommended_budget_estimated_change_weekly_clicks": 0, "campaign_budget.recommended_budget_estimated_change_weekly_cost_micros": 0, "campaign_budget.recommended_budget_estimated_change_weekly_interactions": 0, "campaign_budget.recommended_budget_estimated_change_weekly_views": 0, "campaign_budget.reference_count": 1, "campaign_budget.resource_name": "customers/4651612872/campaignBudgets/10695604507", "campaign_budget.status": ["ENABLED"], "campaign_budget.total_amount_micros": 0, "campaign_budget.type": ["STANDARD"], "segments.date": "2022-04-09", "segments.budget_campaign_association_status.campaign": "customers/4651612872/campaigns/16820250687", "segments.budget_campaign_association_status.status": ["ENABLED"], "metrics.all_conversions": 0.0, "metrics.all_conversions_from_interactions_rate": 0.0, "metrics.all_conversions_value": 0.0, "metrics.average_cost": 70000.0, "metrics.average_cpc": 70000.0, "metrics.average_cpe": 0.0, "metrics.average_cpm": 492957.74647887325, "metrics.average_cpv": 0.0, "metrics.clicks": 1, "metrics.conversions": 0.0, "metrics.conversions_from_interactions_rate": 0.0, "metrics.conversions_value": 0.0, "metrics.cost_micros": 70000, "metrics.cost_per_all_conversions": 0.0, "metrics.cost_per_conversion": 0.0, "metrics.cross_device_conversions": 0.0, "metrics.ctr": 0.007042253521126761, "metrics.engagement_rate": 0.0, "metrics.engagements": 0, "metrics.impressions": 142, "metrics.interaction_event_types": ["InteractionEventType.CLICK"], "metrics.interaction_rate": 0.007042253521126761, "metrics.interactions": 1, "metrics.value_per_all_conversions": 0.0, "metrics.value_per_conversion": 0.0, "metrics.video_view_rate": 0.0, "metrics.video_views": 0, "metrics.view_through_conversions": 0}, "emitted_at": 1688986481808}
91+
{"stream": "campaign_budget", "data": {"campaign_budget.aligned_bidding_strategy_id": 0, "campaign_budget.amount_micros": 750000, "campaign_budget.delivery_method": ["STANDARD"], "campaign_budget.explicitly_shared": false, "campaign_budget.has_recommended_budget": false, "campaign_budget.id": 10695604507, "campaign_budget.name": "Website traffic-Search-15", "campaign_budget.period": ["DAILY"], "campaign_budget.recommended_budget_amount_micros": 0, "campaign_budget.recommended_budget_estimated_change_weekly_clicks": 0, "campaign_budget.recommended_budget_estimated_change_weekly_cost_micros": 0, "campaign_budget.recommended_budget_estimated_change_weekly_interactions": 0, "campaign_budget.recommended_budget_estimated_change_weekly_views": 0, "campaign_budget.reference_count": 1, "campaign_budget.resource_name": "customers/4651612872/campaignBudgets/10695604507", "campaign_budget.status": ["ENABLED"], "campaign_budget.total_amount_micros": 0, "campaign_budget.type": ["STANDARD"], "segments.date": "2022-04-10", "segments.budget_campaign_association_status.campaign": "customers/4651612872/campaigns/16820250687", "segments.budget_campaign_association_status.status": ["ENABLED"], "metrics.all_conversions": 0.0, "metrics.all_conversions_from_interactions_rate": 0.0, "metrics.all_conversions_value": 0.0, "metrics.average_cost": 175000.0, "metrics.average_cpc": 175000.0, "metrics.average_cpe": 0.0, "metrics.average_cpm": 17721518.987341773, "metrics.average_cpv": 0.0, "metrics.clicks": 8, "metrics.conversions": 0.0, "metrics.conversions_from_interactions_rate": 0.0, "metrics.conversions_value": 0.0, "metrics.cost_micros": 1400000, "metrics.cost_per_all_conversions": 0.0, "metrics.cost_per_conversion": 0.0, "metrics.cross_device_conversions": 0.0, "metrics.ctr": 0.10126582278481013, "metrics.engagement_rate": 0.0, "metrics.engagements": 0, "metrics.impressions": 79, "metrics.interaction_event_types": ["InteractionEventType.CLICK"], "metrics.interaction_rate": 0.10126582278481013, "metrics.interactions": 8, "metrics.value_per_all_conversions": 0.0, "metrics.value_per_conversion": 0.0, "metrics.video_view_rate": 0.0, "metrics.video_views": 0, "metrics.view_through_conversions": 0}, "emitted_at": 1688986481810}

airbyte-integrations/connectors/source-google-ads/integration_tests/incremental_catalog.json

+14
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,20 @@
133133
"cursor_field": ["segments.date"],
134134
"primary_key": [["campaign.id"], ["segments.date"]]
135135
},
136+
{
137+
"stream": {
138+
"name": "campaign_budget",
139+
"json_schema": {},
140+
"supported_sync_modes": ["full_refresh", "incremental"],
141+
"source_defined_cursor": true,
142+
"default_cursor_field": ["segments.date"],
143+
"source_defined_primary_key": [["campaign_budget.id"], ["segments.date"]]
144+
},
145+
"sync_mode": "incremental",
146+
"destination_sync_mode": "overwrite",
147+
"cursor_field": ["segments.date"],
148+
"primary_key": [["campaign_budget.id"], ["segments.date"]]
149+
},
136150
{
137151
"stream": {
138152
"name": "user_location_report",

airbyte-integrations/connectors/source-google-ads/source_google_ads/google_ads.py

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"ad_groups": "ad_group",
2525
"ad_group_labels": "ad_group_label",
2626
"campaigns": "campaign",
27+
"campaign_budget": "campaign_budget",
2728
"campaign_labels": "campaign_label",
2829
"account_performance_report": "customer",
2930
"ad_group_ad_report": "ad_group_ad",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"type": "object",
4+
"properties": {
5+
"campaign_budget.aligned_bidding_strategy_id": {
6+
"type": ["null", "integer"]
7+
},
8+
"campaign_budget.amount_micros": {
9+
"type": ["null", "integer"]
10+
},
11+
"campaign_budget.delivery_method": {
12+
"type": ["null", "array"],
13+
"items": {
14+
"type": ["null", "string"]
15+
}
16+
},
17+
"campaign_budget.explicitly_shared": {
18+
"type": ["null", "boolean"]
19+
},
20+
"campaign_budget.has_recommended_budget": {
21+
"type": ["null", "boolean"]
22+
},
23+
"campaign_budget.id": {
24+
"type": ["null", "integer"]
25+
},
26+
"campaign_budget.name": {
27+
"type": ["null", "string"]
28+
},
29+
"campaign_budget.period": {
30+
"type": ["null", "array"],
31+
"items": {
32+
"type": ["null", "string"]
33+
}
34+
},
35+
"campaign_budget.recommended_budget_amount_micros": {
36+
"type": ["null", "integer"]
37+
},
38+
"campaign_budget.recommended_budget_estimated_change_weekly_clicks": {
39+
"type": ["null", "integer"]
40+
},
41+
"campaign_budget.recommended_budget_estimated_change_weekly_cost_micros": {
42+
"type": ["null", "integer"]
43+
},
44+
"campaign_budget.recommended_budget_estimated_change_weekly_interactions": {
45+
"type": ["null", "integer"]
46+
},
47+
"campaign_budget.recommended_budget_estimated_change_weekly_views": {
48+
"type": ["null", "integer"]
49+
},
50+
"campaign_budget.reference_count": {
51+
"type": ["null", "integer"]
52+
},
53+
"campaign_budget.resource_name": {
54+
"type": ["null", "string"]
55+
},
56+
"campaign_budget.status": {
57+
"type": ["null", "array"],
58+
"items": {
59+
"type": ["null", "string"]
60+
}
61+
},
62+
"campaign_budget.total_amount_micros": {
63+
"type": ["null", "integer"]
64+
},
65+
"campaign_budget.type": {
66+
"type": ["null", "array"],
67+
"items": {
68+
"type": ["null", "string"]
69+
}
70+
},
71+
"segments.date": {
72+
"type": ["null", "string"],
73+
"format": "date"
74+
},
75+
"segments.budget_campaign_association_status.campaign": {
76+
"type": ["null", "string"]
77+
},
78+
"segments.budget_campaign_association_status.status": {
79+
"type": ["null", "array"],
80+
"items": {
81+
"type": ["null", "string"]
82+
}
83+
},
84+
"metrics.all_conversions": {
85+
"type": ["null", "number"]
86+
},
87+
"metrics.all_conversions_from_interactions_rate": {
88+
"type": ["null", "number"]
89+
},
90+
"metrics.all_conversions_value": {
91+
"type": ["null", "number"]
92+
},
93+
"metrics.average_cost": {
94+
"type": ["null", "number"]
95+
},
96+
"metrics.average_cpc": {
97+
"type": ["null", "number"]
98+
},
99+
"metrics.average_cpe": {
100+
"type": ["null", "number"]
101+
},
102+
"metrics.average_cpm": {
103+
"type": ["null", "number"]
104+
},
105+
"metrics.average_cpv": {
106+
"type": ["null", "number"]
107+
},
108+
"metrics.clicks": {
109+
"type": ["null", "integer"]
110+
},
111+
"metrics.conversions": {
112+
"type": ["null", "number"]
113+
},
114+
"metrics.conversions_from_interactions_rate": {
115+
"type": ["null", "number"]
116+
},
117+
"metrics.conversions_value": {
118+
"type": ["null", "number"]
119+
},
120+
"metrics.cost_micros": {
121+
"type": ["null", "integer"]
122+
},
123+
"metrics.cost_per_all_conversions": {
124+
"type": ["null", "number"]
125+
},
126+
"metrics.cost_per_conversion": {
127+
"type": ["null", "number"]
128+
},
129+
"metrics.cross_device_conversions": {
130+
"type": ["null", "number"]
131+
},
132+
"metrics.ctr": {
133+
"type": ["null", "number"]
134+
},
135+
"metrics.engagement_rate": {
136+
"type": ["null", "number"]
137+
},
138+
"metrics.engagements": {
139+
"type": ["null", "integer"]
140+
},
141+
"metrics.impressions": {
142+
"type": ["null", "integer"]
143+
},
144+
"metrics.interaction_event_types": {
145+
"type": ["null", "array"],
146+
"items": {
147+
"type": ["null", "string"]
148+
}
149+
},
150+
"metrics.interaction_rate": {
151+
"type": ["null", "number"]
152+
},
153+
"metrics.interactions": {
154+
"type": ["null", "integer"]
155+
},
156+
"metrics.value_per_all_conversions": {
157+
"type": ["null", "number"]
158+
},
159+
"metrics.value_per_conversion": {
160+
"type": ["null", "number"]
161+
},
162+
"metrics.video_view_rate": {
163+
"type": ["null", "number"]
164+
},
165+
"metrics.video_views": {
166+
"type": ["null", "integer"]
167+
},
168+
"metrics.view_through_conversions": {
169+
"type": ["null", "integer"]
170+
}
171+
}
172+
}

airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
AdGroupLabels,
2929
AdGroups,
3030
Audience,
31+
CampaignBudget,
3132
CampaignLabels,
3233
Campaigns,
3334
ClickView,
@@ -151,6 +152,7 @@ def streams(self, config: Mapping[str, Any]) -> List[Stream]:
151152
AdGroupLabels(google_api, customers=customers),
152153
Accounts(**incremental_config),
153154
Audience(google_api, customers=customers),
155+
CampaignBudget(**incremental_config),
154156
CampaignLabels(google_api, customers=customers),
155157
ClickView(**incremental_config),
156158
UserInterest(google_api, customers=customers),

airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py

+9
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,15 @@ class Campaigns(IncrementalGoogleAdsStream):
276276
primary_key = ["campaign.id", "segments.date", "segments.hour"]
277277

278278

279+
class CampaignBudget(IncrementalGoogleAdsStream):
280+
"""
281+
Campaigns stream: https://developers.google.com/google-ads/api/fields/v13/campaign_budget
282+
"""
283+
284+
transformer = TypeTransformer(TransformConfig.DefaultSchemaNormalization)
285+
primary_key = ["campaign_budget.id", "segments.date"]
286+
287+
279288
class CampaignLabels(GoogleAdsStream):
280289
"""
281290
Campaign labels stream: https://developers.google.com/google-ads/api/fields/v11/campaign_label

airbyte-integrations/connectors/source-google-ads/unit_tests/test_source.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def test_chunk_date_range():
144144
def test_streams_count(config, mock_account_info):
145145
source = SourceGoogleAds()
146146
streams = source.streams(config)
147-
expected_streams_number = 21
147+
expected_streams_number = 22
148148
assert len(streams) == expected_streams_number
149149

150150

0 commit comments

Comments
 (0)