diff --git a/airbyte-config-oss/init-oss/src/main/resources/seed/oss_catalog.json b/airbyte-config-oss/init-oss/src/main/resources/seed/oss_catalog.json index 8e90dc9541875..46f1e09fecf1d 100644 --- a/airbyte-config-oss/init-oss/src/main/resources/seed/oss_catalog.json +++ b/airbyte-config-oss/init-oss/src/main/resources/seed/oss_catalog.json @@ -9715,7 +9715,7 @@ "sourceDefinitionId": "47f25999-dd5e-4636-8c39-e7cea2453331", "name": "Bing Ads", "dockerRepository": "airbyte/source-bing-ads", - "dockerImageTag": "0.1.19", + "dockerImageTag": "0.1.20", "documentationUrl": "https://docs.airbyte.com/integrations/sources/bing-ads", "icon": "bingads.svg", "sourceType": "api", @@ -9776,6 +9776,15 @@ "default": "2020-01-01", "description": "The start date from which to begin replicating report data. Any data generated before this date will not be replicated in reports. This is a UTC date in YYYY-MM-DD format.", "order": 5 + }, + "lookback_window": { + "title": "Lookback window", + "description": "Also known as attribution or conversion window. How far into the past to look for records (in days). If your conversion window has an hours/minutes granularity, round it up to the number of days exceeding. Used only for performance report streams in incremental mode.", + "type": "integer", + "default": 0, + "minimum": 0, + "maximum": 90, + "order": 6 } } }, diff --git a/airbyte-config-oss/init-oss/src/main/resources/seed/source_definitions.yaml b/airbyte-config-oss/init-oss/src/main/resources/seed/source_definitions.yaml index 3a4678497b8bc..a033a99837205 100644 --- a/airbyte-config-oss/init-oss/src/main/resources/seed/source_definitions.yaml +++ b/airbyte-config-oss/init-oss/src/main/resources/seed/source_definitions.yaml @@ -211,7 +211,7 @@ - name: Bing Ads sourceDefinitionId: 47f25999-dd5e-4636-8c39-e7cea2453331 dockerRepository: airbyte/source-bing-ads - dockerImageTag: 0.1.19 + dockerImageTag: 0.1.20 documentationUrl: https://docs.airbyte.com/integrations/sources/bing-ads icon: bingads.svg sourceType: api diff --git a/airbyte-config-oss/init-oss/src/main/resources/seed/source_specs.yaml b/airbyte-config-oss/init-oss/src/main/resources/seed/source_specs.yaml index 3dbf916807e20..f1e1c77971d84 100644 --- a/airbyte-config-oss/init-oss/src/main/resources/seed/source_specs.yaml +++ b/airbyte-config-oss/init-oss/src/main/resources/seed/source_specs.yaml @@ -1958,7 +1958,7 @@ - "overwrite" - "append" - "append_dedup" -- dockerImage: "airbyte/source-bing-ads:0.1.19" +- dockerImage: "airbyte/source-bing-ads:0.1.20" spec: documentationUrl: "https://docs.airbyte.com/integrations/sources/bing-ads" connectionSpecification: @@ -2020,6 +2020,17 @@ \ Any data generated before this date will not be replicated in reports.\ \ This is a UTC date in YYYY-MM-DD format." order: 5 + lookback_window: + title: "Lookback window" + description: "Also known as attribution or conversion window. How far into\ + \ the past to look for records (in days). If your conversion window has\ + \ an hours/minutes granularity, round it up to the number of days exceeding.\ + \ Used only for performance report streams in incremental mode." + type: "integer" + default: 0 + minimum: 0 + maximum: 90 + order: 6 supportsNormalization: false supportsDBT: false supported_destination_sync_modes: [] diff --git a/airbyte-integrations/connectors/source-bing-ads/Dockerfile b/airbyte-integrations/connectors/source-bing-ads/Dockerfile index 3a5298feae5c3..d88a7a6a8d184 100644 --- a/airbyte-integrations/connectors/source-bing-ads/Dockerfile +++ b/airbyte-integrations/connectors/source-bing-ads/Dockerfile @@ -12,5 +12,5 @@ RUN pip install . ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=0.1.19 +LABEL io.airbyte.version=0.1.20 LABEL io.airbyte.name=airbyte/source-bing-ads diff --git a/airbyte-integrations/connectors/source-bing-ads/bootstrap.md b/airbyte-integrations/connectors/source-bing-ads/bootstrap.md index 7dc3b750d3b28..aa87f973f8f41 100644 --- a/airbyte-integrations/connectors/source-bing-ads/bootstrap.md +++ b/airbyte-integrations/connectors/source-bing-ads/bootstrap.md @@ -33,6 +33,8 @@ Connector uses `reports_start_date` config for initial reports sync and current Connector has `hourly_reports`, `daily_reports`, `weekly_reports`, `monthly_reports` report streams. For example `account_performance_report_daily`, `ad_group_performance_report_weekly`. All these reports streams will be generated on execute. +If `lookback_window` is set to a non-null value, initial reports sync will start at `reports_start_date - lookback_window`. Following reports sync will start at `cursor_value - lookback_window`. + ## Request caching Based on [library](https://vcrpy.readthedocs.io/en/latest/) diff --git a/airbyte-integrations/connectors/source-bing-ads/integration_tests/invalid_config.json b/airbyte-integrations/connectors/source-bing-ads/integration_tests/invalid_config.json index 078e86a023842..155bc46f2b2b7 100644 --- a/airbyte-integrations/connectors/source-bing-ads/integration_tests/invalid_config.json +++ b/airbyte-integrations/connectors/source-bing-ads/integration_tests/invalid_config.json @@ -4,6 +4,7 @@ "client_id": "123", "developer_token": "asgag4gwag3", "reports_start_date": "2018-11-13", + "lookback_window": 0, "hourly_reports": false, "daily_reports": false, "weekly_reports": true, diff --git a/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/reports.py b/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/reports.py index e36556685664d..b3cd1c5bf47d0 100644 --- a/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/reports.py +++ b/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/reports.py @@ -203,11 +203,7 @@ def get_request_date(self, reporting_service: ServiceClient, date: datetime) -> def request_params( self, stream_state: Mapping[str, Any] = None, account_id: str = None, **kwargs: Mapping[str, Any] ) -> Mapping[str, Any]: - if not stream_state or not account_id or not stream_state.get(account_id, {}).get(self.cursor_field): - start_date = self.client.reports_start_date - else: - # gets starting point for a stream and account - start_date = pendulum.from_timestamp(stream_state[account_id][self.cursor_field]) + start_date = self.get_start_date(stream_state, account_id) reporting_service = self.client.get_service("ReportingService") request_time_zone = reporting_service.factory.create("ReportTimeZone") @@ -228,6 +224,13 @@ def request_params( "timeout_in_milliseconds": self.timeout, } + def get_start_date(self, stream_state: Mapping[str, Any] = None, account_id: str = None): + if stream_state and account_id: + if stream_state.get(account_id, {}).get(self.cursor_field): + return pendulum.from_timestamp(stream_state[account_id][self.cursor_field]) + + return self.client.reports_start_date + def get_updated_state( self, current_stream_state: MutableMapping[str, Any], @@ -337,3 +340,15 @@ def stream_slices( yield {"account_id": account["Id"], "customer_id": account["ParentCustomerId"]} yield from [] + + +class PerformanceReportsMixin(ReportsMixin): + def get_start_date(self, stream_state: Mapping[str, Any] = None, account_id: str = None): + start_date = super().get_start_date(stream_state, account_id) + + if self.config.get("lookback_window"): + # Datetime subtract won't work with days = 0 + # it'll output an AirbuteError + return start_date.subtract(days=self.config["lookback_window"]) + else: + return start_date diff --git a/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/source.py b/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/source.py index 949005f8ebd55..5cfbb6425da1e 100644 --- a/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/source.py +++ b/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/source.py @@ -23,6 +23,7 @@ HISTORICAL_FIELDS, LOW_QUALITY_FIELDS, REVENUE_FIELDS, + PerformanceReportsMixin, ReportsMixin, ) from suds import sudsobject @@ -343,7 +344,7 @@ class BudgetSummaryReport(ReportsMixin, BingAdsStream): ] -class CampaignPerformanceReport(ReportsMixin, BingAdsStream): +class CampaignPerformanceReport(PerformanceReportsMixin, BingAdsStream): data_field: str = "" service_name: str = "ReportingService" report_name: str = "CampaignPerformanceReport" @@ -427,7 +428,7 @@ class CampaignPerformanceReportMonthly(CampaignPerformanceReport): ] -class AdPerformanceReport(ReportsMixin, BingAdsStream): +class AdPerformanceReport(PerformanceReportsMixin, BingAdsStream): data_field: str = "" service_name: str = "ReportingService" report_name: str = "AdPerformanceReport" @@ -499,7 +500,7 @@ class AdPerformanceReportMonthly(AdPerformanceReport): report_aggregation = "Monthly" -class AdGroupPerformanceReport(ReportsMixin, BingAdsStream): +class AdGroupPerformanceReport(PerformanceReportsMixin, BingAdsStream): data_field: str = "" service_name: str = "ReportingService" report_name: str = "AdGroupPerformanceReport" @@ -586,7 +587,7 @@ class AdGroupPerformanceReportMonthly(AdGroupPerformanceReport): ] -class KeywordPerformanceReport(ReportsMixin, BingAdsStream): +class KeywordPerformanceReport(PerformanceReportsMixin, BingAdsStream): data_field: str = "" service_name: str = "ReportingService" report_name: str = "KeywordPerformanceReport" @@ -671,7 +672,7 @@ class KeywordPerformanceReportMonthly(KeywordPerformanceReport): report_aggregation = "Monthly" -class AccountPerformanceReport(ReportsMixin, BingAdsStream): +class AccountPerformanceReport(PerformanceReportsMixin, BingAdsStream): data_field: str = "" service_name: str = "ReportingService" report_name: str = "AccountPerformanceReport" diff --git a/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/spec.json b/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/spec.json index 17044fea91145..613e9d2b969d2 100644 --- a/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/spec.json +++ b/airbyte-integrations/connectors/source-bing-ads/source_bing_ads/spec.json @@ -60,6 +60,15 @@ "default": "2020-01-01", "description": "The start date from which to begin replicating report data. Any data generated before this date will not be replicated in reports. This is a UTC date in YYYY-MM-DD format.", "order": 5 + }, + "lookback_window": { + "title": "Lookback window", + "description": "Also known as attribution or conversion window. How far into the past to look for records (in days). If your conversion window has an hours/minutes granularity, round it up to the number of days exceeding. Used only for performance report streams in incremental mode.", + "type": "integer", + "default": 0, + "minimum": 0, + "maximum": 90, + "order": 6 } } }, diff --git a/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_reports.py b/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_reports.py index 15f7f222f96c0..4d82a559d91f6 100644 --- a/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_reports.py +++ b/airbyte-integrations/connectors/source-bing-ads/unit_tests/test_reports.py @@ -6,7 +6,7 @@ import pendulum from bingads.v13.internal.reporting.row_report_iterator import _RowReportRecord, _RowValues -from source_bing_ads.reports import ReportsMixin +from source_bing_ads.reports import PerformanceReportsMixin, ReportsMixin from source_bing_ads.source import SourceBingAds @@ -23,6 +23,15 @@ def __init__(self) -> None: self.client = TestClient() +class TestPerformanceReport(PerformanceReportsMixin, SourceBingAds): + date_format, report_columns, report_name, cursor_field = "YYYY-MM-DD", None, None, "Time" + report_aggregation = "Monthly" + report_schema_name = "campaign_performance_report" + + def __init__(self) -> None: + self.client = TestClient() + + def test_get_column_value(): row_values = _RowValues( {"AccountId": 1, "AverageCpc": 3, "AdGroupId": 2, "AccountName": 5, "Spend": 4}, @@ -38,6 +47,14 @@ def test_get_column_value(): assert test_report.get_column_value(record, "Spend") == 1.203 +def test_get_updated_state_init_state(): + test_report = TestReport() + stream_state = {} + latest_record = {"AccountId": 123, "Time": "2020-01-02"} + new_state = test_report.get_updated_state(stream_state, latest_record) + assert new_state["123"]["Time"] == (pendulum.parse("2020-01-02")).timestamp() + + def test_get_updated_state_new_state(): test_report = TestReport() stream_state = {"123": {"Time": pendulum.parse("2020-01-01").timestamp()}} @@ -79,3 +96,44 @@ def test_get_report_record_timestamp_hourly(): test_report = TestReport() test_report.report_aggregation = "Hourly" assert pendulum.parse("2020-01-01T15:00:00").timestamp() == test_report.get_report_record_timestamp("2020-01-01|15") + + +def test_report_get_start_date_wo_stream_state(): + expected_start_date = "2020-01-01" + test_report = TestReport() + test_report.client.reports_start_date = "2020-01-01" + stream_state = {} + account_id = "123" + assert expected_start_date == test_report.get_start_date(stream_state, account_id) + + +def test_report_get_start_date_with_stream_state(): + expected_start_date = pendulum.parse("2023-04-17T21:29:57") + test_report = TestReport() + test_report.cursor_field = "cursor_field" + test_report.client.reports_start_date = "2020-01-01" + stream_state = {"123": {"cursor_field": 1681766997}} + account_id = "123" + assert expected_start_date == test_report.get_start_date(stream_state, account_id) + + +def test_report_get_start_date_performance_report_with_stream_state(): + expected_start_date = pendulum.parse("2023-04-07T21:29:57") + test_report = TestPerformanceReport() + test_report.cursor_field = "cursor_field" + test_report.config = {"lookback_window": 10} + stream_state = {"123": {"cursor_field": 1681766997}} + account_id = "123" + assert expected_start_date == test_report.get_start_date(stream_state, account_id) + + +def test_report_get_start_date_performance_report_wo_stream_state(): + days_to_subtract = 10 + reports_start_date = pendulum.parse("2021-04-07T00:00:00") + test_report = TestPerformanceReport() + test_report.cursor_field = "cursor_field" + test_report.client.reports_start_date = reports_start_date + test_report.config = {"lookback_window": days_to_subtract} + stream_state = {} + account_id = "123" + assert reports_start_date.subtract(days=days_to_subtract) == test_report.get_start_date(stream_state, account_id) diff --git a/connectors.md b/connectors.md index 38e53b98adcd6..7776f350c6a36 100644 --- a/connectors.md +++ b/connectors.md @@ -28,7 +28,7 @@ | **BambooHR** | BambooHR icon | Source | airbyte/source-bamboo-hr:0.2.2 | alpha | [docs](https://docs.airbyte.com/integrations/sources/bamboo-hr) | [connectors/source/bamboo-hr](https://github.com/airbytehq/airbyte/issues?q=is:open+is:issue+label:connectors/source/bamboo-hr) | [source-bamboo-hr](https://github.com/airbytehq/airbyte/tree/master/airbyte-integrations/connectors/source-bamboo-hr) | `90916976-a132-4ce9-8bce-82a03dd58788` | | **BigCommerce** | BigCommerce icon | Source | airbyte/source-bigcommerce:0.1.10 | alpha | [docs](https://docs.airbyte.com/integrations/sources/bigcommerce) | [connectors/source/bigcommerce](https://github.com/airbytehq/airbyte/issues?q=is:open+is:issue+label:connectors/source/bigcommerce) | [source-bigcommerce](https://github.com/airbytehq/airbyte/tree/master/airbyte-integrations/connectors/source-bigcommerce) | `59c5501b-9f95-411e-9269-7143c939adbd` | | **BigQuery** | BigQuery icon | Source | airbyte/source-bigquery:0.2.3 | alpha | [docs](https://docs.airbyte.com/integrations/sources/bigquery) | [connectors/source/bigquery](https://github.com/airbytehq/airbyte/issues?q=is:open+is:issue+label:connectors/source/bigquery) | [source-bigquery](https://github.com/airbytehq/airbyte/tree/master/airbyte-integrations/connectors/source-bigquery) | `bfd1ddf8-ae8a-4620-b1d7-55597d2ba08c` | -| **Bing Ads** | Bing Ads icon | Source | airbyte/source-bing-ads:0.1.19 | generally_available | [docs](https://docs.airbyte.com/integrations/sources/bing-ads) | [connectors/source/bing-ads](https://github.com/airbytehq/airbyte/issues?q=is:open+is:issue+label:connectors/source/bing-ads) | [source-bing-ads](https://github.com/airbytehq/airbyte/tree/master/airbyte-integrations/connectors/source-bing-ads) | `47f25999-dd5e-4636-8c39-e7cea2453331` | +| **Bing Ads** | Bing Ads icon | Source | airbyte/source-bing-ads:0.1.20 | generally_available | [docs](https://docs.airbyte.com/integrations/sources/bing-ads) | [connectors/source/bing-ads](https://github.com/airbytehq/airbyte/issues?q=is:open+is:issue+label:connectors/source/bing-ads) | [source-bing-ads](https://github.com/airbytehq/airbyte/tree/master/airbyte-integrations/connectors/source-bing-ads) | `47f25999-dd5e-4636-8c39-e7cea2453331` | | **Braintree** | Braintree icon | Source | airbyte/source-braintree:0.1.4 | alpha | [docs](https://docs.airbyte.com/integrations/sources/braintree) | [connectors/source/braintree](https://github.com/airbytehq/airbyte/issues?q=is:open+is:issue+label:connectors/source/braintree) | [source-braintree](https://github.com/airbytehq/airbyte/tree/master/airbyte-integrations/connectors/source-braintree) | `63cea06f-1c75-458d-88fe-ad48c7cb27fd` | | **Braze** | x | Source | airbyte/source-braze:0.1.3 | alpha | [docs](https://docs.airbyte.io/integrations/sources/braze) | [connectors/source/braze](https://github.com/airbytehq/airbyte/issues?q=is:open+is:issue+label:connectors/source/braze) | [source-braze](https://github.com/airbytehq/airbyte/tree/master/airbyte-integrations/connectors/source-braze) | `68b9c98e-0747-4c84-b05b-d30b47686725` | | **Breezometer** | Breezometer icon | Source | airbyte/source-breezometer:0.1.0 | alpha | [docs](https://docs.airbyte.com/integrations/sources/breezometer) | [connectors/source/breezometer](https://github.com/airbytehq/airbyte/issues?q=is:open+is:issue+label:connectors/source/breezometer) | [source-breezometer](https://github.com/airbytehq/airbyte/tree/master/airbyte-integrations/connectors/source-breezometer) | `7c37685e-8512-4901-addf-9afbef6c0de9` | diff --git a/docs/integrations/sources/bing-ads.md b/docs/integrations/sources/bing-ads.md index f045738ff787e..4d2e5be82fcd1 100644 --- a/docs/integrations/sources/bing-ads.md +++ b/docs/integrations/sources/bing-ads.md @@ -33,9 +33,10 @@ The tenant is used in the authentication URL, for example: `https://login.micros 5. For **Tenant ID**, enter the custom tenant or use the common tenant. 6. Add the developer token from [Step 1](#step-1-set-up-bing-ads). 7. For **Replication Start Date**, enter the date in YYYY-MM-DD format. The data added on and after this date will be replicated. If this field is blank, Airbyte will replicate all data. -8. Click **Authenticate your Bing Ads account**. -9. Log in and authorize the Bing Ads account. -10. Click **Set up source**. +8. For **Lookback window** (also known as attribution or conversion window) enter the number of **days** to look into the past. If your conversion window has an hours/minutes granularity, round it up to the number of days exceeding. If you're not using performance report streams in incremental mode, let it with 0 default value. +9. Click **Authenticate your Bing Ads account**. +10. Log in and authorize the Bing Ads account. +11. Click **Set up source**. @@ -47,7 +48,8 @@ The tenant is used in the authentication URL, for example: `https://login.micros 5. For **Tenant ID**, enter the custom tenant or use the common tenant. 6. Enter the **Client ID**, **Client Secret**, **Refresh Token**, and **Developer Token** from [Step 1](#step-1-set-up-bing-ads). 7. For **Replication Start Date**, enter the date in YYYY-MM-DD format. The data added on and after this date will be replicated. If this field is blank, Airbyte will replicate all data. -8. Click **Set up source**. +8. For **Lookback window** (also known as attribution or conversion window) enter the number of **days** to look into the past. If your conversion window has an hours/minutes granularity, round it up to the number of days exceeding. If you're not using performance report streams in incremental mode, let it with 0 default value. +9. Click **Set up source**. ## Supported sync modes @@ -100,25 +102,26 @@ A report's aggregation window is indicated in its name. For example, `account_pe The Bing Ads API limits the number of requests for all Microsoft Advertising clients. You can find detailed info [here](https://docs.microsoft.com/en-us/advertising/guides/services-protocol?view=bingads-13#throttling). ## Changelog -| Version | Date | Pull Request | Subject | -|:--------|:-----------|:---------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------| -| 0.1.19 | 2023-03-08 | [23868](https://github.com/airbytehq/airbyte/pull/23868) | Add dimensional-type columns for reports. | -| 0.1.18 | 2023-01-30 | [22073](https://github.com/airbytehq/airbyte/pull/22073) | Fix null values in the `Keyword` column of `keyword_performance_report` streams | -| 0.1.17 | 2022-12-10 | [20005](https://github.com/airbytehq/airbyte/pull/20005) | Add `Keyword` to `keyword_performance_report` stream | -| 0.1.16 | 2022-10-12 | [17873](https://github.com/airbytehq/airbyte/pull/17873) | Fix: added missing campaign types in (Audience, Shopping and DynamicSearchAds) in campaigns stream | -| 0.1.15 | 2022-10-03 | [17505](https://github.com/airbytehq/airbyte/pull/17505) | Fix: limit cache size for ServiceClient instances | -| 0.1.14 | 2022-09-29 | [17403](https://github.com/airbytehq/airbyte/pull/17403) | Fix: limit cache size for ReportingServiceManager instances | -| 0.1.13 | 2022-09-29 | [17386](https://github.com/airbytehq/airbyte/pull/17386) | Migrate to per-stream states. | -| 0.1.12 | 2022-09-05 | [16335](https://github.com/airbytehq/airbyte/pull/16335) | Added backoff for socket.timeout | -| 0.1.11 | 2022-08-25 | [15684](https://github.com/airbytehq/airbyte/pull/15684) (published in [15987](https://github.com/airbytehq/airbyte/pull/15987)) | Fixed log messages being unreadable | -| 0.1.10 | 2022-08-12 | [15602](https://github.com/airbytehq/airbyte/pull/15602) | Fixed bug caused Hourly Reports to crash due to invalid fields set | -| 0.1.9 | 2022-08-02 | [14862](https://github.com/airbytehq/airbyte/pull/14862) | Added missing columns | -| 0.1.8 | 2022-06-15 | [13801](https://github.com/airbytehq/airbyte/pull/13801) | All reports `hourly/daily/weekly/monthly` will be generated by default, these options are removed from input configuration | -| 0.1.7 | 2022-05-17 | [12937](https://github.com/airbytehq/airbyte/pull/12937) | Added OAuth2.0 authentication method, removed `redirect_uri` from input configuration | -| 0.1.6 | 2022-04-30 | [12500](https://github.com/airbytehq/airbyte/pull/12500) | Improve input configuration copy | -| 0.1.5 | 2022-01-01 | [11652](https://github.com/airbytehq/airbyte/pull/11652) | Rebump attempt after DockerHub failure at registring the 0.1.4 | -| 0.1.4 | 2022-03-22 | [11311](https://github.com/airbytehq/airbyte/pull/11311) | Added optional Redirect URI & Tenant ID to spec | -| 0.1.3 | 2022-01-14 | [9510](https://github.com/airbytehq/airbyte/pull/9510) | Fixed broken dependency that blocked connector's operations | -| 0.1.2 | 2021-12-14 | [8429](https://github.com/airbytehq/airbyte/pull/8429) | Update titles and descriptions | -| 0.1.1 | 2021-08-31 | [5750](https://github.com/airbytehq/airbyte/pull/5750) | Added reporting streams\) | -| 0.1.0 | 2021-07-22 | [4911](https://github.com/airbytehq/airbyte/pull/4911) | Initial release supported core streams \(Accounts, Campaigns, Ads, AdGroups\) | +| Version | Date | Pull Request | Subject | +|:--------|:-----------|:-----------------------------------------------------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------| +| 0.1.20 | 2023-03-09 | [23663](https://github.com/airbytehq/airbyte/pull/23663) | Add lookback window for performance reports in incremental mode | +| 0.1.19 | 2023-03-08 | [23868](https://github.com/airbytehq/airbyte/pull/23868) | Add dimensional-type columns for reports. | +| 0.1.18 | 2023-01-30 | [22073](https://github.com/airbytehq/airbyte/pull/22073) | Fix null values in the `Keyword` column of `keyword_performance_report` streams | +| 0.1.17 | 2022-12-10 | [20005](https://github.com/airbytehq/airbyte/pull/20005) | Add `Keyword` to `keyword_performance_report` stream | +| 0.1.16 | 2022-10-12 | [17873](https://github.com/airbytehq/airbyte/pull/17873) | Fix: added missing campaign types in (Audience, Shopping and DynamicSearchAds) in campaigns stream | +| 0.1.15 | 2022-10-03 | [17505](https://github.com/airbytehq/airbyte/pull/17505) | Fix: limit cache size for ServiceClient instances | +| 0.1.14 | 2022-09-29 | [17403](https://github.com/airbytehq/airbyte/pull/17403) | Fix: limit cache size for ReportingServiceManager instances | +| 0.1.13 | 2022-09-29 | [17386](https://github.com/airbytehq/airbyte/pull/17386) | Migrate to per-stream states. | +| 0.1.12 | 2022-09-05 | [16335](https://github.com/airbytehq/airbyte/pull/16335) | Added backoff for socket.timeout | +| 0.1.11 | 2022-08-25 | [15684](https://github.com/airbytehq/airbyte/pull/15684) (published in [15987](https://github.com/airbytehq/airbyte/pull/15987)) | Fixed log messages being unreadable | +| 0.1.10 | 2022-08-12 | [15602](https://github.com/airbytehq/airbyte/pull/15602) | Fixed bug caused Hourly Reports to crash due to invalid fields set | +| 0.1.9 | 2022-08-02 | [14862](https://github.com/airbytehq/airbyte/pull/14862) | Added missing columns | +| 0.1.8 | 2022-06-15 | [13801](https://github.com/airbytehq/airbyte/pull/13801) | All reports `hourly/daily/weekly/monthly` will be generated by default, these options are removed from input configuration | +| 0.1.7 | 2022-05-17 | [12937](https://github.com/airbytehq/airbyte/pull/12937) | Added OAuth2.0 authentication method, removed `redirect_uri` from input configuration | +| 0.1.6 | 2022-04-30 | [12500](https://github.com/airbytehq/airbyte/pull/12500) | Improve input configuration copy | +| 0.1.5 | 2022-01-01 | [11652](https://github.com/airbytehq/airbyte/pull/11652) | Rebump attempt after DockerHub failure at registring the 0.1.4 | +| 0.1.4 | 2022-03-22 | [11311](https://github.com/airbytehq/airbyte/pull/11311) | Added optional Redirect URI & Tenant ID to spec | +| 0.1.3 | 2022-01-14 | [9510](https://github.com/airbytehq/airbyte/pull/9510) | Fixed broken dependency that blocked connector's operations | +| 0.1.2 | 2021-12-14 | [8429](https://github.com/airbytehq/airbyte/pull/8429) | Update titles and descriptions | +| 0.1.1 | 2021-08-31 | [5750](https://github.com/airbytehq/airbyte/pull/5750) | Added reporting streams\) | +| 0.1.0 | 2021-07-22 | [4911](https://github.com/airbytehq/airbyte/pull/4911) | Initial release supported core streams \(Accounts, Campaigns, Ads, AdGroups\) |