From 1d42821d117a2f6adbc16ccdc81ae72f87b9e8c7 Mon Sep 17 00:00:00 2001 From: Ella Rohm-Ensing Date: Fri, 7 Jul 2023 14:20:18 -0500 Subject: [PATCH 01/63] bump faker (#28060) * bump faker * add pr ref --- airbyte-integrations/connectors/source-faker/Dockerfile | 2 +- airbyte-integrations/connectors/source-faker/metadata.yaml | 2 +- docs/integrations/sources/faker.md | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/airbyte-integrations/connectors/source-faker/Dockerfile b/airbyte-integrations/connectors/source-faker/Dockerfile index 8bd35b07e3f9..aeda1ef2ec8d 100644 --- a/airbyte-integrations/connectors/source-faker/Dockerfile +++ b/airbyte-integrations/connectors/source-faker/Dockerfile @@ -34,5 +34,5 @@ COPY source_faker ./source_faker ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=3.0.1 +LABEL io.airbyte.version=3.0.2 LABEL io.airbyte.name=airbyte/source-faker diff --git a/airbyte-integrations/connectors/source-faker/metadata.yaml b/airbyte-integrations/connectors/source-faker/metadata.yaml index 953728c9ba5c..287620921efe 100644 --- a/airbyte-integrations/connectors/source-faker/metadata.yaml +++ b/airbyte-integrations/connectors/source-faker/metadata.yaml @@ -4,7 +4,7 @@ data: connectorSubtype: api connectorType: source definitionId: dfd88b22-b603-4c3d-aad7-3701784586b1 - dockerImageTag: 3.0.1 + dockerImageTag: 3.0.2 dockerRepository: airbyte/source-faker githubIssueLabel: source-faker icon: faker.svg diff --git a/docs/integrations/sources/faker.md b/docs/integrations/sources/faker.md index 1fea73d122a9..4be4490c3ca7 100644 --- a/docs/integrations/sources/faker.md +++ b/docs/integrations/sources/faker.md @@ -95,7 +95,8 @@ None! ## Changelog | Version | Date | Pull Request | Subject | -| :------ | :--------- | :-------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------- | +|:--------|:-----------|:----------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------| +| 3.0.2 | 2022-07-07 | [27807](https://github.com/airbytehq/airbyte/pull/28060) | Bump to test publication | | 3.0.1 | 2022-06-28 | [27807](https://github.com/airbytehq/airbyte/pull/27807) | Fix bug with purchase stream updated_at | | 3.0.0 | 2022-06-23 | [27684](https://github.com/airbytehq/airbyte/pull/27684) | Stream cursor is now `updated_at` & remove `records_per_sync` option | | 2.1.0 | 2022-05-08 | [25903](https://github.com/airbytehq/airbyte/pull/25903) | Add user.address (object) | From f2b48d0025fe598cebed0a665cc5b0773fc67e47 Mon Sep 17 00:00:00 2001 From: Mauricio A Date: Fri, 7 Jul 2023 16:12:23 -0400 Subject: [PATCH 02/63] Fixing vulnerabilities for source-salesforce - Premium support (#28021) * Attempt #2 for source-salesforce vulnerabilites fixes CVE-2022-40897 https://security-tracker.debian.org/tracker/CVE-2023-29383 https://security-tracker.debian.org/tracker/CVE-2023-31484 https://security-tracker.debian.org/tracker/CVE-2016-2781 * Changes requested during PR. --- .../connectors/source-salesforce/Dockerfile | 31 +++- .../source-salesforce/metadata.yaml | 2 +- docs/integrations/sources/salesforce.md | 147 +++++++++--------- 3 files changed, 101 insertions(+), 79 deletions(-) diff --git a/airbyte-integrations/connectors/source-salesforce/Dockerfile b/airbyte-integrations/connectors/source-salesforce/Dockerfile index 5d8832558591..84f30cbc8d4e 100644 --- a/airbyte-integrations/connectors/source-salesforce/Dockerfile +++ b/airbyte-integrations/connectors/source-salesforce/Dockerfile @@ -1,7 +1,17 @@ -FROM python:3.9-slim +# Using alpine to remove several vulnerabilities frm slim image +# https://security-tracker.debian.org/tracker/CVE-2023-29383 +# https://security-tracker.debian.org/tracker/CVE-2023-31484 +# https://security-tracker.debian.org/tracker/CVE-2016-2781 +FROM python:3.9-alpine3.18 + + +RUN apk add --update --no-cache \ + build-base \ + openssl-dev \ + libffi-dev \ + zlib-dev \ + bzip2-dev -# Bash is installed for more convenient debugging. -RUN apt-get update && apt-get install -y bash && rm -rf /var/lib/apt/lists/* ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" @@ -9,9 +19,20 @@ WORKDIR /airbyte/integration_code COPY source_salesforce ./source_salesforce COPY setup.py ./ COPY main.py ./ -RUN pip install . + +# Fixing https://nvd.nist.gov/vuln/detail/CVE-2022-40897 +# calling this twice as one upgrades the system pip /usr/local/bin/pip the +# seconf time upgrades the under for the venv /opt/.venv/bin/pip +RUN pip install --upgrade pip setuptools wheel && \ + pip install . +RUN pip install --upgrade pip setuptools + +# add default timezone settings +ENV TZ UTC +RUN cp /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=2.1.0 +LABEL io.airbyte.version=2.1.1 LABEL io.airbyte.name=airbyte/source-salesforce diff --git a/airbyte-integrations/connectors/source-salesforce/metadata.yaml b/airbyte-integrations/connectors/source-salesforce/metadata.yaml index 4506d730a23d..0dbb0e59ec81 100644 --- a/airbyte-integrations/connectors/source-salesforce/metadata.yaml +++ b/airbyte-integrations/connectors/source-salesforce/metadata.yaml @@ -5,7 +5,7 @@ data: connectorSubtype: api connectorType: source definitionId: b117307c-14b6-41aa-9422-947e34922962 - dockerImageTag: 2.1.0 + dockerImageTag: 2.1.1 dockerRepository: airbyte/source-salesforce githubIssueLabel: source-salesforce icon: salesforce.svg diff --git a/docs/integrations/sources/salesforce.md b/docs/integrations/sources/salesforce.md index e853c3a61aa3..c960f149f59a 100644 --- a/docs/integrations/sources/salesforce.md +++ b/docs/integrations/sources/salesforce.md @@ -129,76 +129,77 @@ Now that you have set up the Salesforce source connector, check out the followin ## Changelog -| Version | Date | Pull Request | Subject | -| :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------- | -| 2.1.0 | 2023-06-26 | [27726](https://github.com/airbytehq/airbyte/pull/27726) | License Update: Elv2 | -| 2.0.14 | 2023-05-04 | [25794](https://github.com/airbytehq/airbyte/pull/25794) | Avoid pandas inferring wrong data types by forcing all data type as object | -| 2.0.13 | 2023-04-30 | [25700](https://github.com/airbytehq/airbyte/pull/25700) | Remove pagination and query limits | -| 2.0.12 | 2023-04-25 | [25507](https://github.com/airbytehq/airbyte/pull/25507) | Update API version to 57 | -| 2.0.11 | 2023-04-20 | [25352](https://github.com/airbytehq/airbyte/pull/25352) | Update API version to 53 | -| 2.0.10 | 2023-04-05 | [24888](https://github.com/airbytehq/airbyte/pull/24888) | Add more frequent checkpointing | -| 2.0.9 | 2023-03-29 | [24660](https://github.com/airbytehq/airbyte/pull/24660) | Set default start_date. Sync for last two years if start date is not present in config | -| 2.0.8 | 2023-03-30 | [24690](https://github.com/airbytehq/airbyte/pull/24690) | Handle rate limit for bulk operations | -| 2.0.7 | 2023-03-14 | [24071](https://github.com/airbytehq/airbyte/pull/24071) | Remove regex pattern for start_date, use format validation instead | -| 2.0.6 | 2023-03-03 | [22891](https://github.com/airbytehq/airbyte/pull/22891) | Specified date formatting in specification | -| 2.0.5 | 2023-03-01 | [23610](https://github.com/airbytehq/airbyte/pull/23610) | Handle different Salesforce page size for different queries | -| 2.0.4 | 2023-02-24 | [22636](https://github.com/airbytehq/airbyte/pull/22636) | Turn on default HttpAvailabilityStrategy for all streams that are not of class BulkSalesforceStream | -| 2.0.3 | 2023-02-17 | [23190](https://github.com/airbytehq/airbyte/pull/23190) | In case properties are chunked, fetch primary key in every chunk | -| 2.0.2 | 2023-02-13 | [22896](https://github.com/airbytehq/airbyte/pull/22896) | Count the URL length based on encoded params | -| 2.0.1 | 2023-02-08 | [22597](https://github.com/airbytehq/airbyte/pull/22597) | Make multiple requests if a REST stream has too many properties | -| 2.0.0 | 2023-02-02 | [22322](https://github.com/airbytehq/airbyte/pull/22322) | Remove `ActivityMetricRollup` stream | -| 1.0.30 | 2023-01-27 | [22016](https://github.com/airbytehq/airbyte/pull/22016) | Set `AvailabilityStrategy` for streams explicitly to `None` | -| 1.0.29 | 2023-01-05 | [20886](https://github.com/airbytehq/airbyte/pull/20886) | Remove `ActivityMetric` stream | -| 1.0.28 | 2022-12-29 | [20927](https://github.com/airbytehq/airbyte/pull/20927) | Fix tests; add expected records | -| 1.0.27 | 2022-11-29 | [19869](https://github.com/airbytehq/airbyte/pull/19869) | Remove `AccountHistory` from unsupported BULK streams | -| 1.0.26 | 2022-11-15 | [19286](https://github.com/airbytehq/airbyte/pull/19286) | Bugfix: fallback to REST API if entity is not supported by BULK API | -| 1.0.25 | 2022-11-13 | [19294](https://github.com/airbytehq/airbyte/pull/19294) | Use the correct encoding for non UTF-8 objects and data | -| 1.0.24 | 2022-11-01 | [18799](https://github.com/airbytehq/airbyte/pull/18799) | Update list of unsupported Bulk API objects | -| 1.0.23 | 2022-11-01 | [18753](https://github.com/airbytehq/airbyte/pull/18753) | Add error_display_message for ConnectionError | -| 1.0.22 | 2022-10-12 | [17615](https://github.com/airbytehq/airbyte/pull/17615) | Make paging work, if `cursor_field` is not changed inside one page | -| 1.0.21 | 2022-10-10 | [17778](https://github.com/airbytehq/airbyte/pull/17778) | Add `EventWhoRelation` to the list of unsupported Bulk API objects. | -| 1.0.20 | 2022-09-30 | [17453](https://github.com/airbytehq/airbyte/pull/17453) | Check objects that are not supported by the Bulk API (v52.0) | -| 1.0.19 | 2022-09-29 | [17314](https://github.com/airbytehq/airbyte/pull/17314) | Fixed bug with decoding response | -| 1.0.18 | 2022-09-28 | [17304](https://github.com/airbytehq/airbyte/pull/17304) | Migrate to per-stream states. | -| 1.0.17 | 2022-09-23 | [17094](https://github.com/airbytehq/airbyte/pull/17094) | Tune connection check: fetch a list of available streams | -| 1.0.16 | 2022-09-21 | [17001](https://github.com/airbytehq/airbyte/pull/17001) | Improve writing file of decode | -| 1.0.15 | 2022-08-30 | [16086](https://github.com/airbytehq/airbyte/pull/16086) | Improve API type detection | -| 1.0.14 | 2022-08-29 | [16119](https://github.com/airbytehq/airbyte/pull/16119) | Exclude `KnowledgeArticleVersion` from using bulk API | -| 1.0.13 | 2022-08-23 | [15901](https://github.com/airbytehq/airbyte/pull/15901) | Exclude `KnowledgeArticle` from using bulk API | -| 1.0.12 | 2022-08-09 | [15444](https://github.com/airbytehq/airbyte/pull/15444) | Fixed bug when `Bulk Job` was timeout by the connector, but remained running on the server | -| 1.0.11 | 2022-07-07 | [13729](https://github.com/airbytehq/airbyte/pull/13729) | Improve configuration field descriptions | -| 1.0.10 | 2022-06-09 | [13658](https://github.com/airbytehq/airbyte/pull/13658) | Correct logic to sync stream larger than page size | -| 1.0.9 | 2022-05-06 | [12685](https://github.com/airbytehq/airbyte/pull/12685) | Update CDK to v0.1.56 to emit an `AirbyeTraceMessage` on uncaught exceptions | -| 1.0.8 | 2022-05-04 | [12576](https://github.com/airbytehq/airbyte/pull/12576) | Decode responses as utf-8 and fallback to ISO-8859-1 if needed | -| 1.0.7 | 2022-05-03 | [12552](https://github.com/airbytehq/airbyte/pull/12552) | Decode responses as ISO-8859-1 instead of utf-8 | -| 1.0.6 | 2022-04-27 | [12335](https://github.com/airbytehq/airbyte/pull/12335) | Adding fixtures to mock time.sleep for connectors that explicitly sleep | -| 1.0.5 | 2022-04-25 | [12304](https://github.com/airbytehq/airbyte/pull/12304) | Add `Describe` stream | -| 1.0.4 | 2022-04-20 | [12230](https://github.com/airbytehq/airbyte/pull/12230) | Update connector to use a `spec.yaml` | -| 1.0.3 | 2022-04-04 | [11692](https://github.com/airbytehq/airbyte/pull/11692) | Optimised memory usage for `BULK` API calls | -| 1.0.2 | 2022-03-01 | [10751](https://github.com/airbytehq/airbyte/pull/10751) | Fix broken link anchor in connector configuration | -| 1.0.1 | 2022-02-27 | [10679](https://github.com/airbytehq/airbyte/pull/10679) | Reorganize input parameter order on the UI | -| 1.0.0 | 2022-02-27 | [10516](https://github.com/airbytehq/airbyte/pull/10516) | Speed up schema discovery by using parallelism | -| 0.1.23 | 2022-02-10 | [10141](https://github.com/airbytehq/airbyte/pull/10141) | Processing of failed jobs | -| 0.1.22 | 2022-02-02 | [10012](https://github.com/airbytehq/airbyte/pull/10012) | Increase CSV field_size_limit | -| 0.1.21 | 2022-01-28 | [9499](https://github.com/airbytehq/airbyte/pull/9499) | If a sync reaches daily rate limit it ends the sync early with success status. Read more in `Performance considerations` section | -| 0.1.20 | 2022-01-26 | [9757](https://github.com/airbytehq/airbyte/pull/9757) | Parse CSV with "unix" dialect | -| 0.1.19 | 2022-01-25 | [8617](https://github.com/airbytehq/airbyte/pull/8617) | Update connector fields title/description | -| 0.1.18 | 2022-01-20 | [9478](https://github.com/airbytehq/airbyte/pull/9478) | Add available stream filtering by `queryable` flag | -| 0.1.17 | 2022-01-19 | [9302](https://github.com/airbytehq/airbyte/pull/9302) | Deprecate API Type parameter | -| 0.1.16 | 2022-01-18 | [9151](https://github.com/airbytehq/airbyte/pull/9151) | Fix pagination in REST API streams | -| 0.1.15 | 2022-01-11 | [9409](https://github.com/airbytehq/airbyte/pull/9409) | Correcting the presence of an extra `else` handler in the error handling | -| 0.1.14 | 2022-01-11 | [9386](https://github.com/airbytehq/airbyte/pull/9386) | Handling 400 error, while `sobject` doesn't support `query` or `queryAll` requests | -| 0.1.13 | 2022-01-11 | [8797](https://github.com/airbytehq/airbyte/pull/8797) | Switched from authSpecification to advanced_auth in specefication | -| 0.1.12 | 2021-12-23 | [8871](https://github.com/airbytehq/airbyte/pull/8871) | Fix `examples` for new field in specification | -| 0.1.11 | 2021-12-23 | [8871](https://github.com/airbytehq/airbyte/pull/8871) | Add the ability to filter streams by user | -| 0.1.10 | 2021-12-23 | [9005](https://github.com/airbytehq/airbyte/pull/9005) | Handling 400 error when a stream is not queryable | -| 0.1.9 | 2021-12-07 | [8405](https://github.com/airbytehq/airbyte/pull/8405) | Filter 'null' byte(s) in HTTP responses | -| 0.1.8 | 2021-11-30 | [8191](https://github.com/airbytehq/airbyte/pull/8191) | Make `start_date` optional and change its format to `YYYY-MM-DD` | -| 0.1.7 | 2021-11-24 | [8206](https://github.com/airbytehq/airbyte/pull/8206) | Handling 400 error when trying to create a job for sync using Bulk API. | -| 0.1.6 | 2021-11-16 | [8009](https://github.com/airbytehq/airbyte/pull/8009) | Fix retring of BULK jobs | -| 0.1.5 | 2021-11-15 | [7885](https://github.com/airbytehq/airbyte/pull/7885) | Add `Transform` for output records | -| 0.1.4 | 2021-11-09 | [7778](https://github.com/airbytehq/airbyte/pull/7778) | Fix types for `anyType` fields | -| 0.1.3 | 2021-11-06 | [7592](https://github.com/airbytehq/airbyte/pull/7592) | Fix getting `anyType` fields using BULK API | -| 0.1.2 | 2021-09-30 | [6438](https://github.com/airbytehq/airbyte/pull/6438) | Annotate Oauth2 flow initialization parameters in connector specification | -| 0.1.1 | 2021-09-21 | [6209](https://github.com/airbytehq/airbyte/pull/6209) | Fix bug with pagination for BULK API | -| 0.1.0 | 2021-09-08 | [5619](https://github.com/airbytehq/airbyte/pull/5619) | Salesforce Aitbyte-Native Connector | +| Version | Date | Pull Request | Subject | +|:--------|:-----------|:---------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------| +| 2.1.1 | 2023-07-06 | [28021](https://github.com/airbytehq/airbyte/pull/28021) | Several Vulnerabilities Fixes; switched to use alpine instead of slim, CVE-2022-40897, CVE-2023-29383, CVE-2023-31484, CVE-2016-2781 | +| 2.1.0 | 2023-06-26 | [27726](https://github.com/airbytehq/airbyte/pull/27726) | License Update: Elv2 | +| 2.0.14 | 2023-05-04 | [25794](https://github.com/airbytehq/airbyte/pull/25794) | Avoid pandas inferring wrong data types by forcing all data type as object | +| 2.0.13 | 2023-04-30 | [25700](https://github.com/airbytehq/airbyte/pull/25700) | Remove pagination and query limits | +| 2.0.12 | 2023-04-25 | [25507](https://github.com/airbytehq/airbyte/pull/25507) | Update API version to 57 | +| 2.0.11 | 2023-04-20 | [25352](https://github.com/airbytehq/airbyte/pull/25352) | Update API version to 53 | +| 2.0.10 | 2023-04-05 | [24888](https://github.com/airbytehq/airbyte/pull/24888) | Add more frequent checkpointing | +| 2.0.9 | 2023-03-29 | [24660](https://github.com/airbytehq/airbyte/pull/24660) | Set default start_date. Sync for last two years if start date is not present in config | +| 2.0.8 | 2023-03-30 | [24690](https://github.com/airbytehq/airbyte/pull/24690) | Handle rate limit for bulk operations | +| 2.0.7 | 2023-03-14 | [24071](https://github.com/airbytehq/airbyte/pull/24071) | Remove regex pattern for start_date, use format validation instead | +| 2.0.6 | 2023-03-03 | [22891](https://github.com/airbytehq/airbyte/pull/22891) | Specified date formatting in specification | +| 2.0.5 | 2023-03-01 | [23610](https://github.com/airbytehq/airbyte/pull/23610) | Handle different Salesforce page size for different queries | +| 2.0.4 | 2023-02-24 | [22636](https://github.com/airbytehq/airbyte/pull/22636) | Turn on default HttpAvailabilityStrategy for all streams that are not of class BulkSalesforceStream | +| 2.0.3 | 2023-02-17 | [23190](https://github.com/airbytehq/airbyte/pull/23190) | In case properties are chunked, fetch primary key in every chunk | +| 2.0.2 | 2023-02-13 | [22896](https://github.com/airbytehq/airbyte/pull/22896) | Count the URL length based on encoded params | +| 2.0.1 | 2023-02-08 | [22597](https://github.com/airbytehq/airbyte/pull/22597) | Make multiple requests if a REST stream has too many properties | +| 2.0.0 | 2023-02-02 | [22322](https://github.com/airbytehq/airbyte/pull/22322) | Remove `ActivityMetricRollup` stream | +| 1.0.30 | 2023-01-27 | [22016](https://github.com/airbytehq/airbyte/pull/22016) | Set `AvailabilityStrategy` for streams explicitly to `None` | +| 1.0.29 | 2023-01-05 | [20886](https://github.com/airbytehq/airbyte/pull/20886) | Remove `ActivityMetric` stream | +| 1.0.28 | 2022-12-29 | [20927](https://github.com/airbytehq/airbyte/pull/20927) | Fix tests; add expected records | +| 1.0.27 | 2022-11-29 | [19869](https://github.com/airbytehq/airbyte/pull/19869) | Remove `AccountHistory` from unsupported BULK streams | +| 1.0.26 | 2022-11-15 | [19286](https://github.com/airbytehq/airbyte/pull/19286) | Bugfix: fallback to REST API if entity is not supported by BULK API | +| 1.0.25 | 2022-11-13 | [19294](https://github.com/airbytehq/airbyte/pull/19294) | Use the correct encoding for non UTF-8 objects and data | +| 1.0.24 | 2022-11-01 | [18799](https://github.com/airbytehq/airbyte/pull/18799) | Update list of unsupported Bulk API objects | +| 1.0.23 | 2022-11-01 | [18753](https://github.com/airbytehq/airbyte/pull/18753) | Add error_display_message for ConnectionError | +| 1.0.22 | 2022-10-12 | [17615](https://github.com/airbytehq/airbyte/pull/17615) | Make paging work, if `cursor_field` is not changed inside one page | +| 1.0.21 | 2022-10-10 | [17778](https://github.com/airbytehq/airbyte/pull/17778) | Add `EventWhoRelation` to the list of unsupported Bulk API objects. | +| 1.0.20 | 2022-09-30 | [17453](https://github.com/airbytehq/airbyte/pull/17453) | Check objects that are not supported by the Bulk API (v52.0) | +| 1.0.19 | 2022-09-29 | [17314](https://github.com/airbytehq/airbyte/pull/17314) | Fixed bug with decoding response | +| 1.0.18 | 2022-09-28 | [17304](https://github.com/airbytehq/airbyte/pull/17304) | Migrate to per-stream states. | +| 1.0.17 | 2022-09-23 | [17094](https://github.com/airbytehq/airbyte/pull/17094) | Tune connection check: fetch a list of available streams | +| 1.0.16 | 2022-09-21 | [17001](https://github.com/airbytehq/airbyte/pull/17001) | Improve writing file of decode | +| 1.0.15 | 2022-08-30 | [16086](https://github.com/airbytehq/airbyte/pull/16086) | Improve API type detection | +| 1.0.14 | 2022-08-29 | [16119](https://github.com/airbytehq/airbyte/pull/16119) | Exclude `KnowledgeArticleVersion` from using bulk API | +| 1.0.13 | 2022-08-23 | [15901](https://github.com/airbytehq/airbyte/pull/15901) | Exclude `KnowledgeArticle` from using bulk API | +| 1.0.12 | 2022-08-09 | [15444](https://github.com/airbytehq/airbyte/pull/15444) | Fixed bug when `Bulk Job` was timeout by the connector, but remained running on the server | +| 1.0.11 | 2022-07-07 | [13729](https://github.com/airbytehq/airbyte/pull/13729) | Improve configuration field descriptions | +| 1.0.10 | 2022-06-09 | [13658](https://github.com/airbytehq/airbyte/pull/13658) | Correct logic to sync stream larger than page size | +| 1.0.9 | 2022-05-06 | [12685](https://github.com/airbytehq/airbyte/pull/12685) | Update CDK to v0.1.56 to emit an `AirbyeTraceMessage` on uncaught exceptions | +| 1.0.8 | 2022-05-04 | [12576](https://github.com/airbytehq/airbyte/pull/12576) | Decode responses as utf-8 and fallback to ISO-8859-1 if needed | +| 1.0.7 | 2022-05-03 | [12552](https://github.com/airbytehq/airbyte/pull/12552) | Decode responses as ISO-8859-1 instead of utf-8 | +| 1.0.6 | 2022-04-27 | [12335](https://github.com/airbytehq/airbyte/pull/12335) | Adding fixtures to mock time.sleep for connectors that explicitly sleep | +| 1.0.5 | 2022-04-25 | [12304](https://github.com/airbytehq/airbyte/pull/12304) | Add `Describe` stream | +| 1.0.4 | 2022-04-20 | [12230](https://github.com/airbytehq/airbyte/pull/12230) | Update connector to use a `spec.yaml` | +| 1.0.3 | 2022-04-04 | [11692](https://github.com/airbytehq/airbyte/pull/11692) | Optimised memory usage for `BULK` API calls | +| 1.0.2 | 2022-03-01 | [10751](https://github.com/airbytehq/airbyte/pull/10751) | Fix broken link anchor in connector configuration | +| 1.0.1 | 2022-02-27 | [10679](https://github.com/airbytehq/airbyte/pull/10679) | Reorganize input parameter order on the UI | +| 1.0.0 | 2022-02-27 | [10516](https://github.com/airbytehq/airbyte/pull/10516) | Speed up schema discovery by using parallelism | +| 0.1.23 | 2022-02-10 | [10141](https://github.com/airbytehq/airbyte/pull/10141) | Processing of failed jobs | +| 0.1.22 | 2022-02-02 | [10012](https://github.com/airbytehq/airbyte/pull/10012) | Increase CSV field_size_limit | +| 0.1.21 | 2022-01-28 | [9499](https://github.com/airbytehq/airbyte/pull/9499) | If a sync reaches daily rate limit it ends the sync early with success status. Read more in `Performance considerations` section | +| 0.1.20 | 2022-01-26 | [9757](https://github.com/airbytehq/airbyte/pull/9757) | Parse CSV with "unix" dialect | +| 0.1.19 | 2022-01-25 | [8617](https://github.com/airbytehq/airbyte/pull/8617) | Update connector fields title/description | +| 0.1.18 | 2022-01-20 | [9478](https://github.com/airbytehq/airbyte/pull/9478) | Add available stream filtering by `queryable` flag | +| 0.1.17 | 2022-01-19 | [9302](https://github.com/airbytehq/airbyte/pull/9302) | Deprecate API Type parameter | +| 0.1.16 | 2022-01-18 | [9151](https://github.com/airbytehq/airbyte/pull/9151) | Fix pagination in REST API streams | +| 0.1.15 | 2022-01-11 | [9409](https://github.com/airbytehq/airbyte/pull/9409) | Correcting the presence of an extra `else` handler in the error handling | +| 0.1.14 | 2022-01-11 | [9386](https://github.com/airbytehq/airbyte/pull/9386) | Handling 400 error, while `sobject` doesn't support `query` or `queryAll` requests | +| 0.1.13 | 2022-01-11 | [8797](https://github.com/airbytehq/airbyte/pull/8797) | Switched from authSpecification to advanced_auth in specefication | +| 0.1.12 | 2021-12-23 | [8871](https://github.com/airbytehq/airbyte/pull/8871) | Fix `examples` for new field in specification | +| 0.1.11 | 2021-12-23 | [8871](https://github.com/airbytehq/airbyte/pull/8871) | Add the ability to filter streams by user | +| 0.1.10 | 2021-12-23 | [9005](https://github.com/airbytehq/airbyte/pull/9005) | Handling 400 error when a stream is not queryable | +| 0.1.9 | 2021-12-07 | [8405](https://github.com/airbytehq/airbyte/pull/8405) | Filter 'null' byte(s) in HTTP responses | +| 0.1.8 | 2021-11-30 | [8191](https://github.com/airbytehq/airbyte/pull/8191) | Make `start_date` optional and change its format to `YYYY-MM-DD` | +| 0.1.7 | 2021-11-24 | [8206](https://github.com/airbytehq/airbyte/pull/8206) | Handling 400 error when trying to create a job for sync using Bulk API. | +| 0.1.6 | 2021-11-16 | [8009](https://github.com/airbytehq/airbyte/pull/8009) | Fix retring of BULK jobs | +| 0.1.5 | 2021-11-15 | [7885](https://github.com/airbytehq/airbyte/pull/7885) | Add `Transform` for output records | +| 0.1.4 | 2021-11-09 | [7778](https://github.com/airbytehq/airbyte/pull/7778) | Fix types for `anyType` fields | +| 0.1.3 | 2021-11-06 | [7592](https://github.com/airbytehq/airbyte/pull/7592) | Fix getting `anyType` fields using BULK API | +| 0.1.2 | 2021-09-30 | [6438](https://github.com/airbytehq/airbyte/pull/6438) | Annotate Oauth2 flow initialization parameters in connector specification | +| 0.1.1 | 2021-09-21 | [6209](https://github.com/airbytehq/airbyte/pull/6209) | Fix bug with pagination for BULK API | +| 0.1.0 | 2021-09-08 | [5619](https://github.com/airbytehq/airbyte/pull/5619) | Salesforce Aitbyte-Native Connector | From 38709f997e081b953b932c7ada00127cf7d59d8f Mon Sep 17 00:00:00 2001 From: girarda Date: Sun, 9 Jul 2023 19:38:07 +0000 Subject: [PATCH 03/63] Bump Airbyte version from 0.50.6 to 0.50.7 --- .bumpversion.cfg | 2 +- docs/operator-guides/upgrading-airbyte.md | 2 +- gradle.properties | 2 +- run-ab-platform.sh | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 4dafc1916023..e478d0c3f50b 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.50.6 +current_version = 0.50.7 commit = False tag = False parse = (?P\d+)\.(?P\d+)\.(?P\d+)(\-[a-z]+)? diff --git a/docs/operator-guides/upgrading-airbyte.md b/docs/operator-guides/upgrading-airbyte.md index a682aebfb086..7a79adf7ef16 100644 --- a/docs/operator-guides/upgrading-airbyte.md +++ b/docs/operator-guides/upgrading-airbyte.md @@ -117,7 +117,7 @@ If you are upgrading from (i.e. your current version of Airbyte is) Airbyte vers Here's an example of what it might look like with the values filled in. It assumes that the downloaded `airbyte_archive.tar.gz` is in `/tmp`. ```bash - docker run --rm -v /tmp:/config airbyte/migration:0.50.6 --\ + docker run --rm -v /tmp:/config airbyte/migration:0.50.7 --\ --input /config/airbyte_archive.tar.gz\ --output /config/airbyte_archive_migrated.tar.gz ``` diff --git a/gradle.properties b/gradle.properties index 5eb9b5964c8c..6612c6f5413d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -VERSION=0.50.6 +VERSION=0.50.7 # NOTE: some of these values are overwritten in CI! # NOTE: if you want to override this for your local machine, set overrides in ~/.gradle/gradle.properties diff --git a/run-ab-platform.sh b/run-ab-platform.sh index 9e48407be229..17d3f74f5778 100755 --- a/run-ab-platform.sh +++ b/run-ab-platform.sh @@ -1,6 +1,6 @@ #!/bin/bash -VERSION=0.50.6 +VERSION=0.50.7 # Run away from anything even a little scary set -o nounset # -u exit if a variable is not set set -o errexit # -f exit for any command failure" From c7916d798db0efc1e146057b8bebc02036c4caa0 Mon Sep 17 00:00:00 2001 From: Jimmy Ma Date: Sun, 9 Jul 2023 19:20:38 -0700 Subject: [PATCH 04/63] Add Orchestrator Diagram to the docs (#16675) --- .../.gitbook/assets/orchestrator-lifecycle.png | Bin 0 -> 240190 bytes docs/understanding-airbyte/jobs.md | 4 ++++ 2 files changed, 4 insertions(+) create mode 100644 docs/.gitbook/assets/orchestrator-lifecycle.png diff --git a/docs/.gitbook/assets/orchestrator-lifecycle.png b/docs/.gitbook/assets/orchestrator-lifecycle.png new file mode 100644 index 0000000000000000000000000000000000000000..7db52fea872a552626fa5c4bdc99255360419531 GIT binary patch literal 240190 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 Date: Mon, 10 Jul 2023 13:19:53 +0200 Subject: [PATCH 05/63] Source Google Ads: Add metrics & segment to `Campaigns` (#28042) * Source Google Ads: extend campaigns schema: add metrics & segment * Source Google Ads: bump version * Source Google Ads: update docs * Source Google Ads: update expected_records.jsonl * Source Google Ads: update schema --- .../connectors/source-google-ads/Dockerfile | 2 +- .../integration_tests/expected_records.jsonl | 10 +- .../source-google-ads/metadata.yaml | 2 +- .../source_google_ads/schemas/campaigns.json | 45 ++++++ docs/integrations/sources/google-ads.md | 147 +++++++++--------- 5 files changed, 126 insertions(+), 80 deletions(-) diff --git a/airbyte-integrations/connectors/source-google-ads/Dockerfile b/airbyte-integrations/connectors/source-google-ads/Dockerfile index be06953871c5..8bf43542f46a 100644 --- a/airbyte-integrations/connectors/source-google-ads/Dockerfile +++ b/airbyte-integrations/connectors/source-google-ads/Dockerfile @@ -13,5 +13,5 @@ COPY main.py ./ ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=0.4.3 +LABEL io.airbyte.version=0.5.0 LABEL io.airbyte.name=airbyte/source-google-ads diff --git a/airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl index b53454ae96ad..50deed712fe3 100644 --- a/airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl @@ -74,11 +74,11 @@ {"stream":"ad_group_ads","data":{"ad_group_ad.ad.added_by_google_ads":false,"ad_group_ad.ad.app_ad.descriptions":[],"ad_group_ad.ad.app_ad.headlines":[],"ad_group_ad.ad.app_ad.html5_media_bundles":[],"ad_group_ad.ad.app_ad.images":[],"ad_group_ad.ad.app_ad.mandatory_ad_text":"","ad_group_ad.ad.app_ad.youtube_videos":[],"ad_group_ad.ad.app_engagement_ad.descriptions":[],"ad_group_ad.ad.app_engagement_ad.headlines":[],"ad_group_ad.ad.app_engagement_ad.images":[],"ad_group_ad.ad.app_engagement_ad.videos":[],"ad_group_ad.ad.call_ad.business_name":"","ad_group_ad.ad.call_ad.call_tracked":false,"ad_group_ad.ad.call_ad.conversion_action":"","ad_group_ad.ad.call_ad.conversion_reporting_state":"UNSPECIFIED","ad_group_ad.ad.call_ad.country_code":"","ad_group_ad.ad.call_ad.description1":"","ad_group_ad.ad.call_ad.description2":"","ad_group_ad.ad.call_ad.disable_call_conversion":false,"ad_group_ad.ad.call_ad.headline1":"","ad_group_ad.ad.call_ad.headline2":"","ad_group_ad.ad.call_ad.path1":"","ad_group_ad.ad.call_ad.path2":"","ad_group_ad.ad.call_ad.phone_number":"","ad_group_ad.ad.call_ad.phone_number_verification_url":"","ad_group_ad.ad.device_preference":"UNSPECIFIED","ad_group_ad.ad.display_upload_ad.display_upload_product_type":"UNSPECIFIED","ad_group_ad.ad.display_upload_ad.media_bundle":"","ad_group_ad.ad.display_url":"","ad_group_ad.ad.expanded_dynamic_search_ad.description":"","ad_group_ad.ad.expanded_dynamic_search_ad.description2":"","ad_group_ad.ad.expanded_text_ad.description":"","ad_group_ad.ad.expanded_text_ad.description2":"","ad_group_ad.ad.expanded_text_ad.headline_part1":"","ad_group_ad.ad.expanded_text_ad.headline_part2":"","ad_group_ad.ad.expanded_text_ad.headline_part3":"","ad_group_ad.ad.expanded_text_ad.path1":"","ad_group_ad.ad.expanded_text_ad.path2":"","ad_group_ad.ad.final_app_urls":[],"ad_group_ad.ad.final_mobile_urls":[],"ad_group_ad.ad.final_url_suffix":"","ad_group_ad.ad.final_urls":["https://airbyte.com"],"ad_group_ad.ad.hotel_ad":"","ad_group_ad.ad.id":592078676857,"ad_group_ad.ad.image_ad.image_url":"","ad_group_ad.ad.image_ad.mime_type":"UNSPECIFIED","ad_group_ad.ad.image_ad.name":"","ad_group_ad.ad.image_ad.pixel_height":0,"ad_group_ad.ad.image_ad.pixel_width":0,"ad_group_ad.ad.image_ad.preview_image_url":"","ad_group_ad.ad.image_ad.preview_pixel_height":0,"ad_group_ad.ad.image_ad.preview_pixel_width":0,"ad_group_ad.ad.legacy_app_install_ad":"","ad_group_ad.ad.legacy_responsive_display_ad.accent_color":"","ad_group_ad.ad.legacy_responsive_display_ad.allow_flexible_color":false,"ad_group_ad.ad.legacy_responsive_display_ad.business_name":"","ad_group_ad.ad.legacy_responsive_display_ad.call_to_action_text":"","ad_group_ad.ad.legacy_responsive_display_ad.description":"","ad_group_ad.ad.legacy_responsive_display_ad.format_setting":"UNSPECIFIED","ad_group_ad.ad.legacy_responsive_display_ad.logo_image":"","ad_group_ad.ad.legacy_responsive_display_ad.long_headline":"","ad_group_ad.ad.legacy_responsive_display_ad.main_color":"","ad_group_ad.ad.legacy_responsive_display_ad.marketing_image":"","ad_group_ad.ad.legacy_responsive_display_ad.price_prefix":"","ad_group_ad.ad.legacy_responsive_display_ad.promo_text":"","ad_group_ad.ad.legacy_responsive_display_ad.short_headline":"","ad_group_ad.ad.legacy_responsive_display_ad.square_logo_image":"","ad_group_ad.ad.legacy_responsive_display_ad.square_marketing_image":"","ad_group_ad.ad.local_ad.call_to_actions":[],"ad_group_ad.ad.local_ad.descriptions":[],"ad_group_ad.ad.local_ad.headlines":[],"ad_group_ad.ad.local_ad.logo_images":[],"ad_group_ad.ad.local_ad.marketing_images":[],"ad_group_ad.ad.local_ad.path1":"","ad_group_ad.ad.local_ad.path2":"","ad_group_ad.ad.local_ad.videos":[],"ad_group_ad.ad.name":"","ad_group_ad.ad.resource_name":"customers/4651612872/ads/592078676857","ad_group_ad.ad.responsive_display_ad.accent_color":"","ad_group_ad.ad.responsive_display_ad.allow_flexible_color":false,"ad_group_ad.ad.responsive_display_ad.business_name":"","ad_group_ad.ad.responsive_display_ad.call_to_action_text":"","ad_group_ad.ad.responsive_display_ad.control_spec.enable_asset_enhancements":false,"ad_group_ad.ad.responsive_display_ad.control_spec.enable_autogen_video":false,"ad_group_ad.ad.responsive_display_ad.descriptions":[],"ad_group_ad.ad.responsive_display_ad.format_setting":"UNSPECIFIED","ad_group_ad.ad.responsive_display_ad.headlines":[],"ad_group_ad.ad.responsive_display_ad.logo_images":[],"ad_group_ad.ad.responsive_display_ad.long_headline":"","ad_group_ad.ad.responsive_display_ad.main_color":"","ad_group_ad.ad.responsive_display_ad.marketing_images":[],"ad_group_ad.ad.responsive_display_ad.price_prefix":"","ad_group_ad.ad.responsive_display_ad.promo_text":"","ad_group_ad.ad.responsive_display_ad.square_logo_images":[],"ad_group_ad.ad.responsive_display_ad.square_marketing_images":[],"ad_group_ad.ad.responsive_display_ad.youtube_videos":[],"ad_group_ad.ad.responsive_search_ad.descriptions":["text: \"Behind The Scenes: Testing The Airbyte Maintainer Program\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n","text: \"Airbyte | Open-Source Data Integration Platform | ELT tool\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n","text: \"Upgrading Our Discourse And Slack To Support Our Community Growth\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n"],"ad_group_ad.ad.responsive_search_ad.headlines":["text: \"Airbyte\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n","text: \"ELT tool\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n","text: \"Open-source Data Integration\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n"],"ad_group_ad.ad.responsive_search_ad.path1":"","ad_group_ad.ad.responsive_search_ad.path2":"","ad_group_ad.ad.shopping_comparison_listing_ad.headline":"","ad_group_ad.ad.shopping_product_ad":"","ad_group_ad.ad.shopping_smart_ad":"","ad_group_ad.ad.smart_campaign_ad.descriptions":[],"ad_group_ad.ad.smart_campaign_ad.headlines":[],"ad_group_ad.ad.system_managed_resource_source":"UNSPECIFIED","ad_group_ad.ad.text_ad.description1":"","ad_group_ad.ad.text_ad.description2":"","ad_group_ad.ad.text_ad.headline":"","ad_group_ad.ad.tracking_url_template":"","ad_group_ad.ad.type":"RESPONSIVE_SEARCH_AD","ad_group_ad.ad.url_collections":[],"ad_group_ad.ad.url_custom_parameters":[],"ad_group_ad.ad.video_ad.in_feed.description1":"","ad_group_ad.ad.video_ad.in_feed.description2":"","ad_group_ad.ad.video_ad.in_feed.headline":"","ad_group_ad.ad.video_ad.in_stream.action_button_label":"","ad_group_ad.ad.video_ad.in_stream.action_headline":"","ad_group_ad.ad.video_ad.out_stream.description":"","ad_group_ad.ad.video_ad.out_stream.headline":"","ad_group_ad.ad.video_responsive_ad.call_to_actions":[],"ad_group_ad.ad.video_responsive_ad.companion_banners":[],"ad_group_ad.ad.video_responsive_ad.descriptions":[],"ad_group_ad.ad.video_responsive_ad.headlines":[],"ad_group_ad.ad.video_responsive_ad.long_headlines":[],"ad_group_ad.ad.video_responsive_ad.videos":[],"ad_group_ad.ad_group":"customers/4651612872/adGroups/137051662444","ad_group_ad.ad_strength":"POOR","ad_group_ad.labels":[],"ad_group_ad.policy_summary.approval_status":"APPROVED","ad_group_ad.policy_summary.policy_topic_entries":[],"ad_group_ad.policy_summary.review_status":"REVIEWED","ad_group_ad.resource_name":"customers/4651612872/adGroupAds/137051662444~592078676857","ad_group_ad.status":"REMOVED","segments.date":"2022-04-09"},"emitted_at":1679577402012} {"stream":"ad_group_ads","data":{"ad_group_ad.ad.added_by_google_ads":false,"ad_group_ad.ad.app_ad.descriptions":[],"ad_group_ad.ad.app_ad.headlines":[],"ad_group_ad.ad.app_ad.html5_media_bundles":[],"ad_group_ad.ad.app_ad.images":[],"ad_group_ad.ad.app_ad.mandatory_ad_text":"","ad_group_ad.ad.app_ad.youtube_videos":[],"ad_group_ad.ad.app_engagement_ad.descriptions":[],"ad_group_ad.ad.app_engagement_ad.headlines":[],"ad_group_ad.ad.app_engagement_ad.images":[],"ad_group_ad.ad.app_engagement_ad.videos":[],"ad_group_ad.ad.call_ad.business_name":"","ad_group_ad.ad.call_ad.call_tracked":false,"ad_group_ad.ad.call_ad.conversion_action":"","ad_group_ad.ad.call_ad.conversion_reporting_state":"UNSPECIFIED","ad_group_ad.ad.call_ad.country_code":"","ad_group_ad.ad.call_ad.description1":"","ad_group_ad.ad.call_ad.description2":"","ad_group_ad.ad.call_ad.disable_call_conversion":false,"ad_group_ad.ad.call_ad.headline1":"","ad_group_ad.ad.call_ad.headline2":"","ad_group_ad.ad.call_ad.path1":"","ad_group_ad.ad.call_ad.path2":"","ad_group_ad.ad.call_ad.phone_number":"","ad_group_ad.ad.call_ad.phone_number_verification_url":"","ad_group_ad.ad.device_preference":"UNSPECIFIED","ad_group_ad.ad.display_upload_ad.display_upload_product_type":"UNSPECIFIED","ad_group_ad.ad.display_upload_ad.media_bundle":"","ad_group_ad.ad.display_url":"","ad_group_ad.ad.expanded_dynamic_search_ad.description":"","ad_group_ad.ad.expanded_dynamic_search_ad.description2":"","ad_group_ad.ad.expanded_text_ad.description":"","ad_group_ad.ad.expanded_text_ad.description2":"","ad_group_ad.ad.expanded_text_ad.headline_part1":"","ad_group_ad.ad.expanded_text_ad.headline_part2":"","ad_group_ad.ad.expanded_text_ad.headline_part3":"","ad_group_ad.ad.expanded_text_ad.path1":"","ad_group_ad.ad.expanded_text_ad.path2":"","ad_group_ad.ad.final_app_urls":[],"ad_group_ad.ad.final_mobile_urls":[],"ad_group_ad.ad.final_url_suffix":"","ad_group_ad.ad.final_urls":["https://airbyte.com"],"ad_group_ad.ad.hotel_ad":"","ad_group_ad.ad.id":592078631218,"ad_group_ad.ad.image_ad.image_url":"","ad_group_ad.ad.image_ad.mime_type":"UNSPECIFIED","ad_group_ad.ad.image_ad.name":"","ad_group_ad.ad.image_ad.pixel_height":0,"ad_group_ad.ad.image_ad.pixel_width":0,"ad_group_ad.ad.image_ad.preview_image_url":"","ad_group_ad.ad.image_ad.preview_pixel_height":0,"ad_group_ad.ad.image_ad.preview_pixel_width":0,"ad_group_ad.ad.legacy_app_install_ad":"","ad_group_ad.ad.legacy_responsive_display_ad.accent_color":"","ad_group_ad.ad.legacy_responsive_display_ad.allow_flexible_color":false,"ad_group_ad.ad.legacy_responsive_display_ad.business_name":"","ad_group_ad.ad.legacy_responsive_display_ad.call_to_action_text":"","ad_group_ad.ad.legacy_responsive_display_ad.description":"","ad_group_ad.ad.legacy_responsive_display_ad.format_setting":"UNSPECIFIED","ad_group_ad.ad.legacy_responsive_display_ad.logo_image":"","ad_group_ad.ad.legacy_responsive_display_ad.long_headline":"","ad_group_ad.ad.legacy_responsive_display_ad.main_color":"","ad_group_ad.ad.legacy_responsive_display_ad.marketing_image":"","ad_group_ad.ad.legacy_responsive_display_ad.price_prefix":"","ad_group_ad.ad.legacy_responsive_display_ad.promo_text":"","ad_group_ad.ad.legacy_responsive_display_ad.short_headline":"","ad_group_ad.ad.legacy_responsive_display_ad.square_logo_image":"","ad_group_ad.ad.legacy_responsive_display_ad.square_marketing_image":"","ad_group_ad.ad.local_ad.call_to_actions":[],"ad_group_ad.ad.local_ad.descriptions":[],"ad_group_ad.ad.local_ad.headlines":[],"ad_group_ad.ad.local_ad.logo_images":[],"ad_group_ad.ad.local_ad.marketing_images":[],"ad_group_ad.ad.local_ad.path1":"","ad_group_ad.ad.local_ad.path2":"","ad_group_ad.ad.local_ad.videos":[],"ad_group_ad.ad.name":"","ad_group_ad.ad.resource_name":"customers/4651612872/ads/592078631218","ad_group_ad.ad.responsive_display_ad.accent_color":"","ad_group_ad.ad.responsive_display_ad.allow_flexible_color":false,"ad_group_ad.ad.responsive_display_ad.business_name":"","ad_group_ad.ad.responsive_display_ad.call_to_action_text":"","ad_group_ad.ad.responsive_display_ad.control_spec.enable_asset_enhancements":false,"ad_group_ad.ad.responsive_display_ad.control_spec.enable_autogen_video":false,"ad_group_ad.ad.responsive_display_ad.descriptions":[],"ad_group_ad.ad.responsive_display_ad.format_setting":"UNSPECIFIED","ad_group_ad.ad.responsive_display_ad.headlines":[],"ad_group_ad.ad.responsive_display_ad.logo_images":[],"ad_group_ad.ad.responsive_display_ad.long_headline":"","ad_group_ad.ad.responsive_display_ad.main_color":"","ad_group_ad.ad.responsive_display_ad.marketing_images":[],"ad_group_ad.ad.responsive_display_ad.price_prefix":"","ad_group_ad.ad.responsive_display_ad.promo_text":"","ad_group_ad.ad.responsive_display_ad.square_logo_images":[],"ad_group_ad.ad.responsive_display_ad.square_marketing_images":[],"ad_group_ad.ad.responsive_display_ad.youtube_videos":[],"ad_group_ad.ad.responsive_search_ad.descriptions":["text: \"Behind The Scenes: Testing The Airbyte Maintainer Program\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n","text: \"Airbyte | Open-Source Data Integration Platform | ELT tool\"\nasset_performance_label: PENDING\npolicy_summary_info {\n policy_topic_entries {\n topic: \"TRADEMARKS_IN_AD_TEXT\"\n type_: LIMITED\n evidences {\n text_list {\n texts: \"airbyte\"\n }\n }\n constraints {\n reseller_constraint {\n }\n }\n }\n review_status: REVIEWED\n approval_status: APPROVED_LIMITED\n}\n","text: \"Upgrading Our Discourse And Slack To Support Our Community Growth\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n","text: \"Consolidate your data in your data warehouses, lakes and databases\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n"],"ad_group_ad.ad.responsive_search_ad.headlines":["text: \"Airbyte\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n","text: \"ELT tool\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n","text: \"Open-source Data Integration\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n"],"ad_group_ad.ad.responsive_search_ad.path1":"","ad_group_ad.ad.responsive_search_ad.path2":"","ad_group_ad.ad.shopping_comparison_listing_ad.headline":"","ad_group_ad.ad.shopping_product_ad":"","ad_group_ad.ad.shopping_smart_ad":"","ad_group_ad.ad.smart_campaign_ad.descriptions":[],"ad_group_ad.ad.smart_campaign_ad.headlines":[],"ad_group_ad.ad.system_managed_resource_source":"UNSPECIFIED","ad_group_ad.ad.text_ad.description1":"","ad_group_ad.ad.text_ad.description2":"","ad_group_ad.ad.text_ad.headline":"","ad_group_ad.ad.tracking_url_template":"","ad_group_ad.ad.type":"RESPONSIVE_SEARCH_AD","ad_group_ad.ad.url_collections":[],"ad_group_ad.ad.url_custom_parameters":[],"ad_group_ad.ad.video_ad.in_feed.description1":"","ad_group_ad.ad.video_ad.in_feed.description2":"","ad_group_ad.ad.video_ad.in_feed.headline":"","ad_group_ad.ad.video_ad.in_stream.action_button_label":"","ad_group_ad.ad.video_ad.in_stream.action_headline":"","ad_group_ad.ad.video_ad.out_stream.description":"","ad_group_ad.ad.video_ad.out_stream.headline":"","ad_group_ad.ad.video_responsive_ad.call_to_actions":[],"ad_group_ad.ad.video_responsive_ad.companion_banners":[],"ad_group_ad.ad.video_responsive_ad.descriptions":[],"ad_group_ad.ad.video_responsive_ad.headlines":[],"ad_group_ad.ad.video_responsive_ad.long_headlines":[],"ad_group_ad.ad.video_responsive_ad.videos":[],"ad_group_ad.ad_group":"customers/4651612872/adGroups/137020701042","ad_group_ad.ad_strength":"POOR","ad_group_ad.labels":[],"ad_group_ad.policy_summary.approval_status":"APPROVED_LIMITED","ad_group_ad.policy_summary.policy_topic_entries":["topic: \"TRADEMARKS_IN_AD_TEXT\"\ntype_: LIMITED\nevidences {\n text_list {\n texts: \"airbyte\"\n }\n}\nconstraints {\n reseller_constraint {\n }\n}\n"],"ad_group_ad.policy_summary.review_status":"REVIEWED","ad_group_ad.resource_name":"customers/4651612872/adGroupAds/137020701042~592078631218","ad_group_ad.status":"ENABLED","segments.date":"2022-04-10"},"emitted_at":1679577402018} {"stream":"ad_group_ads","data":{"ad_group_ad.ad.added_by_google_ads":false,"ad_group_ad.ad.app_ad.descriptions":[],"ad_group_ad.ad.app_ad.headlines":[],"ad_group_ad.ad.app_ad.html5_media_bundles":[],"ad_group_ad.ad.app_ad.images":[],"ad_group_ad.ad.app_ad.mandatory_ad_text":"","ad_group_ad.ad.app_ad.youtube_videos":[],"ad_group_ad.ad.app_engagement_ad.descriptions":[],"ad_group_ad.ad.app_engagement_ad.headlines":[],"ad_group_ad.ad.app_engagement_ad.images":[],"ad_group_ad.ad.app_engagement_ad.videos":[],"ad_group_ad.ad.call_ad.business_name":"","ad_group_ad.ad.call_ad.call_tracked":false,"ad_group_ad.ad.call_ad.conversion_action":"","ad_group_ad.ad.call_ad.conversion_reporting_state":"UNSPECIFIED","ad_group_ad.ad.call_ad.country_code":"","ad_group_ad.ad.call_ad.description1":"","ad_group_ad.ad.call_ad.description2":"","ad_group_ad.ad.call_ad.disable_call_conversion":false,"ad_group_ad.ad.call_ad.headline1":"","ad_group_ad.ad.call_ad.headline2":"","ad_group_ad.ad.call_ad.path1":"","ad_group_ad.ad.call_ad.path2":"","ad_group_ad.ad.call_ad.phone_number":"","ad_group_ad.ad.call_ad.phone_number_verification_url":"","ad_group_ad.ad.device_preference":"UNSPECIFIED","ad_group_ad.ad.display_upload_ad.display_upload_product_type":"UNSPECIFIED","ad_group_ad.ad.display_upload_ad.media_bundle":"","ad_group_ad.ad.display_url":"","ad_group_ad.ad.expanded_dynamic_search_ad.description":"","ad_group_ad.ad.expanded_dynamic_search_ad.description2":"","ad_group_ad.ad.expanded_text_ad.description":"","ad_group_ad.ad.expanded_text_ad.description2":"","ad_group_ad.ad.expanded_text_ad.headline_part1":"","ad_group_ad.ad.expanded_text_ad.headline_part2":"","ad_group_ad.ad.expanded_text_ad.headline_part3":"","ad_group_ad.ad.expanded_text_ad.path1":"","ad_group_ad.ad.expanded_text_ad.path2":"","ad_group_ad.ad.final_app_urls":[],"ad_group_ad.ad.final_mobile_urls":[],"ad_group_ad.ad.final_url_suffix":"","ad_group_ad.ad.final_urls":["https://airbyte.com"],"ad_group_ad.ad.hotel_ad":"","ad_group_ad.ad.id":592078676857,"ad_group_ad.ad.image_ad.image_url":"","ad_group_ad.ad.image_ad.mime_type":"UNSPECIFIED","ad_group_ad.ad.image_ad.name":"","ad_group_ad.ad.image_ad.pixel_height":0,"ad_group_ad.ad.image_ad.pixel_width":0,"ad_group_ad.ad.image_ad.preview_image_url":"","ad_group_ad.ad.image_ad.preview_pixel_height":0,"ad_group_ad.ad.image_ad.preview_pixel_width":0,"ad_group_ad.ad.legacy_app_install_ad":"","ad_group_ad.ad.legacy_responsive_display_ad.accent_color":"","ad_group_ad.ad.legacy_responsive_display_ad.allow_flexible_color":false,"ad_group_ad.ad.legacy_responsive_display_ad.business_name":"","ad_group_ad.ad.legacy_responsive_display_ad.call_to_action_text":"","ad_group_ad.ad.legacy_responsive_display_ad.description":"","ad_group_ad.ad.legacy_responsive_display_ad.format_setting":"UNSPECIFIED","ad_group_ad.ad.legacy_responsive_display_ad.logo_image":"","ad_group_ad.ad.legacy_responsive_display_ad.long_headline":"","ad_group_ad.ad.legacy_responsive_display_ad.main_color":"","ad_group_ad.ad.legacy_responsive_display_ad.marketing_image":"","ad_group_ad.ad.legacy_responsive_display_ad.price_prefix":"","ad_group_ad.ad.legacy_responsive_display_ad.promo_text":"","ad_group_ad.ad.legacy_responsive_display_ad.short_headline":"","ad_group_ad.ad.legacy_responsive_display_ad.square_logo_image":"","ad_group_ad.ad.legacy_responsive_display_ad.square_marketing_image":"","ad_group_ad.ad.local_ad.call_to_actions":[],"ad_group_ad.ad.local_ad.descriptions":[],"ad_group_ad.ad.local_ad.headlines":[],"ad_group_ad.ad.local_ad.logo_images":[],"ad_group_ad.ad.local_ad.marketing_images":[],"ad_group_ad.ad.local_ad.path1":"","ad_group_ad.ad.local_ad.path2":"","ad_group_ad.ad.local_ad.videos":[],"ad_group_ad.ad.name":"","ad_group_ad.ad.resource_name":"customers/4651612872/ads/592078676857","ad_group_ad.ad.responsive_display_ad.accent_color":"","ad_group_ad.ad.responsive_display_ad.allow_flexible_color":false,"ad_group_ad.ad.responsive_display_ad.business_name":"","ad_group_ad.ad.responsive_display_ad.call_to_action_text":"","ad_group_ad.ad.responsive_display_ad.control_spec.enable_asset_enhancements":false,"ad_group_ad.ad.responsive_display_ad.control_spec.enable_autogen_video":false,"ad_group_ad.ad.responsive_display_ad.descriptions":[],"ad_group_ad.ad.responsive_display_ad.format_setting":"UNSPECIFIED","ad_group_ad.ad.responsive_display_ad.headlines":[],"ad_group_ad.ad.responsive_display_ad.logo_images":[],"ad_group_ad.ad.responsive_display_ad.long_headline":"","ad_group_ad.ad.responsive_display_ad.main_color":"","ad_group_ad.ad.responsive_display_ad.marketing_images":[],"ad_group_ad.ad.responsive_display_ad.price_prefix":"","ad_group_ad.ad.responsive_display_ad.promo_text":"","ad_group_ad.ad.responsive_display_ad.square_logo_images":[],"ad_group_ad.ad.responsive_display_ad.square_marketing_images":[],"ad_group_ad.ad.responsive_display_ad.youtube_videos":[],"ad_group_ad.ad.responsive_search_ad.descriptions":["text: \"Behind The Scenes: Testing The Airbyte Maintainer Program\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n","text: \"Airbyte | Open-Source Data Integration Platform | ELT tool\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n","text: \"Upgrading Our Discourse And Slack To Support Our Community Growth\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n"],"ad_group_ad.ad.responsive_search_ad.headlines":["text: \"Airbyte\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n","text: \"ELT tool\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n","text: \"Open-source Data Integration\"\nasset_performance_label: PENDING\npolicy_summary_info {\n review_status: REVIEWED\n approval_status: APPROVED\n}\n"],"ad_group_ad.ad.responsive_search_ad.path1":"","ad_group_ad.ad.responsive_search_ad.path2":"","ad_group_ad.ad.shopping_comparison_listing_ad.headline":"","ad_group_ad.ad.shopping_product_ad":"","ad_group_ad.ad.shopping_smart_ad":"","ad_group_ad.ad.smart_campaign_ad.descriptions":[],"ad_group_ad.ad.smart_campaign_ad.headlines":[],"ad_group_ad.ad.system_managed_resource_source":"UNSPECIFIED","ad_group_ad.ad.text_ad.description1":"","ad_group_ad.ad.text_ad.description2":"","ad_group_ad.ad.text_ad.headline":"","ad_group_ad.ad.tracking_url_template":"","ad_group_ad.ad.type":"RESPONSIVE_SEARCH_AD","ad_group_ad.ad.url_collections":[],"ad_group_ad.ad.url_custom_parameters":[],"ad_group_ad.ad.video_ad.in_feed.description1":"","ad_group_ad.ad.video_ad.in_feed.description2":"","ad_group_ad.ad.video_ad.in_feed.headline":"","ad_group_ad.ad.video_ad.in_stream.action_button_label":"","ad_group_ad.ad.video_ad.in_stream.action_headline":"","ad_group_ad.ad.video_ad.out_stream.description":"","ad_group_ad.ad.video_ad.out_stream.headline":"","ad_group_ad.ad.video_responsive_ad.call_to_actions":[],"ad_group_ad.ad.video_responsive_ad.companion_banners":[],"ad_group_ad.ad.video_responsive_ad.descriptions":[],"ad_group_ad.ad.video_responsive_ad.headlines":[],"ad_group_ad.ad.video_responsive_ad.long_headlines":[],"ad_group_ad.ad.video_responsive_ad.videos":[],"ad_group_ad.ad_group":"customers/4651612872/adGroups/137051662444","ad_group_ad.ad_strength":"POOR","ad_group_ad.labels":[],"ad_group_ad.policy_summary.approval_status":"APPROVED","ad_group_ad.policy_summary.policy_topic_entries":[],"ad_group_ad.policy_summary.review_status":"REVIEWED","ad_group_ad.resource_name":"customers/4651612872/adGroupAds/137051662444~592078676857","ad_group_ad.status":"REMOVED","segments.date":"2022-04-10"},"emitted_at":1679577402025} -{"stream":"campaigns","data":{"campaign.accessible_bidding_strategy":"","campaign.ad_serving_optimization_status":"OPTIMIZE","campaign.advertising_channel_sub_type":"UNSPECIFIED","campaign.advertising_channel_type":"SEARCH","campaign.app_campaign_setting.app_id":"","campaign.app_campaign_setting.app_store":"UNSPECIFIED","campaign.app_campaign_setting.bidding_strategy_goal_type":"UNSPECIFIED","campaign.base_campaign":"customers/4651612872/campaigns/16820250687","campaign.bidding_strategy":"","campaign.bidding_strategy_type":"TARGET_SPEND","campaign.campaign_budget":"customers/4651612872/campaignBudgets/10695604507","campaign_budget.amount_micros":750000,"campaign.commission.commission_rate_micros":0,"campaign.dynamic_search_ads_setting.domain_name":"","campaign.dynamic_search_ads_setting.feeds":[],"campaign.dynamic_search_ads_setting.language_code":"","campaign.dynamic_search_ads_setting.use_supplied_urls_only":false,"campaign.end_date":"2037-12-30","campaign.excluded_parent_asset_field_types":[],"campaign.experiment_type":"BASE","campaign.final_url_suffix":"","campaign.frequency_caps":[],"campaign.geo_target_type_setting.negative_geo_target_type":"PRESENCE","campaign.geo_target_type_setting.positive_geo_target_type":"PRESENCE_OR_INTEREST","campaign.hotel_setting.hotel_center_id":0,"campaign.id":16820250687,"campaign.labels":[],"campaign.local_campaign_setting.location_source_type":"UNSPECIFIED","campaign.manual_cpc.enhanced_cpc_enabled":false,"campaign.manual_cpm":"","campaign.manual_cpv":"","campaign.maximize_conversion_value.target_roas":0.0,"campaign.maximize_conversions.target_cpa_micros":0,"campaign.name":"Website traffic-Search-15","campaign.network_settings.target_content_network":true,"campaign.network_settings.target_google_search":true,"campaign.network_settings.target_partner_search_network":false,"campaign.network_settings.target_search_network":true,"campaign.optimization_goal_setting.optimization_goal_types":[],"campaign.optimization_score":0.0,"campaign.payment_mode":"CLICKS","campaign.percent_cpc.cpc_bid_ceiling_micros":0,"campaign.percent_cpc.enhanced_cpc_enabled":false,"campaign.real_time_bidding_setting.opt_in":false,"campaign.resource_name":"customers/4651612872/campaigns/16820250687","campaign.selective_optimization.conversion_actions":[],"campaign.serving_status":"SERVING","campaign.shopping_setting.campaign_priority":0,"campaign.shopping_setting.enable_local":false,"campaign.shopping_setting.merchant_id":0,"campaign.shopping_setting.sales_country":"","campaign.start_date":"2022-04-08","campaign.status":"PAUSED","campaign.target_cpa.cpc_bid_ceiling_micros":0,"campaign.target_cpa.cpc_bid_floor_micros":0,"campaign.target_cpa.target_cpa_micros":0,"campaign.target_cpm.target_frequency_goal.target_count":0,"campaign.target_cpm.target_frequency_goal.time_unit":"UNSPECIFIED","campaign.target_impression_share.cpc_bid_ceiling_micros":0,"campaign.target_impression_share.location":"UNSPECIFIED","campaign.target_impression_share.location_fraction_micros":0,"campaign.target_roas.cpc_bid_ceiling_micros":0,"campaign.target_roas.cpc_bid_floor_micros":0,"campaign.target_roas.target_roas":0.0,"campaign.target_spend.cpc_bid_ceiling_micros":0,"campaign.target_spend.target_spend_micros":0,"campaign.targeting_setting.target_restrictions":["targeting_dimension: AUDIENCE\nbid_only: true\n"],"campaign.tracking_setting.tracking_url":"","campaign.tracking_url_template":"","campaign.url_custom_parameters":[],"campaign.vanity_pharma.vanity_pharma_display_url_mode":"UNSPECIFIED","campaign.vanity_pharma.vanity_pharma_text":"UNSPECIFIED","campaign.video_brand_safety_suitability":"UNSPECIFIED","metrics.clicks":0,"metrics.ctr":0.0,"metrics.conversions":0.0,"metrics.conversions_value":0.0,"metrics.cost_micros":0,"metrics.impressions":2.0,"metrics.video_views":0.0,"metrics.video_quartile_p100_rate":0.0,"segments.date":"2022-04-08","segments.hour":21.0},"emitted_at":1679577498472} -{"stream":"campaigns","data":{"campaign.accessible_bidding_strategy":"","campaign.ad_serving_optimization_status":"OPTIMIZE","campaign.advertising_channel_sub_type":"UNSPECIFIED","campaign.advertising_channel_type":"SEARCH","campaign.app_campaign_setting.app_id":"","campaign.app_campaign_setting.app_store":"UNSPECIFIED","campaign.app_campaign_setting.bidding_strategy_goal_type":"UNSPECIFIED","campaign.base_campaign":"customers/4651612872/campaigns/16820250687","campaign.bidding_strategy":"","campaign.bidding_strategy_type":"TARGET_SPEND","campaign.campaign_budget":"customers/4651612872/campaignBudgets/10695604507","campaign_budget.amount_micros":750000,"campaign.commission.commission_rate_micros":0,"campaign.dynamic_search_ads_setting.domain_name":"","campaign.dynamic_search_ads_setting.feeds":[],"campaign.dynamic_search_ads_setting.language_code":"","campaign.dynamic_search_ads_setting.use_supplied_urls_only":false,"campaign.end_date":"2037-12-30","campaign.excluded_parent_asset_field_types":[],"campaign.experiment_type":"BASE","campaign.final_url_suffix":"","campaign.frequency_caps":[],"campaign.geo_target_type_setting.negative_geo_target_type":"PRESENCE","campaign.geo_target_type_setting.positive_geo_target_type":"PRESENCE_OR_INTEREST","campaign.hotel_setting.hotel_center_id":0,"campaign.id":16820250687,"campaign.labels":[],"campaign.local_campaign_setting.location_source_type":"UNSPECIFIED","campaign.manual_cpc.enhanced_cpc_enabled":false,"campaign.manual_cpm":"","campaign.manual_cpv":"","campaign.maximize_conversion_value.target_roas":0.0,"campaign.maximize_conversions.target_cpa_micros":0,"campaign.name":"Website traffic-Search-15","campaign.network_settings.target_content_network":true,"campaign.network_settings.target_google_search":true,"campaign.network_settings.target_partner_search_network":false,"campaign.network_settings.target_search_network":true,"campaign.optimization_goal_setting.optimization_goal_types":[],"campaign.optimization_score":0.0,"campaign.payment_mode":"CLICKS","campaign.percent_cpc.cpc_bid_ceiling_micros":0,"campaign.percent_cpc.enhanced_cpc_enabled":false,"campaign.real_time_bidding_setting.opt_in":false,"campaign.resource_name":"customers/4651612872/campaigns/16820250687","campaign.selective_optimization.conversion_actions":[],"campaign.serving_status":"SERVING","campaign.shopping_setting.campaign_priority":0,"campaign.shopping_setting.enable_local":false,"campaign.shopping_setting.merchant_id":0,"campaign.shopping_setting.sales_country":"","campaign.start_date":"2022-04-08","campaign.status":"PAUSED","campaign.target_cpa.cpc_bid_ceiling_micros":0,"campaign.target_cpa.cpc_bid_floor_micros":0,"campaign.target_cpa.target_cpa_micros":0,"campaign.target_cpm.target_frequency_goal.target_count":0,"campaign.target_cpm.target_frequency_goal.time_unit":"UNSPECIFIED","campaign.target_impression_share.cpc_bid_ceiling_micros":0,"campaign.target_impression_share.location":"UNSPECIFIED","campaign.target_impression_share.location_fraction_micros":0,"campaign.target_roas.cpc_bid_ceiling_micros":0,"campaign.target_roas.cpc_bid_floor_micros":0,"campaign.target_roas.target_roas":0.0,"campaign.target_spend.cpc_bid_ceiling_micros":0,"campaign.target_spend.target_spend_micros":0,"campaign.targeting_setting.target_restrictions":["targeting_dimension: AUDIENCE\nbid_only: true\n"],"campaign.tracking_setting.tracking_url":"","campaign.tracking_url_template":"","campaign.url_custom_parameters":[],"campaign.vanity_pharma.vanity_pharma_display_url_mode":"UNSPECIFIED","campaign.vanity_pharma.vanity_pharma_text":"UNSPECIFIED","campaign.video_brand_safety_suitability":"UNSPECIFIED","metrics.clicks":0,"metrics.ctr":0.0,"metrics.conversions":0.0,"metrics.conversions_value":0.0,"metrics.cost_micros":0,"metrics.impressions":1.0,"metrics.video_views":0.0,"metrics.video_quartile_p100_rate":0.0,"segments.date":"2022-04-09","segments.hour":2.0},"emitted_at":1679577498477} -{"stream":"campaigns","data":{"campaign.accessible_bidding_strategy":"","campaign.ad_serving_optimization_status":"OPTIMIZE","campaign.advertising_channel_sub_type":"UNSPECIFIED","campaign.advertising_channel_type":"SEARCH","campaign.app_campaign_setting.app_id":"","campaign.app_campaign_setting.app_store":"UNSPECIFIED","campaign.app_campaign_setting.bidding_strategy_goal_type":"UNSPECIFIED","campaign.base_campaign":"customers/4651612872/campaigns/16820250687","campaign.bidding_strategy":"","campaign.bidding_strategy_type":"TARGET_SPEND","campaign.campaign_budget":"customers/4651612872/campaignBudgets/10695604507","campaign_budget.amount_micros":750000,"campaign.commission.commission_rate_micros":0,"campaign.dynamic_search_ads_setting.domain_name":"","campaign.dynamic_search_ads_setting.feeds":[],"campaign.dynamic_search_ads_setting.language_code":"","campaign.dynamic_search_ads_setting.use_supplied_urls_only":false,"campaign.end_date":"2037-12-30","campaign.excluded_parent_asset_field_types":[],"campaign.experiment_type":"BASE","campaign.final_url_suffix":"","campaign.frequency_caps":[],"campaign.geo_target_type_setting.negative_geo_target_type":"PRESENCE","campaign.geo_target_type_setting.positive_geo_target_type":"PRESENCE_OR_INTEREST","campaign.hotel_setting.hotel_center_id":0,"campaign.id":16820250687,"campaign.labels":[],"campaign.local_campaign_setting.location_source_type":"UNSPECIFIED","campaign.manual_cpc.enhanced_cpc_enabled":false,"campaign.manual_cpm":"","campaign.manual_cpv":"","campaign.maximize_conversion_value.target_roas":0.0,"campaign.maximize_conversions.target_cpa_micros":0,"campaign.name":"Website traffic-Search-15","campaign.network_settings.target_content_network":true,"campaign.network_settings.target_google_search":true,"campaign.network_settings.target_partner_search_network":false,"campaign.network_settings.target_search_network":true,"campaign.optimization_goal_setting.optimization_goal_types":[],"campaign.optimization_score":0.0,"campaign.payment_mode":"CLICKS","campaign.percent_cpc.cpc_bid_ceiling_micros":0,"campaign.percent_cpc.enhanced_cpc_enabled":false,"campaign.real_time_bidding_setting.opt_in":false,"campaign.resource_name":"customers/4651612872/campaigns/16820250687","campaign.selective_optimization.conversion_actions":[],"campaign.serving_status":"SERVING","campaign.shopping_setting.campaign_priority":0,"campaign.shopping_setting.enable_local":false,"campaign.shopping_setting.merchant_id":0,"campaign.shopping_setting.sales_country":"","campaign.start_date":"2022-04-08","campaign.status":"PAUSED","campaign.target_cpa.cpc_bid_ceiling_micros":0,"campaign.target_cpa.cpc_bid_floor_micros":0,"campaign.target_cpa.target_cpa_micros":0,"campaign.target_cpm.target_frequency_goal.target_count":0,"campaign.target_cpm.target_frequency_goal.time_unit":"UNSPECIFIED","campaign.target_impression_share.cpc_bid_ceiling_micros":0,"campaign.target_impression_share.location":"UNSPECIFIED","campaign.target_impression_share.location_fraction_micros":0,"campaign.target_roas.cpc_bid_ceiling_micros":0,"campaign.target_roas.cpc_bid_floor_micros":0,"campaign.target_roas.target_roas":0.0,"campaign.target_spend.cpc_bid_ceiling_micros":0,"campaign.target_spend.target_spend_micros":0,"campaign.targeting_setting.target_restrictions":["targeting_dimension: AUDIENCE\nbid_only: true\n"],"campaign.tracking_setting.tracking_url":"","campaign.tracking_url_template":"","campaign.url_custom_parameters":[],"campaign.vanity_pharma.vanity_pharma_display_url_mode":"UNSPECIFIED","campaign.vanity_pharma.vanity_pharma_text":"UNSPECIFIED","campaign.video_brand_safety_suitability":"UNSPECIFIED","metrics.clicks":0,"metrics.ctr":0.0,"metrics.conversions":0.0,"metrics.conversions_value":0.0,"metrics.cost_micros":0,"metrics.impressions":4.0,"metrics.video_views":0.0,"metrics.video_quartile_p100_rate":0.0,"segments.date":"2022-04-09","segments.hour":7.0},"emitted_at":1679577498481} -{"stream":"campaigns","data":{"campaign.accessible_bidding_strategy":"","campaign.ad_serving_optimization_status":"OPTIMIZE","campaign.advertising_channel_sub_type":"UNSPECIFIED","campaign.advertising_channel_type":"SEARCH","campaign.app_campaign_setting.app_id":"","campaign.app_campaign_setting.app_store":"UNSPECIFIED","campaign.app_campaign_setting.bidding_strategy_goal_type":"UNSPECIFIED","campaign.base_campaign":"customers/4651612872/campaigns/16820250687","campaign.bidding_strategy":"","campaign.bidding_strategy_type":"TARGET_SPEND","campaign.campaign_budget":"customers/4651612872/campaignBudgets/10695604507","campaign_budget.amount_micros":750000,"campaign.commission.commission_rate_micros":0,"campaign.dynamic_search_ads_setting.domain_name":"","campaign.dynamic_search_ads_setting.feeds":[],"campaign.dynamic_search_ads_setting.language_code":"","campaign.dynamic_search_ads_setting.use_supplied_urls_only":false,"campaign.end_date":"2037-12-30","campaign.excluded_parent_asset_field_types":[],"campaign.experiment_type":"BASE","campaign.final_url_suffix":"","campaign.frequency_caps":[],"campaign.geo_target_type_setting.negative_geo_target_type":"PRESENCE","campaign.geo_target_type_setting.positive_geo_target_type":"PRESENCE_OR_INTEREST","campaign.hotel_setting.hotel_center_id":0,"campaign.id":16820250687,"campaign.labels":[],"campaign.local_campaign_setting.location_source_type":"UNSPECIFIED","campaign.manual_cpc.enhanced_cpc_enabled":false,"campaign.manual_cpm":"","campaign.manual_cpv":"","campaign.maximize_conversion_value.target_roas":0.0,"campaign.maximize_conversions.target_cpa_micros":0,"campaign.name":"Website traffic-Search-15","campaign.network_settings.target_content_network":true,"campaign.network_settings.target_google_search":true,"campaign.network_settings.target_partner_search_network":false,"campaign.network_settings.target_search_network":true,"campaign.optimization_goal_setting.optimization_goal_types":[],"campaign.optimization_score":0.0,"campaign.payment_mode":"CLICKS","campaign.percent_cpc.cpc_bid_ceiling_micros":0,"campaign.percent_cpc.enhanced_cpc_enabled":false,"campaign.real_time_bidding_setting.opt_in":false,"campaign.resource_name":"customers/4651612872/campaigns/16820250687","campaign.selective_optimization.conversion_actions":[],"campaign.serving_status":"SERVING","campaign.shopping_setting.campaign_priority":0,"campaign.shopping_setting.enable_local":false,"campaign.shopping_setting.merchant_id":0,"campaign.shopping_setting.sales_country":"","campaign.start_date":"2022-04-08","campaign.status":"PAUSED","campaign.target_cpa.cpc_bid_ceiling_micros":0,"campaign.target_cpa.cpc_bid_floor_micros":0,"campaign.target_cpa.target_cpa_micros":0,"campaign.target_cpm.target_frequency_goal.target_count":0,"campaign.target_cpm.target_frequency_goal.time_unit":"UNSPECIFIED","campaign.target_impression_share.cpc_bid_ceiling_micros":0,"campaign.target_impression_share.location":"UNSPECIFIED","campaign.target_impression_share.location_fraction_micros":0,"campaign.target_roas.cpc_bid_ceiling_micros":0,"campaign.target_roas.cpc_bid_floor_micros":0,"campaign.target_roas.target_roas":0.0,"campaign.target_spend.cpc_bid_ceiling_micros":0,"campaign.target_spend.target_spend_micros":0,"campaign.targeting_setting.target_restrictions":["targeting_dimension: AUDIENCE\nbid_only: true\n"],"campaign.tracking_setting.tracking_url":"","campaign.tracking_url_template":"","campaign.url_custom_parameters":[],"campaign.vanity_pharma.vanity_pharma_display_url_mode":"UNSPECIFIED","campaign.vanity_pharma.vanity_pharma_text":"UNSPECIFIED","campaign.video_brand_safety_suitability":"UNSPECIFIED","metrics.clicks":0,"metrics.ctr":0.0,"metrics.conversions":0.0,"metrics.conversions_value":0.0,"metrics.cost_micros":0,"metrics.impressions":1.0,"metrics.video_views":0.0,"metrics.video_quartile_p100_rate":0.0,"segments.date":"2022-04-09","segments.hour":8.0},"emitted_at":1679577498485} -{"stream":"campaigns","data":{"campaign.accessible_bidding_strategy":"","campaign.ad_serving_optimization_status":"OPTIMIZE","campaign.advertising_channel_sub_type":"UNSPECIFIED","campaign.advertising_channel_type":"SEARCH","campaign.app_campaign_setting.app_id":"","campaign.app_campaign_setting.app_store":"UNSPECIFIED","campaign.app_campaign_setting.bidding_strategy_goal_type":"UNSPECIFIED","campaign.base_campaign":"customers/4651612872/campaigns/16820250687","campaign.bidding_strategy":"","campaign.bidding_strategy_type":"TARGET_SPEND","campaign.campaign_budget":"customers/4651612872/campaignBudgets/10695604507","campaign_budget.amount_micros":750000,"campaign.commission.commission_rate_micros":0,"campaign.dynamic_search_ads_setting.domain_name":"","campaign.dynamic_search_ads_setting.feeds":[],"campaign.dynamic_search_ads_setting.language_code":"","campaign.dynamic_search_ads_setting.use_supplied_urls_only":false,"campaign.end_date":"2037-12-30","campaign.excluded_parent_asset_field_types":[],"campaign.experiment_type":"BASE","campaign.final_url_suffix":"","campaign.frequency_caps":[],"campaign.geo_target_type_setting.negative_geo_target_type":"PRESENCE","campaign.geo_target_type_setting.positive_geo_target_type":"PRESENCE_OR_INTEREST","campaign.hotel_setting.hotel_center_id":0,"campaign.id":16820250687,"campaign.labels":[],"campaign.local_campaign_setting.location_source_type":"UNSPECIFIED","campaign.manual_cpc.enhanced_cpc_enabled":false,"campaign.manual_cpm":"","campaign.manual_cpv":"","campaign.maximize_conversion_value.target_roas":0.0,"campaign.maximize_conversions.target_cpa_micros":0,"campaign.name":"Website traffic-Search-15","campaign.network_settings.target_content_network":true,"campaign.network_settings.target_google_search":true,"campaign.network_settings.target_partner_search_network":false,"campaign.network_settings.target_search_network":true,"campaign.optimization_goal_setting.optimization_goal_types":[],"campaign.optimization_score":0.0,"campaign.payment_mode":"CLICKS","campaign.percent_cpc.cpc_bid_ceiling_micros":0,"campaign.percent_cpc.enhanced_cpc_enabled":false,"campaign.real_time_bidding_setting.opt_in":false,"campaign.resource_name":"customers/4651612872/campaigns/16820250687","campaign.selective_optimization.conversion_actions":[],"campaign.serving_status":"SERVING","campaign.shopping_setting.campaign_priority":0,"campaign.shopping_setting.enable_local":false,"campaign.shopping_setting.merchant_id":0,"campaign.shopping_setting.sales_country":"","campaign.start_date":"2022-04-08","campaign.status":"PAUSED","campaign.target_cpa.cpc_bid_ceiling_micros":0,"campaign.target_cpa.cpc_bid_floor_micros":0,"campaign.target_cpa.target_cpa_micros":0,"campaign.target_cpm.target_frequency_goal.target_count":0,"campaign.target_cpm.target_frequency_goal.time_unit":"UNSPECIFIED","campaign.target_impression_share.cpc_bid_ceiling_micros":0,"campaign.target_impression_share.location":"UNSPECIFIED","campaign.target_impression_share.location_fraction_micros":0,"campaign.target_roas.cpc_bid_ceiling_micros":0,"campaign.target_roas.cpc_bid_floor_micros":0,"campaign.target_roas.target_roas":0.0,"campaign.target_spend.cpc_bid_ceiling_micros":0,"campaign.target_spend.target_spend_micros":0,"campaign.targeting_setting.target_restrictions":["targeting_dimension: AUDIENCE\nbid_only: true\n"],"campaign.tracking_setting.tracking_url":"","campaign.tracking_url_template":"","campaign.url_custom_parameters":[],"campaign.vanity_pharma.vanity_pharma_display_url_mode":"UNSPECIFIED","campaign.vanity_pharma.vanity_pharma_text":"UNSPECIFIED","campaign.video_brand_safety_suitability":"UNSPECIFIED","metrics.clicks":1,"metrics.ctr":0.25,"metrics.conversions":0.0,"metrics.conversions_value":0.0,"metrics.cost_micros":70000,"metrics.impressions":4.0,"metrics.video_views":0.0,"metrics.video_quartile_p100_rate":0.0,"segments.date":"2022-04-09","segments.hour":9.0},"emitted_at":1679577498489} +{"stream":"campaigns","data":{"campaign.accessible_bidding_strategy":"","campaign.ad_serving_optimization_status":"OPTIMIZE","campaign.advertising_channel_sub_type":"UNSPECIFIED","campaign.advertising_channel_type":"SEARCH","campaign.app_campaign_setting.app_id":"","campaign.app_campaign_setting.app_store":"UNSPECIFIED","campaign.app_campaign_setting.bidding_strategy_goal_type":"UNSPECIFIED","campaign.base_campaign":"customers/4651612872/campaigns/16820250687","campaign.bidding_strategy":"","campaign.bidding_strategy_type":"TARGET_SPEND","campaign.campaign_budget":"customers/4651612872/campaignBudgets/10695604507","campaign_budget.amount_micros":750000,"campaign.commission.commission_rate_micros":0,"campaign.dynamic_search_ads_setting.domain_name":"","campaign.dynamic_search_ads_setting.feeds":[],"campaign.dynamic_search_ads_setting.language_code":"","campaign.dynamic_search_ads_setting.use_supplied_urls_only":false,"campaign.end_date":"2037-12-30","campaign.excluded_parent_asset_field_types":[],"campaign.experiment_type":"BASE","campaign.final_url_suffix":"","campaign.frequency_caps":[],"campaign.geo_target_type_setting.negative_geo_target_type":"PRESENCE","campaign.geo_target_type_setting.positive_geo_target_type":"PRESENCE_OR_INTEREST","campaign.hotel_setting.hotel_center_id":0,"campaign.id":16820250687,"campaign.labels":[],"campaign.local_campaign_setting.location_source_type":"UNSPECIFIED","campaign.manual_cpc.enhanced_cpc_enabled":false,"campaign.manual_cpm":"","campaign.manual_cpv":"","campaign.maximize_conversion_value.target_roas":0,"campaign.maximize_conversions.target_cpa_micros":0,"campaign.name":"Website traffic-Search-15","campaign.network_settings.target_content_network":true,"campaign.network_settings.target_google_search":true,"campaign.network_settings.target_partner_search_network":false,"campaign.network_settings.target_search_network":true,"campaign.optimization_goal_setting.optimization_goal_types":[],"campaign.optimization_score":0,"campaign.payment_mode":"CLICKS","campaign.percent_cpc.cpc_bid_ceiling_micros":0,"campaign.percent_cpc.enhanced_cpc_enabled":false,"campaign.real_time_bidding_setting.opt_in":false,"campaign.resource_name":"customers/4651612872/campaigns/16820250687","campaign.selective_optimization.conversion_actions":[],"campaign.serving_status":"SERVING","campaign.shopping_setting.campaign_priority":0,"campaign.shopping_setting.enable_local":false,"campaign.shopping_setting.merchant_id":0,"campaign.shopping_setting.sales_country":"","campaign.start_date":"2022-04-08","campaign.status":"PAUSED","campaign.target_cpa.cpc_bid_ceiling_micros":0,"campaign.target_cpa.cpc_bid_floor_micros":0,"campaign.target_cpa.target_cpa_micros":0,"campaign.target_cpm.target_frequency_goal.target_count":0,"campaign.target_cpm.target_frequency_goal.time_unit":"UNSPECIFIED","campaign.target_impression_share.cpc_bid_ceiling_micros":0,"campaign.target_impression_share.location":"UNSPECIFIED","campaign.target_impression_share.location_fraction_micros":0,"campaign.target_roas.cpc_bid_ceiling_micros":0,"campaign.target_roas.cpc_bid_floor_micros":0,"campaign.target_roas.target_roas":0,"campaign.target_spend.cpc_bid_ceiling_micros":0,"campaign.target_spend.target_spend_micros":0,"campaign.targeting_setting.target_restrictions":["targeting_dimension: AUDIENCE\nbid_only: true\n"],"campaign.tracking_setting.tracking_url":"","campaign.tracking_url_template":"","campaign.url_custom_parameters":[],"campaign.vanity_pharma.vanity_pharma_display_url_mode":"UNSPECIFIED","campaign.vanity_pharma.vanity_pharma_text":"UNSPECIFIED","campaign.video_brand_safety_suitability":"UNSPECIFIED","metrics.clicks":0,"metrics.ctr":0,"metrics.conversions":0,"metrics.conversions_value":0,"metrics.cost_micros":0,"metrics.impressions":1,"metrics.video_views":0,"metrics.video_quartile_p100_rate":0,"metrics.active_view_cpm":0,"metrics.active_view_ctr":0,"metrics.active_view_impressions":0,"metrics.active_view_measurability":0,"metrics.active_view_measurable_cost_micros":0,"metrics.active_view_measurable_impressions":0,"metrics.active_view_viewability":0,"metrics.average_cost":0,"metrics.average_cpc":0,"metrics.average_cpm":0,"metrics.interactions":0,"metrics.interaction_event_types":"[]","metrics.value_per_conversion":0,"metrics.cost_per_conversion":0,"segments.date":"2022-05-25","segments.hour":16,"segments.ad_network_type":"SEARCH"},"emitted_at":1688730371371} +{"stream":"campaigns","data":{"campaign.accessible_bidding_strategy":"","campaign.ad_serving_optimization_status":"OPTIMIZE","campaign.advertising_channel_sub_type":"UNSPECIFIED","campaign.advertising_channel_type":"SEARCH","campaign.app_campaign_setting.app_id":"","campaign.app_campaign_setting.app_store":"UNSPECIFIED","campaign.app_campaign_setting.bidding_strategy_goal_type":"UNSPECIFIED","campaign.base_campaign":"customers/4651612872/campaigns/16820250687","campaign.bidding_strategy":"","campaign.bidding_strategy_type":"TARGET_SPEND","campaign.campaign_budget":"customers/4651612872/campaignBudgets/10695604507","campaign_budget.amount_micros":750000,"campaign.commission.commission_rate_micros":0,"campaign.dynamic_search_ads_setting.domain_name":"","campaign.dynamic_search_ads_setting.feeds":[],"campaign.dynamic_search_ads_setting.language_code":"","campaign.dynamic_search_ads_setting.use_supplied_urls_only":false,"campaign.end_date":"2037-12-30","campaign.excluded_parent_asset_field_types":[],"campaign.experiment_type":"BASE","campaign.final_url_suffix":"","campaign.frequency_caps":[],"campaign.geo_target_type_setting.negative_geo_target_type":"PRESENCE","campaign.geo_target_type_setting.positive_geo_target_type":"PRESENCE_OR_INTEREST","campaign.hotel_setting.hotel_center_id":0,"campaign.id":16820250687,"campaign.labels":[],"campaign.local_campaign_setting.location_source_type":"UNSPECIFIED","campaign.manual_cpc.enhanced_cpc_enabled":false,"campaign.manual_cpm":"","campaign.manual_cpv":"","campaign.maximize_conversion_value.target_roas":0,"campaign.maximize_conversions.target_cpa_micros":0,"campaign.name":"Website traffic-Search-15","campaign.network_settings.target_content_network":true,"campaign.network_settings.target_google_search":true,"campaign.network_settings.target_partner_search_network":false,"campaign.network_settings.target_search_network":true,"campaign.optimization_goal_setting.optimization_goal_types":[],"campaign.optimization_score":0,"campaign.payment_mode":"CLICKS","campaign.percent_cpc.cpc_bid_ceiling_micros":0,"campaign.percent_cpc.enhanced_cpc_enabled":false,"campaign.real_time_bidding_setting.opt_in":false,"campaign.resource_name":"customers/4651612872/campaigns/16820250687","campaign.selective_optimization.conversion_actions":[],"campaign.serving_status":"SERVING","campaign.shopping_setting.campaign_priority":0,"campaign.shopping_setting.enable_local":false,"campaign.shopping_setting.merchant_id":0,"campaign.shopping_setting.sales_country":"","campaign.start_date":"2022-04-08","campaign.status":"PAUSED","campaign.target_cpa.cpc_bid_ceiling_micros":0,"campaign.target_cpa.cpc_bid_floor_micros":0,"campaign.target_cpa.target_cpa_micros":0,"campaign.target_cpm.target_frequency_goal.target_count":0,"campaign.target_cpm.target_frequency_goal.time_unit":"UNSPECIFIED","campaign.target_impression_share.cpc_bid_ceiling_micros":0,"campaign.target_impression_share.location":"UNSPECIFIED","campaign.target_impression_share.location_fraction_micros":0,"campaign.target_roas.cpc_bid_ceiling_micros":0,"campaign.target_roas.cpc_bid_floor_micros":0,"campaign.target_roas.target_roas":0,"campaign.target_spend.cpc_bid_ceiling_micros":0,"campaign.target_spend.target_spend_micros":0,"campaign.targeting_setting.target_restrictions":["targeting_dimension: AUDIENCE\nbid_only: true\n"],"campaign.tracking_setting.tracking_url":"","campaign.tracking_url_template":"","campaign.url_custom_parameters":[],"campaign.vanity_pharma.vanity_pharma_display_url_mode":"UNSPECIFIED","campaign.vanity_pharma.vanity_pharma_text":"UNSPECIFIED","campaign.video_brand_safety_suitability":"UNSPECIFIED","metrics.clicks":1,"metrics.ctr":1,"metrics.conversions":0,"metrics.conversions_value":0,"metrics.cost_micros":10000,"metrics.impressions":1,"metrics.video_views":0,"metrics.video_quartile_p100_rate":0,"metrics.active_view_cpm":0,"metrics.active_view_ctr":0,"metrics.active_view_impressions":0,"metrics.active_view_measurability":0,"metrics.active_view_measurable_cost_micros":0,"metrics.active_view_measurable_impressions":0,"metrics.active_view_viewability":0,"metrics.average_cost":10000,"metrics.average_cpc":10000,"metrics.average_cpm":10000000,"metrics.interactions":1,"metrics.interaction_event_types":"['InteractionEventType.CLICK']","metrics.value_per_conversion":0,"metrics.cost_per_conversion":0,"segments.date":"2022-05-25","segments.hour":18,"segments.ad_network_type":"SEARCH"},"emitted_at":1688730371373} +{"stream":"campaigns","data":{"campaign.accessible_bidding_strategy":"","campaign.ad_serving_optimization_status":"OPTIMIZE","campaign.advertising_channel_sub_type":"UNSPECIFIED","campaign.advertising_channel_type":"SEARCH","campaign.app_campaign_setting.app_id":"","campaign.app_campaign_setting.app_store":"UNSPECIFIED","campaign.app_campaign_setting.bidding_strategy_goal_type":"UNSPECIFIED","campaign.base_campaign":"customers/4651612872/campaigns/16820250687","campaign.bidding_strategy":"","campaign.bidding_strategy_type":"TARGET_SPEND","campaign.campaign_budget":"customers/4651612872/campaignBudgets/10695604507","campaign_budget.amount_micros":750000,"campaign.commission.commission_rate_micros":0,"campaign.dynamic_search_ads_setting.domain_name":"","campaign.dynamic_search_ads_setting.feeds":[],"campaign.dynamic_search_ads_setting.language_code":"","campaign.dynamic_search_ads_setting.use_supplied_urls_only":false,"campaign.end_date":"2037-12-30","campaign.excluded_parent_asset_field_types":[],"campaign.experiment_type":"BASE","campaign.final_url_suffix":"","campaign.frequency_caps":[],"campaign.geo_target_type_setting.negative_geo_target_type":"PRESENCE","campaign.geo_target_type_setting.positive_geo_target_type":"PRESENCE_OR_INTEREST","campaign.hotel_setting.hotel_center_id":0,"campaign.id":16820250687,"campaign.labels":[],"campaign.local_campaign_setting.location_source_type":"UNSPECIFIED","campaign.manual_cpc.enhanced_cpc_enabled":false,"campaign.manual_cpm":"","campaign.manual_cpv":"","campaign.maximize_conversion_value.target_roas":0,"campaign.maximize_conversions.target_cpa_micros":0,"campaign.name":"Website traffic-Search-15","campaign.network_settings.target_content_network":true,"campaign.network_settings.target_google_search":true,"campaign.network_settings.target_partner_search_network":false,"campaign.network_settings.target_search_network":true,"campaign.optimization_goal_setting.optimization_goal_types":[],"campaign.optimization_score":0,"campaign.payment_mode":"CLICKS","campaign.percent_cpc.cpc_bid_ceiling_micros":0,"campaign.percent_cpc.enhanced_cpc_enabled":false,"campaign.real_time_bidding_setting.opt_in":false,"campaign.resource_name":"customers/4651612872/campaigns/16820250687","campaign.selective_optimization.conversion_actions":[],"campaign.serving_status":"SERVING","campaign.shopping_setting.campaign_priority":0,"campaign.shopping_setting.enable_local":false,"campaign.shopping_setting.merchant_id":0,"campaign.shopping_setting.sales_country":"","campaign.start_date":"2022-04-08","campaign.status":"PAUSED","campaign.target_cpa.cpc_bid_ceiling_micros":0,"campaign.target_cpa.cpc_bid_floor_micros":0,"campaign.target_cpa.target_cpa_micros":0,"campaign.target_cpm.target_frequency_goal.target_count":0,"campaign.target_cpm.target_frequency_goal.time_unit":"UNSPECIFIED","campaign.target_impression_share.cpc_bid_ceiling_micros":0,"campaign.target_impression_share.location":"UNSPECIFIED","campaign.target_impression_share.location_fraction_micros":0,"campaign.target_roas.cpc_bid_ceiling_micros":0,"campaign.target_roas.cpc_bid_floor_micros":0,"campaign.target_roas.target_roas":0,"campaign.target_spend.cpc_bid_ceiling_micros":0,"campaign.target_spend.target_spend_micros":0,"campaign.targeting_setting.target_restrictions":["targeting_dimension: AUDIENCE\nbid_only: true\n"],"campaign.tracking_setting.tracking_url":"","campaign.tracking_url_template":"","campaign.url_custom_parameters":[],"campaign.vanity_pharma.vanity_pharma_display_url_mode":"UNSPECIFIED","campaign.vanity_pharma.vanity_pharma_text":"UNSPECIFIED","campaign.video_brand_safety_suitability":"UNSPECIFIED","metrics.clicks":0,"metrics.ctr":0,"metrics.conversions":0,"metrics.conversions_value":0,"metrics.cost_micros":0,"metrics.impressions":2,"metrics.video_views":0,"metrics.video_quartile_p100_rate":0,"metrics.active_view_cpm":0,"metrics.active_view_ctr":0,"metrics.active_view_impressions":0,"metrics.active_view_measurability":0,"metrics.active_view_measurable_cost_micros":0,"metrics.active_view_measurable_impressions":0,"metrics.active_view_viewability":0,"metrics.average_cost":0,"metrics.average_cpc":0,"metrics.average_cpm":0,"metrics.interactions":0,"metrics.interaction_event_types":"[]","metrics.value_per_conversion":0,"metrics.cost_per_conversion":0,"segments.date":"2022-05-25","segments.hour":19,"segments.ad_network_type":"SEARCH"},"emitted_at":1688730371374} +{"stream":"campaigns","data":{"campaign.accessible_bidding_strategy":"","campaign.ad_serving_optimization_status":"OPTIMIZE","campaign.advertising_channel_sub_type":"UNSPECIFIED","campaign.advertising_channel_type":"SEARCH","campaign.app_campaign_setting.app_id":"","campaign.app_campaign_setting.app_store":"UNSPECIFIED","campaign.app_campaign_setting.bidding_strategy_goal_type":"UNSPECIFIED","campaign.base_campaign":"customers/4651612872/campaigns/16820250687","campaign.bidding_strategy":"","campaign.bidding_strategy_type":"TARGET_SPEND","campaign.campaign_budget":"customers/4651612872/campaignBudgets/10695604507","campaign_budget.amount_micros":750000,"campaign.commission.commission_rate_micros":0,"campaign.dynamic_search_ads_setting.domain_name":"","campaign.dynamic_search_ads_setting.feeds":[],"campaign.dynamic_search_ads_setting.language_code":"","campaign.dynamic_search_ads_setting.use_supplied_urls_only":false,"campaign.end_date":"2037-12-30","campaign.excluded_parent_asset_field_types":[],"campaign.experiment_type":"BASE","campaign.final_url_suffix":"","campaign.frequency_caps":[],"campaign.geo_target_type_setting.negative_geo_target_type":"PRESENCE","campaign.geo_target_type_setting.positive_geo_target_type":"PRESENCE_OR_INTEREST","campaign.hotel_setting.hotel_center_id":0,"campaign.id":16820250687,"campaign.labels":[],"campaign.local_campaign_setting.location_source_type":"UNSPECIFIED","campaign.manual_cpc.enhanced_cpc_enabled":false,"campaign.manual_cpm":"","campaign.manual_cpv":"","campaign.maximize_conversion_value.target_roas":0,"campaign.maximize_conversions.target_cpa_micros":0,"campaign.name":"Website traffic-Search-15","campaign.network_settings.target_content_network":true,"campaign.network_settings.target_google_search":true,"campaign.network_settings.target_partner_search_network":false,"campaign.network_settings.target_search_network":true,"campaign.optimization_goal_setting.optimization_goal_types":[],"campaign.optimization_score":0,"campaign.payment_mode":"CLICKS","campaign.percent_cpc.cpc_bid_ceiling_micros":0,"campaign.percent_cpc.enhanced_cpc_enabled":false,"campaign.real_time_bidding_setting.opt_in":false,"campaign.resource_name":"customers/4651612872/campaigns/16820250687","campaign.selective_optimization.conversion_actions":[],"campaign.serving_status":"SERVING","campaign.shopping_setting.campaign_priority":0,"campaign.shopping_setting.enable_local":false,"campaign.shopping_setting.merchant_id":0,"campaign.shopping_setting.sales_country":"","campaign.start_date":"2022-04-08","campaign.status":"PAUSED","campaign.target_cpa.cpc_bid_ceiling_micros":0,"campaign.target_cpa.cpc_bid_floor_micros":0,"campaign.target_cpa.target_cpa_micros":0,"campaign.target_cpm.target_frequency_goal.target_count":0,"campaign.target_cpm.target_frequency_goal.time_unit":"UNSPECIFIED","campaign.target_impression_share.cpc_bid_ceiling_micros":0,"campaign.target_impression_share.location":"UNSPECIFIED","campaign.target_impression_share.location_fraction_micros":0,"campaign.target_roas.cpc_bid_ceiling_micros":0,"campaign.target_roas.cpc_bid_floor_micros":0,"campaign.target_roas.target_roas":0,"campaign.target_spend.cpc_bid_ceiling_micros":0,"campaign.target_spend.target_spend_micros":0,"campaign.targeting_setting.target_restrictions":["targeting_dimension: AUDIENCE\nbid_only: true\n"],"campaign.tracking_setting.tracking_url":"","campaign.tracking_url_template":"","campaign.url_custom_parameters":[],"campaign.vanity_pharma.vanity_pharma_display_url_mode":"UNSPECIFIED","campaign.vanity_pharma.vanity_pharma_text":"UNSPECIFIED","campaign.video_brand_safety_suitability":"UNSPECIFIED","metrics.clicks":0,"metrics.ctr":0,"metrics.conversions":0,"metrics.conversions_value":0,"metrics.cost_micros":0,"metrics.impressions":2,"metrics.video_views":0,"metrics.video_quartile_p100_rate":0,"metrics.active_view_cpm":0,"metrics.active_view_ctr":0,"metrics.active_view_impressions":0,"metrics.active_view_measurability":0,"metrics.active_view_measurable_cost_micros":0,"metrics.active_view_measurable_impressions":0,"metrics.active_view_viewability":0,"metrics.average_cost":0,"metrics.average_cpc":0,"metrics.average_cpm":0,"metrics.interactions":0,"metrics.interaction_event_types":"[]","metrics.value_per_conversion":0,"metrics.cost_per_conversion":0,"segments.date":"2022-05-25","segments.hour":20,"segments.ad_network_type":"SEARCH"},"emitted_at":1688730371375} +{"stream":"campaigns","data":{"campaign.accessible_bidding_strategy":"","campaign.ad_serving_optimization_status":"OPTIMIZE","campaign.advertising_channel_sub_type":"UNSPECIFIED","campaign.advertising_channel_type":"SEARCH","campaign.app_campaign_setting.app_id":"","campaign.app_campaign_setting.app_store":"UNSPECIFIED","campaign.app_campaign_setting.bidding_strategy_goal_type":"UNSPECIFIED","campaign.base_campaign":"customers/4651612872/campaigns/16820250687","campaign.bidding_strategy":"","campaign.bidding_strategy_type":"TARGET_SPEND","campaign.campaign_budget":"customers/4651612872/campaignBudgets/10695604507","campaign_budget.amount_micros":750000,"campaign.commission.commission_rate_micros":0,"campaign.dynamic_search_ads_setting.domain_name":"","campaign.dynamic_search_ads_setting.feeds":[],"campaign.dynamic_search_ads_setting.language_code":"","campaign.dynamic_search_ads_setting.use_supplied_urls_only":false,"campaign.end_date":"2037-12-30","campaign.excluded_parent_asset_field_types":[],"campaign.experiment_type":"BASE","campaign.final_url_suffix":"","campaign.frequency_caps":[],"campaign.geo_target_type_setting.negative_geo_target_type":"PRESENCE","campaign.geo_target_type_setting.positive_geo_target_type":"PRESENCE_OR_INTEREST","campaign.hotel_setting.hotel_center_id":0,"campaign.id":16820250687,"campaign.labels":[],"campaign.local_campaign_setting.location_source_type":"UNSPECIFIED","campaign.manual_cpc.enhanced_cpc_enabled":false,"campaign.manual_cpm":"","campaign.manual_cpv":"","campaign.maximize_conversion_value.target_roas":0,"campaign.maximize_conversions.target_cpa_micros":0,"campaign.name":"Website traffic-Search-15","campaign.network_settings.target_content_network":true,"campaign.network_settings.target_google_search":true,"campaign.network_settings.target_partner_search_network":false,"campaign.network_settings.target_search_network":true,"campaign.optimization_goal_setting.optimization_goal_types":[],"campaign.optimization_score":0,"campaign.payment_mode":"CLICKS","campaign.percent_cpc.cpc_bid_ceiling_micros":0,"campaign.percent_cpc.enhanced_cpc_enabled":false,"campaign.real_time_bidding_setting.opt_in":false,"campaign.resource_name":"customers/4651612872/campaigns/16820250687","campaign.selective_optimization.conversion_actions":[],"campaign.serving_status":"SERVING","campaign.shopping_setting.campaign_priority":0,"campaign.shopping_setting.enable_local":false,"campaign.shopping_setting.merchant_id":0,"campaign.shopping_setting.sales_country":"","campaign.start_date":"2022-04-08","campaign.status":"PAUSED","campaign.target_cpa.cpc_bid_ceiling_micros":0,"campaign.target_cpa.cpc_bid_floor_micros":0,"campaign.target_cpa.target_cpa_micros":0,"campaign.target_cpm.target_frequency_goal.target_count":0,"campaign.target_cpm.target_frequency_goal.time_unit":"UNSPECIFIED","campaign.target_impression_share.cpc_bid_ceiling_micros":0,"campaign.target_impression_share.location":"UNSPECIFIED","campaign.target_impression_share.location_fraction_micros":0,"campaign.target_roas.cpc_bid_ceiling_micros":0,"campaign.target_roas.cpc_bid_floor_micros":0,"campaign.target_roas.target_roas":0,"campaign.target_spend.cpc_bid_ceiling_micros":0,"campaign.target_spend.target_spend_micros":0,"campaign.targeting_setting.target_restrictions":["targeting_dimension: AUDIENCE\nbid_only: true\n"],"campaign.tracking_setting.tracking_url":"","campaign.tracking_url_template":"","campaign.url_custom_parameters":[],"campaign.vanity_pharma.vanity_pharma_display_url_mode":"UNSPECIFIED","campaign.vanity_pharma.vanity_pharma_text":"UNSPECIFIED","campaign.video_brand_safety_suitability":"UNSPECIFIED","metrics.clicks":0,"metrics.ctr":0,"metrics.conversions":0,"metrics.conversions_value":0,"metrics.cost_micros":0,"metrics.impressions":1,"metrics.video_views":0,"metrics.video_quartile_p100_rate":0,"metrics.active_view_cpm":0,"metrics.active_view_ctr":0,"metrics.active_view_impressions":0,"metrics.active_view_measurability":0,"metrics.active_view_measurable_cost_micros":0,"metrics.active_view_measurable_impressions":0,"metrics.active_view_viewability":0,"metrics.average_cost":0,"metrics.average_cpc":0,"metrics.average_cpm":0,"metrics.interactions":0,"metrics.interaction_event_types":"[]","metrics.value_per_conversion":0,"metrics.cost_per_conversion":0,"segments.date":"2022-05-25","segments.hour":22,"segments.ad_network_type":"SEARCH"},"emitted_at":1688730371377} {"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-08"},"emitted_at":1679577823324} {"stream":"ad_groups","data":{"ad_group.ad_rotation_mode":"UNSPECIFIED","ad_group.base_ad_group":"customers/4651612872/adGroups/137020701042","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":137020701042,"ad_group.labels":[],"ad_group.name":"Группа объявлений 2","ad_group.percent_cpc_bid_micros":0,"ad_group.resource_name":"customers/4651612872/adGroups/137020701042","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-09"},"emitted_at":1679577823326} {"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-09"},"emitted_at":1679577823327} diff --git a/airbyte-integrations/connectors/source-google-ads/metadata.yaml b/airbyte-integrations/connectors/source-google-ads/metadata.yaml index de5ba7d0b4eb..eae8bed8f083 100644 --- a/airbyte-integrations/connectors/source-google-ads/metadata.yaml +++ b/airbyte-integrations/connectors/source-google-ads/metadata.yaml @@ -6,7 +6,7 @@ data: connectorSubtype: api connectorType: source definitionId: 253487c0-2246-43ba-a21f-5116b20a2c50 - dockerImageTag: 0.4.3 + dockerImageTag: 0.5.0 dockerRepository: airbyte/source-google-ads githubIssueLabel: source-google-ads icon: google-adwords.svg diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/campaigns.json b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/campaigns.json index af0258bdd861..7f7a54c07ce2 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/campaigns.json +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/campaigns.json @@ -269,12 +269,57 @@ "metrics.video_quartile_p100_rate": { "type": ["null", "number"] }, + "metrics.active_view_cpm": { + "type": ["null", "number"] + }, + "metrics.active_view_ctr": { + "type": ["null", "number"] + }, + "metrics.active_view_impressions": { + "type": ["null", "integer"] + }, + "metrics.active_view_measurability": { + "type": ["null", "number"] + }, + "metrics.active_view_measurable_cost_micros": { + "type": ["null", "integer"] + }, + "metrics.active_view_measurable_impressions": { + "type": ["null", "integer"] + }, + "metrics.active_view_viewability": { + "type": ["null", "number"] + }, + "metrics.average_cost": { + "type": ["null", "number"] + }, + "metrics.average_cpc": { + "type": ["null", "number"] + }, + "metrics.average_cpm": { + "type": ["null", "number"] + }, + "metrics.interactions": { + "type": ["null", "integer"] + }, + "metrics.interaction_event_types": { + "type": ["null", "string"] + }, + "metrics.value_per_conversion": { + "type": ["null", "number"] + }, + "metrics.cost_per_conversion": { + "type": ["null", "number"] + }, "segments.date": { "type": ["null", "string"], "format": "date" }, "segments.hour": { "type": ["null", "number"] + }, + "segments.ad_network_type": { + "type": ["null", "string"] } } } diff --git a/docs/integrations/sources/google-ads.md b/docs/integrations/sources/google-ads.md index 5248caf0eb74..c7ac4d95686b 100644 --- a/docs/integrations/sources/google-ads.md +++ b/docs/integrations/sources/google-ads.md @@ -159,78 +159,79 @@ Due to a limitation in the Google Ads API which does not allow getting performan ## Changelog -| Version | Date | Pull Request | Subject | -|:---------|:-----------|:---------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------| -| `0.4.3` | 2023-07-05 | [27959](https://github.com/airbytehq/airbyte/pull/27959) | Add `audience` and `user_interest` streams | -| `0.3.3` | 2023-07-03 | [27913](https://github.com/airbytehq/airbyte/pull/27913) | Improve Google Ads exception handling (wrong customer ID) | -| `0.3.2` | 2023-06-29 | [27835](https://github.com/airbytehq/airbyte/pull/27835) | Fix bug introduced in 0.3.1: update query template | -| `0.3.1` | 2023-06-26 | [27711](https://github.com/airbytehq/airbyte/pull/27711) | Refactor date slicing; make start date inclusive | -| `0.3.0` | 2023-06-26 | [27738](https://github.com/airbytehq/airbyte/pull/27738) | License Update: Elv2 | -| `0.2.24` | 2023-06-06 | [27608](https://github.com/airbytehq/airbyte/pull/27608) | Improve Google Ads exception handling | -| `0.2.23` | 2023-06-06 | [26905](https://github.com/airbytehq/airbyte/pull/26905) | Replace deprecated `authSpecification` in the connector specification with `advancedAuth` | -| `0.2.22` | 2023-06-02 | [26948](https://github.com/airbytehq/airbyte/pull/26948) | Refactor error messages; add `pattern_descriptor` for fields in spec | -| `0.2.21` | 2023-05-30 | [25314](https://github.com/airbytehq/airbyte/pull/25314) | Add full refresh custom table `asset_group_listing_group_filter` | -| `0.2.20` | 2023-05-30 | [25624](https://github.com/airbytehq/airbyte/pull/25624) | Add `asset` Resource to full refresh custom tables (GAQL Queries) | -| `0.2.19` | 2023-05-15 | [26209](https://github.com/airbytehq/airbyte/pull/26209) | Handle Token Refresh errors as `config_error` | -| `0.2.18` | 2023-05-15 | [25947](https://github.com/airbytehq/airbyte/pull/25947) | Improve GAQL parser error message if multiple resources provided | -| `0.2.17` | 2023-05-11 | [25987](https://github.com/airbytehq/airbyte/pull/25987) | Categorized Config Errors Accurately | -| `0.2.16` | 2023-05-10 | [25965](https://github.com/airbytehq/airbyte/pull/25965) | Fix Airbyte date-time data-types | -| `0.2.14` | 2023-03-21 | [24945](https://github.com/airbytehq/airbyte/pull/24945) | For custom google query fixed schema type for "data_type: ENUM" and "is_repeated: true" to array of strings | -| `0.2.13` | 2023-03-21 | [24338](https://github.com/airbytehq/airbyte/pull/24338) | Migrate to v13 | -| `0.2.12` | 2023-03-17 | [22985](https://github.com/airbytehq/airbyte/pull/22985) | Specified date formatting in specification | -| `0.2.11` | 2023-03-13 | [23999](https://github.com/airbytehq/airbyte/pull/23999) | Fix incremental sync for Campaigns stream | -| `0.2.10` | 2023-02-11 | [22703](https://github.com/airbytehq/airbyte/pull/22703) | Add support for custom full_refresh streams | -| `0.2.9` | 2023-01-23 | [21705](https://github.com/airbytehq/airbyte/pull/21705) | Fix multibyte issue; Bump google-ads package to 19.0.0 | -| `0.2.8` | 2023-01-18 | [21517](https://github.com/airbytehq/airbyte/pull/21517) | Write fewer logs | -| `0.2.7` | 2023-01-10 | [20755](https://github.com/airbytehq/airbyte/pull/20755) | Add more logs to debug stuck syncs | -| `0.2.6` | 2022-12-22 | [20855](https://github.com/airbytehq/airbyte/pull/20855) | Retry 429 and 5xx errors | -| `0.2.5` | 2022-11-22 | [19700](https://github.com/airbytehq/airbyte/pull/19700) | Fix schema for `campaigns` stream | -| `0.2.4` | 2022-11-09 | [19208](https://github.com/airbytehq/airbyte/pull/19208) | Add TypeTransofrmer to Campaings stream to force proper type casting | -| `0.2.3` | 2022-10-17 | [18069](https://github.com/airbytehq/airbyte/pull/18069) | Add `segments.hour`, `metrics.ctr`, `metrics.conversions` and `metrics.conversions_values` fields to `campaigns` report stream | -| `0.2.2` | 2022-10-21 | [17412](https://github.com/airbytehq/airbyte/pull/17412) | Release with CDK >= 0.2.2 | -| `0.2.1` | 2022-09-29 | [17412](https://github.com/airbytehq/airbyte/pull/17412) | Always use latest CDK version | -| `0.2.0` | 2022-08-23 | [15858](https://github.com/airbytehq/airbyte/pull/15858) | Mark the `query` and `table_name` fields in `custom_queries` as required | -| `0.1.44` | 2022-07-27 | [15084](https://github.com/airbytehq/airbyte/pull/15084) | Fix data type `ad_group_criterion.topic.path` in `display_topics_performance_report` and shifted `campaigns` to non-managers streams | -| `0.1.43` | 2022-07-12 | [14614](https://github.com/airbytehq/airbyte/pull/14614) | Update API version to `v11`, update `google-ads` to 17.0.0 | -| `0.1.42` | 2022-06-08 | [13624](https://github.com/airbytehq/airbyte/pull/13624) | Update `google-ads` to 15.1.1, pin `protobuf==3.20.0` to work on MacOS M1 machines (AMD) | -| `0.1.41` | 2022-06-08 | [13618](https://github.com/airbytehq/airbyte/pull/13618) | Add missing dependency | -| `0.1.40` | 2022-06-02 | [13423](https://github.com/airbytehq/airbyte/pull/13423) | Fix the missing data [issue](https://github.com/airbytehq/airbyte/issues/12999) | -| `0.1.39` | 2022-05-18 | [12914](https://github.com/airbytehq/airbyte/pull/12914) | Fix GAQL query validation and log auth errors instead of failing the sync | -| `0.1.38` | 2022-05-12 | [12807](https://github.com/airbytehq/airbyte/pull/12807) | Documentation updates | -| `0.1.37` | 2022-05-06 | [12651](https://github.com/airbytehq/airbyte/pull/12651) | Improve integration and unit tests | -| `0.1.36` | 2022-04-19 | [12158](https://github.com/airbytehq/airbyte/pull/12158) | Fix `*_labels` streams data type | -| `0.1.35` | 2022-04-18 | [9310](https://github.com/airbytehq/airbyte/pull/9310) | Add new fields to reports | -| `0.1.34` | 2022-03-29 | [11602](https://github.com/airbytehq/airbyte/pull/11602) | Add budget amount to campaigns stream. | -| `0.1.33` | 2022-03-29 | [11513](https://github.com/airbytehq/airbyte/pull/11513) | When `end_date` is configured in the future, use today's date instead. | -| `0.1.32` | 2022-03-24 | [11371](https://github.com/airbytehq/airbyte/pull/11371) | Improve how connection check returns error messages | -| `0.1.31` | 2022-03-23 | [11301](https://github.com/airbytehq/airbyte/pull/11301) | Update docs and spec to clarify usage | -| `0.1.30` | 2022-03-23 | [11221](https://github.com/airbytehq/airbyte/pull/11221) | Add `*_labels` streams to fetch the label text rather than their IDs | -| `0.1.29` | 2022-03-22 | [10919](https://github.com/airbytehq/airbyte/pull/10919) | Fix user location report schema and add to acceptance tests | -| `0.1.28` | 2022-02-25 | [10372](https://github.com/airbytehq/airbyte/pull/10372) | Add network fields to click view stream | -| `0.1.27` | 2022-02-16 | [10315](https://github.com/airbytehq/airbyte/pull/10315) | Make `ad_group_ads` and other streams support incremental sync. | -| `0.1.26` | 2022-02-11 | [10150](https://github.com/airbytehq/airbyte/pull/10150) | Add support for multiple customer IDs. | -| `0.1.25` | 2022-02-04 | [9812](https://github.com/airbytehq/airbyte/pull/9812) | Handle `EXPIRED_PAGE_TOKEN` exception and retry with updated state. | -| `0.1.24` | 2022-02-04 | [9996](https://github.com/airbytehq/airbyte/pull/9996) | Use Google Ads API version V9. | -| `0.1.23` | 2022-01-25 | [8669](https://github.com/airbytehq/airbyte/pull/8669) | Add end date parameter in spec. | -| `0.1.22` | 2022-01-24 | [9608](https://github.com/airbytehq/airbyte/pull/9608) | Reduce stream slice date range. | -| `0.1.21` | 2021-12-28 | [9149](https://github.com/airbytehq/airbyte/pull/9149) | Update title and description | -| `0.1.20` | 2021-12-22 | [9071](https://github.com/airbytehq/airbyte/pull/9071) | Fix: Keyword schema enum | -| `0.1.19` | 2021-12-14 | [8431](https://github.com/airbytehq/airbyte/pull/8431) | Add new streams: Geographic and Keyword | -| `0.1.18` | 2021-12-09 | [8225](https://github.com/airbytehq/airbyte/pull/8225) | Include time_zone to sync. Remove streams for manager account. | -| `0.1.16` | 2021-11-22 | [8178](https://github.com/airbytehq/airbyte/pull/8178) | Clarify setup fields | -| `0.1.15` | 2021-10-07 | [6684](https://github.com/airbytehq/airbyte/pull/6684) | Add new stream `click_view` | -| `0.1.14` | 2021-10-01 | [6565](https://github.com/airbytehq/airbyte/pull/6565) | Fix OAuth Spec File | -| `0.1.13` | 2021-09-27 | [6458](https://github.com/airbytehq/airbyte/pull/6458) | Update OAuth Spec File | -| `0.1.11` | 2021-09-22 | [6373](https://github.com/airbytehq/airbyte/pull/6373) | Fix inconsistent segments.date field type across all streams | -| `0.1.10` | 2021-09-13 | [6022](https://github.com/airbytehq/airbyte/pull/6022) | Annotate Oauth2 flow initialization parameters in connector spec | -| `0.1.9` | 2021-09-07 | [5302](https://github.com/airbytehq/airbyte/pull/5302) | Add custom query stream support | -| `0.1.8` | 2021-08-03 | [5509](https://github.com/airbytehq/airbyte/pull/5509) | Allow additionalProperties in spec.json | -| `0.1.7` | 2021-08-03 | [5422](https://github.com/airbytehq/airbyte/pull/5422) | Correct query to not skip dates | -| `0.1.6` | 2021-08-03 | [5423](https://github.com/airbytehq/airbyte/pull/5423) | Added new stream UserLocationReport | -| `0.1.5` | 2021-08-03 | [5159](https://github.com/airbytehq/airbyte/pull/5159) | Add field `login_customer_id` to spec | -| `0.1.4` | 2021-07-28 | [4962](https://github.com/airbytehq/airbyte/pull/4962) | Support new Report streams | -| `0.1.3` | 2021-07-23 | [4788](https://github.com/airbytehq/airbyte/pull/4788) | Support main streams, fix bug with exception `DATE_RANGE_TOO_NARROW` for incremental streams | -| `0.1.2` | 2021-07-06 | [4539](https://github.com/airbytehq/airbyte/pull/4539) | Add `AIRBYTE_ENTRYPOINT` for Kubernetes support | -| `0.1.1` | 2021-06-23 | [4288](https://github.com/airbytehq/airbyte/pull/4288) | Fix `Bugfix: Correctly declare required parameters` | +| Version | Date | Pull Request | Subject | +|:---------|:-----------|:---------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------| +| `0.5.0` | 2023-07-07 | [28042](https://github.com/airbytehq/airbyte/pull/28042) | Add metrics & segment to `Campaigns` stream | +| `0.4.3` | 2023-07-05 | [27959](https://github.com/airbytehq/airbyte/pull/27959) | Add `audience` and `user_interest` streams | +| `0.3.3` | 2023-07-03 | [27913](https://github.com/airbytehq/airbyte/pull/27913) | Improve Google Ads exception handling (wrong customer ID) | +| `0.3.2` | 2023-06-29 | [27835](https://github.com/airbytehq/airbyte/pull/27835) | Fix bug introduced in 0.3.1: update query template | +| `0.3.1` | 2023-06-26 | [27711](https://github.com/airbytehq/airbyte/pull/27711) | Refactor date slicing; make start date inclusive | +| `0.3.0` | 2023-06-26 | [27738](https://github.com/airbytehq/airbyte/pull/27738) | License Update: Elv2 | +| `0.2.24` | 2023-06-06 | [27608](https://github.com/airbytehq/airbyte/pull/27608) | Improve Google Ads exception handling | +| `0.2.23` | 2023-06-06 | [26905](https://github.com/airbytehq/airbyte/pull/26905) | Replace deprecated `authSpecification` in the connector specification with `advancedAuth` | +| `0.2.22` | 2023-06-02 | [26948](https://github.com/airbytehq/airbyte/pull/26948) | Refactor error messages; add `pattern_descriptor` for fields in spec | +| `0.2.21` | 2023-05-30 | [25314](https://github.com/airbytehq/airbyte/pull/25314) | Add full refresh custom table `asset_group_listing_group_filter` | +| `0.2.20` | 2023-05-30 | [25624](https://github.com/airbytehq/airbyte/pull/25624) | Add `asset` Resource to full refresh custom tables (GAQL Queries) | +| `0.2.19` | 2023-05-15 | [26209](https://github.com/airbytehq/airbyte/pull/26209) | Handle Token Refresh errors as `config_error` | +| `0.2.18` | 2023-05-15 | [25947](https://github.com/airbytehq/airbyte/pull/25947) | Improve GAQL parser error message if multiple resources provided | +| `0.2.17` | 2023-05-11 | [25987](https://github.com/airbytehq/airbyte/pull/25987) | Categorized Config Errors Accurately | +| `0.2.16` | 2023-05-10 | [25965](https://github.com/airbytehq/airbyte/pull/25965) | Fix Airbyte date-time data-types | +| `0.2.14` | 2023-03-21 | [24945](https://github.com/airbytehq/airbyte/pull/24945) | For custom google query fixed schema type for "data_type: ENUM" and "is_repeated: true" to array of strings | +| `0.2.13` | 2023-03-21 | [24338](https://github.com/airbytehq/airbyte/pull/24338) | Migrate to v13 | +| `0.2.12` | 2023-03-17 | [22985](https://github.com/airbytehq/airbyte/pull/22985) | Specified date formatting in specification | +| `0.2.11` | 2023-03-13 | [23999](https://github.com/airbytehq/airbyte/pull/23999) | Fix incremental sync for Campaigns stream | +| `0.2.10` | 2023-02-11 | [22703](https://github.com/airbytehq/airbyte/pull/22703) | Add support for custom full_refresh streams | +| `0.2.9` | 2023-01-23 | [21705](https://github.com/airbytehq/airbyte/pull/21705) | Fix multibyte issue; Bump google-ads package to 19.0.0 | +| `0.2.8` | 2023-01-18 | [21517](https://github.com/airbytehq/airbyte/pull/21517) | Write fewer logs | +| `0.2.7` | 2023-01-10 | [20755](https://github.com/airbytehq/airbyte/pull/20755) | Add more logs to debug stuck syncs | +| `0.2.6` | 2022-12-22 | [20855](https://github.com/airbytehq/airbyte/pull/20855) | Retry 429 and 5xx errors | +| `0.2.5` | 2022-11-22 | [19700](https://github.com/airbytehq/airbyte/pull/19700) | Fix schema for `campaigns` stream | +| `0.2.4` | 2022-11-09 | [19208](https://github.com/airbytehq/airbyte/pull/19208) | Add TypeTransofrmer to Campaings stream to force proper type casting | +| `0.2.3` | 2022-10-17 | [18069](https://github.com/airbytehq/airbyte/pull/18069) | Add `segments.hour`, `metrics.ctr`, `metrics.conversions` and `metrics.conversions_values` fields to `campaigns` report stream | +| `0.2.2` | 2022-10-21 | [17412](https://github.com/airbytehq/airbyte/pull/17412) | Release with CDK >= 0.2.2 | +| `0.2.1` | 2022-09-29 | [17412](https://github.com/airbytehq/airbyte/pull/17412) | Always use latest CDK version | +| `0.2.0` | 2022-08-23 | [15858](https://github.com/airbytehq/airbyte/pull/15858) | Mark the `query` and `table_name` fields in `custom_queries` as required | +| `0.1.44` | 2022-07-27 | [15084](https://github.com/airbytehq/airbyte/pull/15084) | Fix data type `ad_group_criterion.topic.path` in `display_topics_performance_report` and shifted `campaigns` to non-managers streams | +| `0.1.43` | 2022-07-12 | [14614](https://github.com/airbytehq/airbyte/pull/14614) | Update API version to `v11`, update `google-ads` to 17.0.0 | +| `0.1.42` | 2022-06-08 | [13624](https://github.com/airbytehq/airbyte/pull/13624) | Update `google-ads` to 15.1.1, pin `protobuf==3.20.0` to work on MacOS M1 machines (AMD) | +| `0.1.41` | 2022-06-08 | [13618](https://github.com/airbytehq/airbyte/pull/13618) | Add missing dependency | +| `0.1.40` | 2022-06-02 | [13423](https://github.com/airbytehq/airbyte/pull/13423) | Fix the missing data [issue](https://github.com/airbytehq/airbyte/issues/12999) | +| `0.1.39` | 2022-05-18 | [12914](https://github.com/airbytehq/airbyte/pull/12914) | Fix GAQL query validation and log auth errors instead of failing the sync | +| `0.1.38` | 2022-05-12 | [12807](https://github.com/airbytehq/airbyte/pull/12807) | Documentation updates | +| `0.1.37` | 2022-05-06 | [12651](https://github.com/airbytehq/airbyte/pull/12651) | Improve integration and unit tests | +| `0.1.36` | 2022-04-19 | [12158](https://github.com/airbytehq/airbyte/pull/12158) | Fix `*_labels` streams data type | +| `0.1.35` | 2022-04-18 | [9310](https://github.com/airbytehq/airbyte/pull/9310) | Add new fields to reports | +| `0.1.34` | 2022-03-29 | [11602](https://github.com/airbytehq/airbyte/pull/11602) | Add budget amount to campaigns stream. | +| `0.1.33` | 2022-03-29 | [11513](https://github.com/airbytehq/airbyte/pull/11513) | When `end_date` is configured in the future, use today's date instead. | +| `0.1.32` | 2022-03-24 | [11371](https://github.com/airbytehq/airbyte/pull/11371) | Improve how connection check returns error messages | +| `0.1.31` | 2022-03-23 | [11301](https://github.com/airbytehq/airbyte/pull/11301) | Update docs and spec to clarify usage | +| `0.1.30` | 2022-03-23 | [11221](https://github.com/airbytehq/airbyte/pull/11221) | Add `*_labels` streams to fetch the label text rather than their IDs | +| `0.1.29` | 2022-03-22 | [10919](https://github.com/airbytehq/airbyte/pull/10919) | Fix user location report schema and add to acceptance tests | +| `0.1.28` | 2022-02-25 | [10372](https://github.com/airbytehq/airbyte/pull/10372) | Add network fields to click view stream | +| `0.1.27` | 2022-02-16 | [10315](https://github.com/airbytehq/airbyte/pull/10315) | Make `ad_group_ads` and other streams support incremental sync. | +| `0.1.26` | 2022-02-11 | [10150](https://github.com/airbytehq/airbyte/pull/10150) | Add support for multiple customer IDs. | +| `0.1.25` | 2022-02-04 | [9812](https://github.com/airbytehq/airbyte/pull/9812) | Handle `EXPIRED_PAGE_TOKEN` exception and retry with updated state. | +| `0.1.24` | 2022-02-04 | [9996](https://github.com/airbytehq/airbyte/pull/9996) | Use Google Ads API version V9. | +| `0.1.23` | 2022-01-25 | [8669](https://github.com/airbytehq/airbyte/pull/8669) | Add end date parameter in spec. | +| `0.1.22` | 2022-01-24 | [9608](https://github.com/airbytehq/airbyte/pull/9608) | Reduce stream slice date range. | +| `0.1.21` | 2021-12-28 | [9149](https://github.com/airbytehq/airbyte/pull/9149) | Update title and description | +| `0.1.20` | 2021-12-22 | [9071](https://github.com/airbytehq/airbyte/pull/9071) | Fix: Keyword schema enum | +| `0.1.19` | 2021-12-14 | [8431](https://github.com/airbytehq/airbyte/pull/8431) | Add new streams: Geographic and Keyword | +| `0.1.18` | 2021-12-09 | [8225](https://github.com/airbytehq/airbyte/pull/8225) | Include time_zone to sync. Remove streams for manager account. | +| `0.1.16` | 2021-11-22 | [8178](https://github.com/airbytehq/airbyte/pull/8178) | Clarify setup fields | +| `0.1.15` | 2021-10-07 | [6684](https://github.com/airbytehq/airbyte/pull/6684) | Add new stream `click_view` | +| `0.1.14` | 2021-10-01 | [6565](https://github.com/airbytehq/airbyte/pull/6565) | Fix OAuth Spec File | +| `0.1.13` | 2021-09-27 | [6458](https://github.com/airbytehq/airbyte/pull/6458) | Update OAuth Spec File | +| `0.1.11` | 2021-09-22 | [6373](https://github.com/airbytehq/airbyte/pull/6373) | Fix inconsistent segments.date field type across all streams | +| `0.1.10` | 2021-09-13 | [6022](https://github.com/airbytehq/airbyte/pull/6022) | Annotate Oauth2 flow initialization parameters in connector spec | +| `0.1.9` | 2021-09-07 | [5302](https://github.com/airbytehq/airbyte/pull/5302) | Add custom query stream support | +| `0.1.8` | 2021-08-03 | [5509](https://github.com/airbytehq/airbyte/pull/5509) | Allow additionalProperties in spec.json | +| `0.1.7` | 2021-08-03 | [5422](https://github.com/airbytehq/airbyte/pull/5422) | Correct query to not skip dates | +| `0.1.6` | 2021-08-03 | [5423](https://github.com/airbytehq/airbyte/pull/5423) | Added new stream UserLocationReport | +| `0.1.5` | 2021-08-03 | [5159](https://github.com/airbytehq/airbyte/pull/5159) | Add field `login_customer_id` to spec | +| `0.1.4` | 2021-07-28 | [4962](https://github.com/airbytehq/airbyte/pull/4962) | Support new Report streams | +| `0.1.3` | 2021-07-23 | [4788](https://github.com/airbytehq/airbyte/pull/4788) | Support main streams, fix bug with exception `DATE_RANGE_TOO_NARROW` for incremental streams | +| `0.1.2` | 2021-07-06 | [4539](https://github.com/airbytehq/airbyte/pull/4539) | Add `AIRBYTE_ENTRYPOINT` for Kubernetes support | +| `0.1.1` | 2021-06-23 | [4288](https://github.com/airbytehq/airbyte/pull/4288) | Fix `Bugfix: Correctly declare required parameters` | From 84bfa75e325e8301f572e2e87b096033d8c3d43f Mon Sep 17 00:00:00 2001 From: Arsen Losenko <20901439+arsenlosenko@users.noreply.github.com> Date: Mon, 10 Jul 2023 14:33:07 +0300 Subject: [PATCH 06/63] Source Mixpanel: specify ignored fields for streams funnels and revenue (#28041) --- .../connectors/source-mixpanel/acceptance-test-config.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/airbyte-integrations/connectors/source-mixpanel/acceptance-test-config.yml b/airbyte-integrations/connectors/source-mixpanel/acceptance-test-config.yml index 5cf66816e63f..94aa83f8171e 100644 --- a/airbyte-integrations/connectors/source-mixpanel/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-mixpanel/acceptance-test-config.yml @@ -34,6 +34,13 @@ acceptance_tests: bypass_reason: "Data expired too often" - name: annotations bypass_reason: "Data expired too often" + ignored_fields: + funnels: + - name: date + bypass_reason: "Data changes too often" + revenue: + - name: date + bypass_reason: "Data changes too often" full_refresh: tests: - config_path: "secrets/config_old.json" From 1dba5b1c6e189bcbf72951394ae133bcca0a1cdf Mon Sep 17 00:00:00 2001 From: Artem Inzhyyants <36314070+artem1205@users.noreply.github.com> Date: Mon, 10 Jul 2023 17:03:05 +0200 Subject: [PATCH 07/63] Source Google Ads: Add metrics to `Keyword Report` (#28049) * Source Google Ads: extend keywords schema metrics * Source Google Ads: extend keywords schema metrics * Source Google Ads: update keyword_report schema * Source Google Ads: bump version + expected records * Source Google Ads: fix schema --- .../connectors/source-google-ads/Dockerfile | 2 +- .../integration_tests/expected_records.jsonl | 20 +++++------ .../source-google-ads/metadata.yaml | 2 +- .../schemas/keyword_report.json | 33 +++++++++++++++++++ docs/integrations/sources/google-ads.md | 1 + 5 files changed, 46 insertions(+), 12 deletions(-) diff --git a/airbyte-integrations/connectors/source-google-ads/Dockerfile b/airbyte-integrations/connectors/source-google-ads/Dockerfile index 8bf43542f46a..968e56fb06e8 100644 --- a/airbyte-integrations/connectors/source-google-ads/Dockerfile +++ b/airbyte-integrations/connectors/source-google-ads/Dockerfile @@ -13,5 +13,5 @@ COPY main.py ./ ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=0.5.0 +LABEL io.airbyte.version=0.6.0 LABEL io.airbyte.name=airbyte/source-google-ads diff --git a/airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl index 50deed712fe3..328bd29ca93f 100644 --- a/airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl @@ -18,16 +18,16 @@ {"stream": "geographic_report", "data": {"customer.descriptive_name": "", "geographic_view.country_criterion_id": 2840, "geographic_view.location_type": "LOCATION_OF_PRESENCE", "ad_group.id": 137051662444, "segments.date": "2022-04-09"}, "emitted_at": 1671617280447} {"stream": "geographic_report", "data": {"customer.descriptive_name": "", "geographic_view.country_criterion_id": 2840, "geographic_view.location_type": "AREA_OF_INTEREST", "ad_group.id": 137020701042, "segments.date": "2022-04-10"}, "emitted_at": 1671617280448} {"stream": "geographic_report", "data": {"customer.descriptive_name": "", "geographic_view.country_criterion_id": 2124, "geographic_view.location_type": "LOCATION_OF_PRESENCE", "ad_group.id": 137020701042, "segments.date": "2022-04-10"}, "emitted_at": 1671617280450} -{"stream": "keyword_report", "data": {"customer.descriptive_name": "", "ad_group.id": 123273719655, "ad_group_criterion.type": "KEYWORD", "ad_group_criterion.keyword.text": "open source analytics", "ad_group_criterion.negative": false, "ad_group_criterion.keyword.match_type": "BROAD", "metrics.historical_quality_score": 1, "metrics.ctr": 0.0, "segments.date": "2022-02-16", "campaign.bidding_strategy_type": "TARGET_SPEND", "metrics.clicks": 0, "metrics.cost_micros": 0, "metrics.impressions": 0, "ad_group_criterion.criterion_id": 1732729676}, "emitted_at": 1671617284427} -{"stream": "keyword_report", "data": {"customer.descriptive_name": "", "ad_group.id": 123273719655, "ad_group_criterion.type": "KEYWORD", "ad_group_criterion.keyword.text": "etl pipeline", "ad_group_criterion.negative": false, "ad_group_criterion.keyword.match_type": "BROAD", "metrics.historical_quality_score": 3, "metrics.ctr": 0.0, "segments.date": "2022-02-16", "campaign.bidding_strategy_type": "TARGET_SPEND", "metrics.clicks": 0, "metrics.cost_micros": 0, "metrics.impressions": 0, "ad_group_criterion.criterion_id": 297585172071}, "emitted_at": 1671617284428} -{"stream": "keyword_report", "data": {"customer.descriptive_name": "", "ad_group.id": 123273719655, "ad_group_criterion.type": "KEYWORD", "ad_group_criterion.keyword.text": "open source etl", "ad_group_criterion.negative": false, "ad_group_criterion.keyword.match_type": "BROAD", "metrics.historical_quality_score": 7, "metrics.ctr": 0.0, "segments.date": "2022-02-16", "campaign.bidding_strategy_type": "TARGET_SPEND", "metrics.clicks": 0, "metrics.cost_micros": 0, "metrics.impressions": 0, "ad_group_criterion.criterion_id": 298270671583}, "emitted_at": 1671617284429} -{"stream": "keyword_report", "data": {"customer.descriptive_name": "", "ad_group.id": 123273719655, "ad_group_criterion.type": "KEYWORD", "ad_group_criterion.keyword.text": "data connectors", "ad_group_criterion.negative": false, "ad_group_criterion.keyword.match_type": "BROAD", "metrics.historical_quality_score": 5, "metrics.ctr": 0.0, "segments.date": "2022-02-16", "campaign.bidding_strategy_type": "TARGET_SPEND", "metrics.clicks": 0, "metrics.cost_micros": 0, "metrics.impressions": 0, "ad_group_criterion.criterion_id": 303376179543}, "emitted_at": 1671617284429} -{"stream": "keyword_report", "data": {"customer.descriptive_name": "", "ad_group.id": 123273719655, "ad_group_criterion.type": "KEYWORD", "ad_group_criterion.keyword.text": "open source analytics", "ad_group_criterion.negative": false, "ad_group_criterion.keyword.match_type": "BROAD", "metrics.historical_quality_score": 1, "metrics.ctr": 0.0, "segments.date": "2022-02-17", "campaign.bidding_strategy_type": "TARGET_SPEND", "metrics.clicks": 0, "metrics.cost_micros": 0, "metrics.impressions": 0, "ad_group_criterion.criterion_id": 1732729676}, "emitted_at": 1671617284430} -{"stream": "keyword_report", "data": {"customer.descriptive_name": "", "ad_group.id": 123273719655, "ad_group_criterion.type": "KEYWORD", "ad_group_criterion.keyword.text": "etl pipeline", "ad_group_criterion.negative": false, "ad_group_criterion.keyword.match_type": "BROAD", "metrics.historical_quality_score": 3, "metrics.ctr": 0.0, "segments.date": "2022-02-17", "campaign.bidding_strategy_type": "TARGET_SPEND", "metrics.clicks": 0, "metrics.cost_micros": 0, "metrics.impressions": 0, "ad_group_criterion.criterion_id": 297585172071}, "emitted_at": 1671617284430} -{"stream": "keyword_report", "data": {"customer.descriptive_name": "", "ad_group.id": 123273719655, "ad_group_criterion.type": "KEYWORD", "ad_group_criterion.keyword.text": "open source etl", "ad_group_criterion.negative": false, "ad_group_criterion.keyword.match_type": "BROAD", "metrics.historical_quality_score": 7, "metrics.ctr": 0.0, "segments.date": "2022-02-17", "campaign.bidding_strategy_type": "TARGET_SPEND", "metrics.clicks": 0, "metrics.cost_micros": 0, "metrics.impressions": 0, "ad_group_criterion.criterion_id": 298270671583}, "emitted_at": 1671617284431} -{"stream": "keyword_report", "data": {"customer.descriptive_name": "", "ad_group.id": 123273719655, "ad_group_criterion.type": "KEYWORD", "ad_group_criterion.keyword.text": "data connectors", "ad_group_criterion.negative": false, "ad_group_criterion.keyword.match_type": "BROAD", "metrics.historical_quality_score": 5, "metrics.ctr": 0.0, "segments.date": "2022-02-17", "campaign.bidding_strategy_type": "TARGET_SPEND", "metrics.clicks": 0, "metrics.cost_micros": 0, "metrics.impressions": 0, "ad_group_criterion.criterion_id": 303376179543}, "emitted_at": 1671617284431} -{"stream": "keyword_report", "data": {"customer.descriptive_name": "", "ad_group.id": 123273719655, "ad_group_criterion.type": "KEYWORD", "ad_group_criterion.keyword.text": "open source analytics", "ad_group_criterion.negative": false, "ad_group_criterion.keyword.match_type": "BROAD", "metrics.historical_quality_score": 1, "metrics.ctr": 0.0, "segments.date": "2022-02-18", "campaign.bidding_strategy_type": "TARGET_SPEND", "metrics.clicks": 0, "metrics.cost_micros": 0, "metrics.impressions": 0, "ad_group_criterion.criterion_id": 1732729676}, "emitted_at": 1671617284432} -{"stream": "keyword_report", "data": {"customer.descriptive_name": "", "ad_group.id": 123273719655, "ad_group_criterion.type": "KEYWORD", "ad_group_criterion.keyword.text": "etl pipeline", "ad_group_criterion.negative": false, "ad_group_criterion.keyword.match_type": "BROAD", "metrics.historical_quality_score": 3, "metrics.ctr": 0.0, "segments.date": "2022-02-18", "campaign.bidding_strategy_type": "TARGET_SPEND", "metrics.clicks": 0, "metrics.cost_micros": 0, "metrics.impressions": 0, "ad_group_criterion.criterion_id": 297585172071}, "emitted_at": 1671617284432} +{"stream":"keyword_report","data":{"customer.descriptive_name":"","ad_group.id":123273719655,"ad_group_criterion.type":"KEYWORD","ad_group_criterion.keyword.text":"open source analytics","ad_group_criterion.negative":false,"ad_group_criterion.keyword.match_type":"BROAD","metrics.historical_quality_score":1,"metrics.ctr":0,"segments.date":"2022-02-15","campaign.bidding_strategy_type":"TARGET_SPEND","metrics.clicks":0,"metrics.cost_micros":0,"metrics.impressions":0,"metrics.active_view_impressions":0,"metrics.active_view_measurability":0,"metrics.active_view_measurable_cost_micros":0,"metrics.active_view_measurable_impressions":0,"metrics.active_view_viewability":0,"metrics.conversions":0,"metrics.conversions_value":0,"metrics.interactions":0,"metrics.interaction_event_types":[],"metrics.view_through_conversions":0,"ad_group_criterion.criterion_id":1732729676},"emitted_at":1688988446821} +{"stream":"keyword_report","data":{"customer.descriptive_name":"","ad_group.id":123273719655,"ad_group_criterion.type":"KEYWORD","ad_group_criterion.keyword.text":"etl pipeline","ad_group_criterion.negative":false,"ad_group_criterion.keyword.match_type":"BROAD","metrics.historical_quality_score":3,"metrics.ctr":0,"segments.date":"2022-02-15","campaign.bidding_strategy_type":"TARGET_SPEND","metrics.clicks":0,"metrics.cost_micros":0,"metrics.impressions":0,"metrics.active_view_impressions":0,"metrics.active_view_measurability":0,"metrics.active_view_measurable_cost_micros":0,"metrics.active_view_measurable_impressions":0,"metrics.active_view_viewability":0,"metrics.conversions":0,"metrics.conversions_value":0,"metrics.interactions":0,"metrics.interaction_event_types":[],"metrics.view_through_conversions":0,"ad_group_criterion.criterion_id":297585172071},"emitted_at":1688988446824} +{"stream":"keyword_report","data":{"customer.descriptive_name":"","ad_group.id":123273719655,"ad_group_criterion.type":"KEYWORD","ad_group_criterion.keyword.text":"open source etl","ad_group_criterion.negative":false,"ad_group_criterion.keyword.match_type":"BROAD","metrics.historical_quality_score":7,"metrics.ctr":0,"segments.date":"2022-02-15","campaign.bidding_strategy_type":"TARGET_SPEND","metrics.clicks":0,"metrics.cost_micros":0,"metrics.impressions":0,"metrics.active_view_impressions":0,"metrics.active_view_measurability":0,"metrics.active_view_measurable_cost_micros":0,"metrics.active_view_measurable_impressions":0,"metrics.active_view_viewability":0,"metrics.conversions":0,"metrics.conversions_value":0,"metrics.interactions":0,"metrics.interaction_event_types":[],"metrics.view_through_conversions":0,"ad_group_criterion.criterion_id":298270671583},"emitted_at":1688988446825} +{"stream":"keyword_report","data":{"customer.descriptive_name":"","ad_group.id":123273719655,"ad_group_criterion.type":"KEYWORD","ad_group_criterion.keyword.text":"data connectors","ad_group_criterion.negative":false,"ad_group_criterion.keyword.match_type":"BROAD","metrics.historical_quality_score":5,"metrics.ctr":0,"segments.date":"2022-02-15","campaign.bidding_strategy_type":"TARGET_SPEND","metrics.clicks":0,"metrics.cost_micros":0,"metrics.impressions":0,"metrics.active_view_impressions":0,"metrics.active_view_measurability":0,"metrics.active_view_measurable_cost_micros":0,"metrics.active_view_measurable_impressions":0,"metrics.active_view_viewability":0,"metrics.conversions":0,"metrics.conversions_value":0,"metrics.interactions":0,"metrics.interaction_event_types":[],"metrics.view_through_conversions":0,"ad_group_criterion.criterion_id":303376179543},"emitted_at":1688988446826} +{"stream":"keyword_report","data":{"customer.descriptive_name":"","ad_group.id":123273719655,"ad_group_criterion.type":"KEYWORD","ad_group_criterion.keyword.text":"open source analytics","ad_group_criterion.negative":false,"ad_group_criterion.keyword.match_type":"BROAD","metrics.historical_quality_score":1,"metrics.ctr":0,"segments.date":"2022-02-16","campaign.bidding_strategy_type":"TARGET_SPEND","metrics.clicks":0,"metrics.cost_micros":0,"metrics.impressions":0,"metrics.active_view_impressions":0,"metrics.active_view_measurability":0,"metrics.active_view_measurable_cost_micros":0,"metrics.active_view_measurable_impressions":0,"metrics.active_view_viewability":0,"metrics.conversions":0,"metrics.conversions_value":0,"metrics.interactions":0,"metrics.interaction_event_types":[],"metrics.view_through_conversions":0,"ad_group_criterion.criterion_id":1732729676},"emitted_at":1688988446827} +{"stream":"keyword_report","data":{"customer.descriptive_name":"","ad_group.id":123273719655,"ad_group_criterion.type":"KEYWORD","ad_group_criterion.keyword.text":"etl pipeline","ad_group_criterion.negative":false,"ad_group_criterion.keyword.match_type":"BROAD","metrics.historical_quality_score":3,"metrics.ctr":0,"segments.date":"2022-02-16","campaign.bidding_strategy_type":"TARGET_SPEND","metrics.clicks":0,"metrics.cost_micros":0,"metrics.impressions":0,"metrics.active_view_impressions":0,"metrics.active_view_measurability":0,"metrics.active_view_measurable_cost_micros":0,"metrics.active_view_measurable_impressions":0,"metrics.active_view_viewability":0,"metrics.conversions":0,"metrics.conversions_value":0,"metrics.interactions":0,"metrics.interaction_event_types":[],"metrics.view_through_conversions":0,"ad_group_criterion.criterion_id":297585172071},"emitted_at":1688988446827} +{"stream":"keyword_report","data":{"customer.descriptive_name":"","ad_group.id":123273719655,"ad_group_criterion.type":"KEYWORD","ad_group_criterion.keyword.text":"open source etl","ad_group_criterion.negative":false,"ad_group_criterion.keyword.match_type":"BROAD","metrics.historical_quality_score":7,"metrics.ctr":0,"segments.date":"2022-02-16","campaign.bidding_strategy_type":"TARGET_SPEND","metrics.clicks":0,"metrics.cost_micros":0,"metrics.impressions":0,"metrics.active_view_impressions":0,"metrics.active_view_measurability":0,"metrics.active_view_measurable_cost_micros":0,"metrics.active_view_measurable_impressions":0,"metrics.active_view_viewability":0,"metrics.conversions":0,"metrics.conversions_value":0,"metrics.interactions":0,"metrics.interaction_event_types":[],"metrics.view_through_conversions":0,"ad_group_criterion.criterion_id":298270671583},"emitted_at":1688988446828} +{"stream":"keyword_report","data":{"customer.descriptive_name":"","ad_group.id":123273719655,"ad_group_criterion.type":"KEYWORD","ad_group_criterion.keyword.text":"data connectors","ad_group_criterion.negative":false,"ad_group_criterion.keyword.match_type":"BROAD","metrics.historical_quality_score":5,"metrics.ctr":0,"segments.date":"2022-02-16","campaign.bidding_strategy_type":"TARGET_SPEND","metrics.clicks":0,"metrics.cost_micros":0,"metrics.impressions":0,"metrics.active_view_impressions":0,"metrics.active_view_measurability":0,"metrics.active_view_measurable_cost_micros":0,"metrics.active_view_measurable_impressions":0,"metrics.active_view_viewability":0,"metrics.conversions":0,"metrics.conversions_value":0,"metrics.interactions":0,"metrics.interaction_event_types":[],"metrics.view_through_conversions":0,"ad_group_criterion.criterion_id":303376179543},"emitted_at":1688988446829} +{"stream":"keyword_report","data":{"customer.descriptive_name":"","ad_group.id":123273719655,"ad_group_criterion.type":"KEYWORD","ad_group_criterion.keyword.text":"open source analytics","ad_group_criterion.negative":false,"ad_group_criterion.keyword.match_type":"BROAD","metrics.historical_quality_score":1,"metrics.ctr":0,"segments.date":"2022-02-17","campaign.bidding_strategy_type":"TARGET_SPEND","metrics.clicks":0,"metrics.cost_micros":0,"metrics.impressions":0,"metrics.active_view_impressions":0,"metrics.active_view_measurability":0,"metrics.active_view_measurable_cost_micros":0,"metrics.active_view_measurable_impressions":0,"metrics.active_view_viewability":0,"metrics.conversions":0,"metrics.conversions_value":0,"metrics.interactions":0,"metrics.interaction_event_types":[],"metrics.view_through_conversions":0,"ad_group_criterion.criterion_id":1732729676},"emitted_at":1688988446829} +{"stream":"keyword_report","data":{"customer.descriptive_name":"","ad_group.id":137020701042,"ad_group_criterion.type":"KEYWORD","ad_group_criterion.keyword.text":"airbytes","ad_group_criterion.negative":false,"ad_group_criterion.keyword.match_type":"BROAD","metrics.historical_quality_score":10,"metrics.ctr":0.06666666666666667,"segments.date":"2022-05-14","campaign.bidding_strategy_type":"TARGET_SPEND","metrics.clicks":2,"metrics.cost_micros":50000,"metrics.impressions":30,"metrics.active_view_impressions":0,"metrics.active_view_measurability":0,"metrics.active_view_measurable_cost_micros":0,"metrics.active_view_measurable_impressions":0,"metrics.active_view_viewability":0,"metrics.conversions":0,"metrics.conversions_value":0,"metrics.interactions":2,"metrics.interaction_event_types":["InteractionEventType.CLICK"],"metrics.view_through_conversions":0,"ad_group_criterion.criterion_id":423065099654},"emitted_at":1688988450597} {"stream": "display_keyword_performance_report", "data": {"customer.currency_code": "USD", "customer.descriptive_name": "", "customer.time_zone": "America/Los_Angeles", "metrics.active_view_cpm": 10012000.0, "metrics.active_view_ctr": 0.0, "metrics.active_view_impressions": 1, "metrics.active_view_measurability": 1.0, "metrics.active_view_measurable_cost_micros": 10012, "metrics.active_view_measurable_impressions": 1, "metrics.active_view_viewability": 1.0, "ad_group.id": 143992182864, "ad_group.name": "Video Non-skippable - 2022-05-30", "ad_group.status": "ENABLED", "segments.ad_network_type": "YOUTUBE_WATCH", "metrics.all_conversions_from_interactions_rate": 0.0, "metrics.all_conversions_value": 0.0, "metrics.all_conversions": 0.0, "metrics.average_cost": 0.0, "metrics.average_cpc": 0.0, "metrics.average_cpe": 0.0, "metrics.average_cpm": 10012000.0, "metrics.average_cpv": 0.0, "ad_group.base_ad_group": "customers/4651612872/adGroups/143992182864", "campaign.base_campaign": "customers/4651612872/campaigns/17354032686", "campaign.bidding_strategy": "", "campaign.bidding_strategy_type": "TARGET_CPM", "campaign.id": 17354032686, "campaign.name": "Video Non-skippable - 2022-05-30", "campaign.status": "ENABLED", "metrics.clicks": 0, "metrics.conversions_from_interactions_rate": 0.0, "metrics.conversions_value": 0.0, "metrics.conversions": 0.0, "metrics.cost_micros": 10012, "metrics.cost_per_all_conversions": 0.0, "metrics.cost_per_conversion": 0.0, "ad_group_criterion.effective_cpc_bid_micros": 10000, "ad_group_criterion.effective_cpc_bid_source": "AD_GROUP", "ad_group_criterion.effective_cpm_bid_micros": 10000, "ad_group_criterion.effective_cpm_bid_source": "AD_GROUP", "ad_group_criterion.effective_cpv_bid_micros": 10000, "ad_group_criterion.effective_cpv_bid_source": "AD_GROUP", "ad_group_criterion.keyword.text": "big data software", "metrics.cross_device_conversions": 0.0, "metrics.ctr": 0.0, "segments.day_of_week": "TUESDAY", "segments.device": "MOBILE", "metrics.engagement_rate": 0.0, "metrics.engagements": 0, "customer.id": 4651612872, "ad_group_criterion.final_mobile_urls": [], "ad_group_criterion.final_urls": [], "metrics.gmail_forwards": 0, "metrics.gmail_saves": 0, "metrics.gmail_secondary_clicks": 0, "ad_group_criterion.criterion_id": 26160872903, "metrics.impressions": 1, "metrics.interaction_rate": 0.0, "metrics.interaction_event_types": [], "metrics.interactions": 0, "ad_group_criterion.negative": false, "ad_group.targeting_setting.target_restrictions": ["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", "targeting_dimension: TOPIC\nbid_only: false\n"], "segments.month": "2022-05-01", "segments.quarter": "2022-04-01", "ad_group_criterion.status": "ENABLED", "ad_group_criterion.tracking_url_template": "", "ad_group_criterion.keyword.match_type": "BROAD", "ad_group_criterion.url_custom_parameters": [], "metrics.value_per_all_conversions": 0.0, "metrics.value_per_conversion": 0.0, "metrics.video_quartile_p100_rate": 0.0, "metrics.video_quartile_p25_rate": 0.0, "metrics.video_quartile_p50_rate": 0.0, "metrics.video_quartile_p75_rate": 0.0, "metrics.video_view_rate": 0.0, "metrics.video_views": 0, "metrics.view_through_conversions": 0, "segments.week": "2022-05-30", "segments.year": 2022, "segments.date": "2022-05-31"}, "emitted_at": 1671617298755} {"stream": "campaign_labels", "data": {"campaign.resource_name": "customers/4651612872/campaigns/12124071339", "campaign_label.resource_name": "customers/4651612872/campaignLabels/12124071339~21585034471", "label.name": "edgao-example-label", "label.resource_name": "customers/4651612872/labels/21585034471"}, "emitted_at": 1671617384908} {"stream": "campaign_labels", "data": {"campaign.resource_name": "customers/4651612872/campaigns/13284356762", "campaign_label.resource_name": "customers/4651612872/campaignLabels/13284356762~21585034471", "label.name": "edgao-example-label", "label.resource_name": "customers/4651612872/labels/21585034471"}, "emitted_at": 1671617384909} diff --git a/airbyte-integrations/connectors/source-google-ads/metadata.yaml b/airbyte-integrations/connectors/source-google-ads/metadata.yaml index eae8bed8f083..ac969b74d91b 100644 --- a/airbyte-integrations/connectors/source-google-ads/metadata.yaml +++ b/airbyte-integrations/connectors/source-google-ads/metadata.yaml @@ -6,7 +6,7 @@ data: connectorSubtype: api connectorType: source definitionId: 253487c0-2246-43ba-a21f-5116b20a2c50 - dockerImageTag: 0.5.0 + dockerImageTag: 0.6.0 dockerRepository: airbyte/source-google-ads githubIssueLabel: source-google-ads icon: google-adwords.svg diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/keyword_report.json b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/keyword_report.json index 4116c2ba57df..6ce4e2a4de4c 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/keyword_report.json +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/keyword_report.json @@ -80,6 +80,39 @@ "metrics.impressions": { "type": ["null", "integer"] }, + "metrics.active_view_impressions": { + "type": ["null", "integer"] + }, + "metrics.active_view_measurability": { + "type": ["null", "number"] + }, + "metrics.active_view_measurable_cost_micros": { + "type": ["null", "integer"] + }, + "metrics.active_view_measurable_impressions": { + "type": ["null", "integer"] + }, + "metrics.active_view_viewability": { + "type": ["null", "number"] + }, + "metrics.conversions": { + "type": ["null", "number"] + }, + "metrics.conversions_value": { + "type": ["null", "number"] + }, + "metrics.interactions": { + "type": ["null", "integer"] + }, + "metrics.interaction_event_types": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "metrics.view_through_conversions": { + "type": ["null", "integer"] + }, "ad_group_criterion.criterion_id": { "type": ["null", "integer"] } diff --git a/docs/integrations/sources/google-ads.md b/docs/integrations/sources/google-ads.md index c7ac4d95686b..cb17f5cfbfc8 100644 --- a/docs/integrations/sources/google-ads.md +++ b/docs/integrations/sources/google-ads.md @@ -161,6 +161,7 @@ Due to a limitation in the Google Ads API which does not allow getting performan | Version | Date | Pull Request | Subject | |:---------|:-----------|:---------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------| +| `0.6.0` | 2023-07-10 | [28049](https://github.com/airbytehq/airbyte/pull/28049) | Add `metrics` to `Keyword Report` schema | | `0.5.0` | 2023-07-07 | [28042](https://github.com/airbytehq/airbyte/pull/28042) | Add metrics & segment to `Campaigns` stream | | `0.4.3` | 2023-07-05 | [27959](https://github.com/airbytehq/airbyte/pull/27959) | Add `audience` and `user_interest` streams | | `0.3.3` | 2023-07-03 | [27913](https://github.com/airbytehq/airbyte/pull/27913) | Improve Google Ads exception handling (wrong customer ID) | From a47fcf174b8a63e80dd445369e5fd7f74924c567 Mon Sep 17 00:00:00 2001 From: Baz Date: Mon, 10 Jul 2023 19:50:26 +0300 Subject: [PATCH 08/63] =?UTF-8?q?=F0=9F=8E=89=20Source=20Google=20Ads:=20a?= =?UTF-8?q?dd=20new=20stream=20`Campaign=20Budget`=20(#28078)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../acceptance-test-config.yml | 1 + .../integration_tests/abnormal_state.json | 7 + .../integration_tests/expected_records.jsonl | 3 + .../incremental_catalog.json | 14 ++ .../source_google_ads/google_ads.py | 1 + .../schemas/campaign_budget.json | 172 ++++++++++++++++++ .../source_google_ads/source.py | 2 + .../source_google_ads/streams.py | 9 + .../unit_tests/test_source.py | 2 +- docs/integrations/sources/google-ads.md | 3 +- 10 files changed, 212 insertions(+), 2 deletions(-) create mode 100644 airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/campaign_budget.json diff --git a/airbyte-integrations/connectors/source-google-ads/acceptance-test-config.yml b/airbyte-integrations/connectors/source-google-ads/acceptance-test-config.yml index 971a8f73c6ed..dfa9ed46f596 100644 --- a/airbyte-integrations/connectors/source-google-ads/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-google-ads/acceptance-test-config.yml @@ -60,6 +60,7 @@ acceptance_tests: ad_groups: ["4651612872", "segments.date"] accounts: ["4651612872", "segments.date"] campaigns: ["4651612872", "segments.date"] + campaign_budget: ["4651612872", "segments.date"] user_location_report: ["4651612872", "segments.date"] ad_group_ad_report: ["4651612872", "segments.date"] display_keyword_performance_report: ["4651612872", "segments.date"] diff --git a/airbyte-integrations/connectors/source-google-ads/integration_tests/abnormal_state.json b/airbyte-integrations/connectors/source-google-ads/integration_tests/abnormal_state.json index 9241aad423b4..22056224a81b 100644 --- a/airbyte-integrations/connectors/source-google-ads/integration_tests/abnormal_state.json +++ b/airbyte-integrations/connectors/source-google-ads/integration_tests/abnormal_state.json @@ -89,5 +89,12 @@ "stream_state": { "4651612872": { "segments.date": "2222-01-01" }}, "stream_descriptor": { "name": "display_keyword_performance_report" } } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "4651612872": { "segments.date": "2222-01-01" }}, + "stream_descriptor": { "name": "campaign_budget" } + } } ] diff --git a/airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl index 328bd29ca93f..c05919161e0c 100644 --- a/airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl @@ -86,3 +86,6 @@ {"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} {"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} {"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} +{"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} +{"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} +{"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} diff --git a/airbyte-integrations/connectors/source-google-ads/integration_tests/incremental_catalog.json b/airbyte-integrations/connectors/source-google-ads/integration_tests/incremental_catalog.json index bfe6dbf07f88..071e65aa7c40 100644 --- a/airbyte-integrations/connectors/source-google-ads/integration_tests/incremental_catalog.json +++ b/airbyte-integrations/connectors/source-google-ads/integration_tests/incremental_catalog.json @@ -133,6 +133,20 @@ "cursor_field": ["segments.date"], "primary_key": [["campaign.id"], ["segments.date"]] }, + { + "stream": { + "name": "campaign_budget", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["segments.date"], + "source_defined_primary_key": [["campaign_budget.id"], ["segments.date"]] + }, + "sync_mode": "incremental", + "destination_sync_mode": "overwrite", + "cursor_field": ["segments.date"], + "primary_key": [["campaign_budget.id"], ["segments.date"]] + }, { "stream": { "name": "user_location_report", diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/google_ads.py b/airbyte-integrations/connectors/source-google-ads/source_google_ads/google_ads.py index b1e9bb6868d4..414f784893dd 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/google_ads.py +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/google_ads.py @@ -24,6 +24,7 @@ "ad_groups": "ad_group", "ad_group_labels": "ad_group_label", "campaigns": "campaign", + "campaign_budget": "campaign_budget", "campaign_labels": "campaign_label", "account_performance_report": "customer", "ad_group_ad_report": "ad_group_ad", diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/campaign_budget.json b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/campaign_budget.json new file mode 100644 index 000000000000..8e32a14e3e37 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/campaign_budget.json @@ -0,0 +1,172 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "campaign_budget.aligned_bidding_strategy_id": { + "type": ["null", "integer"] + }, + "campaign_budget.amount_micros": { + "type": ["null", "integer"] + }, + "campaign_budget.delivery_method": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "campaign_budget.explicitly_shared": { + "type": ["null", "boolean"] + }, + "campaign_budget.has_recommended_budget": { + "type": ["null", "boolean"] + }, + "campaign_budget.id": { + "type": ["null", "integer"] + }, + "campaign_budget.name": { + "type": ["null", "string"] + }, + "campaign_budget.period": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "campaign_budget.recommended_budget_amount_micros": { + "type": ["null", "integer"] + }, + "campaign_budget.recommended_budget_estimated_change_weekly_clicks": { + "type": ["null", "integer"] + }, + "campaign_budget.recommended_budget_estimated_change_weekly_cost_micros": { + "type": ["null", "integer"] + }, + "campaign_budget.recommended_budget_estimated_change_weekly_interactions": { + "type": ["null", "integer"] + }, + "campaign_budget.recommended_budget_estimated_change_weekly_views": { + "type": ["null", "integer"] + }, + "campaign_budget.reference_count": { + "type": ["null", "integer"] + }, + "campaign_budget.resource_name": { + "type": ["null", "string"] + }, + "campaign_budget.status": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "campaign_budget.total_amount_micros": { + "type": ["null", "integer"] + }, + "campaign_budget.type": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "segments.date": { + "type": ["null", "string"], + "format": "date" + }, + "segments.budget_campaign_association_status.campaign": { + "type": ["null", "string"] + }, + "segments.budget_campaign_association_status.status": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "metrics.all_conversions": { + "type": ["null", "number"] + }, + "metrics.all_conversions_from_interactions_rate": { + "type": ["null", "number"] + }, + "metrics.all_conversions_value": { + "type": ["null", "number"] + }, + "metrics.average_cost": { + "type": ["null", "number"] + }, + "metrics.average_cpc": { + "type": ["null", "number"] + }, + "metrics.average_cpe": { + "type": ["null", "number"] + }, + "metrics.average_cpm": { + "type": ["null", "number"] + }, + "metrics.average_cpv": { + "type": ["null", "number"] + }, + "metrics.clicks": { + "type": ["null", "integer"] + }, + "metrics.conversions": { + "type": ["null", "number"] + }, + "metrics.conversions_from_interactions_rate": { + "type": ["null", "number"] + }, + "metrics.conversions_value": { + "type": ["null", "number"] + }, + "metrics.cost_micros": { + "type": ["null", "integer"] + }, + "metrics.cost_per_all_conversions": { + "type": ["null", "number"] + }, + "metrics.cost_per_conversion": { + "type": ["null", "number"] + }, + "metrics.cross_device_conversions": { + "type": ["null", "number"] + }, + "metrics.ctr": { + "type": ["null", "number"] + }, + "metrics.engagement_rate": { + "type": ["null", "number"] + }, + "metrics.engagements": { + "type": ["null", "integer"] + }, + "metrics.impressions": { + "type": ["null", "integer"] + }, + "metrics.interaction_event_types": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "metrics.interaction_rate": { + "type": ["null", "number"] + }, + "metrics.interactions": { + "type": ["null", "integer"] + }, + "metrics.value_per_all_conversions": { + "type": ["null", "number"] + }, + "metrics.value_per_conversion": { + "type": ["null", "number"] + }, + "metrics.video_view_rate": { + "type": ["null", "number"] + }, + "metrics.video_views": { + "type": ["null", "integer"] + }, + "metrics.view_through_conversions": { + "type": ["null", "integer"] + } + } +} diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py b/airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py index 10292b21fbf8..ec5f59d998af 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py @@ -28,6 +28,7 @@ AdGroupLabels, AdGroups, Audience, + CampaignBudget, CampaignLabels, Campaigns, ClickView, @@ -151,6 +152,7 @@ def streams(self, config: Mapping[str, Any]) -> List[Stream]: AdGroupLabels(google_api, customers=customers), Accounts(**incremental_config), Audience(google_api, customers=customers), + CampaignBudget(**incremental_config), CampaignLabels(google_api, customers=customers), ClickView(**incremental_config), UserInterest(google_api, customers=customers), diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py b/airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py index 71abcc810049..71fb44526f53 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py @@ -276,6 +276,15 @@ class Campaigns(IncrementalGoogleAdsStream): primary_key = ["campaign.id", "segments.date", "segments.hour"] +class CampaignBudget(IncrementalGoogleAdsStream): + """ + Campaigns stream: https://developers.google.com/google-ads/api/fields/v13/campaign_budget + """ + + transformer = TypeTransformer(TransformConfig.DefaultSchemaNormalization) + primary_key = ["campaign_budget.id", "segments.date"] + + class CampaignLabels(GoogleAdsStream): """ Campaign labels stream: https://developers.google.com/google-ads/api/fields/v11/campaign_label diff --git a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_source.py b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_source.py index 893af1fcff0d..b11f74ea591b 100644 --- a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_source.py @@ -144,7 +144,7 @@ def test_chunk_date_range(): def test_streams_count(config, mock_account_info): source = SourceGoogleAds() streams = source.streams(config) - expected_streams_number = 21 + expected_streams_number = 22 assert len(streams) == expected_streams_number diff --git a/docs/integrations/sources/google-ads.md b/docs/integrations/sources/google-ads.md index cb17f5cfbfc8..c44fbfab08e9 100644 --- a/docs/integrations/sources/google-ads.md +++ b/docs/integrations/sources/google-ads.md @@ -108,6 +108,7 @@ Note that `ad_groups`, `ad_group_ads`, and `campaigns` contain a `labels` field, ### Report Tables - [campaigns](https://developers.google.com/google-ads/api/fields/v11/campaign) +- [campaign budget](https://developers.google.com/google-ads/api/fields/v13/campaign_budget) - [account_performance_report](https://developers.google.com/google-ads/api/docs/migration/mapping#account_performance) - [ad_group_ad_report](https://developers.google.com/google-ads/api/docs/migration/mapping#ad_performance) - [display_keyword_report](https://developers.google.com/google-ads/api/docs/migration/mapping#display_keyword_performance) @@ -161,7 +162,7 @@ Due to a limitation in the Google Ads API which does not allow getting performan | Version | Date | Pull Request | Subject | |:---------|:-----------|:---------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------| -| `0.6.0` | 2023-07-10 | [28049](https://github.com/airbytehq/airbyte/pull/28049) | Add `metrics` to `Keyword Report` schema | +| `0.6.0` | 2023-07-10 | [28078](https://github.com/airbytehq/airbyte/pull/28078) | Add new stream `Campaign Budget` | | `0.5.0` | 2023-07-07 | [28042](https://github.com/airbytehq/airbyte/pull/28042) | Add metrics & segment to `Campaigns` stream | | `0.4.3` | 2023-07-05 | [27959](https://github.com/airbytehq/airbyte/pull/27959) | Add `audience` and `user_interest` streams | | `0.3.3` | 2023-07-03 | [27913](https://github.com/airbytehq/airbyte/pull/27913) | Improve Google Ads exception handling (wrong customer ID) | From cc8081d5123994b8589cf84bb76cd2fc4fcde881 Mon Sep 17 00:00:00 2001 From: Akash Kulkarni <113392464+akashkulk@users.noreply.github.com> Date: Mon, 10 Jul 2023 10:58:46 -0700 Subject: [PATCH 09/63] =?UTF-8?q?=F0=9F=8E=89=20source-postgres=20:=20Enab?= =?UTF-8?q?le=20xmin=20replication=20=20(#26723)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add logging functionality - Add logging for DB version (all JDBC sources) - Add logging for Xmin values * Automated Change * Renaming + comments * More comments * Initial commit for xmin prototype - Add spec.json - Catalog - Try to change incremental query * Skeleton for sync Decision is to use a whole new sync method * With cursor * Working catalog + attempt at xmin record iterator * Unit tested code * Fix build break * Fixing state * more xmin * Revert unchanged files * Addressing code review comments * use generated pojo * Add iniital XminStateManagerTest * Additional unit tests * Added unit test * Update xmin state manager test * Remove spec.json xmin option * Fixed bug where full refresh streams were not being filtered out for Xmin * Fix latest safe change boundary issue * Xmin spec update * Fix * Automated Commit - Format and Process Resources Changes * Remove full_refresh as an option for xmin syncs and always include incremental syncs * Fix integ test * revert unused files * revert * Bump docker + update change log * Modify order of CDC * Update expected_spec.json * Update expected_json Fix acceptance tests * Reverse order for xmin replication * Update expected strict encrypt json --------- Co-authored-by: akashkulk Co-authored-by: subodh --- .../source-postgres-strict-encrypt/Dockerfile | 2 +- .../metadata.yaml | 2 +- .../expected_strict_encrypt_spec.json | 18 +- .../connectors/source-postgres/Dockerfile | 2 +- .../connectors/source-postgres/metadata.yaml | 2 +- .../src/main/resources/spec.json | 18 +- .../XminPostgresSourceAcceptanceTest.java | 203 ++++++++++++++++++ .../resources/expected_spec.json | 18 +- docs/integrations/sources/postgres.md | 10 + 9 files changed, 262 insertions(+), 13 deletions(-) create mode 100644 airbyte-integrations/connectors/source-postgres/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/XminPostgresSourceAcceptanceTest.java diff --git a/airbyte-integrations/connectors/source-postgres-strict-encrypt/Dockerfile b/airbyte-integrations/connectors/source-postgres-strict-encrypt/Dockerfile index af8c92d4bc7c..ce02dc3becff 100644 --- a/airbyte-integrations/connectors/source-postgres-strict-encrypt/Dockerfile +++ b/airbyte-integrations/connectors/source-postgres-strict-encrypt/Dockerfile @@ -24,5 +24,5 @@ ENV APPLICATION source-postgres-strict-encrypt COPY --from=build /airbyte /airbyte -LABEL io.airbyte.version=2.1.0 +LABEL io.airbyte.version=2.1.1 LABEL io.airbyte.name=airbyte/source-postgres-strict-encrypt diff --git a/airbyte-integrations/connectors/source-postgres-strict-encrypt/metadata.yaml b/airbyte-integrations/connectors/source-postgres-strict-encrypt/metadata.yaml index b0d976d08dbe..61911e508dcc 100644 --- a/airbyte-integrations/connectors/source-postgres-strict-encrypt/metadata.yaml +++ b/airbyte-integrations/connectors/source-postgres-strict-encrypt/metadata.yaml @@ -12,7 +12,7 @@ data: connectorType: source definitionId: decd338e-5647-4c0b-adf4-da0e75f5a750 maxSecondsBetweenMessages: 7200 - dockerImageTag: 2.1.0 + dockerImageTag: 2.1.1 dockerRepository: airbyte/source-postgres-strict-encrypt githubIssueLabel: source-postgres icon: postgresql.svg diff --git a/airbyte-integrations/connectors/source-postgres-strict-encrypt/src/test-integration/resources/expected_strict_encrypt_spec.json b/airbyte-integrations/connectors/source-postgres-strict-encrypt/src/test-integration/resources/expected_strict_encrypt_spec.json index add556c58b41..1dccfc85a9e8 100644 --- a/airbyte-integrations/connectors/source-postgres-strict-encrypt/src/test-integration/resources/expected_strict_encrypt_spec.json +++ b/airbyte-integrations/connectors/source-postgres-strict-encrypt/src/test-integration/resources/expected_strict_encrypt_spec.json @@ -230,13 +230,13 @@ "group": "advanced", "oneOf": [ { - "title": "Standard", - "description": "Standard replication requires no setup on the DB side but will not be able to represent deletions incrementally.", + "title": "Standard (Xmin)", + "description": "Xmin replication requires no setup on the DB side but will not be able to represent deletions incrementally.", "required": ["method"], "properties": { "method": { "type": "string", - "const": "Standard", + "const": "Xmin", "order": 0 } } @@ -302,6 +302,18 @@ "order": 7 } } + }, + { + "title": "Standard", + "description": "Standard replication requires no setup on the DB side but will not be able to represent deletions incrementally.", + "required": ["method"], + "properties": { + "method": { + "type": "string", + "const": "Standard", + "order": 8 + } + } } ] }, diff --git a/airbyte-integrations/connectors/source-postgres/Dockerfile b/airbyte-integrations/connectors/source-postgres/Dockerfile index 031df84ef695..dec76967e02c 100644 --- a/airbyte-integrations/connectors/source-postgres/Dockerfile +++ b/airbyte-integrations/connectors/source-postgres/Dockerfile @@ -24,5 +24,5 @@ ENV APPLICATION source-postgres COPY --from=build /airbyte /airbyte -LABEL io.airbyte.version=2.1.0 +LABEL io.airbyte.version=2.1.1 LABEL io.airbyte.name=airbyte/source-postgres diff --git a/airbyte-integrations/connectors/source-postgres/metadata.yaml b/airbyte-integrations/connectors/source-postgres/metadata.yaml index 4604d50015e7..8e27e690892e 100644 --- a/airbyte-integrations/connectors/source-postgres/metadata.yaml +++ b/airbyte-integrations/connectors/source-postgres/metadata.yaml @@ -6,7 +6,7 @@ data: connectorSubtype: database connectorType: source definitionId: decd338e-5647-4c0b-adf4-da0e75f5a750 - dockerImageTag: 2.1.0 + dockerImageTag: 2.1.1 maxSecondsBetweenMessages: 7200 dockerRepository: airbyte/source-postgres githubIssueLabel: source-postgres diff --git a/airbyte-integrations/connectors/source-postgres/src/main/resources/spec.json b/airbyte-integrations/connectors/source-postgres/src/main/resources/spec.json index 944c03a47a73..bf749864f76c 100644 --- a/airbyte-integrations/connectors/source-postgres/src/main/resources/spec.json +++ b/airbyte-integrations/connectors/source-postgres/src/main/resources/spec.json @@ -229,13 +229,13 @@ "group": "advanced", "oneOf": [ { - "title": "Standard", - "description": "Standard replication requires no setup on the DB side but will not be able to represent deletions incrementally.", + "title": "Standard (Xmin)", + "description": "Xmin replication requires no setup on the DB side but will not be able to represent deletions incrementally.", "required": ["method"], "properties": { "method": { "type": "string", - "const": "Standard", + "const": "Xmin", "order": 0 } } @@ -301,6 +301,18 @@ "order": 7 } } + }, + { + "title": "Standard", + "description": "Standard replication requires no setup on the DB side but will not be able to represent deletions incrementally.", + "required": ["method"], + "properties": { + "method": { + "type": "string", + "const": "Standard", + "order": 8 + } + } } ] } diff --git a/airbyte-integrations/connectors/source-postgres/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/XminPostgresSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-postgres/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/XminPostgresSourceAcceptanceTest.java new file mode 100644 index 000000000000..3e25ff37b32a --- /dev/null +++ b/airbyte-integrations/connectors/source-postgres/src/test-integration/java/io/airbyte/integrations/io/airbyte/integration_tests/sources/XminPostgresSourceAcceptanceTest.java @@ -0,0 +1,203 @@ +package io.airbyte.integrations.io.airbyte.integration_tests.sources; + +import com.fasterxml.jackson.databind.JsonNode; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import io.airbyte.commons.features.EnvVariableFeatureFlags; +import io.airbyte.commons.json.Jsons; +import io.airbyte.db.Database; +import io.airbyte.db.factory.DSLContextFactory; +import io.airbyte.db.factory.DatabaseDriver; +import io.airbyte.db.jdbc.JdbcUtils; +import io.airbyte.integrations.standardtest.source.TestDestinationEnv; +import io.airbyte.integrations.util.HostPortResolver; +import io.airbyte.protocol.models.Field; +import io.airbyte.protocol.models.JsonSchemaType; +import io.airbyte.protocol.models.v0.CatalogHelpers; +import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; +import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; +import io.airbyte.protocol.models.v0.DestinationSyncMode; +import io.airbyte.protocol.models.v0.SyncMode; +import java.util.HashMap; +import java.util.List; +import org.jooq.DSLContext; +import org.jooq.SQLDialect; +import org.junit.jupiter.api.extension.ExtendWith; +import org.testcontainers.containers.PostgreSQLContainer; +import uk.org.webcompere.systemstubs.environment.EnvironmentVariables; +import uk.org.webcompere.systemstubs.jupiter.SystemStub; +import uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension; + +@ExtendWith(SystemStubsExtension.class) +public class XminPostgresSourceAcceptanceTest extends AbstractPostgresSourceAcceptanceTest { + + private static final String STREAM_NAME = "id_and_name"; + private static final String STREAM_NAME2 = "starships"; + private static final String STREAM_NAME_MATERIALIZED_VIEW = "testview"; + private static final String SCHEMA_NAME = "public"; + @SystemStub + private EnvironmentVariables environmentVariables; + + private PostgreSQLContainer container; + private JsonNode config; + private Database database; + private ConfiguredAirbyteCatalog configCatalog; + + @Override + protected JsonNode getConfig() throws Exception { + return config; + } + + @Override + protected void setupEnvironment(final TestDestinationEnv environment) throws Exception { + environmentVariables.set(EnvVariableFeatureFlags.USE_STREAM_CAPABLE_STATE, "true"); + + container = new PostgreSQLContainer<>("postgres:13-alpine"); + container.start(); + final String username = container.getUsername(); + final String password = container.getPassword(); + final List schemas = List.of("public"); + config = getXminConfig(username, password, schemas); + try (final DSLContext dslContext = DSLContextFactory.create( + config.get(JdbcUtils.USERNAME_KEY).asText(), + config.get(JdbcUtils.PASSWORD_KEY).asText(), + DatabaseDriver.POSTGRESQL.getDriverClassName(), + String.format(DatabaseDriver.POSTGRESQL.getUrlFormatString(), + container.getHost(), + container.getFirstMappedPort(), + config.get(JdbcUtils.DATABASE_KEY).asText()), + SQLDialect.POSTGRES)) { + database = new Database(dslContext); + + database.query(ctx -> { + ctx.fetch("CREATE TABLE id_and_name(id INTEGER, name VARCHAR(200));"); + ctx.fetch("INSERT INTO id_and_name (id, name) VALUES (1,'picard'), (2, 'crusher'), (3, 'vash');"); + ctx.fetch("CREATE TABLE starships(id INTEGER, name VARCHAR(200));"); + ctx.fetch("INSERT INTO starships (id, name) VALUES (1,'enterprise-d'), (2, 'defiant'), (3, 'yamato');"); + ctx.fetch("CREATE MATERIALIZED VIEW testview AS select * from id_and_name where id = '2';"); + return null; + }); + configCatalog = getXminCatalog(); + } + } + + private JsonNode getConfig(final String username, final String password, final List schemas) { + final JsonNode replicationMethod = Jsons.jsonNode(ImmutableMap.builder() + .put("method", "Standard") + .build()); + return Jsons.jsonNode(ImmutableMap.builder() + .put(JdbcUtils.HOST_KEY, HostPortResolver.resolveHost(container)) + .put(JdbcUtils.PORT_KEY, HostPortResolver.resolvePort(container)) + .put(JdbcUtils.DATABASE_KEY, container.getDatabaseName()) + .put(JdbcUtils.SCHEMAS_KEY, Jsons.jsonNode(schemas)) + .put(JdbcUtils.USERNAME_KEY, username) + .put(JdbcUtils.PASSWORD_KEY, password) + .put(JdbcUtils.SSL_KEY, false) + .put("replication_method", replicationMethod) + .build()); + } + + private JsonNode getXminConfig(final String username, final String password, final List schemas) { + final JsonNode replicationMethod = Jsons.jsonNode(ImmutableMap.builder() + .put("method", "Xmin") + .build()); + return Jsons.jsonNode(ImmutableMap.builder() + .put(JdbcUtils.HOST_KEY, HostPortResolver.resolveHost(container)) + .put(JdbcUtils.PORT_KEY, HostPortResolver.resolvePort(container)) + .put(JdbcUtils.DATABASE_KEY, container.getDatabaseName()) + .put(JdbcUtils.SCHEMAS_KEY, Jsons.jsonNode(schemas)) + .put(JdbcUtils.USERNAME_KEY, username) + .put(JdbcUtils.PASSWORD_KEY, password) + .put(JdbcUtils.SSL_KEY, false) + .put("replication_method", replicationMethod) + .build()); + } + + @Override + protected void tearDown(final TestDestinationEnv testEnv) throws Exception { + container.close(); + } + + @Override + protected ConfiguredAirbyteCatalog getConfiguredCatalog() throws Exception { + return configCatalog; + } + + @Override + protected JsonNode getState() throws Exception { + return Jsons.jsonNode(new HashMap<>()); + } + + @Override + protected boolean supportsPerStream() { + return true; + } + + private ConfiguredAirbyteCatalog getCommonConfigCatalog() { + return new ConfiguredAirbyteCatalog().withStreams(Lists.newArrayList( + new ConfiguredAirbyteStream() + .withSyncMode(SyncMode.INCREMENTAL) + .withCursorField(Lists.newArrayList("id")) + .withDestinationSyncMode(DestinationSyncMode.APPEND) + .withStream(CatalogHelpers.createAirbyteStream( + STREAM_NAME, SCHEMA_NAME, + Field.of("id", JsonSchemaType.NUMBER), + Field.of("name", JsonSchemaType.STRING)) + .withSupportedSyncModes(Lists.newArrayList(SyncMode.INCREMENTAL)) + .withSourceDefinedPrimaryKey(List.of(List.of("id")))), + new ConfiguredAirbyteStream() + .withSyncMode(SyncMode.INCREMENTAL) + .withCursorField(Lists.newArrayList("id")) + .withDestinationSyncMode(DestinationSyncMode.APPEND) + .withStream(CatalogHelpers.createAirbyteStream( + STREAM_NAME2, SCHEMA_NAME, + Field.of("id", JsonSchemaType.NUMBER), + Field.of("name", JsonSchemaType.STRING)) + .withSupportedSyncModes(Lists.newArrayList(SyncMode.INCREMENTAL)) + .withSourceDefinedPrimaryKey(List.of(List.of("id")))), + new ConfiguredAirbyteStream() + .withSyncMode(SyncMode.INCREMENTAL) + .withCursorField(Lists.newArrayList("id")) + .withDestinationSyncMode(DestinationSyncMode.APPEND) + .withStream(CatalogHelpers.createAirbyteStream( + STREAM_NAME_MATERIALIZED_VIEW, SCHEMA_NAME, + Field.of("id", JsonSchemaType.NUMBER), + Field.of("name", JsonSchemaType.STRING)) + .withSupportedSyncModes(Lists.newArrayList(SyncMode.INCREMENTAL)) + .withSourceDefinedPrimaryKey(List.of(List.of("id")))))); + } + + private ConfiguredAirbyteCatalog getXminCatalog() { + return new ConfiguredAirbyteCatalog().withStreams(Lists.newArrayList( + new ConfiguredAirbyteStream() + .withSyncMode(SyncMode.INCREMENTAL) + .withDestinationSyncMode(DestinationSyncMode.APPEND) + .withStream(CatalogHelpers.createAirbyteStream( + STREAM_NAME, SCHEMA_NAME, + Field.of("id", JsonSchemaType.NUMBER), + Field.of("name", JsonSchemaType.STRING)) + .withSupportedSyncModes(Lists.newArrayList(SyncMode.INCREMENTAL)) + .withSourceDefinedCursor(true) + .withSourceDefinedPrimaryKey(List.of(List.of("id")))), + new ConfiguredAirbyteStream() + .withSyncMode(SyncMode.INCREMENTAL) + .withDestinationSyncMode(DestinationSyncMode.APPEND) + .withStream(CatalogHelpers.createAirbyteStream( + STREAM_NAME2, SCHEMA_NAME, + Field.of("id", JsonSchemaType.NUMBER), + Field.of("name", JsonSchemaType.STRING)) + .withSupportedSyncModes(Lists.newArrayList(SyncMode.INCREMENTAL)) + .withSourceDefinedCursor(true) + .withSourceDefinedPrimaryKey(List.of(List.of("id")))), + new ConfiguredAirbyteStream() + .withSyncMode(SyncMode.INCREMENTAL) + .withDestinationSyncMode(DestinationSyncMode.APPEND) + .withStream(CatalogHelpers.createAirbyteStream( + STREAM_NAME_MATERIALIZED_VIEW, SCHEMA_NAME, + Field.of("id", JsonSchemaType.NUMBER), + Field.of("name", JsonSchemaType.STRING)) + .withSupportedSyncModes(Lists.newArrayList(SyncMode.INCREMENTAL)) + .withSourceDefinedCursor(true) + .withSourceDefinedPrimaryKey(List.of(List.of("id")))))); + } +} \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-postgres/src/test-integration/resources/expected_spec.json b/airbyte-integrations/connectors/source-postgres/src/test-integration/resources/expected_spec.json index d03e067bb550..a691f1e7ee09 100644 --- a/airbyte-integrations/connectors/source-postgres/src/test-integration/resources/expected_spec.json +++ b/airbyte-integrations/connectors/source-postgres/src/test-integration/resources/expected_spec.json @@ -229,13 +229,13 @@ "group": "advanced", "oneOf": [ { - "title": "Standard", - "description": "Standard replication requires no setup on the DB side but will not be able to represent deletions incrementally.", + "title": "Standard (Xmin)", + "description": "Xmin replication requires no setup on the DB side but will not be able to represent deletions incrementally.", "required": ["method"], "properties": { "method": { "type": "string", - "const": "Standard", + "const": "Xmin", "order": 0 } } @@ -301,6 +301,18 @@ "order": 7 } } + }, + { + "title": "Standard", + "description": "Standard replication requires no setup on the DB side but will not be able to represent deletions incrementally.", + "required": ["method"], + "properties": { + "method": { + "type": "string", + "const": "Standard", + "order": 8 + } + } } ] }, diff --git a/docs/integrations/sources/postgres.md b/docs/integrations/sources/postgres.md index 98ed64447bd5..a63756b938f0 100644 --- a/docs/integrations/sources/postgres.md +++ b/docs/integrations/sources/postgres.md @@ -267,6 +267,15 @@ If you know there are database changes to be synced, but the connector cannot re In [Step 2](#step-2-set-up-the-postgres-connector-in-airbyte) of the connector setup guide, enter the replication slot and publication you just created. +## Xmin replication mode +Xmin replication is a new cursor-less replication method for Postgres. Cursorless syncs enable syncing new or updated rows without explicitly choosing a cursor field. The xmin system column which is available in all Postgres databases is used to track inserts and updates to your source data. + +This is a good solution if: +- There is not a well-defined cursor candidate to use for Standard incremental mode. +- You want to replace a previously configured full-refresh sync. +- You are replicating Postgres tables less than 500GB. + + ## Supported sync modes The Postgres source connector supports the following [sync modes](https://docs.airbyte.com/cloud/core-concepts#connection-sync-modes): @@ -398,6 +407,7 @@ Some larger tables may encounter an error related to the temporary file size lim | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | +| 2.1.1 | 2023-07-06 | [26723](https://github.com/airbytehq/airbyte/pull/26723) | Add new xmin replication method. | | 2.1.0 | 2023-06-26 | [27737](https://github.com/airbytehq/airbyte/pull/27737) | License Update: Elv2 | | 2.0.34 | 2023-06-20 | [27212](https://github.com/airbytehq/airbyte/pull/27212) | Fix silent exception swallowing in StreamingJdbcDatabase | | 2.0.33 | 2023-06-01 | [26873](https://github.com/airbytehq/airbyte/pull/26873) | Add prepareThreshold=0 to JDBC url to mitigate PGBouncer prepared statement [X] already exists. | From 99cace9cab50cc63f9246cd2f60f3db9fa021b37 Mon Sep 17 00:00:00 2001 From: sh4sh <6833405+sh4sh@users.noreply.github.com> Date: Mon, 10 Jul 2023 12:23:48 -0600 Subject: [PATCH 10/63] connector checklist: update pr naming conventions link (#28088) --- airbyte-ci/connectors/CONNECTOR_CHECKLIST.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airbyte-ci/connectors/CONNECTOR_CHECKLIST.yaml b/airbyte-ci/connectors/CONNECTOR_CHECKLIST.yaml index 2ee2e253f94e..95419a652f20 100644 --- a/airbyte-ci/connectors/CONNECTOR_CHECKLIST.yaml +++ b/airbyte-ci/connectors/CONNECTOR_CHECKLIST.yaml @@ -1,6 +1,6 @@ paths: "airbyte-integrations/connectors/**": - - PR name follows [PR naming conventions](https://docs.airbyte.com/contributing-to-airbyte/issues-and-pull-requests#pull-request-title-convention) + - PR name follows [PR naming conventions](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#pull-request-title-convention) - "[Breaking changes are considered](https://docs.airbyte.com/contributing-to-airbyte/#breaking-changes-to-connectors). If a **Breaking Change** is being introduced, ensure an Airbyte engineer has created a Breaking Change Plan and you've followed all steps in the [Breaking Changes Checklist](https://docs.airbyte.com/contributing-to-airbyte/#checklist-for-contributors)" - Connector version has been incremented in the Dockerfile and metadata.yaml according to our [Semantic Versioning for Connectors](https://docs.airbyte.com/contributing-to-airbyte/#semantic-versioning-for-connectors) guidelines - Secrets in the connector's spec are annotated with `airbyte_secret` From 67a8c05b7f3baddf1cfbcc5ca0c9fdfdd1763531 Mon Sep 17 00:00:00 2001 From: ParthG21 <68982328+ParthG21@users.noreply.github.com> Date: Tue, 11 Jul 2023 00:40:04 +0530 Subject: [PATCH 11/63] =?UTF-8?q?=F0=9F=90=9B=20Source=20Square:=20fix=20d?= =?UTF-8?q?isplay=20order=20of=20spec=20fields=20(#28019)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Removed comma from the value of order field for square source connector specification, which was causing it to be a String instead of an Integer * increment connector version * add changelog entry --------- Co-authored-by: Sunny Hashmi <6833405+sh4sh@users.noreply.github.com> --- airbyte-integrations/connectors/source-square/Dockerfile | 2 +- airbyte-integrations/connectors/source-square/metadata.yaml | 2 +- .../connectors/source-square/source_square/spec.yaml | 2 +- docs/integrations/sources/square.md | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/airbyte-integrations/connectors/source-square/Dockerfile b/airbyte-integrations/connectors/source-square/Dockerfile index 548c53df03ce..c18311a47f48 100644 --- a/airbyte-integrations/connectors/source-square/Dockerfile +++ b/airbyte-integrations/connectors/source-square/Dockerfile @@ -34,5 +34,5 @@ COPY source_square ./source_square ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=1.1.1 +LABEL io.airbyte.version=1.1.2 LABEL io.airbyte.name=airbyte/source-square diff --git a/airbyte-integrations/connectors/source-square/metadata.yaml b/airbyte-integrations/connectors/source-square/metadata.yaml index e1553ae0272b..7935416d352c 100644 --- a/airbyte-integrations/connectors/source-square/metadata.yaml +++ b/airbyte-integrations/connectors/source-square/metadata.yaml @@ -6,7 +6,7 @@ data: connectorSubtype: api connectorType: source definitionId: 77225a51-cd15-4a13-af02-65816bd0ecf4 - dockerImageTag: 1.1.1 + dockerImageTag: 1.1.2 dockerRepository: airbyte/source-square githubIssueLabel: source-square icon: square.svg diff --git a/airbyte-integrations/connectors/source-square/source_square/spec.yaml b/airbyte-integrations/connectors/source-square/source_square/spec.yaml index bd2ddf0cdd52..742adcf22fa2 100644 --- a/airbyte-integrations/connectors/source-square/source_square/spec.yaml +++ b/airbyte-integrations/connectors/source-square/source_square/spec.yaml @@ -67,7 +67,7 @@ connectionSpecification: title: Start Date default: "2021-01-01" pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ - order: 2, + order: 2 format: date include_deleted_objects: type: boolean diff --git a/docs/integrations/sources/square.md b/docs/integrations/sources/square.md index 55fc6a778112..d1e9075bde04 100644 --- a/docs/integrations/sources/square.md +++ b/docs/integrations/sources/square.md @@ -97,6 +97,7 @@ Exponential [Backoff](https://developer.squareup.com/forums/t/current-square-api | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:---------------------------------------------------------------------------| +| 1.1.2 | 2023-07-10 | [28019](https://github.com/airbytehq/airbyte/pull/28019) | fix display order of spec fields | | 1.1.1 | 2023-06-28 | [27762](https://github.com/airbytehq/airbyte/pull/27762) | Update following state breaking changes | | 1.1.0 | 2023-05-24 | [26485](https://github.com/airbytehq/airbyte/pull/26485) | Remove deprecated authSpecification in favour of advancedAuth | | 1.0.1 | 2023-05-03 | [25784](https://github.com/airbytehq/airbyte/pull/25784) | Fix Authenticator | From 1006559b3e12c0ebfbdd23133f259698efe637e2 Mon Sep 17 00:00:00 2001 From: Mal Hancock Date: Mon, 10 Jul 2023 13:41:42 -0700 Subject: [PATCH 12/63] =?UTF-8?q?=F0=9F=9A=A8=F0=9F=9A=A8=F0=9F=90=9B=20So?= =?UTF-8?q?urce=20Coda:=20Update=20Schemas=20and=20Fix=20Tests=20(#28093)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update schemas and iterate version * properly raise an exception when connection fails * add changelog --- .../connectors/source-coda/Dockerfile | 2 +- .../source-coda/acceptance-test-config.yml | 4 + .../connectors/source-coda/metadata.yaml | 2 +- .../source-coda/source_coda/schemas/docs.json | 2 +- .../source_coda/schemas/pages.json | 76 +++++++++++++++++++ .../source-coda/source_coda/source.py | 2 + docs/integrations/sources/coda.md | 1 + 7 files changed, 86 insertions(+), 3 deletions(-) diff --git a/airbyte-integrations/connectors/source-coda/Dockerfile b/airbyte-integrations/connectors/source-coda/Dockerfile index f8d116a3a924..bcb600c57a25 100644 --- a/airbyte-integrations/connectors/source-coda/Dockerfile +++ b/airbyte-integrations/connectors/source-coda/Dockerfile @@ -34,5 +34,5 @@ COPY source_coda ./source_coda ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=0.1.0 +LABEL io.airbyte.version=1.0.0 LABEL io.airbyte.name=airbyte/source-coda diff --git a/airbyte-integrations/connectors/source-coda/acceptance-test-config.yml b/airbyte-integrations/connectors/source-coda/acceptance-test-config.yml index a692eb177d65..ee2795726cee 100644 --- a/airbyte-integrations/connectors/source-coda/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-coda/acceptance-test-config.yml @@ -5,6 +5,8 @@ acceptance_tests: spec: tests: - spec_path: "source_coda/spec.yaml" + backward_compatibility_tests_config: + disable_for_version: "0.1.0" connection: tests: - config_path: "secrets/config.json" @@ -14,6 +16,8 @@ acceptance_tests: discovery: tests: - config_path: "secrets/config.json" + backward_compatibility_tests_config: + disable_for_version: "0.1.0" basic_read: tests: - config_path: "secrets/config.json" diff --git a/airbyte-integrations/connectors/source-coda/metadata.yaml b/airbyte-integrations/connectors/source-coda/metadata.yaml index b547db60428d..b03b3914aecf 100644 --- a/airbyte-integrations/connectors/source-coda/metadata.yaml +++ b/airbyte-integrations/connectors/source-coda/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 27f910fd-f832-4b2e-bcfd-6ab342e434d8 - dockerImageTag: 0.1.0 + dockerImageTag: 1.0.0 dockerRepository: airbyte/source-coda githubIssueLabel: source-coda icon: coda.svg diff --git a/airbyte-integrations/connectors/source-coda/source_coda/schemas/docs.json b/airbyte-integrations/connectors/source-coda/source_coda/schemas/docs.json index 3a28e58b0c33..4135cdd252cd 100644 --- a/airbyte-integrations/connectors/source-coda/source_coda/schemas/docs.json +++ b/airbyte-integrations/connectors/source-coda/source_coda/schemas/docs.json @@ -34,7 +34,7 @@ "owner": { "type": "string" }, - "owner_name": { + "ownerName": { "type": "string" }, "docSize": { diff --git a/airbyte-integrations/connectors/source-coda/source_coda/schemas/pages.json b/airbyte-integrations/connectors/source-coda/source_coda/schemas/pages.json index 79ca344a2b13..f141fd093464 100644 --- a/airbyte-integrations/connectors/source-coda/source_coda/schemas/pages.json +++ b/airbyte-integrations/connectors/source-coda/source_coda/schemas/pages.json @@ -159,6 +159,82 @@ } } } + }, + "createdAt": { + "type": ["null", "string"] + }, + "contentType": { + "type": ["null", "string"], + "enum": [ + "canvas", + "embed" + ] + }, + "createdBy": { + "type": "object", + "properties": { + "@context": { + "type": "string" + }, + "@type": { + "type": "string" + }, + "additionalType": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "authors": { + "type": ["null", "array"], + "items": { + "type": "object", + "properties": { + "@context": { + "type": "string" + }, + "@type": { + "type": "string" + }, + "additionalType": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + }, + "updatedBy": { + "type": ["null", "object"], + "properties": { + "@context": { + "type": "string" + }, + "@type": { + "type": "string" + }, + "additionalType": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "updatedAt": { + "type": ["null", "string"] } } } diff --git a/airbyte-integrations/connectors/source-coda/source_coda/source.py b/airbyte-integrations/connectors/source-coda/source_coda/source.py index 08ceb1a32a15..d61a05371e43 100755 --- a/airbyte-integrations/connectors/source-coda/source_coda/source.py +++ b/airbyte-integrations/connectors/source-coda/source_coda/source.py @@ -151,6 +151,8 @@ def check_connection(self, logger, config) -> Tuple[bool, any]: r = requests.get(f"{BASE_URL}whoami", headers=headers) if r.status_code == 200: return True, None + else: + r.raise_for_status() except Exception as e: return False, e diff --git a/docs/integrations/sources/coda.md b/docs/integrations/sources/coda.md index c39e90b19cc0..8b01a97302f9 100755 --- a/docs/integrations/sources/coda.md +++ b/docs/integrations/sources/coda.md @@ -63,4 +63,5 @@ The Coda source connector supports the following [sync modes](https://docs.airby | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------- | +| 1.0.0 | 2023-07-10 | [28093](https://github.com/airbytehq/airbyte/pull/28093) | Update `docs` and `pages` schemas | | 0.1.0 | 2022-11-17 | [18675](https://github.com/airbytehq/airbyte/pull/18675) | 🎉 New source: Coda [python cdk] | From 79beae8a07cb1d5816dc7d37f56789bfe4db4798 Mon Sep 17 00:00:00 2001 From: Himanshu Date: Tue, 11 Jul 2023 03:02:35 +0530 Subject: [PATCH 13/63] =?UTF-8?q?=E2=9C=A8=20Source=20Coda:=20Add=20rows?= =?UTF-8?q?=20to=20codaio=20source=20(#27797)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Add rows to codaio source * fix formatting, iterate version, update docs --------- Co-authored-by: Mal Hancock --- .../connectors/source-coda/Dockerfile | 2 +- .../connectors/source-coda/metadata.yaml | 2 +- .../source-coda/source_coda/schemas/rows.json | 45 +++++++++++++++++++ .../source-coda/source_coda/source.py | 17 +++++++ .../source-coda/unit_tests/test_source.py | 2 +- docs/integrations/sources/coda.md | 2 + 6 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 airbyte-integrations/connectors/source-coda/source_coda/schemas/rows.json diff --git a/airbyte-integrations/connectors/source-coda/Dockerfile b/airbyte-integrations/connectors/source-coda/Dockerfile index bcb600c57a25..041ab711ed49 100644 --- a/airbyte-integrations/connectors/source-coda/Dockerfile +++ b/airbyte-integrations/connectors/source-coda/Dockerfile @@ -34,5 +34,5 @@ COPY source_coda ./source_coda ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=1.0.0 +LABEL io.airbyte.version=1.1.0 LABEL io.airbyte.name=airbyte/source-coda diff --git a/airbyte-integrations/connectors/source-coda/metadata.yaml b/airbyte-integrations/connectors/source-coda/metadata.yaml index b03b3914aecf..725e83df623b 100644 --- a/airbyte-integrations/connectors/source-coda/metadata.yaml +++ b/airbyte-integrations/connectors/source-coda/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: 27f910fd-f832-4b2e-bcfd-6ab342e434d8 - dockerImageTag: 1.0.0 + dockerImageTag: 1.1.0 dockerRepository: airbyte/source-coda githubIssueLabel: source-coda icon: coda.svg diff --git a/airbyte-integrations/connectors/source-coda/source_coda/schemas/rows.json b/airbyte-integrations/connectors/source-coda/source_coda/schemas/rows.json new file mode 100644 index 000000000000..3444cac46f97 --- /dev/null +++ b/airbyte-integrations/connectors/source-coda/source_coda/schemas/rows.json @@ -0,0 +1,45 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + }, + "href": { + "type": "string" + }, + "name": { + "type": "string" + }, + "index": { + "type": "number" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "browserLink": { + "type": "string" + }, + "values": { + "type": "object", + "properties": { + "^c-_": { + "type": [ + "string", + "number", + "object", + "array", + "boolean", + "null" + ] + } + } + } + } +} diff --git a/airbyte-integrations/connectors/source-coda/source_coda/source.py b/airbyte-integrations/connectors/source-coda/source_coda/source.py index d61a05371e43..940e0dfe22f1 100755 --- a/airbyte-integrations/connectors/source-coda/source_coda/source.py +++ b/airbyte-integrations/connectors/source-coda/source_coda/source.py @@ -114,6 +114,22 @@ def path( return f"docs/{doc_id}/tables" +class Rows(CodaStreamDoc): + + primary_key = "id" + + def __init__(self, **kwargs): + super().__init__(**kwargs) + + def path( + self, stream_state: Mapping[str, Any] = None, stream_slice: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None + ) -> str: + doc_id = stream_slice["doc_id"] + tableid_or_name = stream_slice["tableid"] + + return f"docs/{doc_id}/tables/${tableid_or_name}/rows" + + class Formulas(CodaStreamDoc): primary_key = "id" @@ -169,4 +185,5 @@ def streams(self, config: Mapping[str, Any]) -> List[Stream]: Tables(**stream_args), Formulas(**stream_args), Controls(**stream_args), + Rows(**stream_args), ] diff --git a/airbyte-integrations/connectors/source-coda/unit_tests/test_source.py b/airbyte-integrations/connectors/source-coda/unit_tests/test_source.py index 163a5d37fa21..f0f8a7d6b24c 100644 --- a/airbyte-integrations/connectors/source-coda/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-coda/unit_tests/test_source.py @@ -48,5 +48,5 @@ def test_streams(mocker): source = SourceCoda() config_mock = MagicMock() streams = source.streams(config_mock) - expected_streams_number = 7 + expected_streams_number = 8 assert len(streams) == expected_streams_number diff --git a/docs/integrations/sources/coda.md b/docs/integrations/sources/coda.md index 8b01a97302f9..da52242953e5 100755 --- a/docs/integrations/sources/coda.md +++ b/docs/integrations/sources/coda.md @@ -49,6 +49,7 @@ The Coda source connector supports the following [sync modes](https://docs.airby - [Tables](https://coda.io/developers/apis/v1#tag/Tables/operation/listTables) - [Formulas](https://coda.io/developers/apis/v1#tag/Formulas/operation/listFormulas) - [Controls](https://coda.io/developers/apis/v1#tag/Controls/operation/listControls) +- [Rows](https://coda.io/developers/apis/v1#tag/Rows/operation/listRows) ## Data type map @@ -63,5 +64,6 @@ The Coda source connector supports the following [sync modes](https://docs.airby | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------- | +| 1.1.0 | 2023-07-10 | [27797](https://github.com/airbytehq/airbyte/pull/27797) | Add `rows` stream | | 1.0.0 | 2023-07-10 | [28093](https://github.com/airbytehq/airbyte/pull/28093) | Update `docs` and `pages` schemas | | 0.1.0 | 2022-11-17 | [18675](https://github.com/airbytehq/airbyte/pull/18675) | 🎉 New source: Coda [python cdk] | From f3ea989ca219067816198b0079fbce69a5204425 Mon Sep 17 00:00:00 2001 From: Akash Kulkarni <113392464+akashkulk@users.noreply.github.com> Date: Mon, 10 Jul 2023 15:17:16 -0700 Subject: [PATCH 14/63] Fixing `XminCtidUtils` unit test (#28104) * Add logging functionality - Add logging for DB version (all JDBC sources) - Add logging for Xmin values * Automated Change * Renaming + comments * More comments * Initial commit for xmin prototype - Add spec.json - Catalog - Try to change incremental query * Skeleton for sync Decision is to use a whole new sync method * With cursor * Working catalog + attempt at xmin record iterator * Unit tested code * Fix build break * Fixing state * more xmin * Revert unchanged files * Addressing code review comments * use generated pojo * Add iniital XminStateManagerTest * Additional unit tests * Added unit test * Update xmin state manager test * Remove spec.json xmin option * Fixed bug where full refresh streams were not being filtered out for Xmin * Fix latest safe change boundary issue * Xmin spec update * Fix * Automated Commit - Format and Process Resources Changes * Remove full_refresh as an option for xmin syncs and always include incremental syncs * Fix integ test * revert unused files * revert * Bump docker + update change log * Modify order of CDC * Update expected_spec.json * Update expected_json Fix acceptance tests * Reverse order for xmin replication * Update expected strict encrypt json * Fix broken XminCtidUtilsTest - Logic was added to XminCtidUtils to filter for incremental syncs, but the test data wasn't updated to represent this. This doesn't require any publishing --------- Co-authored-by: akashkulk Co-authored-by: subodh --- .../source/postgres/xmin/XminCtidUtilsTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/xmin/XminCtidUtilsTest.java b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/xmin/XminCtidUtilsTest.java index 6a5ceb13cb1d..2cefbb4e047b 100644 --- a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/xmin/XminCtidUtilsTest.java +++ b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/xmin/XminCtidUtilsTest.java @@ -40,7 +40,8 @@ public class XminCtidUtilsTest { Field.of("COL_MAKE_ID", JsonSchemaType.INTEGER), Field.of("COL_MODEL", JsonSchemaType.STRING)) .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL)) - .withSourceDefinedPrimaryKey(List.of(List.of("COL_ID")))); + .withSourceDefinedPrimaryKey(List.of(List.of("COL_ID")))) + .withSyncMode(SyncMode.INCREMENTAL); private static final ConfiguredAirbyteStream MODELS_STREAM_2 = CatalogHelpers.toDefaultConfiguredStream(CatalogHelpers.createAirbyteStream( "MODELS_STREAM_NAME_2", @@ -49,7 +50,8 @@ public class XminCtidUtilsTest { Field.of("COL_MAKE_ID", JsonSchemaType.INTEGER), Field.of("COL_MODEL", JsonSchemaType.STRING)) .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL)) - .withSourceDefinedPrimaryKey(List.of(List.of("COL_ID")))); + .withSourceDefinedPrimaryKey(List.of(List.of("COL_ID")))) + .withSyncMode(SyncMode.INCREMENTAL); @Test public void emptyStateTest() { From f79aa72d64de412c2710ab806cd1148df7314133 Mon Sep 17 00:00:00 2001 From: Brian Lai <51336873+brianjlai@users.noreply.github.com> Date: Mon, 10 Jul 2023 20:27:02 -0400 Subject: [PATCH 15/63] refactor config validation_policy to not store policies on the config (#28097) --- .../config/file_based_stream_config.py | 28 +++++------ .../sources/file_based/exceptions.py | 1 + .../sources/file_based/file_based_source.py | 7 ++- .../stream/abstract_file_based_stream.py | 13 +++++- .../stream/default_file_based_stream.py | 4 +- .../config/test_file_based_stream_config.py | 46 +++++++++++++++++-- .../file_based/scenarios/check_scenarios.py | 6 +-- 7 files changed, 76 insertions(+), 29 deletions(-) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py index b210a16fd1bc..f50156be84a6 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py @@ -7,7 +7,7 @@ from typing import Any, Dict, List, Mapping, Optional, Union from airbyte_cdk.models import ConfiguredAirbyteCatalog -from pydantic import BaseModel, root_validator, validator +from pydantic import BaseModel, validator PrimaryKeyType = Optional[Union[str, List[str], List[List[str]]]] @@ -66,7 +66,6 @@ class FileBasedStreamConfig(BaseModel): file_type: str globs: Optional[List[str]] validation_policy: Union[str, Any] - validation_policies: Dict[str, Any] catalog_schema: Optional[ConfiguredAirbyteCatalog] input_schema: Optional[Dict[str, Any]] primary_key: PrimaryKeyType @@ -74,23 +73,18 @@ class FileBasedStreamConfig(BaseModel): days_to_sync_if_history_is_full: Optional[int] format: Optional[Mapping[str, CsvFormat]] # this will eventually be a Union once we have more than one format type + @validator("file_type", pre=True) + def validate_file_type(cls, v): + if v not in VALID_FILE_TYPES: + raise ValueError(f"Format filetype {v} is not a supported file type") + return v + @validator("format", pre=True) def transform_format(cls, v): if isinstance(v, Mapping): file_type = v.get("filetype", "") - if file_type.casefold() not in VALID_FILE_TYPES: - raise ValueError(f"Format filetype {file_type} is not a supported file type") - return {file_type: {key: val for key, val in v.items()}} + if file_type: + if file_type.casefold() not in VALID_FILE_TYPES: + raise ValueError(f"Format filetype {file_type} is not a supported file type") + return {file_type: {key: val for key, val in v.items()}} return v - - @root_validator - def set_validation_policy(cls, values): - validation_policy_key = values.get("validation_policy") - validation_policies = values.get("validation_policies") - - if validation_policy_key not in validation_policies: - raise ValueError(f"validation_policy must be one of {list(validation_policies.keys())}") - - values["validation_policy"] = validation_policies[validation_policy_key] - - return values diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/exceptions.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/exceptions.py index 93f705261b61..acad810899e3 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/exceptions.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/exceptions.py @@ -30,6 +30,7 @@ class FileBasedSourceError(Enum): CONFIG_VALIDATION_ERROR = "Error creating stream config object." MISSING_SCHEMA = "Expected `json_schema` in the configured catalog but it is missing." UNDEFINED_PARSER = "No parser is defined for this file type." + UNDEFINED_VALIDATION_POLICY = "The validation policy defined in the config does not exist for the source." class BaseFileBasedSourceError(Exception): diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py index e3fc7031b89d..5aa9c704ae48 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py @@ -81,7 +81,11 @@ def streams(self, config: Mapping[str, Any]) -> List[AbstractFileBasedStream]: try: streams = [] for stream in config["streams"]: - stream_config = FileBasedStreamConfig(validation_policies=self.validation_policies, **stream) + stream_config = FileBasedStreamConfig(**stream) + if stream_config.validation_policy not in self.validation_policies: + raise ValidationError( + f"validation_policy must be one of {list(self.validation_policies.keys())}", model=FileBasedStreamConfig + ) streams.append( DefaultFileBasedStream( config=stream_config, @@ -90,6 +94,7 @@ def streams(self, config: Mapping[str, Any]) -> List[AbstractFileBasedStream]: availability_strategy=self.availability_strategy, discovery_policy=self.discovery_policy, parsers=self.parsers, + validation_policies=self.validation_policies, cursor=DefaultFileBasedCursor(stream_config.max_history_size, stream_config.days_to_sync_if_history_is_full), ) ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py index 5f3ec4d5dbe5..f538b2924cd2 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py @@ -9,10 +9,11 @@ from airbyte_cdk.models import ConfiguredAirbyteCatalog, SyncMode from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig, PrimaryKeyType from airbyte_cdk.sources.file_based.discovery_policy import AbstractDiscoveryPolicy -from airbyte_cdk.sources.file_based.exceptions import FileBasedSourceError, UndefinedParserError +from airbyte_cdk.sources.file_based.exceptions import FileBasedSourceError, RecordParseError, UndefinedParserError from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser from airbyte_cdk.sources.file_based.remote_file import RemoteFile +from airbyte_cdk.sources.file_based.schema_validation_policies import AbstractSchemaValidationPolicy from airbyte_cdk.sources.file_based.types import StreamSlice, StreamState from airbyte_cdk.sources.streams import Stream from airbyte_cdk.sources.streams.availability_strategy import AvailabilityStrategy @@ -42,6 +43,7 @@ def __init__( availability_strategy: AvailabilityStrategy, discovery_policy: AbstractDiscoveryPolicy, parsers: Dict[str, FileTypeParser], + validation_policies: Dict[str, AbstractSchemaValidationPolicy], ): super().__init__() self.config = config @@ -50,6 +52,7 @@ def __init__( self._discovery_policy = discovery_policy self._availability_strategy = availability_strategy self._parsers = parsers + self._validation_policies = validation_policies @property @abstractmethod @@ -122,7 +125,13 @@ def get_parser(self, file_type: str) -> FileTypeParser: raise UndefinedParserError(FileBasedSourceError.UNDEFINED_PARSER, stream=self.name, file_type=file_type) def record_passes_validation_policy(self, record: Mapping[str, Any]) -> bool: - return self.config.validation_policy.record_passes_validation_policy(record, self._catalog_schema) + validation_policy = self._validation_policies.get(self.config.validation_policy) + if validation_policy: + return validation_policy.record_passes_validation_policy(record=record, schema=self._catalog_schema) + else: + raise RecordParseError( + FileBasedSourceError.UNDEFINED_VALIDATION_POLICY, stream=self.name, validation_policy=self.config.validation_policy + ) @cached_property def availability_strategy(self): diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/default_file_based_stream.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/default_file_based_stream.py index 19bbf59fd309..96fbddb7a3fa 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/default_file_based_stream.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/default_file_based_stream.py @@ -93,7 +93,7 @@ def read_records_from_slice(self, stream_slice: StreamSlice) -> Iterable[Mapping type=Type.LOG, log=AirbyteLogMessage( level=Level.INFO, - message=f"Stopping sync in accordance with the configured validation policy. Records in file did not conform to the schema. stream={self.name} file={file.uri} validation_policy={self.config.validation_policy.name} n_skipped={n_skipped}", + message=f"Stopping sync in accordance with the configured validation policy. Records in file did not conform to the schema. stream={self.name} file={file.uri} validation_policy={self.config.validation_policy} n_skipped={n_skipped}", ), ) break @@ -114,7 +114,7 @@ def read_records_from_slice(self, stream_slice: StreamSlice) -> Iterable[Mapping type=Type.LOG, log=AirbyteLogMessage( level=Level.INFO, - message=f"Records in file did not pass validation policy. stream={self.name} file={file.uri} n_skipped={n_skipped} validation_policy={self.config.validation_policy.name}", + message=f"Records in file did not pass validation policy. stream={self.name} file={file.uri} n_skipped={n_skipped} validation_policy={self.config.validation_policy}", ), ) diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/config/test_file_based_stream_config.py b/airbyte-cdk/python/unit_tests/sources/file_based/config/test_file_based_stream_config.py index 32d578554111..3391b4954001 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/config/test_file_based_stream_config.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/config/test_file_based_stream_config.py @@ -3,8 +3,7 @@ # import pytest as pytest -from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig, QuotingBehavior -from airbyte_cdk.sources.file_based.schema_validation_policies import EmitRecordPolicy +from airbyte_cdk.sources.file_based.config.file_based_stream_config import CsvFormat, FileBasedStreamConfig, QuotingBehavior from pydantic import ValidationError @@ -27,9 +26,11 @@ def test_csv_config(file_type, input_format, expected_format, expected_error): "file_type": file_type, "globs": ["*"], "validation_policy": "emit_record", - "validation_policies": {"emit_record": EmitRecordPolicy()}, - "format": input_format, + "format": { + file_type: input_format + }, } + if expected_error: with pytest.raises(expected_error): FileBasedStreamConfig(**stream_config) @@ -37,4 +38,41 @@ def test_csv_config(file_type, input_format, expected_format, expected_error): actual_config = FileBasedStreamConfig(**stream_config) assert not hasattr(actual_config.format[file_type], "filetype") for expected_format_field, expected_format_value in expected_format.items(): + assert isinstance(actual_config.format[file_type], CsvFormat) assert getattr(actual_config.format[file_type], expected_format_field) == expected_format_value + + +def test_legacy_format(): + """ + This test verifies that we can process the legacy format of the config object used by the existing S3 source with a + single `format` option as opposed to the current file_type -> format mapping. + """ + stream_config = { + "name": "stream1", + "file_type": "csv", + "globs": ["*"], + "validation_policy": "emit_record_on_schema_mismatch", + "format": { + "filetype": "csv", + "delimiter": "d", + "quote_char": "q", + "escape_char": "e", + "encoding": "ascii", + "double_quote": True, + "quoting_behavior": "Quote All" + }, + } + + expected_format = { + "delimiter": "d", + "quote_char": "q", + "escape_char": "e", + "encoding": "ascii", + "double_quote": True, + "quoting_behavior": QuotingBehavior.QUOTE_ALL + } + + actual_config = FileBasedStreamConfig(**stream_config) + assert isinstance(actual_config.format["csv"], CsvFormat) + for expected_format_field, expected_format_value in expected_format.items(): + assert getattr(actual_config.format["csv"], expected_format_field) == expected_format_value diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/check_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/check_scenarios.py index f6d840a41641..97edcbc36e30 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/check_scenarios.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/check_scenarios.py @@ -2,7 +2,7 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # -from airbyte_cdk.sources.file_based.exceptions import ConfigValidationError, FileBasedSourceError +from airbyte_cdk.sources.file_based.exceptions import FileBasedSourceError from unit_tests.sources.file_based.helpers import ( FailingSchemaValidationPolicy, TestErrorListMatchingFilesInMemoryFilesStreamReader, @@ -174,8 +174,8 @@ ], } ) - .set_validation_policies(FailingSchemaValidationPolicy) - .set_expected_check_error(ConfigValidationError, FileBasedSourceError.ERROR_VALIDATING_RECORD) + .set_validation_policies({FailingSchemaValidationPolicy.ALWAYS_FAIL: FailingSchemaValidationPolicy()}) + .set_expected_check_error(None, FileBasedSourceError.ERROR_VALIDATING_RECORD) ).build() From 57a7a03705525543417856fcc0c822fd272e7d3b Mon Sep 17 00:00:00 2001 From: Marcos Marx Date: Tue, 11 Jul 2023 11:50:32 -0300 Subject: [PATCH 16/63] change discourse to github discussion (#28152) --- README.md | 2 +- docs/archive/examples/zoom-activity-dashboard.md | 2 +- docs/archive/faq/README.md | 2 +- docs/cli-documentation.md | 2 +- docs/connector-development/cdk-python/README.md | 2 +- docs/integrations/sources/jira.md | 4 ++-- docs/integrations/sources/shopify.md | 2 +- docs/quickstart/deploy-airbyte.md | 2 +- docs/troubleshooting.md | 14 ++++++-------- octavia-cli/README.md | 2 +- 10 files changed, 16 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 7298b49a8186..bdf4db5d1544 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ Try it out yourself with our [demo app](https://demo.airbyte.io/), visit our [fu ### Join the Airbyte Community -The Airbyte community can be found in the [Airbyte Community Slack](https://airbyte.com/community), where you can ask questions and voice ideas. You can also ask for help in our [Discourse forum](https://discuss.airbyte.io/), or join our [office hours](https://airbyte.io/weekly-office-hours/). Airbyte's roadmap is publicly viewable on [GitHub](https://github.com/orgs/airbytehq/projects/37/views/1?pane=issue&itemId=26937554). +The Airbyte community can be found in the [Airbyte Community Slack](https://airbyte.com/community), where you can ask questions and voice ideas. You can also ask for help in our [Airbyte Forum](https://github.com/airbytehq/airbyte/discussions), or join our [Office Hours](https://airbyte.io/daily-office-hours/). Airbyte's roadmap is publicly viewable on [GitHub](https://github.com/orgs/airbytehq/projects/37/views/1?pane=issue&itemId=26937554). For videos and blogs on data engineering and building your data stack, check out Airbyte's [Content Hub](https://airbyte.com/content-hub), [Youtube](https://www.youtube.com/c/AirbyteHQ), and sign up for our [newsletter](https://airbyte.com/newsletter). diff --git a/docs/archive/examples/zoom-activity-dashboard.md b/docs/archive/examples/zoom-activity-dashboard.md index 8dc8b2c98ad1..a141f2da418a 100644 --- a/docs/archive/examples/zoom-activity-dashboard.md +++ b/docs/archive/examples/zoom-activity-dashboard.md @@ -32,7 +32,7 @@ In order to replicate Zoom data, we will need to use [Airbyte’s Zoom connector `docker-compose up` -You can find more details about this in the [Getting Started FAQ](https://discuss.airbyte.io/c/faq/15) on our Discourse Forum. +You can find more details about this in the [Getting Started FAQ](https://discuss.airbyte.io/c/faq/15) on our [Airbyte Forum](https://github.com/airbytehq/airbyte/discussions). This will start up Airbyte on `localhost:8000`; open that address in your browser to access the Airbyte dashboard. diff --git a/docs/archive/faq/README.md b/docs/archive/faq/README.md index daec5e69ead1..1f6a217b74c7 100644 --- a/docs/archive/faq/README.md +++ b/docs/archive/faq/README.md @@ -1,5 +1,5 @@ # FAQ -Our FAQ is now a section on our Discourse forum. Check it out [here](https://discuss.airbyte.io/c/faq/15)! +Our FAQ is now a section on our Airbyte Forum. Check it out [here](https://github.com/airbytehq/airbyte/discussions)! If you don't see your question answered, feel free to open up a new topic for it. \ No newline at end of file diff --git a/docs/cli-documentation.md b/docs/cli-documentation.md index 1df96e2b6f27..ccf89fef1b3a 100644 --- a/docs/cli-documentation.md +++ b/docs/cli-documentation.md @@ -27,7 +27,7 @@ These are non-exhaustive use cases `octavia` can be convenient for: - Integrating the Airbyte configuration deployment in a dev ops tooling stack: Helm, Ansible etc. - Streamlining the deployment of Airbyte configurations to multiple Airbyte instance. -Feel free to share your use cases with the community in [#octavia-cli](https://airbytehq.slack.com/archives/C02RRUG9CP5) or on [Discourse](https://discuss.airbyte.io/). +Feel free to share your use cases with the community in [#octavia-cli](https://airbytehq.slack.com/archives/C02RRUG9CP5) or on [Airbyte Forum](https://github.com/airbytehq/airbyte/discussions). ## Table of content diff --git a/docs/connector-development/cdk-python/README.md b/docs/connector-development/cdk-python/README.md index b6e97a65e167..5e2c63af32e2 100644 --- a/docs/connector-development/cdk-python/README.md +++ b/docs/connector-development/cdk-python/README.md @@ -18,7 +18,7 @@ The CDK provides an improved developer experience by providing basic implementat This document is a general introduction to the CDK. Readers should have basic familiarity with the [Airbyte Specification](https://docs.airbyte.com/understanding-airbyte/airbyte-protocol/) before proceeding. -If you have any issues with troubleshooting or want to learn more about the CDK from the Airbyte team, head to [the Connector Development section of our Discourse forum](https://discuss.airbyte.io/c/connector-development/16) to inquire further! +If you have any issues with troubleshooting or want to learn more about the CDK from the Airbyte team, head to [the Connector Development section of our Airbyte Forum](https://github.com/airbytehq/airbyte/discussions) to inquire further! ## Getting Started diff --git a/docs/integrations/sources/jira.md b/docs/integrations/sources/jira.md index 772a077fdac2..63b86cfb5574 100644 --- a/docs/integrations/sources/jira.md +++ b/docs/integrations/sources/jira.md @@ -41,7 +41,7 @@ The Jira source connector supports the following [sync modes](https://docs.airby ## Troubleshooting -Check out common troubleshooting issues for the Jira connector on our Discourse [here](https://discuss.airbyte.io/tags/c/connector/11/source-jira). +Check out common troubleshooting issues for the Jira connector on our Airbyte Forum [here](https://github.com/airbytehq/airbyte/discussions). ## Supported Streams @@ -116,7 +116,7 @@ or disallow these tables to be selected when configuring a connection. ## Troubleshooting -Check out common troubleshooting issues for the Jira connector on our Discourse [here](https://discuss.airbyte.io/tags/c/connector/11/source-jira). +Check out common troubleshooting issues for the Jira connector on our Airbyte Forum [here](https://github.com/airbytehq/airbyte/discussions). ## Rate Limiting & Performance diff --git a/docs/integrations/sources/shopify.md b/docs/integrations/sources/shopify.md index 65d21c0f685a..d0dbcc66d25b 100644 --- a/docs/integrations/sources/shopify.md +++ b/docs/integrations/sources/shopify.md @@ -70,7 +70,7 @@ This source can sync data for the [Shopify REST API](https://shopify.dev/api/adm ## Troubleshooting tips -Check out common troubleshooting issues for the Shopify source connector on our Discourse [here](https://discuss.airbyte.io/tags/c/connector/11/source-shopify). +Check out common troubleshooting issues for the Shopify source connector on our Airbyte Forum [here](https://github.com/airbytehq/airbyte/discussions). ## Supported Streams diff --git a/docs/quickstart/deploy-airbyte.md b/docs/quickstart/deploy-airbyte.md index 040adc3dd49c..4df34e9aa05a 100644 --- a/docs/quickstart/deploy-airbyte.md +++ b/docs/quickstart/deploy-airbyte.md @@ -19,7 +19,7 @@ If you need direct access to our team for any kind of assistance, don't hesitate ## FAQ -If you have any questions about the Airbyte Open-Source setup and deployment process, head over to our [Getting Started FAQ](https://discuss.airbyte.io/c/faq/15) on our Discourse that answers the following questions and more: +If you have any questions about the Airbyte Open-Source setup and deployment process, head over to our [Getting Started FAQ](https://github.com/airbytehq/airbyte/discussions/categories/questions) on our Airbyte Forum that answers the following questions and more: - How long does it take to set up Airbyte? - Where can I see my data once I've run a sync? diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index d56a7526c995..b9a5d7d12472 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -47,15 +47,13 @@ You can access Airbyte Slack [here](https://slack.airbyte.com/). * `#help-contributions`: for any questions about contributing to Airbyte’s codebase ## Airbyte Forum -We are driving our community support from our [forum](https://discuss.airbyte.io/). +We are driving our community support from our [forum](https://github.com/airbytehq/airbyte/discussions). **Before posting on this forum please first check if a similar question was already answered.** **The existing categories**: -* [Connector Issues](https://discuss.airbyte.io/c/issues/11): Support requests on connector issues. -* [Platform, Deploy & Infra Issues](https://discuss.airbyte.io/c/deploy-infra-issues/24): Discussion about Airbyte Platform or deploys/infrastructure issues. -* [API, CLI & Orchestrations Issues](https://discuss.airbyte.io/c/api-cli-orchestration-issues/25): Discussion about how to use or issues with the API, CLI or orchestration -* [Connector Development](https://discuss.airbyte.io/c/connector-development/16): Ask help when you're developing a new connector. -* [Q&A](https://discuss.airbyte.io/c/faq/15): Ask anything that doesn’t belong to the other categories. -* [Guides](https://discuss.airbyte.io/c/guides/17): Small tutorials and guides solving deployments or workarounds using connectors. -* [Frequently Asked Questions](https://discuss.airbyte.io/c/read-answers-by-the-airbyte-team-to-commonly-asked-questions-from-our-community/22): Read answers from the Airbyte team for commonly asked questions from the community. \ No newline at end of file +* 🙏 Questions: Ask the community for help on your question. As a reminder, the Airbyte team won’t provide help here, as our support is part of our Airbyte Cloud and Airbyte Enterprise offers. +* 💡 Ideas: Share ideas for new features, improvements, or feedback. +* 🙌 Show & Tell: Share projects, tutorials, videos, and articles you are working on. +* 🫶 Kind words: Show off something you love about Airbyte +* 🐙 General: For anything that doesn’t fit in the above categories diff --git a/octavia-cli/README.md b/octavia-cli/README.md index b8cc6cc4d777..2529e1dbf94c 100644 --- a/octavia-cli/README.md +++ b/octavia-cli/README.md @@ -27,7 +27,7 @@ These are non-exhaustive use cases `octavia` can be convenient for: - Integrating the Airbyte configuration deployment in a dev ops tooling stack: Helm, Ansible etc. - Streamlining the deployment of Airbyte configurations to multiple Airbyte instance. -Feel free to share your use cases with the community in [#octavia-cli](https://airbytehq.slack.com/archives/C02RRUG9CP5) or on [Discourse](https://discuss.airbyte.io/). +Feel free to share your use cases with the community in [#octavia-cli](https://airbytehq.slack.com/archives/C02RRUG9CP5) or on [Airbyte Forum](https://github.com/airbytehq/airbyte/discussions). ## Table of content From 9217c1221bb484792517fd7bcee2165f68171338 Mon Sep 17 00:00:00 2001 From: Christo Grabowski <108154848+ChristoGrab@users.noreply.github.com> Date: Tue, 11 Jul 2023 11:48:26 -0400 Subject: [PATCH 17/63] =?UTF-8?q?Source=20Close.com:=20add=20human=20reada?= =?UTF-8?q?ble=20titles=20to=20`api-key`=20and=20`start=5Fd=E2=80=A6=20(#2?= =?UTF-8?q?7950)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Source Close.com: add human readable titles to `api-key` and `start_date` fields - Added `api-key` title: `API Key` - Added `start_date` title: `Replication Start Date` * update version to 0.4.1 in metadata.yaml * update version to 0.4.1 in Dockerfile * update close-com.md changelog to 0.4.1 * Update airbyte-integrations/connectors/source-close-com/source_close_com/spec.json Co-authored-by: Sherif A. Nada --------- Co-authored-by: Sherif A. Nada --- airbyte-integrations/connectors/source-close-com/Dockerfile | 2 +- .../connectors/source-close-com/metadata.yaml | 2 +- .../connectors/source-close-com/source_close_com/spec.json | 4 +++- docs/integrations/sources/close-com.md | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/airbyte-integrations/connectors/source-close-com/Dockerfile b/airbyte-integrations/connectors/source-close-com/Dockerfile index a4ad64d7e1a5..accf25de76c0 100644 --- a/airbyte-integrations/connectors/source-close-com/Dockerfile +++ b/airbyte-integrations/connectors/source-close-com/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.4.0 +LABEL io.airbyte.version=0.4.1 LABEL io.airbyte.name=airbyte/source-close-com diff --git a/airbyte-integrations/connectors/source-close-com/metadata.yaml b/airbyte-integrations/connectors/source-close-com/metadata.yaml index 235dd94eb686..86a4ee68da90 100644 --- a/airbyte-integrations/connectors/source-close-com/metadata.yaml +++ b/airbyte-integrations/connectors/source-close-com/metadata.yaml @@ -5,7 +5,7 @@ data: connectorSubtype: api connectorType: source definitionId: dfffecb7-9a13-43e9-acdc-b92af7997ca9 - dockerImageTag: 0.4.0 + dockerImageTag: 0.4.1 dockerRepository: airbyte/source-close-com githubIssueLabel: source-close-com icon: close.svg diff --git a/airbyte-integrations/connectors/source-close-com/source_close_com/spec.json b/airbyte-integrations/connectors/source-close-com/source_close_com/spec.json index 173feb2e30ad..1b642bf19eee 100644 --- a/airbyte-integrations/connectors/source-close-com/source_close_com/spec.json +++ b/airbyte-integrations/connectors/source-close-com/source_close_com/spec.json @@ -8,13 +8,15 @@ "additionalProperties": true, "properties": { "api_key": { + "title": "API Key", "type": "string", "description": "Close.com API key (usually starts with 'api_'; find yours here).", "airbyte_secret": true }, "start_date": { + "title": "Replication Start Date", "type": "string", - "description": "The start date to sync data. Leave blank for full sync. Format: YYYY-MM-DD.", + "description": "The start date to sync data; all data after this date will be replicated. Leave blank to retrieve all the data available in the account. Format: YYYY-MM-DD.", "examples": ["2021-01-01"], "default": "2021-01-01", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$", diff --git a/docs/integrations/sources/close-com.md b/docs/integrations/sources/close-com.md index 8e86986eb6b8..ee6a12fce5f4 100644 --- a/docs/integrations/sources/close-com.md +++ b/docs/integrations/sources/close-com.md @@ -105,6 +105,7 @@ The Close.com connector is subject to rate limits. For more information on this | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:-------------------------------------------------------------------------------------------------------| +| 0.4.1 | 2023-07-04 | [27950](https://github.com/airbytehq/airbyte/pull/27950) | Add human readable titles to API Key and Start Date fields | | 0.4.0 | 2023-06-27 | [27776](https://github.com/airbytehq/airbyte/pull/27776) | Update the `Email Followup Tasks` stream schema | | 0.3.0 | 2023-05-12 | [26024](https://github.com/airbytehq/airbyte/pull/26024) | Update the `Email sequences` stream schema | | 0.2.2 | 2023-05-05 | [25868](https://github.com/airbytehq/airbyte/pull/25868) | Added `CDK TypeTransformer` to gurantee JSON Schema types, added missing properties for `roles` stream | From 07286f7069a09304f77af1bfda77b32898eab3b4 Mon Sep 17 00:00:00 2001 From: Catherine Noll Date: Tue, 11 Jul 2023 11:52:47 -0400 Subject: [PATCH 18/63] File-based CDK: implement schemaless option (#28063) --- .../config/file_based_stream_config.py | 1 + .../sources/file_based/file_based_source.py | 13 +- .../sources/file_based/schema_helpers.py | 2 + .../stream/default_file_based_stream.py | 9 +- .../file_based/scenarios/csv_scenarios.py | 352 +++++++++++++++++- .../sources/file_based/test_scenarios.py | 10 + 6 files changed, 379 insertions(+), 8 deletions(-) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py index f50156be84a6..5c1313508a9f 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py @@ -72,6 +72,7 @@ class FileBasedStreamConfig(BaseModel): max_history_size: Optional[int] days_to_sync_if_history_is_full: Optional[int] format: Optional[Mapping[str, CsvFormat]] # this will eventually be a Union once we have more than one format type + schemaless: bool = False @validator("file_type", pre=True) def validate_file_type(cls, v): diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py index 5aa9c704ae48..de5b52f3d31a 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py @@ -74,6 +74,14 @@ def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> return not bool(errors), (errors or None) + def _validate_stream_config(self, stream_config: FileBasedStreamConfig): + if stream_config.validation_policy not in self.validation_policies: + raise ValidationError( + f"`validation_policy` must be one of {list(self.validation_policies.keys())}", model=FileBasedStreamConfig + ) + if stream_config.input_schema and stream_config.schemaless: + raise ValidationError("`input_schema` and `schemaless` options cannot both be set", model=FileBasedStreamConfig) + def streams(self, config: Mapping[str, Any]) -> List[AbstractFileBasedStream]: """ Return a list of this source's streams. @@ -82,10 +90,7 @@ def streams(self, config: Mapping[str, Any]) -> List[AbstractFileBasedStream]: streams = [] for stream in config["streams"]: stream_config = FileBasedStreamConfig(**stream) - if stream_config.validation_policy not in self.validation_policies: - raise ValidationError( - f"validation_policy must be one of {list(self.validation_policies.keys())}", model=FileBasedStreamConfig - ) + self._validate_stream_config(stream_config) streams.append( DefaultFileBasedStream( config=stream_config, diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_helpers.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_helpers.py index c15c28e2293b..9954dbe5e442 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_helpers.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_helpers.py @@ -14,6 +14,8 @@ JsonSchemaSupportedType = Union[List, Literal["string"], str] SchemaType = Dict[str, Dict[str, JsonSchemaSupportedType]] +schemaless_schema = {"data": {"type": "object"}} + @total_ordering class ComparableType(Enum): diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/default_file_based_stream.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/default_file_based_stream.py index 96fbddb7a3fa..a125a7716694 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/default_file_based_stream.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/default_file_based_stream.py @@ -18,7 +18,7 @@ StopSyncPerValidationPolicy, ) from airbyte_cdk.sources.file_based.remote_file import RemoteFile -from airbyte_cdk.sources.file_based.schema_helpers import merge_schemas +from airbyte_cdk.sources.file_based.schema_helpers import merge_schemas, schemaless_schema from airbyte_cdk.sources.file_based.stream import AbstractFileBasedStream from airbyte_cdk.sources.file_based.stream.cursor import FileBasedCursor from airbyte_cdk.sources.file_based.types import StreamSlice @@ -79,8 +79,9 @@ def read_records_from_slice(self, stream_slice: StreamSlice) -> Iterable[Mapping try: for record in parser.parse_records(self.config, file, self._stream_reader): line_no += 1 - - if not self.record_passes_validation_policy(record): + if self.config.schemaless: + record = {"data": record} + elif not self.record_passes_validation_policy(record): n_skipped += 1 continue record[self.ab_last_mod_col] = file_datetime_string @@ -148,6 +149,8 @@ def get_json_schema(self) -> JsonSchema: def _get_raw_json_schema(self) -> JsonSchema: if self.config.input_schema: schema = self.config.input_schema + elif self.config.schemaless: + return schemaless_schema else: files = self.list_files() max_n_files_for_schema_inference = self._discovery_policy.max_n_files_for_schema_inference diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py index af66e7710d3f..abae2caf3b66 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py @@ -2,7 +2,7 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # -from airbyte_cdk.sources.file_based.exceptions import FileBasedSourceError, InvalidSchemaError, SchemaInferenceError +from airbyte_cdk.sources.file_based.exceptions import ConfigValidationError, FileBasedSourceError, InvalidSchemaError, SchemaInferenceError from unit_tests.sources.file_based.helpers import EmptySchemaParser, LowInferenceLimitDiscoveryPolicy from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenarioBuilder @@ -778,3 +778,353 @@ ] ) ).build() + + +schemaless_csv_scenario = ( + TestScenarioBuilder() + .set_name("schemaless_csv_scenario") + .set_config( + { + "streams": [ + { + "name": "stream1", + "file_type": "csv", + "globs": ["*"], + "validation_policy": "skip_record", + "schemaless": True, + } + ] + } + ) + .set_files( + { + "a.csv": { + "contents": [ + ("col1", "col2"), + ("val11a", "val12a"), + ("val21a", "val22a"), + ], + "last_modified": "2023-06-05T03:54:07.000Z", + }, + "b.csv": { + "contents": [ + ("col1", "col2", "col3"), + ("val11b", "val12b", "val13b"), + ("val21b", "val22b", "val23b"), + ], + "last_modified": "2023-06-05T03:54:07.000Z", + }, + } + ) + .set_file_type("csv") + .set_expected_catalog( + { + "streams": [ + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "data": { + "type": "object" + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + } + }, + "name": "stream1", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + } + ] + } + ) + .set_expected_records( + [ + {"data": {"data": {"col1": "val11a", "col2": "val12a"}, "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"data": {"col1": "val21a", "col2": "val22a"}, "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"data": {"col1": "val11b", "col2": "val12b", "col3": "val13b"}, "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, + {"data": {"data": {"col1": "val21b", "col2": "val22b", "col3": "val23b"}, "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, + ] + ) +).build() + + +schemaless_csv_multi_stream_scenario = ( + TestScenarioBuilder() + .set_name("schemaless_csv_multi_stream_scenario") + .set_config( + { + "streams": [ + { + "name": "stream1", + "file_type": "csv", + "globs": ["a.csv"], + "validation_policy": "skip_record", + "schemaless": True, + }, + { + "name": "stream2", + "file_type": "csv", + "globs": ["b.csv"], + "validation_policy": "skip_record", + } + ] + } + ) + .set_files( + { + "a.csv": { + "contents": [ + ("col1", "col2"), + ("val11a", "val12a"), + ("val21a", "val22a"), + ], + "last_modified": "2023-06-05T03:54:07.000Z", + }, + "b.csv": { + "contents": [ + ("col3",), + ("val13b",), + ("val23b",), + ], + "last_modified": "2023-06-05T03:54:07.000Z", + }, + } + ) + .set_file_type("csv") + .set_expected_catalog( + { + "streams": [ + { + "json_schema": { + "type": "object", + "properties": { + "data": { + "type": "object" + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + }, + }, + "name": "stream1", + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": True, + "default_cursor_field": ["_ab_source_file_last_modified"], + }, + { + "json_schema": { + "type": "object", + "properties": { + "col3": { + "type": "string" + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + }, + }, + "name": "stream2", + "source_defined_cursor": True, + "default_cursor_field": ["_ab_source_file_last_modified"], + "supported_sync_modes": ["full_refresh", "incremental"], + }, + ] + } + ) + .set_expected_records( + [ + {"data": {"data": {"col1": "val11a", "col2": "val12a"}, "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"data": {"col1": "val21a", "col2": "val22a"}, "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "b.csv"}, + "stream": "stream2"}, + {"data": {"col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "b.csv"}, + "stream": "stream2"}, + ] + ) +).build() + + +schemaless_with_user_input_schema_fails_connection_check_scenario = ( + TestScenarioBuilder() + .set_name("schemaless_with_user_input_schema_fails_connection_check_scenario") + .set_config( + { + "streams": [ + { + "name": "stream1", + "file_type": "csv", + "globs": ["*"], + "validation_policy": "skip_record", + "input_schema": {"col1": "string", "col2": "string", "col3": "string"}, + "schemaless": True, + } + ] + } + ) + .set_files( + { + "a.csv": { + "contents": [ + ("col1", "col2"), + ("val11a", "val12a"), + ("val21a", "val22a"), + ], + "last_modified": "2023-06-05T03:54:07.000Z", + }, + "b.csv": { + "contents": [ + ("col1", "col2", "col3"), + ("val11b", "val12b", "val13b"), + ("val21b", "val22b", "val23b"), + ], + "last_modified": "2023-06-05T03:54:07.000Z", + }, + } + ) + .set_file_type("csv") + .set_expected_catalog( + { + "streams": [ + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "data": { + "type": "object" + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + } + }, + "name": "stream1", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + } + ] + } + ) + .set_expected_check_status("FAILED") + .set_expected_check_error(ConfigValidationError, FileBasedSourceError.CONFIG_VALIDATION_ERROR.value) + .set_expected_discover_error(ConfigValidationError, FileBasedSourceError.CONFIG_VALIDATION_ERROR.value) + .set_expected_read_error(ConfigValidationError, FileBasedSourceError.CONFIG_VALIDATION_ERROR.value) +).build() + + +schemaless_with_user_input_schema_fails_connection_check_multi_stream_scenario = ( + TestScenarioBuilder() + .set_name("schemaless_with_user_input_schema_fails_connection_check_multi_stream_scenario") + .set_config( + { + "streams": [ + { + "name": "stream1", + "file_type": "csv", + "globs": ["a.csv"], + "validation_policy": "skip_record", + "schemaless": True, + "input_schema": {"col1": "string", "col2": "string", "col3": "string"}, + }, + { + "name": "stream2", + "file_type": "csv", + "globs": ["b.csv"], + "validation_policy": "skip_record", + } + ] + } + ) + .set_files( + { + "a.csv": { + "contents": [ + ("col1", "col2"), + ("val11a", "val12a"), + ("val21a", "val22a"), + ], + "last_modified": "2023-06-05T03:54:07.000Z", + }, + "b.csv": { + "contents": [ + ("col3",), + ("val13b",), + ("val23b",), + ], + "last_modified": "2023-06-05T03:54:07.000Z", + }, + } + ) + .set_file_type("csv") + .set_expected_catalog( + { + "streams": [ + { + "json_schema": { + "type": "object", + "properties": { + "data": { + "type": "object" + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + }, + }, + "name": "stream1", + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": True, + "default_cursor_field": ["_ab_source_file_last_modified"], + }, + { + "json_schema": { + "type": "object", + "properties": { + "col3": { + "type": "string" + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + }, + }, + "name": "stream2", + "source_defined_cursor": True, + "default_cursor_field": ["_ab_source_file_last_modified"], + "supported_sync_modes": ["full_refresh", "incremental"], + }, + ] + } + ) + .set_expected_check_status("FAILED") + .set_expected_check_error(ConfigValidationError, FileBasedSourceError.CONFIG_VALIDATION_ERROR.value) + .set_expected_discover_error(ConfigValidationError, FileBasedSourceError.CONFIG_VALIDATION_ERROR.value) + .set_expected_read_error(ConfigValidationError, FileBasedSourceError.CONFIG_VALIDATION_ERROR.value) +).build() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py index 74e384fdd440..6f94945f635a 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py @@ -32,6 +32,10 @@ multi_csv_scenario, multi_csv_stream_n_file_exceeds_limit_for_inference, multi_stream_custom_format, + schemaless_csv_multi_stream_scenario, + schemaless_csv_scenario, + schemaless_with_user_input_schema_fails_connection_check_multi_stream_scenario, + schemaless_with_user_input_schema_fails_connection_check_scenario, single_csv_scenario, ) from unit_tests.sources.file_based.scenarios.incremental_scenarios import ( @@ -87,6 +91,10 @@ csv_custom_format_scenario, multi_stream_custom_format, empty_schema_inference_scenario, + schemaless_csv_scenario, + schemaless_csv_multi_stream_scenario, + schemaless_with_user_input_schema_fails_connection_check_multi_stream_scenario, + schemaless_with_user_input_schema_fails_connection_check_scenario, ] @@ -178,6 +186,8 @@ def run_test_read_incremental(capsys, tmp_path, scenario): success_extensionless_scenario, success_multi_stream_scenario, success_user_provided_schema_scenario, + schemaless_with_user_input_schema_fails_connection_check_multi_stream_scenario, + schemaless_with_user_input_schema_fails_connection_check_scenario, ] From 0e11a6fc3b8daf4a62ead6b032a154f0f53e9d9b Mon Sep 17 00:00:00 2001 From: Denys Davydov Date: Tue, 11 Jul 2023 19:00:36 +0300 Subject: [PATCH 19/63] :rotating_light: :rotating_light: Source Recharge: fix stream schema (#27612) * Connector health: source hubspot, gitlab, snapchat-marketing: fix builds * #1879 source recharge: fix schema * #1879 source recharge: upd changelog * upd CAT config * source recharge: upd CAT config --------- Co-authored-by: Augustin --- airbyte-integrations/connectors/source-recharge/Dockerfile | 2 +- .../connectors/source-recharge/acceptance-test-config.yml | 2 +- airbyte-integrations/connectors/source-recharge/metadata.yaml | 2 +- .../source-recharge/source_recharge/schemas/charges.json | 2 +- docs/integrations/sources/recharge.md | 1 + 5 files changed, 5 insertions(+), 4 deletions(-) diff --git a/airbyte-integrations/connectors/source-recharge/Dockerfile b/airbyte-integrations/connectors/source-recharge/Dockerfile index cea6ab99afd6..bbc8964f4f60 100644 --- a/airbyte-integrations/connectors/source-recharge/Dockerfile +++ b/airbyte-integrations/connectors/source-recharge/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.2.10 +LABEL io.airbyte.version=1.0.0 LABEL io.airbyte.name=airbyte/source-recharge diff --git a/airbyte-integrations/connectors/source-recharge/acceptance-test-config.yml b/airbyte-integrations/connectors/source-recharge/acceptance-test-config.yml index 9e8b757d0d14..c7b80b0e67e0 100644 --- a/airbyte-integrations/connectors/source-recharge/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-recharge/acceptance-test-config.yml @@ -35,7 +35,7 @@ acceptance_tests: discovery: tests: - backward_compatibility_tests_config: - disable_for_version: 0.2.0 + disable_for_version: 0.2.10 config_path: secrets/config.json full_refresh: tests: diff --git a/airbyte-integrations/connectors/source-recharge/metadata.yaml b/airbyte-integrations/connectors/source-recharge/metadata.yaml index 1ff1bb6e0d32..d2e6c2c8a0b3 100644 --- a/airbyte-integrations/connectors/source-recharge/metadata.yaml +++ b/airbyte-integrations/connectors/source-recharge/metadata.yaml @@ -5,7 +5,7 @@ data: connectorSubtype: api connectorType: source definitionId: 45d2e135-2ede-49e1-939f-3e3ec357a65e - dockerImageTag: 0.2.10 + dockerImageTag: 1.0.0 dockerRepository: airbyte/source-recharge githubIssueLabel: source-recharge icon: recharge.svg diff --git a/airbyte-integrations/connectors/source-recharge/source_recharge/schemas/charges.json b/airbyte-integrations/connectors/source-recharge/source_recharge/schemas/charges.json index 29814d448a64..40faaeb50fe6 100644 --- a/airbyte-integrations/connectors/source-recharge/source_recharge/schemas/charges.json +++ b/airbyte-integrations/connectors/source-recharge/source_recharge/schemas/charges.json @@ -213,7 +213,7 @@ "type": ["null", "string"] }, "shopify_variant_id_not_found": { - "type": ["null", "integer"] + "type": ["null", "string"] }, "status": { "type": ["null", "string"] diff --git a/docs/integrations/sources/recharge.md b/docs/integrations/sources/recharge.md index bc0afa5fc3da..ce15a8559e2a 100644 --- a/docs/integrations/sources/recharge.md +++ b/docs/integrations/sources/recharge.md @@ -76,6 +76,7 @@ The Recharge connector should gracefully handle Recharge API limitations under n | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:------------------------------------------------------------------------------------------| +| 1.0.0 | 2023-06-22 | [27612](https://github.com/airbytehq/airbyte/pull/27612) | Change data type of the `shopify_variant_id_not_found` field of the `Charges` stream | | 0.2.10 | 2023-06-20 | [27503](https://github.com/airbytehq/airbyte/pull/27503) | Update API version to 2021-11 | | 0.2.9 | 2023-04-10 | [25009](https://github.com/airbytehq/airbyte/pull/25009) | Fix owner slicing for `Metafields` stream | | 0.2.8 | 2023-04-07 | [24990](https://github.com/airbytehq/airbyte/pull/24990) | Add slicing to connector | From 4bd0358c69aa5cfae97fc17a379c975ddc79b4e9 Mon Sep 17 00:00:00 2001 From: Anatolii Yatsuk <35109939+tolik0@users.noreply.github.com> Date: Tue, 11 Jul 2023 19:07:33 +0300 Subject: [PATCH 20/63] :bug: Source Monday: Add new streams and update old (#27410) Add new streams: Tags, Workspaces. Add new fields for existing streams. --------- Co-authored-by: Oleksandr Bazarnov Co-authored-by: Sherif A. Nada --- .../connectors/source-monday/Dockerfile | 2 +- .../source-monday/acceptance-test-config.yml | 26 ++- .../integration_tests/__init__.py | 2 +- .../integration_tests/configured_catalog.json | 20 +++ .../integration_tests/expected_records.jsonl | 168 ++++++++++-------- .../connectors/source-monday/metadata.yaml | 4 +- .../source-monday/source_monday/__init__.py | 2 +- .../source_monday/graphql_requester.py | 2 +- .../source-monday/source_monday/manifest.yaml | 14 +- .../source_monday/schemas/boards.json | 19 +- .../source_monday/schemas/items.json | 23 ++- .../source_monday/schemas/tags.json | 9 + .../source_monday/schemas/updates.json | 16 +- .../source_monday/schemas/workspaces.json | 73 ++++++++ .../source-monday/unit_tests/__init__.py | 2 +- docs/integrations/sources/monday.md | 39 ++-- 16 files changed, 311 insertions(+), 110 deletions(-) create mode 100644 airbyte-integrations/connectors/source-monday/source_monday/schemas/tags.json create mode 100644 airbyte-integrations/connectors/source-monday/source_monday/schemas/workspaces.json diff --git a/airbyte-integrations/connectors/source-monday/Dockerfile b/airbyte-integrations/connectors/source-monday/Dockerfile index 8e7eb1c27d9f..f8210bd6dbf2 100644 --- a/airbyte-integrations/connectors/source-monday/Dockerfile +++ b/airbyte-integrations/connectors/source-monday/Dockerfile @@ -34,5 +34,5 @@ COPY source_monday ./source_monday ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=0.2.6 +LABEL io.airbyte.version=1.0.0 LABEL io.airbyte.name=airbyte/source-monday diff --git a/airbyte-integrations/connectors/source-monday/acceptance-test-config.yml b/airbyte-integrations/connectors/source-monday/acceptance-test-config.yml index d781a9a9e0ce..a3975fc4d233 100644 --- a/airbyte-integrations/connectors/source-monday/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-monday/acceptance-test-config.yml @@ -19,16 +19,18 @@ acceptance_tests: tests: - config_path: "secrets/config.json" # `boards`, `items`, `updates` streams schemas were modified - # when `type: array` is used, the `items` should be set, instead of `properties`. - # this change applies for all configs bellow. + # changed type of id for assets in items and updates + # change deprecated owner to owners in boards + # All changes described in corresponding pr + # Changes applies to all configs backward_compatibility_tests_config: - disable_for_version: "0.2.5" + disable_for_version: "0.2.6" - config_path: "secrets/config_api_token.json" backward_compatibility_tests_config: - disable_for_version: "0.2.5" + disable_for_version: "0.2.6" - config_path: "secrets/config_oauth.json" backward_compatibility_tests_config: - disable_for_version: "0.2.5" + disable_for_version: "0.2.6" basic_read: tests: - config_path: "secrets/config_api_token.json" @@ -40,6 +42,13 @@ acceptance_tests: empty_streams: - name: teams bypass_reason: "unable to populate" + ignored_fields: + items: + - name: assets/*/public_url + bypass_reason: "Unstable data" + updates: + - name: assets/*/public_url + bypass_reason: "Unstable data" - config_path: "secrets/config_oauth.json" expect_records: path: "integration_tests/expected_records.jsonl" @@ -49,6 +58,13 @@ acceptance_tests: empty_streams: - name: teams bypass_reason: "unable to populate" + ignored_fields: + items: + - name: assets/*/public_url + bypass_reason: "Unstable data" + updates: + - name: assets/*/public_url + bypass_reason: "Unstable data" full_refresh: tests: - config_path: "secrets/config_api_token.json" diff --git a/airbyte-integrations/connectors/source-monday/integration_tests/__init__.py b/airbyte-integrations/connectors/source-monday/integration_tests/__init__.py index 46b7376756ec..c941b3045795 100644 --- a/airbyte-integrations/connectors/source-monday/integration_tests/__init__.py +++ b/airbyte-integrations/connectors/source-monday/integration_tests/__init__.py @@ -1,3 +1,3 @@ # -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. # diff --git a/airbyte-integrations/connectors/source-monday/integration_tests/configured_catalog.json b/airbyte-integrations/connectors/source-monday/integration_tests/configured_catalog.json index a44855e5ae74..df3c46a3e156 100644 --- a/airbyte-integrations/connectors/source-monday/integration_tests/configured_catalog.json +++ b/airbyte-integrations/connectors/source-monday/integration_tests/configured_catalog.json @@ -49,6 +49,26 @@ }, "sync_mode": "full_refresh", "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "workspaces", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "tags", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" } ] } diff --git a/airbyte-integrations/connectors/source-monday/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-monday/integration_tests/expected_records.jsonl index c2443f941ff7..a1fbe20708fd 100644 --- a/airbyte-integrations/connectors/source-monday/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-monday/integration_tests/expected_records.jsonl @@ -1,76 +1,92 @@ -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"id": "manager1", "value": null, "additional_info": null, "text": "", "title": "Owner", "type": "multiple-person"}, {"id": "date4", "value": "{\"date\":\"2019-04-11\",\"icon\":null,\"changed_at\":\"2019-04-10 08:06:40 UTC\"}", "additional_info": null, "text": "2019-04-11", "title": "Request date", "type": "date"}, {"id": "status1", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:36.561Z\"}", "additional_info": "{\"label\":\"Evaluating\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-07-22T06:28:36.561Z\"}", "text": "Evaluating", "title": "Procurement status", "type": "color"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Manager", "type": "multiple-person"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:09:58.545Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:09:58.545Z\"}", "text": "Approved", "title": "Manager approval", "type": "color"}, {"id": "budget_owner", "value": null, "additional_info": null, "text": "", "title": "POC owner", "type": "multiple-person"}, {"id": "budget_owner_approval4", "value": null, "additional_info": null, "text": null, "title": "POC status", "type": "color"}, {"id": "manager", "value": null, "additional_info": null, "text": "", "title": "Budget owner", "type": "multiple-person"}, {"id": "status4", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:11:20.855Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:11:20.855Z\"}", "text": "Approved", "title": "Budget owner approval", "type": "color"}, {"id": "people", "value": null, "additional_info": null, "text": "", "title": "Procurement team", "type": "multiple-person"}, {"id": "budget_owner_approval", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:14:00.506Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:14:00.506Z\"}", "text": "Approved", "title": "Procurement approval", "type": "color"}, {"id": "procurement_team", "value": null, "additional_info": null, "text": "", "title": "Finance", "type": "multiple-person"}, {"id": "procurement_approval", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2019-05-15T14:34:59.145Z\"}", "additional_info": "{\"label\":\"Declined\",\"color\":\"#e2445c\",\"changed_at\":\"2019-05-15T14:34:59.145Z\"}", "text": "Declined", "title": "Finance approval", "type": "color"}, {"id": "finance", "value": null, "additional_info": null, "text": "", "title": "Legal", "type": "multiple-person"}, {"id": "finance_approval", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2019-04-10T08:17:41.900Z\"}", "additional_info": "{\"label\":\"On Hold\",\"color\":\"#fdab3d\",\"changed_at\":\"2019-04-10T08:17:41.900Z\"}", "text": "On Hold", "title": "Legal approval", "type": "color"}, {"id": "file", "value": "{\"files\":null}", "additional_info": null, "text": "", "title": "File", "type": "file"}, {"id": "legal", "value": null, "additional_info": null, "text": "", "title": "Security", "type": "multiple-person"}, {"id": "legal_approval", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2019-04-30T15:43:35.438Z\"}", "additional_info": "{\"label\":\"Declined\",\"color\":\"#e2445c\",\"changed_at\":\"2019-04-30T15:43:35.438Z\"}", "text": "Declined", "title": "Security approval", "type": "color"}, {"id": "date", "value": null, "additional_info": null, "text": "", "title": "Renewal date", "type": "date"}, {"id": "last_updated", "value": null, "additional_info": null, "text": "2022-11-21 14:36:51 UTC", "title": "Last updated", "type": "pulse-updated"}], "created_at": "2022-11-21T14:36:51Z", "creator_id": "25479561", "group": {"id": "topics"}, "id": "3555407934", "name": "Zendesk", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:51Z", "updates": []}, "emitted_at": 1670509826492} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"id": "manager1", "value": null, "additional_info": null, "text": "", "title": "Owner", "type": "multiple-person"}, {"id": "date4", "value": "{\"date\":\"2019-04-11\",\"changed_at\":\"2019-04-02T07:03:23.375Z\"}", "additional_info": null, "text": "2019-04-11", "title": "Request date", "type": "date"}, {"id": "status1", "value": "{\"index\":11,\"post_id\":null,\"changed_at\":\"2020-06-25T11:41:22.421Z\"}", "additional_info": "{\"label\":\"On hold\",\"color\":\"#BB3354\",\"changed_at\":\"2020-06-25T11:41:22.421Z\"}", "text": "On hold", "title": "Procurement status", "type": "color"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Manager", "type": "multiple-person"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-03-01T17:28:23.178Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-03-01T17:28:23.178Z\"}", "text": "Approved", "title": "Manager approval", "type": "color"}, {"id": "budget_owner", "value": null, "additional_info": null, "text": "", "title": "POC owner", "type": "multiple-person"}, {"id": "budget_owner_approval4", "value": null, "additional_info": null, "text": null, "title": "POC status", "type": "color"}, {"id": "manager", "value": null, "additional_info": null, "text": "", "title": "Budget owner", "type": "multiple-person"}, {"id": "status4", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2019-04-10T08:11:26.186Z\"}", "additional_info": "{\"label\":\"Declined\",\"color\":\"#e2445c\",\"changed_at\":\"2019-04-10T08:11:26.186Z\"}", "text": "Declined", "title": "Budget owner approval", "type": "color"}, {"id": "people", "value": null, "additional_info": null, "text": "", "title": "Procurement team", "type": "multiple-person"}, {"id": "budget_owner_approval", "value": null, "additional_info": null, "text": null, "title": "Procurement approval", "type": "color"}, {"id": "procurement_team", "value": null, "additional_info": null, "text": "", "title": "Finance", "type": "multiple-person"}, {"id": "procurement_approval", "value": null, "additional_info": null, "text": null, "title": "Finance approval", "type": "color"}, {"id": "finance", "value": null, "additional_info": null, "text": "", "title": "Legal", "type": "multiple-person"}, {"id": "finance_approval", "value": null, "additional_info": null, "text": null, "title": "Legal approval", "type": "color"}, {"id": "file", "value": "{\"files\":null}", "additional_info": null, "text": "", "title": "File", "type": "file"}, {"id": "legal", "value": null, "additional_info": null, "text": "", "title": "Security", "type": "multiple-person"}, {"id": "legal_approval", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-25T06:36:38.993Z\"}", "additional_info": "{\"label\":\"On Hold\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-25T06:36:38.993Z\"}", "text": "On Hold", "title": "Security approval", "type": "color"}, {"id": "date", "value": null, "additional_info": null, "text": "", "title": "Renewal date", "type": "date"}, {"id": "last_updated", "value": null, "additional_info": null, "text": "2022-11-21 14:36:52 UTC", "title": "Last updated", "type": "pulse-updated"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "25479561", "group": {"id": "topics"}, "id": "3555407944", "name": "Salesforce", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1670509826493} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"id": "manager1", "value": null, "additional_info": null, "text": "", "title": "Owner", "type": "multiple-person"}, {"id": "date4", "value": "{\"date\":\"2019-04-17\",\"changed_at\":\"2019-04-02T07:03:25.251Z\"}", "additional_info": null, "text": "2019-04-17", "title": "Request date", "type": "date"}, {"id": "status1", "value": "{\"index\":14,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:39.711Z\"}", "additional_info": "{\"label\":\"Waiting for vendor\",\"color\":\"#784BD1\",\"changed_at\":\"2020-07-22T06:28:39.711Z\"}", "text": "Waiting for vendor", "title": "Procurement status", "type": "color"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Manager", "type": "multiple-person"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:10:00.038Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:10:00.038Z\"}", "text": "Approved", "title": "Manager approval", "type": "color"}, {"id": "budget_owner", "value": null, "additional_info": null, "text": "", "title": "POC owner", "type": "multiple-person"}, {"id": "budget_owner_approval4", "value": null, "additional_info": null, "text": null, "title": "POC status", "type": "color"}, {"id": "manager", "value": null, "additional_info": null, "text": "", "title": "Budget owner", "type": "multiple-person"}, {"id": "status4", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:11:23.942Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:11:23.942Z\"}", "text": "Approved", "title": "Budget owner approval", "type": "color"}, {"id": "people", "value": null, "additional_info": null, "text": "", "title": "Procurement team", "type": "multiple-person"}, {"id": "budget_owner_approval", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:14:02.186Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:14:02.186Z\"}", "text": "Approved", "title": "Procurement approval", "type": "color"}, {"id": "procurement_team", "value": null, "additional_info": null, "text": "", "title": "Finance", "type": "multiple-person"}, {"id": "procurement_approval", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:16:19.222Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:16:19.222Z\"}", "text": "Approved", "title": "Finance approval", "type": "color"}, {"id": "finance", "value": null, "additional_info": null, "text": "", "title": "Legal", "type": "multiple-person"}, {"id": "finance_approval", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:17:46.022Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:17:46.022Z\"}", "text": "Approved", "title": "Legal approval", "type": "color"}, {"id": "file", "value": "{\"files\":null}", "additional_info": null, "text": "", "title": "File", "type": "file"}, {"id": "legal", "value": null, "additional_info": null, "text": "", "title": "Security", "type": "multiple-person"}, {"id": "legal_approval", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-25T06:36:40.961Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-25T06:36:40.961Z\"}", "text": "Approved", "title": "Security approval", "type": "color"}, {"id": "date", "value": null, "additional_info": null, "text": "", "title": "Renewal date", "type": "date"}, {"id": "last_updated", "value": null, "additional_info": null, "text": "2022-11-21 14:36:52 UTC", "title": "Last updated", "type": "pulse-updated"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "25479561", "group": {"id": "topics"}, "id": "3555407952", "name": "YouCanBookMe", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1670509826494} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"id": "manager1", "value": null, "additional_info": null, "text": "", "title": "Owner", "type": "multiple-person"}, {"id": "date4", "value": null, "additional_info": null, "text": "", "title": "Request date", "type": "date"}, {"id": "status1", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-25T11:41:48.118Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-25T11:41:48.118Z\"}", "text": "Done", "title": "Procurement status", "type": "color"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Manager", "type": "multiple-person"}, {"id": "status", "value": null, "additional_info": null, "text": null, "title": "Manager approval", "type": "color"}, {"id": "budget_owner", "value": null, "additional_info": null, "text": "", "title": "POC owner", "type": "multiple-person"}, {"id": "budget_owner_approval4", "value": null, "additional_info": null, "text": null, "title": "POC status", "type": "color"}, {"id": "manager", "value": null, "additional_info": null, "text": "", "title": "Budget owner", "type": "multiple-person"}, {"id": "status4", "value": null, "additional_info": null, "text": null, "title": "Budget owner approval", "type": "color"}, {"id": "people", "value": null, "additional_info": null, "text": "", "title": "Procurement team", "type": "multiple-person"}, {"id": "budget_owner_approval", "value": null, "additional_info": null, "text": null, "title": "Procurement approval", "type": "color"}, {"id": "procurement_team", "value": null, "additional_info": null, "text": "", "title": "Finance", "type": "multiple-person"}, {"id": "procurement_approval", "value": null, "additional_info": null, "text": null, "title": "Finance approval", "type": "color"}, {"id": "finance", "value": null, "additional_info": null, "text": "", "title": "Legal", "type": "multiple-person"}, {"id": "finance_approval", "value": null, "additional_info": null, "text": null, "title": "Legal approval", "type": "color"}, {"id": "file", "value": null, "additional_info": null, "text": "", "title": "File", "type": "file"}, {"id": "legal", "value": null, "additional_info": null, "text": "", "title": "Security", "type": "multiple-person"}, {"id": "legal_approval", "value": null, "additional_info": null, "text": null, "title": "Security approval", "type": "color"}, {"id": "date", "value": null, "additional_info": null, "text": "", "title": "Renewal date", "type": "date"}, {"id": "last_updated", "value": null, "additional_info": null, "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408067", "name": "Box", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1670509826495} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"id": "manager1", "value": null, "additional_info": null, "text": "", "title": "Owner", "type": "multiple-person"}, {"id": "date4", "value": null, "additional_info": null, "text": "", "title": "Request date", "type": "date"}, {"id": "status1", "value": "{\"index\":108,\"post_id\":null,\"changed_at\":\"2020-07-22T06:27:41.551Z\"}", "additional_info": "{\"label\":\"Approved for use\",\"color\":\"#4eccc6\",\"changed_at\":\"2020-07-22T06:27:41.551Z\"}", "text": "Approved for use", "title": "Procurement status", "type": "color"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Manager", "type": "multiple-person"}, {"id": "status", "value": null, "additional_info": null, "text": null, "title": "Manager approval", "type": "color"}, {"id": "budget_owner", "value": null, "additional_info": null, "text": "", "title": "POC owner", "type": "multiple-person"}, {"id": "budget_owner_approval4", "value": null, "additional_info": null, "text": null, "title": "POC status", "type": "color"}, {"id": "manager", "value": null, "additional_info": null, "text": "", "title": "Budget owner", "type": "multiple-person"}, {"id": "status4", "value": null, "additional_info": null, "text": null, "title": "Budget owner approval", "type": "color"}, {"id": "people", "value": null, "additional_info": null, "text": "", "title": "Procurement team", "type": "multiple-person"}, {"id": "budget_owner_approval", "value": null, "additional_info": null, "text": null, "title": "Procurement approval", "type": "color"}, {"id": "procurement_team", "value": null, "additional_info": null, "text": "", "title": "Finance", "type": "multiple-person"}, {"id": "procurement_approval", "value": null, "additional_info": null, "text": null, "title": "Finance approval", "type": "color"}, {"id": "finance", "value": null, "additional_info": null, "text": "", "title": "Legal", "type": "multiple-person"}, {"id": "finance_approval", "value": null, "additional_info": null, "text": null, "title": "Legal approval", "type": "color"}, {"id": "file", "value": null, "additional_info": null, "text": "", "title": "File", "type": "file"}, {"id": "legal", "value": null, "additional_info": null, "text": "", "title": "Security", "type": "multiple-person"}, {"id": "legal_approval", "value": null, "additional_info": null, "text": null, "title": "Security approval", "type": "color"}, {"id": "date", "value": null, "additional_info": null, "text": "", "title": "Renewal date", "type": "date"}, {"id": "last_updated", "value": null, "additional_info": null, "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408077", "name": "Slack", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1670509826495} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"id": "manager1", "value": null, "additional_info": null, "text": "", "title": "Owner", "type": "multiple-person"}, {"id": "date4", "value": null, "additional_info": null, "text": "", "title": "Request date", "type": "date"}, {"id": "status1", "value": "{\"index\":108,\"post_id\":null,\"changed_at\":\"2020-07-22T06:26:53.835Z\"}", "additional_info": "{\"label\":\"Approved for use\",\"color\":\"#4eccc6\",\"changed_at\":\"2020-07-22T06:26:53.835Z\"}", "text": "Approved for use", "title": "Procurement status", "type": "color"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Manager", "type": "multiple-person"}, {"id": "status", "value": null, "additional_info": null, "text": null, "title": "Manager approval", "type": "color"}, {"id": "budget_owner", "value": null, "additional_info": null, "text": "", "title": "POC owner", "type": "multiple-person"}, {"id": "budget_owner_approval4", "value": null, "additional_info": null, "text": null, "title": "POC status", "type": "color"}, {"id": "manager", "value": null, "additional_info": null, "text": "", "title": "Budget owner", "type": "multiple-person"}, {"id": "status4", "value": null, "additional_info": null, "text": null, "title": "Budget owner approval", "type": "color"}, {"id": "people", "value": null, "additional_info": null, "text": "", "title": "Procurement team", "type": "multiple-person"}, {"id": "budget_owner_approval", "value": null, "additional_info": null, "text": null, "title": "Procurement approval", "type": "color"}, {"id": "procurement_team", "value": null, "additional_info": null, "text": "", "title": "Finance", "type": "multiple-person"}, {"id": "procurement_approval", "value": null, "additional_info": null, "text": null, "title": "Finance approval", "type": "color"}, {"id": "finance", "value": null, "additional_info": null, "text": "", "title": "Legal", "type": "multiple-person"}, {"id": "finance_approval", "value": null, "additional_info": null, "text": null, "title": "Legal approval", "type": "color"}, {"id": "file", "value": null, "additional_info": null, "text": "", "title": "File", "type": "file"}, {"id": "legal", "value": null, "additional_info": null, "text": "", "title": "Security", "type": "multiple-person"}, {"id": "legal_approval", "value": null, "additional_info": null, "text": null, "title": "Security approval", "type": "color"}, {"id": "date", "value": null, "additional_info": null, "text": "", "title": "Renewal date", "type": "date"}, {"id": "last_updated", "value": null, "additional_info": null, "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408088", "name": "HelpJuice", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1670509826496} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"id": "manager1", "value": null, "additional_info": null, "text": "", "title": "Owner", "type": "multiple-person"}, {"id": "date4", "value": null, "additional_info": null, "text": "", "title": "Request date", "type": "date"}, {"id": "status1", "value": "{\"index\":108,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:31.709Z\"}", "additional_info": "{\"label\":\"Approved for use\",\"color\":\"#4eccc6\",\"changed_at\":\"2020-07-22T06:28:31.709Z\"}", "text": "Approved for use", "title": "Procurement status", "type": "color"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Manager", "type": "multiple-person"}, {"id": "status", "value": null, "additional_info": null, "text": null, "title": "Manager approval", "type": "color"}, {"id": "budget_owner", "value": null, "additional_info": null, "text": "", "title": "POC owner", "type": "multiple-person"}, {"id": "budget_owner_approval4", "value": null, "additional_info": null, "text": null, "title": "POC status", "type": "color"}, {"id": "manager", "value": null, "additional_info": null, "text": "", "title": "Budget owner", "type": "multiple-person"}, {"id": "status4", "value": null, "additional_info": null, "text": null, "title": "Budget owner approval", "type": "color"}, {"id": "people", "value": null, "additional_info": null, "text": "", "title": "Procurement team", "type": "multiple-person"}, {"id": "budget_owner_approval", "value": null, "additional_info": null, "text": null, "title": "Procurement approval", "type": "color"}, {"id": "procurement_team", "value": null, "additional_info": null, "text": "", "title": "Finance", "type": "multiple-person"}, {"id": "procurement_approval", "value": null, "additional_info": null, "text": null, "title": "Finance approval", "type": "color"}, {"id": "finance", "value": null, "additional_info": null, "text": "", "title": "Legal", "type": "multiple-person"}, {"id": "finance_approval", "value": null, "additional_info": null, "text": null, "title": "Legal approval", "type": "color"}, {"id": "file", "value": null, "additional_info": null, "text": "", "title": "File", "type": "file"}, {"id": "legal", "value": null, "additional_info": null, "text": "", "title": "Security", "type": "multiple-person"}, {"id": "legal_approval", "value": null, "additional_info": null, "text": null, "title": "Security approval", "type": "color"}, {"id": "date", "value": null, "additional_info": null, "text": "", "title": "Renewal date", "type": "date"}, {"id": "last_updated", "value": null, "additional_info": null, "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408094", "name": "LucidChart", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1670509826497} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"id": "manager1", "value": null, "additional_info": null, "text": "", "title": "Owner", "type": "multiple-person"}, {"id": "date4", "value": "{\"date\":\"2019-04-11\",\"changed_at\":\"2019-04-02T07:03:23.375Z\"}", "additional_info": null, "text": "2019-04-11", "title": "Request date", "type": "date"}, {"id": "status1", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:25.645Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-07-22T06:28:25.645Z\"}", "text": "Done", "title": "Procurement status", "type": "color"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Manager", "type": "multiple-person"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-03-01T17:28:23.178Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-03-01T17:28:23.178Z\"}", "text": "Approved", "title": "Manager approval", "type": "color"}, {"id": "budget_owner", "value": null, "additional_info": null, "text": "", "title": "POC owner", "type": "multiple-person"}, {"id": "budget_owner_approval4", "value": null, "additional_info": null, "text": null, "title": "POC status", "type": "color"}, {"id": "manager", "value": null, "additional_info": null, "text": "", "title": "Budget owner", "type": "multiple-person"}, {"id": "status4", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:06.894Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:06.894Z\"}", "text": "Approved", "title": "Budget owner approval", "type": "color"}, {"id": "people", "value": null, "additional_info": null, "text": "", "title": "Procurement team", "type": "multiple-person"}, {"id": "budget_owner_approval", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:08.700Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:08.700Z\"}", "text": "Approved", "title": "Procurement approval", "type": "color"}, {"id": "procurement_team", "value": null, "additional_info": null, "text": "", "title": "Finance", "type": "multiple-person"}, {"id": "procurement_approval", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:10.209Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:10.209Z\"}", "text": "Approved", "title": "Finance approval", "type": "color"}, {"id": "finance", "value": null, "additional_info": null, "text": "", "title": "Legal", "type": "multiple-person"}, {"id": "finance_approval", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:11.909Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:11.909Z\"}", "text": "Approved", "title": "Legal approval", "type": "color"}, {"id": "file", "value": "{\"files\":null}", "additional_info": null, "text": "", "title": "File", "type": "file"}, {"id": "legal", "value": null, "additional_info": null, "text": "", "title": "Security", "type": "multiple-person"}, {"id": "legal_approval", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:15.385Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:15.385Z\"}", "text": "Approved", "title": "Security approval", "type": "color"}, {"id": "date", "value": null, "additional_info": null, "text": "", "title": "Renewal date", "type": "date"}, {"id": "last_updated", "value": null, "additional_info": null, "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "25479561", "group": {"id": "new_group"}, "id": "3555408048", "name": "Aircall", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1670509826498} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"id": "manager1", "value": null, "additional_info": null, "text": "", "title": "Owner", "type": "multiple-person"}, {"id": "date4", "value": "{\"date\":\"2019-04-17\",\"changed_at\":\"2019-04-02T07:03:25.251Z\"}", "additional_info": null, "text": "2019-04-17", "title": "Request date", "type": "date"}, {"id": "status1", "value": "{\"index\":108,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:29.177Z\"}", "additional_info": "{\"label\":\"Approved for use\",\"color\":\"#4eccc6\",\"changed_at\":\"2020-07-22T06:28:29.177Z\"}", "text": "Approved for use", "title": "Procurement status", "type": "color"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Manager", "type": "multiple-person"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:10:00.038Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:10:00.038Z\"}", "text": "Approved", "title": "Manager approval", "type": "color"}, {"id": "budget_owner", "value": null, "additional_info": null, "text": "", "title": "POC owner", "type": "multiple-person"}, {"id": "budget_owner_approval4", "value": null, "additional_info": null, "text": null, "title": "POC status", "type": "color"}, {"id": "manager", "value": null, "additional_info": null, "text": "", "title": "Budget owner", "type": "multiple-person"}, {"id": "status4", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:11:23.942Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:11:23.942Z\"}", "text": "Approved", "title": "Budget owner approval", "type": "color"}, {"id": "people", "value": null, "additional_info": null, "text": "", "title": "Procurement team", "type": "multiple-person"}, {"id": "budget_owner_approval", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:14:02.186Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:14:02.186Z\"}", "text": "Approved", "title": "Procurement approval", "type": "color"}, {"id": "procurement_team", "value": null, "additional_info": null, "text": "", "title": "Finance", "type": "multiple-person"}, {"id": "procurement_approval", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:16:19.222Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:16:19.222Z\"}", "text": "Approved", "title": "Finance approval", "type": "color"}, {"id": "finance", "value": null, "additional_info": null, "text": "", "title": "Legal", "type": "multiple-person"}, {"id": "finance_approval", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:17:46.022Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:17:46.022Z\"}", "text": "Approved", "title": "Legal approval", "type": "color"}, {"id": "file", "value": "{\"files\":null}", "additional_info": null, "text": "", "title": "File", "type": "file"}, {"id": "legal", "value": null, "additional_info": null, "text": "", "title": "Security", "type": "multiple-person"}, {"id": "legal_approval", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:17.250Z\"}", "additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:17.250Z\"}", "text": "Approved", "title": "Security approval", "type": "color"}, {"id": "date", "value": null, "additional_info": null, "text": "", "title": "Renewal date", "type": "date"}, {"id": "last_updated", "value": null, "additional_info": null, "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "25479561", "group": {"id": "new_group"}, "id": "3555408057", "name": "Zoom", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1670509826499} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"id": "manager1", "value": null, "additional_info": null, "text": "", "title": "Owner", "type": "multiple-person"}, {"id": "date4", "value": null, "additional_info": null, "text": "", "title": "Request date", "type": "date"}, {"id": "status1", "value": "{\"index\":3,\"post_id\":null,\"changed_at\":\"2020-07-22T06:27:17.793Z\"}", "additional_info": "{\"label\":\"Waiting for legal\",\"color\":\"#0086c0\",\"changed_at\":\"2020-07-22T06:27:17.793Z\"}", "text": "Waiting for legal", "title": "Procurement status", "type": "color"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Manager", "type": "multiple-person"}, {"id": "status", "value": null, "additional_info": null, "text": null, "title": "Manager approval", "type": "color"}, {"id": "budget_owner", "value": null, "additional_info": null, "text": "", "title": "POC owner", "type": "multiple-person"}, {"id": "budget_owner_approval4", "value": null, "additional_info": null, "text": null, "title": "POC status", "type": "color"}, {"id": "manager", "value": null, "additional_info": null, "text": "", "title": "Budget owner", "type": "multiple-person"}, {"id": "status4", "value": null, "additional_info": null, "text": null, "title": "Budget owner approval", "type": "color"}, {"id": "people", "value": null, "additional_info": null, "text": "", "title": "Procurement team", "type": "multiple-person"}, {"id": "budget_owner_approval", "value": null, "additional_info": null, "text": null, "title": "Procurement approval", "type": "color"}, {"id": "procurement_team", "value": null, "additional_info": null, "text": "", "title": "Finance", "type": "multiple-person"}, {"id": "procurement_approval", "value": null, "additional_info": null, "text": null, "title": "Finance approval", "type": "color"}, {"id": "finance", "value": null, "additional_info": null, "text": "", "title": "Legal", "type": "multiple-person"}, {"id": "finance_approval", "value": null, "additional_info": null, "text": null, "title": "Legal approval", "type": "color"}, {"id": "file", "value": null, "additional_info": null, "text": "", "title": "File", "type": "file"}, {"id": "legal", "value": null, "additional_info": null, "text": "", "title": "Security", "type": "multiple-person"}, {"id": "legal_approval", "value": null, "additional_info": null, "text": null, "title": "Security approval", "type": "color"}, {"id": "date", "value": null, "additional_info": null, "text": "", "title": "Renewal date", "type": "date"}, {"id": "last_updated", "value": null, "additional_info": null, "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group2816"}, "id": "3555408102", "name": "Gaviti", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1670509826500} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"id": "manager1", "value": null, "additional_info": null, "text": "", "title": "Owner", "type": "multiple-person"}, {"id": "date4", "value": null, "additional_info": null, "text": "", "title": "Request date", "type": "date"}, {"id": "status1", "value": "{\"index\":15,\"post_id\":null,\"changed_at\":\"2020-07-22T06:27:22.578Z\"}", "additional_info": "{\"label\":\"Negotiation\",\"color\":\"#9CD326\",\"changed_at\":\"2020-07-22T06:27:22.578Z\"}", "text": "Negotiation", "title": "Procurement status", "type": "color"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Manager", "type": "multiple-person"}, {"id": "status", "value": null, "additional_info": null, "text": null, "title": "Manager approval", "type": "color"}, {"id": "budget_owner", "value": null, "additional_info": null, "text": "", "title": "POC owner", "type": "multiple-person"}, {"id": "budget_owner_approval4", "value": null, "additional_info": null, "text": null, "title": "POC status", "type": "color"}, {"id": "manager", "value": null, "additional_info": null, "text": "", "title": "Budget owner", "type": "multiple-person"}, {"id": "status4", "value": null, "additional_info": null, "text": null, "title": "Budget owner approval", "type": "color"}, {"id": "people", "value": null, "additional_info": null, "text": "", "title": "Procurement team", "type": "multiple-person"}, {"id": "budget_owner_approval", "value": null, "additional_info": null, "text": null, "title": "Procurement approval", "type": "color"}, {"id": "procurement_team", "value": null, "additional_info": null, "text": "", "title": "Finance", "type": "multiple-person"}, {"id": "procurement_approval", "value": null, "additional_info": null, "text": null, "title": "Finance approval", "type": "color"}, {"id": "finance", "value": null, "additional_info": null, "text": "", "title": "Legal", "type": "multiple-person"}, {"id": "finance_approval", "value": null, "additional_info": null, "text": null, "title": "Legal approval", "type": "color"}, {"id": "file", "value": null, "additional_info": null, "text": "", "title": "File", "type": "file"}, {"id": "legal", "value": null, "additional_info": null, "text": "", "title": "Security", "type": "multiple-person"}, {"id": "legal_approval", "value": null, "additional_info": null, "text": null, "title": "Security approval", "type": "color"}, {"id": "date", "value": null, "additional_info": null, "text": "", "title": "Renewal date", "type": "date"}, {"id": "last_updated", "value": null, "additional_info": null, "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group2816"}, "id": "3555408118", "name": "Priority", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1670509826501} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"SN56456\"", "additional_info": null, "text": "SN56456", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2020-06-22T08:37:41.248Z\"}", "additional_info": "{\"label\":\"Needs replacement\",\"color\":\"#e2445c\",\"changed_at\":\"2020-06-22T08:37:41.248Z\"}", "text": "Needs replacement", "title": "Status", "type": "color"}, {"id": "date4", "value": "{\"date\":\"2020-05-14\",\"changed_at\":\"2020-06-22T11:25:44.457Z\"}", "additional_info": null, "text": "2020-05-14", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": "\"Zakariah Macleod\"", "additional_info": null, "text": "Zakariah Macleod", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-06-10\",\"changed_at\":\"2020-06-24T10:59:53.938Z\"}", "additional_info": null, "text": "2020-06-10", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_tvs___projectors"}, "id": "3555407991", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1670509828048} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"SN 94-34-AS-GT-66\"", "additional_info": null, "text": "SN 94-34-AS-GT-66", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-22T08:37:42.971Z\"}", "additional_info": "{\"label\":\"Out for repair\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-22T08:37:42.971Z\"}", "text": "Out for repair", "title": "Status", "type": "color"}, {"id": "date4", "value": "{\"date\":\"2020-06-10\",\"changed_at\":\"2020-06-22T11:25:46.599Z\"}", "additional_info": null, "text": "2020-06-10", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": "\"Corbin Blackburn\"", "additional_info": null, "text": "Corbin Blackburn", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-06-11\",\"changed_at\":\"2020-06-24T10:59:55.752Z\"}", "additional_info": null, "text": "2020-06-11", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_tvs___projectors"}, "id": "3555407997", "name": "Sonos One", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1670509828051} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"P2219G\"", "additional_info": null, "text": "P2219G", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-22T08:37:44.792Z\"}", "additional_info": "{\"label\":\"Out for repair\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-22T08:37:44.792Z\"}", "text": "Out for repair", "title": "Status", "type": "color"}, {"id": "date4", "value": "{\"date\":\"2020-06-02\",\"changed_at\":\"2020-06-22T11:25:48.402Z\"}", "additional_info": null, "text": "2020-06-02", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": "\"Jorge Mcgowan\"", "additional_info": null, "text": "Jorge Mcgowan", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-06-28\",\"changed_at\":\"2020-06-24T10:59:57.460Z\"}", "additional_info": null, "text": "2020-06-28", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_tvs___projectors"}, "id": "3555408009", "name": "Dell", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1670509828055} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"SN FVFYVE57L21Y\"", "additional_info": null, "text": "SN FVFYVE57L21Y", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "text": "Working well", "title": "Status", "type": "color"}, {"id": "date4", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-22T11:25:52.834Z\"}", "additional_info": null, "text": "2020-06-03", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": "\"Rylee Pham\"", "additional_info": null, "text": "Rylee Pham", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-03-11\",\"changed_at\":\"2020-06-24T11:00:01.660Z\"}", "additional_info": null, "text": "2020-03-11", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:51Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407931", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:51Z", "updates": []}, "emitted_at": 1670509828057} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"SN FVFYVE57L22Y\"", "additional_info": null, "text": "SN FVFYVE57L22Y", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "text": "Working well", "title": "Status", "type": "color"}, {"id": "date4", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-22T11:25:56.327Z\"}", "additional_info": null, "text": "2020-06-03", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": "\"Kaydon Gamble\"", "additional_info": null, "text": "Kaydon Gamble", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-02-19\",\"changed_at\":\"2020-06-24T11:00:06.248Z\"}", "additional_info": null, "text": "2020-02-19", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407941", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1670509828060} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"SN FVFYVE57L23W\"", "additional_info": null, "text": "SN FVFYVE57L23W", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "text": "Working well", "title": "Status", "type": "color"}, {"id": "date4", "value": "{\"date\":\"2020-06-04\",\"changed_at\":\"2020-06-22T11:25:58.156Z\"}", "additional_info": null, "text": "2020-06-04", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": "\"Eli Reyes\"", "additional_info": null, "text": "Eli Reyes", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-03-26\",\"changed_at\":\"2020-06-24T11:00:13.482Z\"}", "additional_info": null, "text": "2020-03-26", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407947", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1670509828062} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"SN FVFYVE57L41V\"", "additional_info": null, "text": "SN FVFYVE57L41V", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "text": "Working well", "title": "Status", "type": "color"}, {"id": "date4", "value": "{\"date\":\"2020-06-11\",\"changed_at\":\"2020-06-22T11:26:00.305Z\"}", "additional_info": null, "text": "2020-06-11", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": "\"Finley Hilton\"", "additional_info": null, "text": "Finley Hilton", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-03-12\",\"changed_at\":\"2020-06-24T11:00:09.820Z\"}", "additional_info": null, "text": "2020-03-12", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407961", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1670509828063} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"SN FVFYVE67L21Y\"", "additional_info": null, "text": "SN FVFYVE67L21Y", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "text": "Working well", "title": "Status", "type": "color"}, {"id": "date4", "value": "{\"date\":\"2020-06-17\",\"changed_at\":\"2020-06-22T11:26:02.141Z\"}", "additional_info": null, "text": "2020-06-17", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": "\"Fabien Morton\"", "additional_info": null, "text": "Fabien Morton", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-04-21\",\"changed_at\":\"2020-06-24T11:00:17.305Z\"}", "additional_info": null, "text": "2020-04-21", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407968", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1670509828065} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"SN FVFYVE57L28Y\"", "additional_info": null, "text": "SN FVFYVE57L28Y", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "text": "Working well", "title": "Status", "type": "color"}, {"id": "date4", "value": "{\"date\":\"2020-06-18\",\"changed_at\":\"2020-06-22T11:26:04.062Z\"}", "additional_info": null, "text": "2020-06-18", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": "\"Amelia-Mae Flower\"", "additional_info": null, "text": "Amelia-Mae Flower", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-06-04\",\"changed_at\":\"2020-06-24T11:00:21.416Z\"}", "additional_info": null, "text": "2020-06-04", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407977", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1670509828067} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"3sBeKstD\"", "additional_info": null, "text": "3sBeKstD", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "text": "Working well", "title": "Status", "type": "color"}, {"id": "date4", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-22T11:26:06.624Z\"}", "additional_info": null, "text": "2020-06-03", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": "\"Masuma Carver\"", "additional_info": null, "text": "Masuma Carver", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-04-07\",\"changed_at\":\"2020-06-24T11:00:35.389Z\"}", "additional_info": null, "text": "2020-04-07", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408016", "name": "Dell - U2417H", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1670509828068} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"eqK2M67W\"", "additional_info": null, "text": "eqK2M67W", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "text": "Working well", "title": "Status", "type": "color"}, {"id": "date4", "value": "{\"date\":\"2020-06-10\",\"changed_at\":\"2020-06-22T11:26:08.798Z\"}", "additional_info": null, "text": "2020-06-10", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": "\"Tadhg Hensley\"", "additional_info": null, "text": "Tadhg Hensley", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-06-04\",\"changed_at\":\"2020-06-24T11:00:23.245Z\"}", "additional_info": null, "text": "2020-06-04", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408058", "name": "Dell - U2418H", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1670509828069} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"39QTALuj\"", "additional_info": null, "text": "39QTALuj", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "text": "Working well", "title": "Status", "type": "color"}, {"id": "date4", "value": "{\"date\":\"2020-06-09\",\"changed_at\":\"2020-06-22T11:26:10.906Z\"}", "additional_info": null, "text": "2020-06-09", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": "\"Aanya Booth\"", "additional_info": null, "text": "Aanya Booth", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-06-05\",\"changed_at\":\"2020-06-24T11:00:25.468Z\"}", "additional_info": null, "text": "2020-06-05", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408070", "name": "Dell - U2416H", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1670509828071} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"LTgqT9cY\"", "additional_info": null, "text": "LTgqT9cY", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "text": "Working well", "title": "Status", "type": "color"}, {"id": "date4", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-22T11:26:12.701Z\"}", "additional_info": null, "text": "2020-06-03", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": "\"Kiana Burnett\"", "additional_info": null, "text": "Kiana Burnett", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-06-20\",\"changed_at\":\"2020-06-24T11:00:27.706Z\"}", "additional_info": null, "text": "2020-06-20", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408083", "name": "Dell - U2419HX", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1670509828072} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"FjE7nsrs\"", "additional_info": null, "text": "FjE7nsrs", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "text": "Working well", "title": "Status", "type": "color"}, {"id": "date4", "value": "{\"date\":\"2020-06-10\",\"changed_at\":\"2020-06-22T11:26:17.156Z\"}", "additional_info": null, "text": "2020-06-10", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": "\"Roxie Forbes\"", "additional_info": null, "text": "Roxie Forbes", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-05-06\",\"changed_at\":\"2020-06-24T11:00:31.519Z\"}", "additional_info": null, "text": "2020-05-06", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408091", "name": "Dell - P2219H", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1670509828073} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"SN32456\"", "additional_info": null, "text": "SN32456", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "text": "Working well", "title": "Status", "type": "color"}, {"id": "date4", "value": null, "additional_info": null, "text": "", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-05-05\",\"changed_at\":\"2020-06-24T11:00:39.214Z\"}", "additional_info": null, "text": "2020-05-05", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408021", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1670509828074} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"SN32457\"", "additional_info": null, "text": "SN32457", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "text": "Working well", "title": "Status", "type": "color"}, {"id": "date4", "value": null, "additional_info": null, "text": "", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-05-07\",\"changed_at\":\"2020-06-24T11:00:42.752Z\"}", "additional_info": null, "text": "2020-05-07", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408033", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1670509828075} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"SN32458\"", "additional_info": null, "text": "SN32458", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "text": "Working well", "title": "Status", "type": "color"}, {"id": "date4", "value": null, "additional_info": null, "text": "", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-05-21\",\"changed_at\":\"2020-06-24T11:00:46.170Z\"}", "additional_info": null, "text": "2020-05-21", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408041", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1670509828077} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"id": "text4", "value": "\"SN32458\"", "additional_info": null, "text": "SN32458", "title": "SN", "type": "text"}, {"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "text": "Working well", "title": "Status", "type": "color"}, {"id": "date4", "value": null, "additional_info": null, "text": "", "title": "Date given to current owner", "type": "date"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "Current owner", "type": "text"}, {"id": "date_given_to_current_owner", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-24T11:00:48.979Z\"}", "additional_info": null, "text": "2020-06-03", "title": "Last checked", "type": "date"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408052", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1670509828079} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"id": "people", "value": null, "additional_info": null, "text": "", "title": "IT owner", "type": "multiple-person"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Responsible HR", "type": "multiple-person"}, {"id": "date4", "value": null, "additional_info": null, "text": "", "title": "Start date", "type": "date"}, {"id": "status", "value": null, "additional_info": null, "text": null, "title": "Team", "type": "color"}, {"id": "status8", "value": null, "additional_info": null, "text": null, "title": "Site", "type": "color"}, {"id": "status1", "value": null, "additional_info": null, "text": null, "title": "Computer type", "type": "color"}, {"id": "status2", "value": null, "additional_info": null, "text": null, "title": "Computer setup", "type": "color"}, {"id": "computer_setup", "value": null, "additional_info": null, "text": null, "title": "Google account", "type": "color"}, {"id": "google_account", "value": null, "additional_info": null, "text": null, "title": "Zoom account", "type": "color"}, {"id": "zoom_account", "value": null, "additional_info": null, "text": null, "title": "365 account", "type": "color"}, {"id": "365_account3", "value": null, "additional_info": null, "text": null, "title": "Setup desk monitor", "type": "color"}, {"id": "set_up_desk_monitor", "value": null, "additional_info": null, "text": null, "title": "Setup entrance tag", "type": "color"}, {"id": "email", "value": null, "additional_info": null, "text": "", "title": "Email", "type": "email"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "25479561", "group": {"id": "airbyte_group"}, "id": "3555408019", "name": "new item", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:56Z", "updates": [{"id": "1825289531"}]}, "emitted_at": 1670509828865} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"id": "people", "value": null, "additional_info": null, "text": "", "title": "IT owner", "type": "multiple-person"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Responsible HR", "type": "multiple-person"}, {"id": "date4", "value": null, "additional_info": null, "text": "", "title": "Start date", "type": "date"}, {"id": "status", "value": null, "additional_info": null, "text": null, "title": "Team", "type": "color"}, {"id": "status8", "value": null, "additional_info": null, "text": null, "title": "Site", "type": "color"}, {"id": "status1", "value": null, "additional_info": null, "text": null, "title": "Computer type", "type": "color"}, {"id": "status2", "value": null, "additional_info": null, "text": null, "title": "Computer setup", "type": "color"}, {"id": "computer_setup", "value": null, "additional_info": null, "text": null, "title": "Google account", "type": "color"}, {"id": "google_account", "value": null, "additional_info": null, "text": null, "title": "Zoom account", "type": "color"}, {"id": "zoom_account", "value": null, "additional_info": null, "text": null, "title": "365 account", "type": "color"}, {"id": "365_account3", "value": null, "additional_info": null, "text": null, "title": "Setup desk monitor", "type": "color"}, {"id": "set_up_desk_monitor", "value": null, "additional_info": null, "text": null, "title": "Setup entrance tag", "type": "color"}, {"id": "email", "value": null, "additional_info": null, "text": "", "title": "Email", "type": "email"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555407986", "name": "Hi there! \ud83d\udc4b Click here for more information \u27a1\ufe0f", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [{"id": "1825289518"}]}, "emitted_at": 1670509828869} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"id": "people", "value": null, "additional_info": null, "text": "", "title": "IT owner", "type": "multiple-person"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Responsible HR", "type": "multiple-person"}, {"id": "date4", "value": "{\"date\":\"2020-06-23\"}", "additional_info": null, "text": "2020-06-23", "title": "Start date", "type": "date"}, {"id": "status", "value": "{\"index\":7,\"post_id\":null}", "additional_info": "{\"label\":\"Finance\",\"color\":\"#579bfc\",\"changed_at\":null}", "text": "Finance", "title": "Team", "type": "color"}, {"id": "status8", "value": "{\"index\":1,\"post_id\":null}", "additional_info": "{\"label\":\"Denver\",\"color\":\"#225091\",\"changed_at\":null}", "text": "Denver", "title": "Site", "type": "color"}, {"id": "status1", "value": "{\"index\":14,\"post_id\":null}", "additional_info": "{\"label\":\"PC\",\"color\":\"#784BD1\",\"changed_at\":null}", "text": "PC", "title": "Computer type", "type": "color"}, {"id": "status2", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-21T13:46:33.895Z\"}", "additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-21T13:46:33.895Z\"}", "text": "Working on it", "title": "Computer setup", "type": "color"}, {"id": "computer_setup", "value": null, "additional_info": null, "text": null, "title": "Google account", "type": "color"}, {"id": "google_account", "value": null, "additional_info": null, "text": null, "title": "Zoom account", "type": "color"}, {"id": "zoom_account", "value": null, "additional_info": null, "text": null, "title": "365 account", "type": "color"}, {"id": "365_account3", "value": null, "additional_info": null, "text": null, "title": "Setup desk monitor", "type": "color"}, {"id": "set_up_desk_monitor", "value": null, "additional_info": null, "text": null, "title": "Setup entrance tag", "type": "color"}, {"id": "email", "value": "{\"text\":\"bjornk@yahoo.com\",\"email\":\"bjornk@yahoo.com\"}", "additional_info": null, "text": "bjornk@yahoo.com", "title": "Email", "type": "email"}], "created_at": "2022-11-21T14:36:51Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407939", "name": "Employee name 3", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1670509828873} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"id": "people", "value": null, "additional_info": null, "text": "", "title": "IT owner", "type": "multiple-person"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Responsible HR", "type": "multiple-person"}, {"id": "date4", "value": "{\"date\":\"2020-06-19\"}", "additional_info": null, "text": "2020-06-19", "title": "Start date", "type": "date"}, {"id": "status", "value": "{\"index\":4,\"post_id\":null}", "additional_info": "{\"label\":\"Sales\",\"color\":\"#a25ddc\",\"changed_at\":null}", "text": "Sales", "title": "Team", "type": "color"}, {"id": "status8", "value": "{\"index\":1,\"post_id\":null}", "additional_info": "{\"label\":\"Denver\",\"color\":\"#225091\",\"changed_at\":null}", "text": "Denver", "title": "Site", "type": "color"}, {"id": "status1", "value": "{\"index\":14,\"post_id\":null}", "additional_info": "{\"label\":\"PC\",\"color\":\"#784BD1\",\"changed_at\":null}", "text": "PC", "title": "Computer type", "type": "color"}, {"id": "status2", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:46:39.331Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:46:39.331Z\"}", "text": "Done", "title": "Computer setup", "type": "color"}, {"id": "computer_setup", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:46:40.460Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:46:40.460Z\"}", "text": "Done", "title": "Google account", "type": "color"}, {"id": "google_account", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-21T13:46:41.571Z\"}", "additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-21T13:46:41.571Z\"}", "text": "Working on it", "title": "Zoom account", "type": "color"}, {"id": "zoom_account", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:15.506Z\"}", "additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-21T13:49:15.506Z\"}", "text": "Working on it", "title": "365 account", "type": "color"}, {"id": "365_account3", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T06:24:56.006Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T06:24:56.006Z\"}", "text": "Done", "title": "Setup desk monitor", "type": "color"}, {"id": "set_up_desk_monitor", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T06:24:57.281Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T06:24:57.281Z\"}", "text": "Done", "title": "Setup entrance tag", "type": "color"}, {"id": "email", "value": "{\"text\":\"fangorn@att.net\",\"email\":\"fangorn@att.net\"}", "additional_info": null, "text": "fangorn@att.net", "title": "Email", "type": "email"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407955", "name": "Employee name 5", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1670509828876} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"id": "people", "value": null, "additional_info": null, "text": "", "title": "IT owner", "type": "multiple-person"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Responsible HR", "type": "multiple-person"}, {"id": "date4", "value": "{\"date\":\"2020-05-15\"}", "additional_info": null, "text": "2020-05-15", "title": "Start date", "type": "date"}, {"id": "status", "value": "{\"index\":6,\"post_id\":null}", "additional_info": "{\"label\":\"Partners\",\"color\":\"#037f4c\",\"changed_at\":null}", "text": "Partners", "title": "Team", "type": "color"}, {"id": "status8", "value": "{\"index\":2,\"post_id\":null}", "additional_info": "{\"label\":\"Florida\",\"color\":\"#FF642E\",\"changed_at\":null}", "text": "Florida", "title": "Site", "type": "color"}, {"id": "status1", "value": "{\"index\":1,\"post_id\":null}", "additional_info": "{\"label\":\"Mac\",\"color\":\"#00c875\",\"changed_at\":null}", "text": "Mac", "title": "Computer type", "type": "color"}, {"id": "status2", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:51.414Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:51.414Z\"}", "text": "Done", "title": "Computer setup", "type": "color"}, {"id": "computer_setup", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:52.581Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:52.581Z\"}", "text": "Done", "title": "Google account", "type": "color"}, {"id": "google_account", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:54.106Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:54.106Z\"}", "text": "Done", "title": "Zoom account", "type": "color"}, {"id": "zoom_account", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:55.348Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:55.348Z\"}", "text": "Done", "title": "365 account", "type": "color"}, {"id": "365_account3", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:55.348Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:55.348Z\"}", "text": "Done", "title": "Setup desk monitor", "type": "color"}, {"id": "set_up_desk_monitor", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:55.348Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:55.348Z\"}", "text": "Done", "title": "Setup entrance tag", "type": "color"}, {"id": "email", "value": "{\"text\":\"mdielmann@me.com\",\"email\":\"mdielmann@me.com\"}", "additional_info": null, "text": "mdielmann@me.com", "title": "Email", "type": "email"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555407946", "name": "Employee name 4", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1670509828879} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"id": "people", "value": null, "additional_info": null, "text": "", "title": "IT owner", "type": "multiple-person"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Responsible HR", "type": "multiple-person"}, {"id": "date4", "value": "{\"date\":\"2020-04-16\"}", "additional_info": null, "text": "2020-04-16", "title": "Start date", "type": "date"}, {"id": "status", "value": "{\"index\":3,\"post_id\":null}", "additional_info": "{\"label\":\"R&D\",\"color\":\"#0086c0\",\"changed_at\":null}", "text": "R&D", "title": "Team", "type": "color"}, {"id": "status8", "value": "{\"index\":14,\"post_id\":null}", "additional_info": "{\"label\":\"New York\",\"color\":\"#784BD1\",\"changed_at\":null}", "text": "New York", "title": "Site", "type": "color"}, {"id": "status1", "value": "{\"index\":1,\"post_id\":null}", "additional_info": "{\"label\":\"Mac\",\"color\":\"#00c875\",\"changed_at\":null}", "text": "Mac", "title": "Computer type", "type": "color"}, {"id": "status2", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:57.121Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:57.121Z\"}", "text": "Done", "title": "Computer setup", "type": "color"}, {"id": "computer_setup", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:59.755Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:59.755Z\"}", "text": "Done", "title": "Google account", "type": "color"}, {"id": "google_account", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:02.766Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:02.766Z\"}", "text": "Done", "title": "Zoom account", "type": "color"}, {"id": "zoom_account", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:06.494Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:06.494Z\"}", "text": "Done", "title": "365 account", "type": "color"}, {"id": "365_account3", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:06.494Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:06.494Z\"}", "text": "Done", "title": "Setup desk monitor", "type": "color"}, {"id": "set_up_desk_monitor", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:06.494Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:06.494Z\"}", "text": "Done", "title": "Setup entrance tag", "type": "color"}, {"id": "email", "value": "{\"text\":\"bjornk@outlook.com\",\"email\":\"bjornk@outlook.com\"}", "additional_info": null, "text": "bjornk@outlook.com", "title": "Email", "type": "email"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_new_hires___6_25_"}, "id": "3555407966", "name": "Employee name 6", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1670509828881} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"id": "people", "value": null, "additional_info": null, "text": "", "title": "IT owner", "type": "multiple-person"}, {"id": "person", "value": null, "additional_info": null, "text": "", "title": "Responsible HR", "type": "multiple-person"}, {"id": "date4", "value": "{\"date\":\"2020-04-29\"}", "additional_info": null, "text": "2020-04-29", "title": "Start date", "type": "date"}, {"id": "status", "value": "{\"index\":4,\"post_id\":null}", "additional_info": "{\"label\":\"Sales\",\"color\":\"#a25ddc\",\"changed_at\":null}", "text": "Sales", "title": "Team", "type": "color"}, {"id": "status8", "value": "{\"index\":1,\"post_id\":null}", "additional_info": "{\"label\":\"Denver\",\"color\":\"#225091\",\"changed_at\":null}", "text": "Denver", "title": "Site", "type": "color"}, {"id": "status1", "value": "{\"index\":1,\"post_id\":null}", "additional_info": "{\"label\":\"Mac\",\"color\":\"#00c875\",\"changed_at\":null}", "text": "Mac", "title": "Computer type", "type": "color"}, {"id": "status2", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:58.600Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:58.600Z\"}", "text": "Done", "title": "Computer setup", "type": "color"}, {"id": "computer_setup", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:01.489Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:01.489Z\"}", "text": "Done", "title": "Google account", "type": "color"}, {"id": "google_account", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:04.009Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:04.009Z\"}", "text": "Done", "title": "Zoom account", "type": "color"}, {"id": "zoom_account", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:05.324Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:05.324Z\"}", "text": "Done", "title": "365 account", "type": "color"}, {"id": "365_account3", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:05.324Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:05.324Z\"}", "text": "Done", "title": "Setup desk monitor", "type": "color"}, {"id": "set_up_desk_monitor", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:05.324Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:05.324Z\"}", "text": "Done", "title": "Setup entrance tag", "type": "color"}, {"id": "email", "value": "{\"text\":\"mcmillan@gmail.com\",\"email\":\"mcmillan@gmail.com\"}", "additional_info": null, "text": "mcmillan@gmail.com", "title": "Email", "type": "email"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_new_hires___6_25_"}, "id": "3555407969", "name": "Employee name 7", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1670509828883} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"id": "status", "value": null, "additional_info": null, "text": null, "title": "Status", "type": "color"}, {"id": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1wC5EQFsISkGAYLTKtcw1sG3ppHNLwESl/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:27.555Z\"}", "additional_info": null, "text": "Link - https://drive.google.com/file/d/1wC5EQFsISkGAYLTKtcw1sG3ppHNLwESl/view", "title": "Link", "type": "link"}, {"id": "label", "value": null, "additional_info": null, "text": null, "title": "Label", "type": "color"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "Text", "type": "text"}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179394", "name": "API session", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": []}, "emitted_at": 1670509829849} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"id": "status", "value": null, "additional_info": null, "text": null, "title": "Status", "type": "color"}, {"id": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1BbEblAXGDOxTiTIDIcqOzfhAh43IyuTu/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:31.968Z\"}", "additional_info": null, "text": "Link - https://drive.google.com/file/d/1BbEblAXGDOxTiTIDIcqOzfhAh43IyuTu/view", "title": "Link", "type": "link"}, {"id": "label", "value": null, "additional_info": null, "text": null, "title": "Label", "type": "color"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "Text", "type": "text"}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179405", "name": "Build a view", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": []}, "emitted_at": 1670509829853} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"id": "status", "value": null, "additional_info": null, "text": null, "title": "Status", "type": "color"}, {"id": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1ByMoeo2yhQcZfEOLhPP_iTjhutsLHipO/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:38.402Z\"}", "additional_info": null, "text": "Link - https://drive.google.com/file/d/1ByMoeo2yhQcZfEOLhPP_iTjhutsLHipO/view", "title": "Link", "type": "link"}, {"id": "label", "value": null, "additional_info": null, "text": null, "title": "Label", "type": "color"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "Text", "type": "text"}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179418", "name": "Build an integration", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": []}, "emitted_at": 1670509829857} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"id": "status", "value": null, "additional_info": null, "text": null, "title": "Status", "type": "color"}, {"id": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1MbhkWgJY8piKmH0uivIHaKnwYPyNr3rS/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:48.148Z\"}", "additional_info": null, "text": "Link - https://drive.google.com/file/d/1MbhkWgJY8piKmH0uivIHaKnwYPyNr3rS/view", "title": "Link", "type": "link"}, {"id": "label", "value": null, "additional_info": null, "text": null, "title": "Label", "type": "color"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "Text", "type": "text"}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179422", "name": "Authentication", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": []}, "emitted_at": 1670509829860} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"id": "status", "value": null, "additional_info": null, "text": null, "title": "Status", "type": "color"}, {"id": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1ZUwXi9VA7MfD3JZJgvVXmpdvaosHJIKm/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:53.319Z\"}", "additional_info": null, "text": "Link - https://drive.google.com/file/d/1ZUwXi9VA7MfD3JZJgvVXmpdvaosHJIKm/view", "title": "Link", "type": "link"}, {"id": "label", "value": null, "additional_info": null, "text": null, "title": "Label", "type": "color"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "Text", "type": "text"}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179431", "name": "Build a Workspace template", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": []}, "emitted_at": 1670509829863} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"id": "status", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-11-21T14:40:58.550Z\"}", "additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2022-11-21T14:40:58.550Z\"}", "text": "Done", "title": "Status", "type": "color"}, {"id": "link", "value": "{\"url\":\"https://airbyte.com/\",\"text\":\"Airbyte\",\"changed_at\":\"2022-11-21T14:40:42.184Z\"}", "additional_info": null, "text": "Airbyte - https://airbyte.com/", "title": "Link", "type": "link"}, {"id": "label", "value": "{\"index\":156,\"post_id\":null,\"changed_at\":\"2022-11-21T14:41:45.550Z\"}", "additional_info": "{\"label\":\"Label 3\",\"color\":\"#9D99B9\",\"changed_at\":\"2022-11-21T14:41:45.550Z\"}", "text": "Label 3", "title": "Label", "type": "color"}, {"id": "text", "value": "\"Test test test\"", "additional_info": null, "text": "Test test test", "title": "Text", "type": "text"}], "created_at": "2022-11-21T14:40:34Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555433784", "name": "Test", "parent_item": {"id": "3555179351"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:42:01Z", "updates": []}, "emitted_at": 1670509829866} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"id": "status", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-11-21T14:41:32.359Z\"}", "additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2022-11-21T14:41:32.359Z\"}", "text": "Working on it", "title": "Status", "type": "color"}, {"id": "link", "value": null, "additional_info": null, "text": "", "title": "Link", "type": "link"}, {"id": "label", "value": "{\"index\":105,\"post_id\":null,\"changed_at\":\"2022-11-21T14:41:43.450Z\"}", "additional_info": "{\"label\":\"Label 1\",\"color\":\"#9AADBD\",\"changed_at\":\"2022-11-21T14:41:43.450Z\"}", "text": "Label 1", "title": "Label", "type": "color"}, {"id": "text", "value": "\"one two three #!!\"", "additional_info": null, "text": "one two three #!!", "title": "Text", "type": "text"}], "created_at": "2022-11-21T14:41:12Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555437747", "name": "Test1", "parent_item": {"id": "3555179351"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:42:09Z", "updates": [{"id": "1825302913"}]}, "emitted_at": 1670509829868} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": null, "additional_info": null, "text": "", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-06-07T11:29:38.019Z\"}", "additional_info": "{\"label\":\"Done!\",\"color\":\"#00c875\",\"changed_at\":\"2022-06-07T11:29:38.019Z\"}", "text": "Done!", "title": "Status", "type": "color"}, {"id": "status_10", "value": null, "additional_info": null, "text": "Other", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179259", "name": "Create a dev account", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1670509831250} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": "{\"linkedPulseIds\":[{\"linkedPulseId\":3555433784},{\"linkedPulseId\":3555437747}]}", "additional_info": null, "text": "Test, Test1", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": null, "additional_info": null, "text": "", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:29:19.711Z\"}", "additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2022-06-07T11:29:19.711Z\"}", "text": "Working on it", "title": "Status", "type": "color"}, {"id": "status_10", "value": null, "additional_info": null, "text": "Other", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179351", "name": "Click to read this update \ud83e\udd29", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:41:13Z", "updates": [{"id": "1825206780"}]}, "emitted_at": 1670509831253} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://www.youtube.com/watch?v=nUMK6d1JcCY\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:16:13.208Z\"}", "additional_info": null, "text": "Link - https://www.youtube.com/watch?v=nUMK6d1JcCY", "title": "Link", "type": "link"}, {"id": "text", "value": "\"You can write you notes here\"", "additional_info": null, "text": "You can write you notes here", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2022-06-07T11:16:08.728Z\"}", "additional_info": "{\"label\":\"Video\",\"color\":\"#e2445c\",\"changed_at\":\"2022-06-07T11:16:08.728Z\"}", "text": "Video", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "14293832", "group": {"id": "topics"}, "id": "3555179247", "name": "What is monday - 2 min video \ud83c\udfa5 (Very cool)", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1670509831256} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": null, "additional_info": null, "text": "", "title": "Link", "type": "link"}, {"id": "text", "value": "\"Notes\"", "additional_info": null, "text": "Notes", "title": "My notes", "type": "text"}, {"id": "status_1", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-11-21T14:42:28.383Z\"}", "additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2022-11-21T14:42:28.383Z\"}", "text": "Working on it", "title": "Status", "type": "color"}, {"id": "status_10", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-11-21T14:42:31.122Z\"}", "additional_info": "{\"label\":\"Documentation\",\"color\":\"#175A63\",\"changed_at\":\"2022-11-21T14:42:31.122Z\"}", "text": "Documentation", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:42:29Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555446655", "name": "Item 1", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:42:42Z", "updates": []}, "emitted_at": 1670509831257} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": null, "additional_info": null, "text": "", "title": "Link", "type": "link"}, {"id": "text", "value": "\"Note 2\"", "additional_info": null, "text": "Note 2", "title": "My notes", "type": "text"}, {"id": "status_1", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2022-11-21T14:42:44.903Z\"}", "additional_info": "{\"label\":\"Stuck\",\"color\":\"#e2445c\",\"changed_at\":\"2022-11-21T14:42:44.903Z\"}", "text": "Stuck", "title": "Status", "type": "color"}, {"id": "status_10", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-11-21T14:42:47.315Z\"}", "additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-11-21T14:42:47.315Z\"}", "text": "Article", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:42:48Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555448801", "name": "Item 2", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:42:58Z", "updates": []}, "emitted_at": 1670509831260} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360001267945-The-board-views\",\"text\":\"LInk\",\"changed_at\":\"2022-06-07T11:18:26.141Z\"}", "additional_info": null, "text": "LInk - https://support.monday.com/hc/en-us/articles/360001267945-The-board-views", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:17:57.718Z\"}", "additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:17:57.718Z\"}", "text": "Article", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "new_group37570"}, "id": "3555179253", "name": "Board views", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1670509831262} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360017143959-The-Item-Card-\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:57:42.870Z\"}", "additional_info": null, "text": "Link - https://support.monday.com/hc/en-us/articles/360017143959-The-Item-Card-", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:22:29.156Z\"}", "additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:22:29.156Z\"}", "text": "Article", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group37570"}, "id": "3555179292", "name": "Item views", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1670509831263} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360003445540-monday-com-Integrations\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:51:35.374Z\"}", "additional_info": null, "text": "Link - https://support.monday.com/hc/en-us/articles/360003445540-monday-com-Integrations", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:22:29.156Z\"}", "additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:22:29.156Z\"}", "text": "Article", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group37570"}, "id": "3555179262", "name": "Integrations", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1670509831265} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360002187819-The-Dashboards\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:54:50.218Z\"}", "additional_info": null, "text": "Link - https://support.monday.com/hc/en-us/articles/360002187819-The-Dashboards", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:22:29.156Z\"}", "additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:22:29.156Z\"}", "text": "Article", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group37570"}, "id": "3555179270", "name": "Dashboard widgets", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1670509831266} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360001362625-monday-com-board-templates\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:56:20.627Z\"}", "additional_info": null, "text": "Link - https://support.monday.com/hc/en-us/articles/360001362625-monday-com-board-templates", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:56:23.316Z\"}", "additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:56:23.316Z\"}", "text": "Article", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group37570"}, "id": "3555179288", "name": "Workspace template", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1670509831268} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://monday.com/marketplace\",\"text\":\"Apps marketplace\",\"changed_at\":\"2022-04-12T13:55:17.553Z\"}", "additional_info": null, "text": "Apps marketplace - https://monday.com/marketplace", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": null, "additional_info": null, "text": "Other", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:38Z", "creator_id": "14293832", "group": {"id": "group_title"}, "id": "3555179185", "name": "Check out our marketplace - The puzzle icon on the left pane", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:38Z", "updates": []}, "emitted_at": 1670509831269} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://apps.developer.monday.com/docs/monday-app-development-process\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:58:53.115Z\"}", "additional_info": null, "text": "Link - https://apps.developer.monday.com/docs/monday-app-development-process", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:58:38.720Z\"}", "additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:58:38.720Z\"}", "text": "Article", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "14293832", "group": {"id": "group_title"}, "id": "3555179305", "name": "Plan your app", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1670509831270} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://monday.com/developers/apps/intro\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:59:07.145Z\"}", "additional_info": null, "text": "Link - https://monday.com/developers/apps/intro", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-06-07T11:58:40.733Z\"}", "additional_info": "{\"label\":\"Documentation\",\"color\":\"#175A63\",\"changed_at\":\"2022-06-07T11:58:40.733Z\"}", "text": "Documentation", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555179310", "name": "Check out our monday apps documentation", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": []}, "emitted_at": 1670509831271} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://apps.developer.monday.com/docs/workspace-templates\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:59:30.527Z\"}", "additional_info": null, "text": "Link - https://apps.developer.monday.com/docs/workspace-templates", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-06-07T11:58:43.818Z\"}", "additional_info": "{\"label\":\"Documentation\",\"color\":\"#175A63\",\"changed_at\":\"2022-06-07T11:58:43.818Z\"}", "text": "Documentation", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555179318", "name": "Bundling templates with your app", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": []}, "emitted_at": 1670509831272} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": "{\"linkedPulseIds\":[{\"linkedPulseId\":3555179394},{\"linkedPulseId\":3555179405},{\"linkedPulseId\":3555179418},{\"linkedPulseId\":3555179422},{\"linkedPulseId\":3555179431}]}", "additional_info": null, "text": "API session, Build a view, Build an integration, Authentication, Build a Workspace template", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": null, "additional_info": null, "text": "", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2022-06-07T11:59:35.220Z\"}", "additional_info": "{\"label\":\"Video\",\"color\":\"#e2445c\",\"changed_at\":\"2022-06-07T11:59:35.220Z\"}", "text": "Video", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "29814928", "group": {"id": "group_title"}, "id": "3555179341", "name": "Sessions recordings - See the framework in action (Subitems)", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:42Z", "updates": []}, "emitted_at": 1670509831273} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://apps.developer.monday.com/docs/submit-your-app\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T12:06:37.152Z\"}", "additional_info": null, "text": "Link - https://apps.developer.monday.com/docs/submit-your-app", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T12:06:30.006Z\"}", "additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T12:06:30.006Z\"}", "text": "Article", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "36694549", "group": {"id": "new_group45036"}, "id": "3555179324", "name": "Prepare for marketplace review", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": []}, "emitted_at": 1670509831275} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://view.monday.com/2586384041-f47a2dae812b0a295f0a974bfc39b42d?r=use1\",\"text\":\"Link to board\",\"changed_at\":\"2022-04-25T09:16:11.585Z\"}", "additional_info": null, "text": "Link to board - https://view.monday.com/2586384041-f47a2dae812b0a295f0a974bfc39b42d?r=use1", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": null, "additional_info": null, "text": "Other", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group45036"}, "id": "3555179218", "name": "App review template board", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1670509831276} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://forms.monday.com/forms/c390831d51274ee8882bf4fc96a6fb17\",\"text\":\"Submission form\",\"changed_at\":\"2022-04-12T14:04:58.308Z\"}", "additional_info": null, "text": "Submission form - https://forms.monday.com/forms/c390831d51274ee8882bf4fc96a6fb17", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": null, "additional_info": null, "text": "Other", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "new_group45036"}, "id": "3555179230", "name": "Submit your app to review", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1670509831277} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://community.monday.com/c/developers/8\",\"text\":\"Link \",\"changed_at\":\"2022-04-12T14:02:46.916Z\"}", "additional_info": null, "text": "Link - https://community.monday.com/c/developers/8", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": null, "additional_info": null, "text": "Other", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:38Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555179200", "name": "Developers community \ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:38Z", "updates": []}, "emitted_at": 1670509831278} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://style.monday.com/?path=/docs/welcome--page\",\"text\":\"Link\",\"changed_at\":\"2022-04-12T14:03:00.031Z\"}", "additional_info": null, "text": "Link - https://style.monday.com/?path=/docs/welcome--page", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": null, "additional_info": null, "text": "Other", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555179207", "name": "Design kit \ud83d\udc69\ud83c\udffb\u200d\ud83c\udfa8", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1670509831279} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://apps.developer.monday.com/docs/monetization\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T12:07:37.151Z\"}", "additional_info": null, "text": "Link - https://apps.developer.monday.com/docs/monetization", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-06-07T12:07:24.046Z\"}", "additional_info": "{\"label\":\"Documentation\",\"color\":\"#175A63\",\"changed_at\":\"2022-06-07T12:07:24.046Z\"}", "text": "Documentation", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555179327", "name": "monday apps monetization \ud83d\udcb0", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": []}, "emitted_at": 1670509831280} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"mailto:appsupport@monday.com/\",\"text\":\"appsupport@monday.com\",\"changed_at\":\"2022-04-13T20:54:57.089Z\"}", "additional_info": null, "text": "appsupport@monday.com - mailto:appsupport@monday.com/", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": null, "additional_info": null, "text": "Other", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555179211", "name": "Technical support team \ud83e\udd70", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1670509831281} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"id": "subitems", "value": null, "additional_info": null, "text": "", "title": "Subitems", "type": "subtasks"}, {"id": "link", "value": "{\"url\":\"https://mondayclimatechallenge.devpost.com/\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T13:40:18.751Z\"}", "additional_info": null, "text": "Link - https://mondayclimatechallenge.devpost.com/", "title": "Link", "type": "link"}, {"id": "text", "value": null, "additional_info": null, "text": "", "title": "My notes", "type": "text"}, {"id": "status_1", "value": null, "additional_info": null, "text": "Need to review", "title": "Status", "type": "color"}, {"id": "status_10", "value": null, "additional_info": null, "text": "Other", "title": "Type", "type": "color"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "29814928", "group": {"id": "new_group"}, "id": "3555179334", "name": "Make sure you saw to see challenge post (awesome prizes included)", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": []}, "emitted_at": 1670509831281} -{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 380}, {"archived": false, "id": "manager1", "settings_str": "{}", "title": "Owner", "type": "multiple-person", "width": 80}, {"archived": false, "id": "date4", "settings_str": "{}", "title": "Request date", "type": "date", "width": null}, {"archived": false, "id": "status1", "settings_str": "{\"labels\":{\"0\":\"Evaluating\",\"1\":\"Done\",\"2\":\"Denied\",\"3\":\"Waiting for legal\",\"6\":\"Approved for POC\",\"11\":\"On hold\",\"14\":\"Waiting for vendor\",\"15\":\"Negotiation\",\"108\":\"Approved for use\"},\"labels_positions_v2\":{\"0\":0,\"1\":1,\"2\":7,\"3\":8,\"5\":9,\"6\":3,\"11\":6,\"14\":5,\"15\":4,\"108\":2},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"3\":{\"color\":\"#0086c0\",\"border\":\"#3DB0DF\",\"var_name\":\"blue-links\"},\"6\":{\"color\":\"#037f4c\",\"border\":\"#006B38\",\"var_name\":\"grass-green\"},\"11\":{\"color\":\"#BB3354\",\"border\":\"#A42D4A\",\"var_name\":\"dark-red\"},\"14\":{\"color\":\"#784BD1\",\"border\":\"#8F4DC4\",\"var_name\":\"dark-purple\"},\"15\":{\"color\":\"#9CD326\",\"border\":\"#89B921\",\"var_name\":\"lime-green\"},\"108\":{\"color\":\"#4eccc6\",\"border\":\"#4eccc6\",\"var_name\":\"australia\"}}}", "title": "Procurement status", "type": "color", "width": null}, {"archived": false, "id": "person", "settings_str": "{}", "title": "Manager", "type": "multiple-person", "width": 80}, {"archived": false, "id": "status", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Manager approval", "type": "color", "width": null}, {"archived": false, "id": "budget_owner", "settings_str": "{}", "title": "POC owner", "type": "multiple-person", "width": 80}, {"archived": false, "id": "budget_owner_approval4", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "POC status", "type": "color", "width": null}, {"archived": false, "id": "manager", "settings_str": "{}", "title": "Budget owner", "type": "multiple-person", "width": 80}, {"archived": false, "id": "status4", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Budget owner approval", "type": "color", "width": 185}, {"archived": false, "id": "people", "settings_str": "{}", "title": "Procurement team", "type": "multiple-person", "width": null}, {"archived": false, "id": "budget_owner_approval", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Procurement approval", "type": "color", "width": null}, {"archived": false, "id": "procurement_team", "settings_str": "{}", "title": "Finance", "type": "multiple-person", "width": null}, {"archived": false, "id": "procurement_approval", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Finance approval", "type": "color", "width": null}, {"archived": false, "id": "finance", "settings_str": "{}", "title": "Legal", "type": "multiple-person", "width": null}, {"archived": false, "id": "finance_approval", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Redlines\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Legal approval", "type": "color", "width": null}, {"archived": false, "id": "file", "settings_str": "{}", "title": "File", "type": "file", "width": null}, {"archived": false, "id": "legal", "settings_str": "{}", "title": "Security", "type": "multiple-person", "width": null}, {"archived": false, "id": "legal_approval", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Security approval", "type": "color", "width": null}, {"archived": false, "id": "date", "settings_str": "{\"hide_footer\":false}", "title": "Renewal date", "type": "date", "width": null}, {"archived": false, "id": "last_updated", "settings_str": "{}", "title": "Last updated", "type": "pulse-updated", "width": 129}], "communication": null, "description": "Many IT departments need to handle the procurement process for new services. The essence of this board is to streamline this process by providing an intuitive structure that supports collaboration and efficiency.", "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Reviewing"}, {"archived": null, "color": "#FF642E", "deleted": null, "id": "new_group", "position": "98304.0", "title": "Corporate IT"}, {"archived": null, "color": "#037f4c", "deleted": null, "id": "new_group2816", "position": "114688.0", "title": "Finance"}], "id": "3555407826", "name": "Procurement process", "owner": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2022-11-21T14:36:50Z", "updates": [], "views": [{"id": "80969928"}], "workspace": null}, "emitted_at": 1670509832350} -{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 523}, {"archived": false, "id": "text4", "settings_str": "{}", "title": "SN", "type": "text", "width": null}, {"archived": false, "id": "status", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Out for repair\",\"1\":\"Working well\",\"2\":\"Needs replacement\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Status", "type": "color", "width": null}, {"archived": false, "id": "date4", "settings_str": "{}", "title": "Date given to current owner", "type": "date", "width": 204}, {"archived": false, "id": "text", "settings_str": "{}", "title": "Current owner", "type": "text", "width": null}, {"archived": false, "id": "date_given_to_current_owner", "settings_str": "{}", "title": "Last checked", "type": "date", "width": 129}], "communication": null, "description": "Welcome to your inventory management board. This is the place to track and manage all of your IT equipment inventory.", "groups": [{"archived": null, "color": "#BB3354", "deleted": null, "id": "duplicate_of_tvs___projectors", "position": "65408", "title": "Out of service"}, {"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Laptops"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "group_title", "position": "98304", "title": "Monitors"}, {"archived": null, "color": "#037f4c", "deleted": null, "id": "new_group", "position": "163840.0", "title": "TVs & projectors"}], "id": "3555407785", "name": "Inventory management", "owner": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "duplicate_of_tvs___projectors"}, "updated_at": "2022-11-21T14:36:49Z", "updates": [], "views": [], "workspace": null}, "emitted_at": 1670509832352} -{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 347}, {"archived": false, "id": "people", "settings_str": "{}", "title": "IT owner", "type": "multiple-person", "width": 98}, {"archived": false, "id": "person", "settings_str": "{}", "title": "Responsible HR", "type": "multiple-person", "width": 112}, {"archived": false, "id": "date4", "settings_str": "{}", "title": "Start date", "type": "date", "width": 114}, {"archived": false, "id": "status", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"color_mapping\":{\"0\":16,\"1\":11,\"11\":1,\"16\":0},\"labels\":{\"0\":\"Product\",\"1\":\"Design\",\"2\":\"HR\",\"3\":\"R\\u0026D\",\"4\":\"Sales\",\"6\":\"Partners\",\"7\":\"Finance\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"3\":3,\"4\":4,\"5\":7,\"6\":5,\"7\":6},\"labels_colors\":{\"0\":{\"color\":\"#66CCFF\",\"border\":\"#5AB3E0\",\"var_name\":\"turquoise\"},\"1\":{\"color\":\"#BB3354\",\"border\":\"#A42D4A\",\"var_name\":\"dark-red\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"3\":{\"color\":\"#0086c0\",\"border\":\"#3DB0DF\",\"var_name\":\"blue-links\"},\"4\":{\"color\":\"#a25ddc\",\"border\":\"#9238AF\",\"var_name\":\"purple\"},\"6\":{\"color\":\"#037f4c\",\"border\":\"#006B38\",\"var_name\":\"grass-green\"},\"7\":{\"color\":\"#579bfc\",\"border\":\"#4387E8\",\"var_name\":\"bright-blue\"}}}", "title": "Team", "type": "color", "width": 103}, {"archived": false, "id": "status8", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"color_mapping\":{\"1\":107,\"2\":19,\"3\":1,\"19\":2,\"107\":3},\"labels\":{\"1\":\"Denver\",\"2\":\"Florida\",\"14\":\"New York\"},\"labels_positions_v2\":{\"1\":2,\"2\":0,\"5\":3,\"14\":1},\"labels_colors\":{\"1\":{\"color\":\"#225091\",\"border\":\"#225091\",\"var_name\":\"navy\"},\"2\":{\"color\":\"#FF642E\",\"border\":\"#E05828\",\"var_name\":\"dark-orange\"},\"14\":{\"color\":\"#784BD1\",\"border\":\"#8F4DC4\",\"var_name\":\"dark-purple\"}}}", "title": "Site", "type": "color", "width": 80}, {"archived": false, "id": "status1", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"1\":\"Mac\",\"14\":\"PC\"},\"labels_positions_v2\":{\"1\":0,\"5\":2,\"14\":1},\"labels_colors\":{\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"14\":{\"color\":\"#784BD1\",\"border\":\"#8F4DC4\",\"var_name\":\"dark-purple\"}}}", "title": "Computer type", "type": "color", "width": 107}, {"archived": false, "id": "status2", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Computer setup", "type": "color", "width": 116}, {"archived": false, "id": "computer_setup", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Google account", "type": "color", "width": 110}, {"archived": false, "id": "google_account", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Zoom account", "type": "color", "width": 104}, {"archived": false, "id": "zoom_account", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "365 account", "type": "color", "width": 102}, {"archived": false, "id": "365_account3", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Setup desk monitor", "type": "color", "width": 132}, {"archived": false, "id": "set_up_desk_monitor", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Setup entrance tag", "type": "color", "width": null}, {"archived": false, "id": "email", "settings_str": "{}", "title": "Email", "type": "email", "width": null}], "communication": null, "description": "This is an IT onboarding process board. The essence of this board is to track the IT onboarding process of new employees.", "groups": [{"archived": null, "color": "#037f4c", "deleted": null, "id": "airbyte_group27398", "position": "16352.0", "title": "Airbyte group"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "airbyte_group", "position": "32704.0", "title": "Airbyte group"}, {"archived": null, "color": "#FF642E", "deleted": null, "id": "new_group", "position": "65408", "title": "More information about this template:"}, {"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "New Hires - June"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "group_title", "position": "98304", "title": "New Hires - May"}, {"archived": null, "color": "#037f4c", "deleted": null, "id": "duplicate_of_new_hires___6_25_", "position": "196608.0", "title": "New Hires - April"}], "id": "3555407698", "name": "IT Onboarding", "owner": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "airbyte_group27398"}, "updated_at": "2022-11-21T14:36:49Z", "updates": [{"id": "1825289531"}], "views": [{"id": "80969927"}, {"id": "80969929"}], "workspace": null}, "emitted_at": 1670509832353} -{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 414}, {"archived": false, "id": "status", "settings_str": "{\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Status", "type": "color", "width": null}, {"archived": false, "id": "link", "settings_str": "{}", "title": "Link", "type": "link", "width": null}, {"archived": false, "id": "label", "settings_str": "{\"done_colors\":[1],\"labels\":{\"3\":\"Label 2\",\"105\":\"Label 1\",\"156\":\"Label 3\"},\"labels_positions_v2\":{\"3\":1,\"5\":3,\"105\":0,\"156\":2},\"labels_colors\":{\"3\":{\"color\":\"#0086c0\",\"border\":\"#3DB0DF\",\"var_name\":\"blue-links\"},\"105\":{\"color\":\"#9AADBD\",\"border\":\"#9AADBD\",\"var_name\":\"winter\"},\"156\":{\"color\":\"#9D99B9\",\"border\":\"#9D99B9\",\"var_name\":\"purple_gray\"}}}", "title": "Label", "type": "color", "width": null}, {"archived": false, "id": "text", "settings_str": "{}", "title": "Text", "type": "text", "width": null}], "communication": null, "description": null, "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Subitems"}], "id": "3555179105", "name": "Subitems of Welcome to your monday dev account \ud83d\ude0d", "owner": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2022-11-21T14:42:06Z", "updates": [{"id": "1825302913"}], "views": [], "workspace": null}, "emitted_at": 1670509832355} -{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 596}, {"archived": false, "id": "subitems", "settings_str": "{\"allowMultipleItems\":true,\"itemTypeName\":\"column.subtasks.title\",\"displayType\":\"BOARD_INLINE\",\"boardIds\":[3555179105]}", "title": "Subitems", "type": "subtasks", "width": null}, {"archived": false, "id": "link", "settings_str": "{}", "title": "Link", "type": "link", "width": 168}, {"archived": false, "id": "text", "settings_str": "{}", "title": "My notes", "type": "text", "width": 262}, {"archived": false, "id": "status_1", "settings_str": "{\"labels\":{\"0\":\"Working on it\",\"1\":\"Done!\",\"2\":\"Stuck\",\"5\":\"Need to review\"},\"labels_positions_v2\":{\"0\":0,\"1\":1,\"2\":2,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"5\":{\"color\":\"#c4c4c4\",\"border\":\"#B0B0B0\",\"var_name\":\"grey\"}}}", "title": "Status", "type": "color", "width": null}, {"archived": false, "id": "status_10", "settings_str": "{\"done_colors\":[1],\"color_mapping\":{\"0\":16,\"1\":160,\"16\":0,\"160\":1},\"labels\":{\"0\":\"Article\",\"1\":\"Documentation\",\"2\":\"Video\",\"5\":\"Other\"},\"labels_colors\":{\"0\":{\"color\":\"#66CCFF\",\"border\":\"#5AB3E0\",\"var_name\":\"turquoise\"},\"1\":{\"color\":\"#175A63\",\"border\":\"#175A63\",\"var_name\":\"eden\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"5\":{\"color\":\"#c4c4c4\",\"border\":\"#B0B0B0\",\"var_name\":\"grey\"}}}", "title": "Type", "type": "color", "width": null}], "communication": null, "description": null, "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "81920", "title": "Get to know monday.com"}, {"archived": null, "color": "#FF158A", "deleted": null, "id": "new_group37570", "position": "90112", "title": "What can be developed on monday.com"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "group_title", "position": "98304", "title": "Build your monday app"}, {"archived": null, "color": "#fdab3d", "deleted": null, "id": "new_group45036", "position": "131072.0", "title": "Prepare for app submission"}, {"archived": null, "color": "#0086c0", "deleted": null, "id": "new_group", "position": "163840.0", "title": "Helpful resources"}], "id": "3555179067", "name": "Welcome to your monday dev account \ud83d\ude0d", "owner": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2022-11-21T14:04:38Z", "updates": [{"id": "1825206780"}], "views": [{"id": "80965788"}], "workspace": null}, "emitted_at": 1670509832356} -{"stream": "updates", "data": {"assets": [], "body": "

\ufeffTest

", "created_at": "2022-11-21T14:41:21Z", "creator_id": "36694549", "id": "1825302913", "item_id": "3555437747", "replies": [{"id": "1825303266", "creator_id": "36694549", "created_at": "2022-11-21T14:41:29Z", "text_body": "Test test", "updated_at": "2022-11-21T14:41:29Z", "body": "

\ufeffTest test

"}], "text_body": "Test", "updated_at": "2022-11-21T14:41:29Z"}, "emitted_at": 1676683112518} -{"stream": "updates", "data": {"assets": [], "body": "

\ufeffHey there \ud83d\udc4b

\ufeffThis is an update, we usually use this to...update \ud83d\ude04

\ufeffWe love to communicate with the context of a specific item.

\ufeff

\ufeffRight above this box, there are tabs for different item views which can also be used for apps.

", "created_at": "2022-06-08T12:53:39Z", "creator_id": "-7", "id": "1825206780", "item_id": "3555179351", "replies": [], "text_body": "Hey there \ud83d\udc4b\n\nThis is an update, we usually use this to...update \ud83d\ude04\n\nWe love to communicate with the context of a specific item.\n\n\n\nRight above this box, there are tabs for different item views which can also be used for apps.", "updated_at": "2022-11-21T14:04:40Z"}, "emitted_at": 1676683112520} -{"stream": "updates", "data": {"assets": [], "body": "

@Airbyte Testin \ufeffhi\ufeff

", "created_at": "2021-10-22T17:02:22Z", "creator_id": "-7", "id": "1825289531", "item_id": "3555408019", "replies": [], "text_body": "@Airbyte Testin hi", "updated_at": "2022-11-21T14:36:53Z"}, "emitted_at": 1676683112522} -{"stream": "users", "data": {"birthday": null, "country_code": "UA", "created_at": "2022-11-21T14:03:00Z", "join_date": null, "email": "integration-test@airbyte.io", "enabled": true, "id": 36694549, "is_admin": true, "is_guest": false, "is_pending": false, "is_view_only": false, "is_verified": true, "location": null, "mobile_phone": null, "name": "Airbyte Team", "phone": "", "photo_original": "https://files.monday.com/use1/photos/36694549/original/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "photo_small": "https://files.monday.com/use1/photos/36694549/small/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "photo_thumb": "https://files.monday.com/use1/photos/36694549/thumb/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "photo_thumb_small": "https://files.monday.com/use1/photos/36694549/thumb_small/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "photo_tiny": "https://files.monday.com/use1/photos/36694549/tiny/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "time_zone_identifier": "Europe/Kiev", "title": "Airbyte Developer Account", "url": "https://airbyte-unit.monday.com/users/36694549", "utc_hours_diff": 3}, "emitted_at": 1670509895766} -{"stream": "users", "data": {"birthday": null, "country_code": "UA", "created_at": "2022-11-21T14:33:18Z", "join_date": null, "email": "iryna.grankova@airbyte.io", "enabled": true, "id": 36695702, "is_admin": false, "is_guest": false, "is_pending": false, "is_view_only": false, "is_verified": true, "location": null, "mobile_phone": null, "name": "Iryna Grankova", "phone": null, "photo_original": "https://files.monday.com/use1/photos/36695702/original/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "photo_small": "https://files.monday.com/use1/photos/36695702/small/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "photo_thumb": "https://files.monday.com/use1/photos/36695702/thumb/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "photo_thumb_small": "https://files.monday.com/use1/photos/36695702/thumb_small/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "photo_tiny": "https://files.monday.com/use1/photos/36695702/tiny/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "time_zone_identifier": "Europe/Athens", "title": null, "url": "https://airbyte-unit.monday.com/users/36695702", "utc_hours_diff": 3}, "emitted_at": 1670509895770} \ No newline at end of file +{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2019-03-01T17:24:57.321Z\"}", "description": null, "id": "status", "text": "Working on it", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2019-03-01T17:24:57.321Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2023-06-11", "title": "Date", "type": "date", "value": "{\"date\":\"2023-06-11\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:25.871Z\"}"}, {"additional_info": null, "description": null, "id": "tags", "text": "open", "title": "Tags", "type": "tag", "value": "{\"tag_ids\":[19038090]}"}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "4635211945", "name": "Item 1", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-15T16:19:37Z", "updates": [{"id": "2223820299"}, {"id": "2223818363"}]}, "emitted_at": 1687273314210} +{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2019-03-01T17:28:23.178Z\"}", "description": null, "id": "status", "text": "Done", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-03-01T17:28:23.178Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2023-06-11", "title": "Date", "type": "date", "value": "{\"date\":\"2023-06-11\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:25.871Z\"}"}, {"additional_info": null, "description": null, "id": "tags", "text": "closed", "title": "Tags", "type": "tag", "value": "{\"tag_ids\":[19038091]}"}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "4635211964", "name": "Item 2", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-13T13:59:36Z", "updates": []}, "emitted_at": 1687273314214} +{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":null,\"color\":\"#c4c4c4\",\"changed_at\":\"2019-03-01T17:25:02.248Z\"}", "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": "{\"index\":5,\"post_id\":null,\"changed_at\":\"2019-03-01T17:25:02.248Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2023-06-13", "title": "Date", "type": "date", "value": "{\"date\":\"2023-06-13\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:26.291Z\"}"}, {"additional_info": null, "description": null, "id": "tags", "text": "", "title": "Tags", "type": "tag", "value": null}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "4635211977", "name": "Item 3", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-13T13:58:26Z", "updates": []}, "emitted_at": 1687273314216} +{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2023-06-13", "title": "Date", "type": "date", "value": "{\"date\":\"2023-06-13\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:25.469Z\"}"}, {"additional_info": null, "description": null, "id": "tags", "text": "", "title": "Tags", "type": "tag", "value": null}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "4635212008", "name": "Item 4", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-13T13:58:25Z", "updates": []}, "emitted_at": 1687273314218} +{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2023-06-13", "title": "Date", "type": "date", "value": "{\"date\":\"2023-06-13\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:25.469Z\"}"}, {"additional_info": null, "description": null, "id": "tags", "text": "", "title": "Tags", "type": "tag", "value": null}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "4635211995", "name": "Item 5", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-13T13:58:25Z", "updates": []}, "emitted_at": 1687273314220} +{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2023-06-20T12:12:53.948Z\"}", "description": null, "id": "status", "text": "Done", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2023-06-20T12:12:53.948Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "tags", "text": "", "title": "Tags", "type": "tag", "value": null}], "created_at": "2023-06-20T12:12:51Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "4672922929", "name": "Item 6", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-20T12:12:54Z", "updates": []}, "emitted_at": 1687273314222} +{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "tags", "text": "", "title": "Tags", "type": "tag", "value": null}], "created_at": "2023-06-20T12:13:03Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "4672924165", "name": "Item 7", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-20T12:13:03Z", "updates": []}, "emitted_at": 1687273314224} +{"stream": "items", "data": {"assets": [{"created_at": "2023-06-14T12:30:13Z", "file_extension": ".jpg", "file_size": 116107, "id": "916811099", "name": "black_cat.jpg", "original_geometry": "473x600", "public_url": "https://files-monday-com.s3.amazonaws.com/14202902/resources/916811099/black_cat.jpg?response-content-disposition=attachment&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA4MPVJMFXGWGLJTLY%2F20230620%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230620T150154Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=8ea33a5b6d6eeff76cb887301b5bbad7ee0617efa2357e0e078687d80f8d2385", "uploaded_by": {"id": 36694549}, "url": "https://airbyte-unit.monday.com/protected_static/14202902/resources/916811099/black_cat.jpg", "url_thumbnail": "https://airbyte-unit.monday.com/protected_static/14202902/resources/916811099/thumb_small-black_cat.jpg"}], "board": {"id": "4634950289"}, "column_values": [{"additional_info": null, "description": null, "id": "files", "text": "https://airbyte-unit.monday.com/protected_static/14202902/resources/916811099/black_cat.jpg", "title": "Files", "type": "file", "value": "{\"files\":[{\"name\":\"black_cat.jpg\",\"assetId\":916811099,\"isImage\":\"true\",\"fileType\":\"ASSET\",\"createdAt\":1686745812452,\"createdBy\":\"36694549\"}]}"}], "created_at": "2023-06-13T13:28:32Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "4634950329", "name": "Doc Comments", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-14T12:30:14Z", "updates": []}, "emitted_at": 1687273314762} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2019-04-11", "title": "Request date", "type": "date", "value": "{\"date\":\"2019-04-11\",\"icon\":null,\"changed_at\":\"2019-04-10 08:06:40 UTC\"}"}, {"additional_info": "{\"label\":\"Evaluating\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-07-22T06:28:36.561Z\"}", "description": null, "id": "status1", "text": "Evaluating", "title": "Procurement status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:36.561Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:09:58.545Z\"}", "description": null, "id": "status", "text": "Approved", "title": "Manager approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:09:58.545Z\"}"}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:11:20.855Z\"}", "description": null, "id": "status4", "text": "Approved", "title": "Budget owner approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:11:20.855Z\"}"}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:14:00.506Z\"}", "description": null, "id": "budget_owner_approval", "text": "Approved", "title": "Procurement approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:14:00.506Z\"}"}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Declined\",\"color\":\"#e2445c\",\"changed_at\":\"2019-05-15T14:34:59.145Z\"}", "description": null, "id": "procurement_approval", "text": "Declined", "title": "Finance approval", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2019-05-15T14:34:59.145Z\"}"}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"On Hold\",\"color\":\"#fdab3d\",\"changed_at\":\"2019-04-10T08:17:41.900Z\"}", "description": null, "id": "finance_approval", "text": "On Hold", "title": "Legal approval", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2019-04-10T08:17:41.900Z\"}"}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": "{\"files\":null}"}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Declined\",\"color\":\"#e2445c\",\"changed_at\":\"2019-04-30T15:43:35.438Z\"}", "description": null, "id": "legal_approval", "text": "Declined", "title": "Security approval", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2019-04-30T15:43:35.438Z\"}"}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:51 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:51Z", "creator_id": "25479561", "group": {"id": "topics"}, "id": "3555407934", "name": "Zendesk", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:51Z", "updates": []}, "emitted_at": 1687273317078} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2019-04-11", "title": "Request date", "type": "date", "value": "{\"date\":\"2019-04-11\",\"changed_at\":\"2019-04-02T07:03:23.375Z\"}"}, {"additional_info": "{\"label\":\"On hold\",\"color\":\"#BB3354\",\"changed_at\":\"2020-06-25T11:41:22.421Z\"}", "description": null, "id": "status1", "text": "On hold", "title": "Procurement status", "type": "color", "value": "{\"index\":11,\"post_id\":null,\"changed_at\":\"2020-06-25T11:41:22.421Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-03-01T17:28:23.178Z\"}", "description": null, "id": "status", "text": "Approved", "title": "Manager approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-03-01T17:28:23.178Z\"}"}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Declined\",\"color\":\"#e2445c\",\"changed_at\":\"2019-04-10T08:11:26.186Z\"}", "description": null, "id": "status4", "text": "Declined", "title": "Budget owner approval", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2019-04-10T08:11:26.186Z\"}"}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": "{\"files\":null}"}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"On Hold\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-25T06:36:38.993Z\"}", "description": null, "id": "legal_approval", "text": "On Hold", "title": "Security approval", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-25T06:36:38.993Z\"}"}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:52 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "25479561", "group": {"id": "topics"}, "id": "3555407944", "name": "Salesforce", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273317080} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2019-04-17", "title": "Request date", "type": "date", "value": "{\"date\":\"2019-04-17\",\"changed_at\":\"2019-04-02T07:03:25.251Z\"}"}, {"additional_info": "{\"label\":\"Waiting for vendor\",\"color\":\"#784BD1\",\"changed_at\":\"2020-07-22T06:28:39.711Z\"}", "description": null, "id": "status1", "text": "Waiting for vendor", "title": "Procurement status", "type": "color", "value": "{\"index\":14,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:39.711Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:10:00.038Z\"}", "description": null, "id": "status", "text": "Approved", "title": "Manager approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:10:00.038Z\"}"}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:11:23.942Z\"}", "description": null, "id": "status4", "text": "Approved", "title": "Budget owner approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:11:23.942Z\"}"}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:14:02.186Z\"}", "description": null, "id": "budget_owner_approval", "text": "Approved", "title": "Procurement approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:14:02.186Z\"}"}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:16:19.222Z\"}", "description": null, "id": "procurement_approval", "text": "Approved", "title": "Finance approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:16:19.222Z\"}"}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:17:46.022Z\"}", "description": null, "id": "finance_approval", "text": "Approved", "title": "Legal approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:17:46.022Z\"}"}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": "{\"files\":null}"}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-25T06:36:40.961Z\"}", "description": null, "id": "legal_approval", "text": "Approved", "title": "Security approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-25T06:36:40.961Z\"}"}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:52 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "25479561", "group": {"id": "topics"}, "id": "3555407952", "name": "YouCanBookMe", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273317082} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-25T11:41:48.118Z\"}", "description": null, "id": "status1", "text": "Done", "title": "Procurement status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-25T11:41:48.118Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408067", "name": "Box", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273317084} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Approved for use\",\"color\":\"#4eccc6\",\"changed_at\":\"2020-07-22T06:27:41.551Z\"}", "description": null, "id": "status1", "text": "Approved for use", "title": "Procurement status", "type": "color", "value": "{\"index\":108,\"post_id\":null,\"changed_at\":\"2020-07-22T06:27:41.551Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408077", "name": "Slack", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273317086} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Approved for use\",\"color\":\"#4eccc6\",\"changed_at\":\"2020-07-22T06:26:53.835Z\"}", "description": null, "id": "status1", "text": "Approved for use", "title": "Procurement status", "type": "color", "value": "{\"index\":108,\"post_id\":null,\"changed_at\":\"2020-07-22T06:26:53.835Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408088", "name": "HelpJuice", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273317087} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Approved for use\",\"color\":\"#4eccc6\",\"changed_at\":\"2020-07-22T06:28:31.709Z\"}", "description": null, "id": "status1", "text": "Approved for use", "title": "Procurement status", "type": "color", "value": "{\"index\":108,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:31.709Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408094", "name": "LucidChart", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273317089} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2019-04-11", "title": "Request date", "type": "date", "value": "{\"date\":\"2019-04-11\",\"changed_at\":\"2019-04-02T07:03:23.375Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-07-22T06:28:25.645Z\"}", "description": null, "id": "status1", "text": "Done", "title": "Procurement status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:25.645Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-03-01T17:28:23.178Z\"}", "description": null, "id": "status", "text": "Approved", "title": "Manager approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-03-01T17:28:23.178Z\"}"}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:06.894Z\"}", "description": null, "id": "status4", "text": "Approved", "title": "Budget owner approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:06.894Z\"}"}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:08.700Z\"}", "description": null, "id": "budget_owner_approval", "text": "Approved", "title": "Procurement approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:08.700Z\"}"}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:10.209Z\"}", "description": null, "id": "procurement_approval", "text": "Approved", "title": "Finance approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:10.209Z\"}"}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:11.909Z\"}", "description": null, "id": "finance_approval", "text": "Approved", "title": "Legal approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:11.909Z\"}"}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": "{\"files\":null}"}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:15.385Z\"}", "description": null, "id": "legal_approval", "text": "Approved", "title": "Security approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:15.385Z\"}"}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "25479561", "group": {"id": "new_group"}, "id": "3555408048", "name": "Aircall", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273317091} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2019-04-17", "title": "Request date", "type": "date", "value": "{\"date\":\"2019-04-17\",\"changed_at\":\"2019-04-02T07:03:25.251Z\"}"}, {"additional_info": "{\"label\":\"Approved for use\",\"color\":\"#4eccc6\",\"changed_at\":\"2020-07-22T06:28:29.177Z\"}", "description": null, "id": "status1", "text": "Approved for use", "title": "Procurement status", "type": "color", "value": "{\"index\":108,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:29.177Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:10:00.038Z\"}", "description": null, "id": "status", "text": "Approved", "title": "Manager approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:10:00.038Z\"}"}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:11:23.942Z\"}", "description": null, "id": "status4", "text": "Approved", "title": "Budget owner approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:11:23.942Z\"}"}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:14:02.186Z\"}", "description": null, "id": "budget_owner_approval", "text": "Approved", "title": "Procurement approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:14:02.186Z\"}"}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:16:19.222Z\"}", "description": null, "id": "procurement_approval", "text": "Approved", "title": "Finance approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:16:19.222Z\"}"}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:17:46.022Z\"}", "description": null, "id": "finance_approval", "text": "Approved", "title": "Legal approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:17:46.022Z\"}"}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": "{\"files\":null}"}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:17.250Z\"}", "description": null, "id": "legal_approval", "text": "Approved", "title": "Security approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:17.250Z\"}"}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "25479561", "group": {"id": "new_group"}, "id": "3555408057", "name": "Zoom", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273317093} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Waiting for legal\",\"color\":\"#0086c0\",\"changed_at\":\"2020-07-22T06:27:17.793Z\"}", "description": null, "id": "status1", "text": "Waiting for legal", "title": "Procurement status", "type": "color", "value": "{\"index\":3,\"post_id\":null,\"changed_at\":\"2020-07-22T06:27:17.793Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group2816"}, "id": "3555408102", "name": "Gaviti", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273317095} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Negotiation\",\"color\":\"#9CD326\",\"changed_at\":\"2020-07-22T06:27:22.578Z\"}", "description": null, "id": "status1", "text": "Negotiation", "title": "Procurement status", "type": "color", "value": "{\"index\":15,\"post_id\":null,\"changed_at\":\"2020-07-22T06:27:22.578Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group2816"}, "id": "3555408118", "name": "Priority", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273317096} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN56456", "title": "SN", "type": "text", "value": "\"SN56456\""}, {"additional_info": "{\"label\":\"Needs replacement\",\"color\":\"#e2445c\",\"changed_at\":\"2020-06-22T08:37:41.248Z\"}", "description": null, "id": "status", "text": "Needs replacement", "title": "Status", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2020-06-22T08:37:41.248Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-05-14", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-05-14\",\"changed_at\":\"2020-06-22T11:25:44.457Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Zakariah Macleod", "title": "Current owner", "type": "text", "value": "\"Zakariah Macleod\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-10", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-10\",\"changed_at\":\"2020-06-24T10:59:53.938Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_tvs___projectors"}, "id": "3555407991", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318766} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN 94-34-AS-GT-66", "title": "SN", "type": "text", "value": "\"SN 94-34-AS-GT-66\""}, {"additional_info": "{\"label\":\"Out for repair\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-22T08:37:42.971Z\"}", "description": null, "id": "status", "text": "Out for repair", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-22T08:37:42.971Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-10", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-10\",\"changed_at\":\"2020-06-22T11:25:46.599Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Corbin Blackburn", "title": "Current owner", "type": "text", "value": "\"Corbin Blackburn\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-11", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-11\",\"changed_at\":\"2020-06-24T10:59:55.752Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_tvs___projectors"}, "id": "3555407997", "name": "Sonos One", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318769} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "P2219G", "title": "SN", "type": "text", "value": "\"P2219G\""}, {"additional_info": "{\"label\":\"Out for repair\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-22T08:37:44.792Z\"}", "description": null, "id": "status", "text": "Out for repair", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-22T08:37:44.792Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-02", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-02\",\"changed_at\":\"2020-06-22T11:25:48.402Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Jorge Mcgowan", "title": "Current owner", "type": "text", "value": "\"Jorge Mcgowan\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-28", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-28\",\"changed_at\":\"2020-06-24T10:59:57.460Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_tvs___projectors"}, "id": "3555408009", "name": "Dell", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318771} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE57L21Y", "title": "SN", "type": "text", "value": "\"SN FVFYVE57L21Y\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-03", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-22T11:25:52.834Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Rylee Pham", "title": "Current owner", "type": "text", "value": "\"Rylee Pham\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-03-11", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-03-11\",\"changed_at\":\"2020-06-24T11:00:01.660Z\"}"}], "created_at": "2022-11-21T14:36:51Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407931", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:51Z", "updates": []}, "emitted_at": 1687273318773} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE57L22Y", "title": "SN", "type": "text", "value": "\"SN FVFYVE57L22Y\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-03", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-22T11:25:56.327Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Kaydon Gamble", "title": "Current owner", "type": "text", "value": "\"Kaydon Gamble\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-02-19", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-02-19\",\"changed_at\":\"2020-06-24T11:00:06.248Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407941", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318774} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE57L23W", "title": "SN", "type": "text", "value": "\"SN FVFYVE57L23W\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-04", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-04\",\"changed_at\":\"2020-06-22T11:25:58.156Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Eli Reyes", "title": "Current owner", "type": "text", "value": "\"Eli Reyes\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-03-26", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-03-26\",\"changed_at\":\"2020-06-24T11:00:13.482Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407947", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318776} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE57L41V", "title": "SN", "type": "text", "value": "\"SN FVFYVE57L41V\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-11", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-11\",\"changed_at\":\"2020-06-22T11:26:00.305Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Finley Hilton", "title": "Current owner", "type": "text", "value": "\"Finley Hilton\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-03-12", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-03-12\",\"changed_at\":\"2020-06-24T11:00:09.820Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407961", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318778} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE67L21Y", "title": "SN", "type": "text", "value": "\"SN FVFYVE67L21Y\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-17", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-17\",\"changed_at\":\"2020-06-22T11:26:02.141Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Fabien Morton", "title": "Current owner", "type": "text", "value": "\"Fabien Morton\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-04-21", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-04-21\",\"changed_at\":\"2020-06-24T11:00:17.305Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407968", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318779} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE57L28Y", "title": "SN", "type": "text", "value": "\"SN FVFYVE57L28Y\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-18", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-18\",\"changed_at\":\"2020-06-22T11:26:04.062Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Amelia-Mae Flower", "title": "Current owner", "type": "text", "value": "\"Amelia-Mae Flower\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-04", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-04\",\"changed_at\":\"2020-06-24T11:00:21.416Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407977", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318781} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "", "title": "SN", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date given to current owner", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Current owner", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "", "title": "Last checked", "type": "date", "value": null}], "created_at": "2023-06-20T12:21:27Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "4672979272", "name": "Macbook", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-20T12:21:27Z", "updates": []}, "emitted_at": 1687273318783} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "3sBeKstD", "title": "SN", "type": "text", "value": "\"3sBeKstD\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-03", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-22T11:26:06.624Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Masuma Carver", "title": "Current owner", "type": "text", "value": "\"Masuma Carver\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-04-07", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-04-07\",\"changed_at\":\"2020-06-24T11:00:35.389Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408016", "name": "Dell - U2417H", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318784} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "eqK2M67W", "title": "SN", "type": "text", "value": "\"eqK2M67W\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-10", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-10\",\"changed_at\":\"2020-06-22T11:26:08.798Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Tadhg Hensley", "title": "Current owner", "type": "text", "value": "\"Tadhg Hensley\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-04", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-04\",\"changed_at\":\"2020-06-24T11:00:23.245Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408058", "name": "Dell - U2418H", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273318786} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "39QTALuj", "title": "SN", "type": "text", "value": "\"39QTALuj\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-09", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-09\",\"changed_at\":\"2020-06-22T11:26:10.906Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Aanya Booth", "title": "Current owner", "type": "text", "value": "\"Aanya Booth\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-05", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-05\",\"changed_at\":\"2020-06-24T11:00:25.468Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408070", "name": "Dell - U2416H", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273318788} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "LTgqT9cY", "title": "SN", "type": "text", "value": "\"LTgqT9cY\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-03", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-22T11:26:12.701Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Kiana Burnett", "title": "Current owner", "type": "text", "value": "\"Kiana Burnett\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-20", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-20\",\"changed_at\":\"2020-06-24T11:00:27.706Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408083", "name": "Dell - U2419HX", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273318789} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "FjE7nsrs", "title": "SN", "type": "text", "value": "\"FjE7nsrs\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-10", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-10\",\"changed_at\":\"2020-06-22T11:26:17.156Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Roxie Forbes", "title": "Current owner", "type": "text", "value": "\"Roxie Forbes\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-05-06", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-05-06\",\"changed_at\":\"2020-06-24T11:00:31.519Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408091", "name": "Dell - P2219H", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273318791} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN32456", "title": "SN", "type": "text", "value": "\"SN32456\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date given to current owner", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Current owner", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-05-05", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-05-05\",\"changed_at\":\"2020-06-24T11:00:39.214Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408021", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273318793} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN32457", "title": "SN", "type": "text", "value": "\"SN32457\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date given to current owner", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Current owner", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-05-07", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-05-07\",\"changed_at\":\"2020-06-24T11:00:42.752Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408033", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273318794} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN32458", "title": "SN", "type": "text", "value": "\"SN32458\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date given to current owner", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Current owner", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-05-21", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-05-21\",\"changed_at\":\"2020-06-24T11:00:46.170Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408041", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273318796} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN32458", "title": "SN", "type": "text", "value": "\"SN32458\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date given to current owner", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Current owner", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-03", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-24T11:00:48.979Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408052", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273318798} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Start date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Team", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status8", "text": null, "title": "Site", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status1", "text": null, "title": "Computer type", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status2", "text": null, "title": "Computer setup", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "computer_setup", "text": null, "title": "Google account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "google_account", "text": null, "title": "Zoom account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "zoom_account", "text": null, "title": "365 account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "365_account3", "text": null, "title": "Setup desk monitor", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "set_up_desk_monitor", "text": null, "title": "Setup entrance tag", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "email", "text": "", "title": "Email", "type": "email", "value": null}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "25479561", "group": {"id": "airbyte_group"}, "id": "3555408019", "name": "new item", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:56Z", "updates": [{"id": "1825289531"}]}, "emitted_at": 1687273381500} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Start date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Team", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status8", "text": null, "title": "Site", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status1", "text": null, "title": "Computer type", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status2", "text": null, "title": "Computer setup", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "computer_setup", "text": null, "title": "Google account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "google_account", "text": null, "title": "Zoom account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "zoom_account", "text": null, "title": "365 account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "365_account3", "text": null, "title": "Setup desk monitor", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "set_up_desk_monitor", "text": null, "title": "Setup entrance tag", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "email", "text": "", "title": "Email", "type": "email", "value": null}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555407986", "name": "Hi there! \ud83d\udc4b Click here for more information \u27a1\ufe0f", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [{"id": "1825289518"}]}, "emitted_at": 1687273381502} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-23", "title": "Start date", "type": "date", "value": "{\"date\":\"2020-06-23\"}"}, {"additional_info": "{\"label\":\"Finance\",\"color\":\"#579bfc\",\"changed_at\":null}", "description": null, "id": "status", "text": "Finance", "title": "Team", "type": "color", "value": "{\"index\":7,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Denver\",\"color\":\"#225091\",\"changed_at\":null}", "description": null, "id": "status8", "text": "Denver", "title": "Site", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"PC\",\"color\":\"#784BD1\",\"changed_at\":null}", "description": null, "id": "status1", "text": "PC", "title": "Computer type", "type": "color", "value": "{\"index\":14,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-21T13:46:33.895Z\"}", "description": null, "id": "status2", "text": "Working on it", "title": "Computer setup", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-21T13:46:33.895Z\"}"}, {"additional_info": null, "description": null, "id": "computer_setup", "text": null, "title": "Google account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "google_account", "text": null, "title": "Zoom account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "zoom_account", "text": null, "title": "365 account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "365_account3", "text": null, "title": "Setup desk monitor", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "set_up_desk_monitor", "text": null, "title": "Setup entrance tag", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "email", "text": "bjornk@yahoo.com", "title": "Email", "type": "email", "value": "{\"text\":\"bjornk@yahoo.com\",\"email\":\"bjornk@yahoo.com\"}"}], "created_at": "2022-11-21T14:36:51Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407939", "name": "Employee name 3", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273381504} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-19", "title": "Start date", "type": "date", "value": "{\"date\":\"2020-06-19\"}"}, {"additional_info": "{\"label\":\"Sales\",\"color\":\"#a25ddc\",\"changed_at\":null}", "description": null, "id": "status", "text": "Sales", "title": "Team", "type": "color", "value": "{\"index\":4,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Denver\",\"color\":\"#225091\",\"changed_at\":null}", "description": null, "id": "status8", "text": "Denver", "title": "Site", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"PC\",\"color\":\"#784BD1\",\"changed_at\":null}", "description": null, "id": "status1", "text": "PC", "title": "Computer type", "type": "color", "value": "{\"index\":14,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:46:39.331Z\"}", "description": null, "id": "status2", "text": "Done", "title": "Computer setup", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:46:39.331Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:46:40.460Z\"}", "description": null, "id": "computer_setup", "text": "Done", "title": "Google account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:46:40.460Z\"}"}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-21T13:46:41.571Z\"}", "description": null, "id": "google_account", "text": "Working on it", "title": "Zoom account", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-21T13:46:41.571Z\"}"}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-21T13:49:15.506Z\"}", "description": null, "id": "zoom_account", "text": "Working on it", "title": "365 account", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:15.506Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T06:24:56.006Z\"}", "description": null, "id": "365_account3", "text": "Done", "title": "Setup desk monitor", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T06:24:56.006Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T06:24:57.281Z\"}", "description": null, "id": "set_up_desk_monitor", "text": "Done", "title": "Setup entrance tag", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T06:24:57.281Z\"}"}, {"additional_info": null, "description": null, "id": "email", "text": "fangorn@att.net", "title": "Email", "type": "email", "value": "{\"text\":\"fangorn@att.net\",\"email\":\"fangorn@att.net\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407955", "name": "Employee name 5", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273381506} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-05-15", "title": "Start date", "type": "date", "value": "{\"date\":\"2020-05-15\"}"}, {"additional_info": "{\"label\":\"Partners\",\"color\":\"#037f4c\",\"changed_at\":null}", "description": null, "id": "status", "text": "Partners", "title": "Team", "type": "color", "value": "{\"index\":6,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Florida\",\"color\":\"#FF642E\",\"changed_at\":null}", "description": null, "id": "status8", "text": "Florida", "title": "Site", "type": "color", "value": "{\"index\":2,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Mac\",\"color\":\"#00c875\",\"changed_at\":null}", "description": null, "id": "status1", "text": "Mac", "title": "Computer type", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:51.414Z\"}", "description": null, "id": "status2", "text": "Done", "title": "Computer setup", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:51.414Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:52.581Z\"}", "description": null, "id": "computer_setup", "text": "Done", "title": "Google account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:52.581Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:54.106Z\"}", "description": null, "id": "google_account", "text": "Done", "title": "Zoom account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:54.106Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:55.348Z\"}", "description": null, "id": "zoom_account", "text": "Done", "title": "365 account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:55.348Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:55.348Z\"}", "description": null, "id": "365_account3", "text": "Done", "title": "Setup desk monitor", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:55.348Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:55.348Z\"}", "description": null, "id": "set_up_desk_monitor", "text": "Done", "title": "Setup entrance tag", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:55.348Z\"}"}, {"additional_info": null, "description": null, "id": "email", "text": "mdielmann@me.com", "title": "Email", "type": "email", "value": "{\"text\":\"mdielmann@me.com\",\"email\":\"mdielmann@me.com\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555407946", "name": "Employee name 4", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273381508} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-04-16", "title": "Start date", "type": "date", "value": "{\"date\":\"2020-04-16\"}"}, {"additional_info": "{\"label\":\"R&D\",\"color\":\"#0086c0\",\"changed_at\":null}", "description": null, "id": "status", "text": "R&D", "title": "Team", "type": "color", "value": "{\"index\":3,\"post_id\":null}"}, {"additional_info": "{\"label\":\"New York\",\"color\":\"#784BD1\",\"changed_at\":null}", "description": null, "id": "status8", "text": "New York", "title": "Site", "type": "color", "value": "{\"index\":14,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Mac\",\"color\":\"#00c875\",\"changed_at\":null}", "description": null, "id": "status1", "text": "Mac", "title": "Computer type", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:57.121Z\"}", "description": null, "id": "status2", "text": "Done", "title": "Computer setup", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:57.121Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:59.755Z\"}", "description": null, "id": "computer_setup", "text": "Done", "title": "Google account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:59.755Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:02.766Z\"}", "description": null, "id": "google_account", "text": "Done", "title": "Zoom account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:02.766Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:06.494Z\"}", "description": null, "id": "zoom_account", "text": "Done", "title": "365 account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:06.494Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:06.494Z\"}", "description": null, "id": "365_account3", "text": "Done", "title": "Setup desk monitor", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:06.494Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:06.494Z\"}", "description": null, "id": "set_up_desk_monitor", "text": "Done", "title": "Setup entrance tag", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:06.494Z\"}"}, {"additional_info": null, "description": null, "id": "email", "text": "bjornk@outlook.com", "title": "Email", "type": "email", "value": "{\"text\":\"bjornk@outlook.com\",\"email\":\"bjornk@outlook.com\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_new_hires___6_25_"}, "id": "3555407966", "name": "Employee name 6", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273381509} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-04-29", "title": "Start date", "type": "date", "value": "{\"date\":\"2020-04-29\"}"}, {"additional_info": "{\"label\":\"Sales\",\"color\":\"#a25ddc\",\"changed_at\":null}", "description": null, "id": "status", "text": "Sales", "title": "Team", "type": "color", "value": "{\"index\":4,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Denver\",\"color\":\"#225091\",\"changed_at\":null}", "description": null, "id": "status8", "text": "Denver", "title": "Site", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Mac\",\"color\":\"#00c875\",\"changed_at\":null}", "description": null, "id": "status1", "text": "Mac", "title": "Computer type", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:58.600Z\"}", "description": null, "id": "status2", "text": "Done", "title": "Computer setup", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:58.600Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:01.489Z\"}", "description": null, "id": "computer_setup", "text": "Done", "title": "Google account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:01.489Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:04.009Z\"}", "description": null, "id": "google_account", "text": "Done", "title": "Zoom account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:04.009Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:05.324Z\"}", "description": null, "id": "zoom_account", "text": "Done", "title": "365 account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:05.324Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:05.324Z\"}", "description": null, "id": "365_account3", "text": "Done", "title": "Setup desk monitor", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:05.324Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:05.324Z\"}", "description": null, "id": "set_up_desk_monitor", "text": "Done", "title": "Setup entrance tag", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:05.324Z\"}"}, {"additional_info": null, "description": null, "id": "email", "text": "mcmillan@gmail.com", "title": "Email", "type": "email", "value": "{\"text\":\"mcmillan@gmail.com\",\"email\":\"mcmillan@gmail.com\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_new_hires___6_25_"}, "id": "3555407969", "name": "Employee name 7", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273381511} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://drive.google.com/file/d/1wC5EQFsISkGAYLTKtcw1sG3ppHNLwESl/view", "title": "Link", "type": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1wC5EQFsISkGAYLTKtcw1sG3ppHNLwESl/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:27.555Z\"}"}, {"additional_info": null, "description": "", "id": "label", "text": null, "title": "Label", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Text", "type": "text", "value": null}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179394", "name": "API session", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": []}, "emitted_at": 1687273382214} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://drive.google.com/file/d/1BbEblAXGDOxTiTIDIcqOzfhAh43IyuTu/view", "title": "Link", "type": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1BbEblAXGDOxTiTIDIcqOzfhAh43IyuTu/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:31.968Z\"}"}, {"additional_info": null, "description": "", "id": "label", "text": null, "title": "Label", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Text", "type": "text", "value": null}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179405", "name": "Build a view", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": []}, "emitted_at": 1687273382217} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://drive.google.com/file/d/1ByMoeo2yhQcZfEOLhPP_iTjhutsLHipO/view", "title": "Link", "type": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1ByMoeo2yhQcZfEOLhPP_iTjhutsLHipO/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:38.402Z\"}"}, {"additional_info": null, "description": "", "id": "label", "text": null, "title": "Label", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Text", "type": "text", "value": null}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179418", "name": "Build an integration", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": []}, "emitted_at": 1687273382219} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://drive.google.com/file/d/1MbhkWgJY8piKmH0uivIHaKnwYPyNr3rS/view", "title": "Link", "type": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1MbhkWgJY8piKmH0uivIHaKnwYPyNr3rS/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:48.148Z\"}"}, {"additional_info": null, "description": "", "id": "label", "text": null, "title": "Label", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Text", "type": "text", "value": null}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179422", "name": "Authentication", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": []}, "emitted_at": 1687273382221} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://drive.google.com/file/d/1ZUwXi9VA7MfD3JZJgvVXmpdvaosHJIKm/view", "title": "Link", "type": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1ZUwXi9VA7MfD3JZJgvVXmpdvaosHJIKm/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:53.319Z\"}"}, {"additional_info": null, "description": "", "id": "label", "text": null, "title": "Label", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Text", "type": "text", "value": null}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179431", "name": "Build a Workspace template", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": []}, "emitted_at": 1687273382223} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2022-11-21T14:40:58.550Z\"}", "description": null, "id": "status", "text": "Done", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-11-21T14:40:58.550Z\"}"}, {"additional_info": null, "description": null, "id": "link", "text": "Airbyte - https://airbyte.com/", "title": "Link", "type": "link", "value": "{\"url\":\"https://airbyte.com/\",\"text\":\"Airbyte\",\"changed_at\":\"2022-11-21T14:40:42.184Z\"}"}, {"additional_info": "{\"label\":\"Label 3\",\"color\":\"#9D99B9\",\"changed_at\":\"2022-11-21T14:41:45.550Z\"}", "description": "", "id": "label", "text": "Label 3", "title": "Label", "type": "color", "value": "{\"index\":156,\"post_id\":null,\"changed_at\":\"2022-11-21T14:41:45.550Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Test test test", "title": "Text", "type": "text", "value": "\"Test test test\""}], "created_at": "2022-11-21T14:40:34Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555433784", "name": "Test", "parent_item": {"id": "3555179351"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:42:01Z", "updates": []}, "emitted_at": 1687273382224} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2022-11-21T14:41:32.359Z\"}", "description": null, "id": "status", "text": "Working on it", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-11-21T14:41:32.359Z\"}"}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": "{\"label\":\"Label 1\",\"color\":\"#9AADBD\",\"changed_at\":\"2022-11-21T14:41:43.450Z\"}", "description": "", "id": "label", "text": "Label 1", "title": "Label", "type": "color", "value": "{\"index\":105,\"post_id\":null,\"changed_at\":\"2022-11-21T14:41:43.450Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "one two three #!!", "title": "Text", "type": "text", "value": "\"one two three #!!\""}], "created_at": "2022-11-21T14:41:12Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555437747", "name": "Test1", "parent_item": {"id": "3555179351"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-15T16:14:33Z", "updates": [{"id": "1825302913"}]}, "emitted_at": 1687273382226} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": "{\"label\":\"Done!\",\"color\":\"#00c875\",\"changed_at\":\"2022-06-07T11:29:38.019Z\"}", "description": null, "id": "status_1", "text": "Done!", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-06-07T11:29:38.019Z\"}"}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179259", "name": "Create a dev account", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384036} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "Test, Test1", "title": "Subitems", "type": "subtasks", "value": "{\"linkedPulseIds\":[{\"linkedPulseId\":3555433784},{\"linkedPulseId\":3555437747}]}"}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2022-06-07T11:29:19.711Z\"}", "description": null, "id": "status_1", "text": "Working on it", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:29:19.711Z\"}"}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179351", "name": "Click to read this update \ud83e\udd29", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:41:13Z", "updates": [{"id": "1825206780"}]}, "emitted_at": 1687273384038} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://www.youtube.com/watch?v=nUMK6d1JcCY", "title": "Link", "type": "link", "value": "{\"url\":\"https://www.youtube.com/watch?v=nUMK6d1JcCY\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:16:13.208Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "You can write you notes here", "title": "My notes", "type": "text", "value": "\"You can write you notes here\""}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Video\",\"color\":\"#e2445c\",\"changed_at\":\"2022-06-07T11:16:08.728Z\"}", "description": null, "id": "status_10", "text": "Video", "title": "Type", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2022-06-07T11:16:08.728Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "14293832", "group": {"id": "topics"}, "id": "3555179247", "name": "What is monday - 2 min video \ud83c\udfa5 (Very cool)", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384040} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "Notes", "title": "My notes", "type": "text", "value": "\"Notes\""}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2022-11-21T14:42:28.383Z\"}", "description": null, "id": "status_1", "text": "Working on it", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-11-21T14:42:28.383Z\"}"}, {"additional_info": "{\"label\":\"Documentation\",\"color\":\"#175A63\",\"changed_at\":\"2022-11-21T14:42:31.122Z\"}", "description": null, "id": "status_10", "text": "Documentation", "title": "Type", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-11-21T14:42:31.122Z\"}"}], "created_at": "2022-11-21T14:42:29Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555446655", "name": "Item 1", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:42:42Z", "updates": []}, "emitted_at": 1687273384042} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "Note 2", "title": "My notes", "type": "text", "value": "\"Note 2\""}, {"additional_info": "{\"label\":\"Stuck\",\"color\":\"#e2445c\",\"changed_at\":\"2022-11-21T14:42:44.903Z\"}", "description": null, "id": "status_1", "text": "Stuck", "title": "Status", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2022-11-21T14:42:44.903Z\"}"}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-11-21T14:42:47.315Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-11-21T14:42:47.315Z\"}"}], "created_at": "2022-11-21T14:42:48Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555448801", "name": "Item 2", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:42:58Z", "updates": []}, "emitted_at": 1687273384043} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "LInk - https://support.monday.com/hc/en-us/articles/360001267945-The-board-views", "title": "Link", "type": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360001267945-The-board-views\",\"text\":\"LInk\",\"changed_at\":\"2022-06-07T11:18:26.141Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:17:57.718Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:17:57.718Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "new_group37570"}, "id": "3555179253", "name": "Board views", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384045} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://support.monday.com/hc/en-us/articles/360017143959-The-Item-Card-", "title": "Link", "type": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360017143959-The-Item-Card-\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:57:42.870Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:22:29.156Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:22:29.156Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group37570"}, "id": "3555179292", "name": "Item views", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384047} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://support.monday.com/hc/en-us/articles/360003445540-monday-com-Integrations", "title": "Link", "type": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360003445540-monday-com-Integrations\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:51:35.374Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:22:29.156Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:22:29.156Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group37570"}, "id": "3555179262", "name": "Integrations", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384048} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://support.monday.com/hc/en-us/articles/360002187819-The-Dashboards", "title": "Link", "type": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360002187819-The-Dashboards\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:54:50.218Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:22:29.156Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:22:29.156Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group37570"}, "id": "3555179270", "name": "Dashboard widgets", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384050} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://support.monday.com/hc/en-us/articles/360001362625-monday-com-board-templates", "title": "Link", "type": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360001362625-monday-com-board-templates\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:56:20.627Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:56:23.316Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:56:23.316Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group37570"}, "id": "3555179288", "name": "Workspace template", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384052} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Apps marketplace - https://monday.com/marketplace", "title": "Link", "type": "link", "value": "{\"url\":\"https://monday.com/marketplace\",\"text\":\"Apps marketplace\",\"changed_at\":\"2022-04-12T13:55:17.553Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:38Z", "creator_id": "14293832", "group": {"id": "group_title"}, "id": "3555179185", "name": "Check out our marketplace - The puzzle icon on the left pane", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:38Z", "updates": []}, "emitted_at": 1687273384054} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://apps.developer.monday.com/docs/monday-app-development-process", "title": "Link", "type": "link", "value": "{\"url\":\"https://apps.developer.monday.com/docs/monday-app-development-process\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:58:53.115Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:58:38.720Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:58:38.720Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "14293832", "group": {"id": "group_title"}, "id": "3555179305", "name": "Plan your app", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384055} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://monday.com/developers/apps/intro", "title": "Link", "type": "link", "value": "{\"url\":\"https://monday.com/developers/apps/intro\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:59:07.145Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Documentation\",\"color\":\"#175A63\",\"changed_at\":\"2022-06-07T11:58:40.733Z\"}", "description": null, "id": "status_10", "text": "Documentation", "title": "Type", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-06-07T11:58:40.733Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555179310", "name": "Check out our monday apps documentation", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": []}, "emitted_at": 1687273384057} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://apps.developer.monday.com/docs/workspace-templates", "title": "Link", "type": "link", "value": "{\"url\":\"https://apps.developer.monday.com/docs/workspace-templates\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:59:30.527Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Documentation\",\"color\":\"#175A63\",\"changed_at\":\"2022-06-07T11:58:43.818Z\"}", "description": null, "id": "status_10", "text": "Documentation", "title": "Type", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-06-07T11:58:43.818Z\"}"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555179318", "name": "Bundling templates with your app", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": []}, "emitted_at": 1687273384059} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "API session, Build a view, Build an integration, Authentication, Build a Workspace template", "title": "Subitems", "type": "subtasks", "value": "{\"linkedPulseIds\":[{\"linkedPulseId\":3555179394},{\"linkedPulseId\":3555179405},{\"linkedPulseId\":3555179418},{\"linkedPulseId\":3555179422},{\"linkedPulseId\":3555179431}]}"}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Video\",\"color\":\"#e2445c\",\"changed_at\":\"2022-06-07T11:59:35.220Z\"}", "description": null, "id": "status_10", "text": "Video", "title": "Type", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2022-06-07T11:59:35.220Z\"}"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "29814928", "group": {"id": "group_title"}, "id": "3555179341", "name": "Sessions recordings - See the framework in action (Subitems)", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:42Z", "updates": []}, "emitted_at": 1687273384060} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://apps.developer.monday.com/docs/submit-your-app", "title": "Link", "type": "link", "value": "{\"url\":\"https://apps.developer.monday.com/docs/submit-your-app\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T12:06:37.152Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T12:06:30.006Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T12:06:30.006Z\"}"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "36694549", "group": {"id": "new_group45036"}, "id": "3555179324", "name": "Prepare for marketplace review", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": []}, "emitted_at": 1687273384062} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link to board - https://view.monday.com/2586384041-f47a2dae812b0a295f0a974bfc39b42d?r=use1", "title": "Link", "type": "link", "value": "{\"url\":\"https://view.monday.com/2586384041-f47a2dae812b0a295f0a974bfc39b42d?r=use1\",\"text\":\"Link to board\",\"changed_at\":\"2022-04-25T09:16:11.585Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group45036"}, "id": "3555179218", "name": "App review template board", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384064} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Submission form - https://forms.monday.com/forms/c390831d51274ee8882bf4fc96a6fb17", "title": "Link", "type": "link", "value": "{\"url\":\"https://forms.monday.com/forms/c390831d51274ee8882bf4fc96a6fb17\",\"text\":\"Submission form\",\"changed_at\":\"2022-04-12T14:04:58.308Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "new_group45036"}, "id": "3555179230", "name": "Submit your app to review", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384065} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://community.monday.com/c/developers/8", "title": "Link", "type": "link", "value": "{\"url\":\"https://community.monday.com/c/developers/8\",\"text\":\"Link \",\"changed_at\":\"2022-04-12T14:02:46.916Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:38Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555179200", "name": "Developers community \ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:38Z", "updates": []}, "emitted_at": 1687273384067} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://style.monday.com/?path=/docs/welcome--page", "title": "Link", "type": "link", "value": "{\"url\":\"https://style.monday.com/?path=/docs/welcome--page\",\"text\":\"Link\",\"changed_at\":\"2022-04-12T14:03:00.031Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555179207", "name": "Design kit \ud83d\udc69\ud83c\udffb\u200d\ud83c\udfa8", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384069} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://apps.developer.monday.com/docs/monetization", "title": "Link", "type": "link", "value": "{\"url\":\"https://apps.developer.monday.com/docs/monetization\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T12:07:37.151Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Documentation\",\"color\":\"#175A63\",\"changed_at\":\"2022-06-07T12:07:24.046Z\"}", "description": null, "id": "status_10", "text": "Documentation", "title": "Type", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-06-07T12:07:24.046Z\"}"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555179327", "name": "monday apps monetization \ud83d\udcb0", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": []}, "emitted_at": 1687273384070} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "appsupport@monday.com - mailto:appsupport@monday.com/", "title": "Link", "type": "link", "value": "{\"url\":\"mailto:appsupport@monday.com/\",\"text\":\"appsupport@monday.com\",\"changed_at\":\"2022-04-13T20:54:57.089Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555179211", "name": "Technical support team \ud83e\udd70", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384072} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://mondayclimatechallenge.devpost.com/", "title": "Link", "type": "link", "value": "{\"url\":\"https://mondayclimatechallenge.devpost.com/\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T13:40:18.751Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "29814928", "group": {"id": "new_group"}, "id": "3555179334", "name": "Make sure you saw to see challenge post (awesome prizes included)", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": []}, "emitted_at": 1687273384074} +{"stream": "updates", "data": {"assets": [{"created_at": "2023-06-15T16:19:31Z", "file_extension": ".jpg", "file_size": 116107, "id": "919077184", "name": "black_cat.jpg", "original_geometry": "473x600", "public_url": "https://files-monday-com.s3.amazonaws.com/14202902/resources/919077184/black_cat.jpg?response-content-disposition=attachment&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA4MPVJMFXGWGLJTLY%2F20230620%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230620T150408Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=9566e1bf805b4cbddada084f15418ea7bb7f07b62e7c27cd068ca465c170375d", "uploaded_by": {"id": 36694549}, "url": "https://airbyte-unit.monday.com/protected_static/14202902/resources/919077184/black_cat.jpg", "url_thumbnail": "https://airbyte-unit.monday.com/protected_static/14202902/resources/919077184/thumb_small-black_cat.jpg"}], "body": "", "created_at": "2023-06-15T16:19:36Z", "creator_id": "36694549", "id": "2223820299", "item_id": "4635211945", "replies": [], "text_body": "", "updated_at": "2023-06-15T16:19:36Z"}, "emitted_at": 1687273448305} +{"stream": "updates", "data": {"assets": [], "body": "



", "created_at": "2023-06-15T16:18:50Z", "creator_id": "36694549", "id": "2223818363", "item_id": "4635211945", "replies": [], "text_body": "", "updated_at": "2023-06-15T16:18:50Z"}, "emitted_at": 1687273448308} +{"stream": "updates", "data": {"assets": [], "body": "

\ufeffTest

", "created_at": "2022-11-21T14:41:21Z", "creator_id": "36694549", "id": "1825302913", "item_id": "3555437747", "replies": [{"id": "1825303266", "creator_id": "36694549", "created_at": "2022-11-21T14:41:29Z", "text_body": "Test test", "updated_at": "2022-11-21T14:41:29Z", "body": "

\ufeffTest test

"}, {"id": "2223806079", "creator_id": "36694549", "created_at": "2023-06-15T16:14:13Z", "text_body": "", "updated_at": "2023-06-15T16:14:13Z", "body": "



"}], "text_body": "Test", "updated_at": "2023-06-15T16:14:13Z"}, "emitted_at": 1687273448310} +{"stream": "updates", "data": {"assets": [], "body": "

\ufeffHey there \ud83d\udc4b

\ufeffThis is an update, we usually use this to...update \ud83d\ude04

\ufeffWe love to communicate with the context of a specific item.

\ufeff

\ufeffRight above this box, there are tabs for different item views which can also be used for apps.

", "created_at": "2022-06-08T12:53:39Z", "creator_id": "-7", "id": "1825206780", "item_id": "3555179351", "replies": [], "text_body": "Hey there \ud83d\udc4b\n\nThis is an update, we usually use this to...update \ud83d\ude04\n\nWe love to communicate with the context of a specific item.\n\n\n\nRight above this box, there are tabs for different item views which can also be used for apps.", "updated_at": "2022-11-21T14:04:40Z"}, "emitted_at": 1687273448312} +{"stream": "updates", "data": {"assets": [], "body": "

@Airbyte Testin \ufeffhi\ufeff

", "created_at": "2021-10-22T17:02:22Z", "creator_id": "-7", "id": "1825289531", "item_id": "3555408019", "replies": [], "text_body": "@Airbyte Testin hi", "updated_at": "2022-11-21T14:36:53Z"}, "emitted_at": 1687273448314} +{"stream": "users", "data": {"birthday": null, "country_code": "UA", "created_at": "2022-11-21T14:03:00Z", "join_date": null, "email": "integration-test@airbyte.io", "enabled": true, "id": 36694549, "is_admin": true, "is_guest": false, "is_pending": false, "is_view_only": false, "is_verified": true, "location": null, "mobile_phone": null, "name": "Airbyte Team", "phone": "", "photo_original": "https://files.monday.com/use1/photos/36694549/original/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "photo_small": "https://files.monday.com/use1/photos/36694549/small/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "photo_thumb": "https://files.monday.com/use1/photos/36694549/thumb/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "photo_thumb_small": "https://files.monday.com/use1/photos/36694549/thumb_small/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "photo_tiny": "https://files.monday.com/use1/photos/36694549/tiny/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "time_zone_identifier": "Europe/Kiev", "title": "Airbyte Developer Account", "url": "https://airbyte-unit.monday.com/users/36694549", "utc_hours_diff": 3}, "emitted_at": 1687273448747} +{"stream": "users", "data": {"birthday": null, "country_code": "UA", "created_at": "2022-11-21T14:33:18Z", "join_date": null, "email": "iryna.grankova@airbyte.io", "enabled": true, "id": 36695702, "is_admin": false, "is_guest": false, "is_pending": false, "is_view_only": false, "is_verified": true, "location": null, "mobile_phone": null, "name": "Iryna Grankova", "phone": null, "photo_original": "https://files.monday.com/use1/photos/36695702/original/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "photo_small": "https://files.monday.com/use1/photos/36695702/small/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "photo_thumb": "https://files.monday.com/use1/photos/36695702/thumb/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "photo_thumb_small": "https://files.monday.com/use1/photos/36695702/thumb_small/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "photo_tiny": "https://files.monday.com/use1/photos/36695702/tiny/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "time_zone_identifier": "Europe/Athens", "title": null, "url": "https://airbyte-unit.monday.com/users/36695702", "utc_hours_diff": 3}, "emitted_at": 1687273448751} +{"stream": "workspaces", "data": {"created_at": "2023-06-08T11:26:44Z", "description": null, "id": 2845647, "kind": "open", "name": "Test workspace", "state": "active", "account_product": {"id": 2248222, "kind": "core"}, "owners_subscribers": [{"id": 36694549}], "settings": {"icon": {"color": "#FDAB3D", "image": null}}, "team_owners_subscribers": [], "teams_subscribers": [], "users_subscribers": [{"id": 36694549}]}, "emitted_at": 1687273449181} +{"stream": "tags", "data": {"color": "#00c875", "id": 19038090, "name": "open"}, "emitted_at": 1687273449547} +{"stream": "tags", "data": {"color": "#fdab3d", "id": 19038091, "name": "closed"}, "emitted_at": 1687273449550} +{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 400}, {"archived": false, "description": null, "id": "person", "settings_str": "{}", "title": "Person", "type": "multiple-person", "width": null}, {"archived": false, "description": null, "id": "status", "settings_str": "{\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "date4", "settings_str": "{}", "title": "Date", "type": "date", "width": null}, {"archived": false, "description": null, "id": "tags", "settings_str": "{\"hide_footer\":false}", "title": "Tags", "type": "tag", "width": null}], "communication": null, "description": null, "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Group Title"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "group_title", "position": "98304", "title": "Group Title"}, {"archived": null, "color": "#808080", "deleted": null, "id": "new_group", "position": "163840.0", "title": "New Group unit board"}], "id": "4635211873", "name": "New Board", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2023-06-20T12:13:03Z", "updates": [{"id": "2223820299"}, {"id": "2223818363"}], "views": [], "workspace": {"id": 2845647, "name": "Test workspace", "kind": "open", "description": null}}, "emitted_at": 1687273446935} +{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 400}, {"archived": false, "description": null, "id": "files", "settings_str": "{\"hide_footer\":false}", "title": "Files", "type": "file", "width": null}], "communication": null, "description": null, "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Group Title"}], "id": "4634950289", "name": "test doc", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2023-06-14T12:30:14Z", "updates": [], "views": [{"id": "103920755", "name": "Table", "settings_str": "{}", "type": "FeatureBoardView", "view_specific_data_str": "{}"}], "workspace": {"id": 2845647, "name": "Test workspace", "kind": "open", "description": null}}, "emitted_at": 1687273446940} +{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 380}, {"archived": false, "description": null, "id": "manager1", "settings_str": "{}", "title": "Owner", "type": "multiple-person", "width": 80}, {"archived": false, "description": null, "id": "date4", "settings_str": "{}", "title": "Request date", "type": "date", "width": null}, {"archived": false, "description": null, "id": "status1", "settings_str": "{\"labels\":{\"0\":\"Evaluating\",\"1\":\"Done\",\"2\":\"Denied\",\"3\":\"Waiting for legal\",\"6\":\"Approved for POC\",\"11\":\"On hold\",\"14\":\"Waiting for vendor\",\"15\":\"Negotiation\",\"108\":\"Approved for use\"},\"labels_positions_v2\":{\"0\":0,\"1\":1,\"2\":7,\"3\":8,\"5\":9,\"6\":3,\"11\":6,\"14\":5,\"15\":4,\"108\":2},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"3\":{\"color\":\"#0086c0\",\"border\":\"#3DB0DF\",\"var_name\":\"blue-links\"},\"6\":{\"color\":\"#037f4c\",\"border\":\"#006B38\",\"var_name\":\"grass-green\"},\"11\":{\"color\":\"#BB3354\",\"border\":\"#A42D4A\",\"var_name\":\"dark-red\"},\"14\":{\"color\":\"#784BD1\",\"border\":\"#8F4DC4\",\"var_name\":\"dark-purple\"},\"15\":{\"color\":\"#9CD326\",\"border\":\"#89B921\",\"var_name\":\"lime-green\"},\"108\":{\"color\":\"#4eccc6\",\"border\":\"#4eccc6\",\"var_name\":\"australia\"}}}", "title": "Procurement status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "person", "settings_str": "{}", "title": "Manager", "type": "multiple-person", "width": 80}, {"archived": false, "description": null, "id": "status", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Manager approval", "type": "color", "width": null}, {"archived": false, "description": null, "id": "budget_owner", "settings_str": "{}", "title": "POC owner", "type": "multiple-person", "width": 80}, {"archived": false, "description": null, "id": "budget_owner_approval4", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "POC status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "manager", "settings_str": "{}", "title": "Budget owner", "type": "multiple-person", "width": 80}, {"archived": false, "description": null, "id": "status4", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Budget owner approval", "type": "color", "width": 185}, {"archived": false, "description": null, "id": "people", "settings_str": "{}", "title": "Procurement team", "type": "multiple-person", "width": null}, {"archived": false, "description": null, "id": "budget_owner_approval", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Procurement approval", "type": "color", "width": null}, {"archived": false, "description": null, "id": "procurement_team", "settings_str": "{}", "title": "Finance", "type": "multiple-person", "width": null}, {"archived": false, "description": null, "id": "procurement_approval", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Finance approval", "type": "color", "width": null}, {"archived": false, "description": null, "id": "finance", "settings_str": "{}", "title": "Legal", "type": "multiple-person", "width": null}, {"archived": false, "description": null, "id": "finance_approval", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Redlines\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Legal approval", "type": "color", "width": null}, {"archived": false, "description": null, "id": "file", "settings_str": "{}", "title": "File", "type": "file", "width": null}, {"archived": false, "description": null, "id": "legal", "settings_str": "{}", "title": "Security", "type": "multiple-person", "width": null}, {"archived": false, "description": null, "id": "legal_approval", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Security approval", "type": "color", "width": null}, {"archived": false, "description": null, "id": "date", "settings_str": "{\"hide_footer\":false}", "title": "Renewal date", "type": "date", "width": null}, {"archived": false, "description": null, "id": "last_updated", "settings_str": "{}", "title": "Last updated", "type": "pulse-updated", "width": 129}], "communication": null, "description": "Many IT departments need to handle the procurement process for new services. The essence of this board is to streamline this process by providing an intuitive structure that supports collaboration and efficiency.", "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Reviewing"}, {"archived": null, "color": "#FF642E", "deleted": null, "id": "new_group", "position": "98304.0", "title": "Corporate IT"}, {"archived": null, "color": "#037f4c", "deleted": null, "id": "new_group2816", "position": "114688.0", "title": "Finance"}], "id": "3555407826", "name": "Procurement process", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2022-11-21T14:36:50Z", "updates": [], "views": [{"id": "80969928", "name": "Chart", "settings_str": "{\"x_axis_columns\":{\"status1\":true},\"y_axis_columns\":{\"default-label-count\":true},\"z_axis_columns\":{},\"guideline_base\":{},\"graph_type\":\"column\",\"empty_values\":false,\"group_by\":\"month\"}", "type": "GraphBoardView", "view_specific_data_str": "{}"}], "workspace": null}, "emitted_at": 1687273446943} +{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 523}, {"archived": false, "description": null, "id": "text4", "settings_str": "{}", "title": "SN", "type": "text", "width": null}, {"archived": false, "description": null, "id": "status", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Out for repair\",\"1\":\"Working well\",\"2\":\"Needs replacement\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "date4", "settings_str": "{}", "title": "Date given to current owner", "type": "date", "width": 204}, {"archived": false, "description": null, "id": "text", "settings_str": "{}", "title": "Current owner", "type": "text", "width": null}, {"archived": false, "description": null, "id": "date_given_to_current_owner", "settings_str": "{}", "title": "Last checked", "type": "date", "width": 129}], "communication": null, "description": "Welcome to your inventory management board. This is the place to track and manage all of your IT equipment inventory.", "groups": [{"archived": null, "color": "#BB3354", "deleted": null, "id": "duplicate_of_tvs___projectors", "position": "65408", "title": "Out of service"}, {"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Laptops"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "group_title", "position": "98304", "title": "Monitors"}, {"archived": null, "color": "#037f4c", "deleted": null, "id": "new_group", "position": "163840.0", "title": "TVs & projectors"}], "id": "3555407785", "name": "Inventory management", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "duplicate_of_tvs___projectors"}, "updated_at": "2023-06-20T12:21:27Z", "updates": [], "views": [], "workspace": null}, "emitted_at": 1687273446945} +{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 347}, {"archived": false, "description": null, "id": "people", "settings_str": "{}", "title": "IT owner", "type": "multiple-person", "width": 98}, {"archived": false, "description": null, "id": "person", "settings_str": "{}", "title": "Responsible HR", "type": "multiple-person", "width": 112}, {"archived": false, "description": null, "id": "date4", "settings_str": "{}", "title": "Start date", "type": "date", "width": 114}, {"archived": false, "description": null, "id": "status", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"color_mapping\":{\"0\":16,\"1\":11,\"11\":1,\"16\":0},\"labels\":{\"0\":\"Product\",\"1\":\"Design\",\"2\":\"HR\",\"3\":\"R\\u0026D\",\"4\":\"Sales\",\"6\":\"Partners\",\"7\":\"Finance\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"3\":3,\"4\":4,\"5\":7,\"6\":5,\"7\":6},\"labels_colors\":{\"0\":{\"color\":\"#66CCFF\",\"border\":\"#5AB3E0\",\"var_name\":\"turquoise\"},\"1\":{\"color\":\"#BB3354\",\"border\":\"#A42D4A\",\"var_name\":\"dark-red\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"3\":{\"color\":\"#0086c0\",\"border\":\"#3DB0DF\",\"var_name\":\"blue-links\"},\"4\":{\"color\":\"#a25ddc\",\"border\":\"#9238AF\",\"var_name\":\"purple\"},\"6\":{\"color\":\"#037f4c\",\"border\":\"#006B38\",\"var_name\":\"grass-green\"},\"7\":{\"color\":\"#579bfc\",\"border\":\"#4387E8\",\"var_name\":\"bright-blue\"}}}", "title": "Team", "type": "color", "width": 103}, {"archived": false, "description": null, "id": "status8", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"color_mapping\":{\"1\":107,\"2\":19,\"3\":1,\"19\":2,\"107\":3},\"labels\":{\"1\":\"Denver\",\"2\":\"Florida\",\"14\":\"New York\"},\"labels_positions_v2\":{\"1\":2,\"2\":0,\"5\":3,\"14\":1},\"labels_colors\":{\"1\":{\"color\":\"#225091\",\"border\":\"#225091\",\"var_name\":\"navy\"},\"2\":{\"color\":\"#FF642E\",\"border\":\"#E05828\",\"var_name\":\"dark-orange\"},\"14\":{\"color\":\"#784BD1\",\"border\":\"#8F4DC4\",\"var_name\":\"dark-purple\"}}}", "title": "Site", "type": "color", "width": 80}, {"archived": false, "description": null, "id": "status1", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"1\":\"Mac\",\"14\":\"PC\"},\"labels_positions_v2\":{\"1\":0,\"5\":2,\"14\":1},\"labels_colors\":{\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"14\":{\"color\":\"#784BD1\",\"border\":\"#8F4DC4\",\"var_name\":\"dark-purple\"}}}", "title": "Computer type", "type": "color", "width": 107}, {"archived": false, "description": null, "id": "status2", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Computer setup", "type": "color", "width": 116}, {"archived": false, "description": null, "id": "computer_setup", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Google account", "type": "color", "width": 110}, {"archived": false, "description": null, "id": "google_account", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Zoom account", "type": "color", "width": 104}, {"archived": false, "description": null, "id": "zoom_account", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "365 account", "type": "color", "width": 102}, {"archived": false, "description": null, "id": "365_account3", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Setup desk monitor", "type": "color", "width": 132}, {"archived": false, "description": null, "id": "set_up_desk_monitor", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Setup entrance tag", "type": "color", "width": null}, {"archived": false, "description": null, "id": "email", "settings_str": "{}", "title": "Email", "type": "email", "width": null}], "communication": null, "description": "This is an IT onboarding process board. The essence of this board is to track the IT onboarding process of new employees.", "groups": [{"archived": null, "color": "#037f4c", "deleted": null, "id": "airbyte_group27398", "position": "16352.0", "title": "Airbyte group"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "airbyte_group", "position": "32704.0", "title": "Airbyte group"}, {"archived": null, "color": "#FF642E", "deleted": null, "id": "new_group", "position": "65408", "title": "More information about this template:"}, {"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "New Hires - June"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "group_title", "position": "98304", "title": "New Hires - May"}, {"archived": null, "color": "#037f4c", "deleted": null, "id": "duplicate_of_new_hires___6_25_", "position": "196608.0", "title": "New Hires - April"}], "id": "3555407698", "name": "IT Onboarding", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "airbyte_group27398"}, "updated_at": "2022-11-21T14:36:49Z", "updates": [{"id": "1825289531"}], "views": [{"id": "80969927", "name": "Timeline", "settings_str": "{\"group_by_id\":{\"people\":true},\"columns\":{\"all\":true},\"show_today_line\":true,\"show_weekends\":true,\"show_rollup\":true,\"enable_visual_dependencies\":true,\"display_legend\":true,\"color_by_id\":{\"people\":true},\"label_by_id\":{\"name\":true}}", "type": "TimelineGanttBoardView", "view_specific_data_str": "{}"}, {"id": "80969929", "name": "Hires by month", "settings_str": "{\"x_axis_columns\":{\"group\":true},\"y_axis_columns\":{\"default-label-count\":true},\"z_axis_columns\":{},\"guideline_base\":{},\"graph_type\":\"column\",\"empty_values\":false,\"group_by\":\"month\"}", "type": "GraphBoardView", "view_specific_data_str": "{}"}], "workspace": null}, "emitted_at": 1687273446947} +{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 414}, {"archived": false, "description": null, "id": "status", "settings_str": "{\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "link", "settings_str": "{}", "title": "Link", "type": "link", "width": null}, {"archived": false, "description": "", "id": "label", "settings_str": "{\"done_colors\":[1],\"labels\":{\"3\":\"Label 2\",\"105\":\"Label 1\",\"156\":\"Label 3\"},\"labels_positions_v2\":{\"3\":1,\"5\":3,\"105\":0,\"156\":2},\"labels_colors\":{\"3\":{\"color\":\"#0086c0\",\"border\":\"#3DB0DF\",\"var_name\":\"blue-links\"},\"105\":{\"color\":\"#9AADBD\",\"border\":\"#9AADBD\",\"var_name\":\"winter\"},\"156\":{\"color\":\"#9D99B9\",\"border\":\"#9D99B9\",\"var_name\":\"purple_gray\"}}}", "title": "Label", "type": "color", "width": null}, {"archived": false, "description": null, "id": "text", "settings_str": "{}", "title": "Text", "type": "text", "width": null}], "communication": null, "description": null, "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Subitems"}], "id": "3555179105", "name": "Subitems of Welcome to your monday dev account \ud83d\ude0d", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2022-11-21T14:42:06Z", "updates": [{"id": "1825302913"}], "views": [], "workspace": null}, "emitted_at": 1687273446949} +{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 596}, {"archived": false, "description": null, "id": "subitems", "settings_str": "{\"allowMultipleItems\":true,\"itemTypeName\":\"column.subtasks.title\",\"displayType\":\"BOARD_INLINE\",\"boardIds\":[3555179105]}", "title": "Subitems", "type": "subtasks", "width": null}, {"archived": false, "description": null, "id": "link", "settings_str": "{}", "title": "Link", "type": "link", "width": 168}, {"archived": false, "description": null, "id": "text", "settings_str": "{}", "title": "My notes", "type": "text", "width": 262}, {"archived": false, "description": null, "id": "status_1", "settings_str": "{\"labels\":{\"0\":\"Working on it\",\"1\":\"Done!\",\"2\":\"Stuck\",\"5\":\"Need to review\"},\"labels_positions_v2\":{\"0\":0,\"1\":1,\"2\":2,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"5\":{\"color\":\"#c4c4c4\",\"border\":\"#B0B0B0\",\"var_name\":\"grey\"}}}", "title": "Status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "status_10", "settings_str": "{\"done_colors\":[1],\"color_mapping\":{\"0\":16,\"1\":160,\"16\":0,\"160\":1},\"labels\":{\"0\":\"Article\",\"1\":\"Documentation\",\"2\":\"Video\",\"5\":\"Other\"},\"labels_colors\":{\"0\":{\"color\":\"#66CCFF\",\"border\":\"#5AB3E0\",\"var_name\":\"turquoise\"},\"1\":{\"color\":\"#175A63\",\"border\":\"#175A63\",\"var_name\":\"eden\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"5\":{\"color\":\"#c4c4c4\",\"border\":\"#B0B0B0\",\"var_name\":\"grey\"}}}", "title": "Type", "type": "color", "width": null}], "communication": null, "description": null, "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "81920", "title": "Get to know monday.com"}, {"archived": null, "color": "#FF158A", "deleted": null, "id": "new_group37570", "position": "90112", "title": "What can be developed on monday.com"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "group_title", "position": "98304", "title": "Build your monday app"}, {"archived": null, "color": "#fdab3d", "deleted": null, "id": "new_group45036", "position": "131072.0", "title": "Prepare for app submission"}, {"archived": null, "color": "#0086c0", "deleted": null, "id": "new_group", "position": "163840.0", "title": "Helpful resources"}], "id": "3555179067", "name": "Welcome to your monday dev account \ud83d\ude0d", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2022-11-21T14:04:38Z", "updates": [{"id": "1825206780"}], "views": [{"id": "80965788", "name": "Table", "settings_str": "{}", "type": "TableBoardView", "view_specific_data_str": "{}"}], "workspace": null}, "emitted_at": 1687273446951} diff --git a/airbyte-integrations/connectors/source-monday/metadata.yaml b/airbyte-integrations/connectors/source-monday/metadata.yaml index c629ce1f3d94..1ec5b8c5b059 100644 --- a/airbyte-integrations/connectors/source-monday/metadata.yaml +++ b/airbyte-integrations/connectors/source-monday/metadata.yaml @@ -5,7 +5,7 @@ data: connectorSubtype: api connectorType: source definitionId: 80a54ea2-9959-4040-aac1-eee42423ec9b - dockerImageTag: 0.2.6 + dockerImageTag: 1.0.0 dockerRepository: airbyte/source-monday githubIssueLabel: source-monday icon: monday.svg @@ -16,7 +16,7 @@ data: enabled: true oss: enabled: true - releaseStage: beta + releaseStage: generally_available documentationUrl: https://docs.airbyte.com/integrations/sources/monday tags: - language:low-code diff --git a/airbyte-integrations/connectors/source-monday/source_monday/__init__.py b/airbyte-integrations/connectors/source-monday/source_monday/__init__.py index 8e3109b2c13e..ec982cff1605 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/__init__.py +++ b/airbyte-integrations/connectors/source-monday/source_monday/__init__.py @@ -1,5 +1,5 @@ # -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. # from .graphql_requester import MondayGraphqlRequester diff --git a/airbyte-integrations/connectors/source-monday/source_monday/graphql_requester.py b/airbyte-integrations/connectors/source-monday/source_monday/graphql_requester.py index 7432a583b380..c15eb5a31701 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/graphql_requester.py +++ b/airbyte-integrations/connectors/source-monday/source_monday/graphql_requester.py @@ -76,7 +76,7 @@ def _build_items_query(self, object_name: str, field_schema: dict, sub_page: Opt def _build_teams_query(self, object_name: str, field_schema: dict, **object_arguments) -> str: """ Special optimization needed for tests to pass successfully because of rate limits. - It makes a query cost less points and should not be used to production + It makes a query cost less points, but it is never used in production """ teams_limit = self.config.get("teams_limit") if teams_limit: diff --git a/airbyte-integrations/connectors/source-monday/source_monday/manifest.yaml b/airbyte-integrations/connectors/source-monday/source_monday/manifest.yaml index 1db971eba1e6..feabb83b8d3a 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/manifest.yaml +++ b/airbyte-integrations/connectors/source-monday/source_monday/manifest.yaml @@ -96,6 +96,11 @@ definitions: name: "boards" path: "" items_per_page: 100 + tags_stream: + $ref: "#/definitions/base_nopagination_stream" + $parameters: + name: "tags" + path: "" teams_stream: $ref: "#/definitions/base_nopagination_stream" $parameters: @@ -111,14 +116,21 @@ definitions: $parameters: name: "users" path: "" + workspaces_stream: + $ref: "#/definitions/base_stream" + $parameters: + name: "workspaces" + path: "" streams: - "#/definitions/items_stream" - "#/definitions/boards_stream" + - "#/definitions/tags_stream" - "#/definitions/teams_stream" - "#/definitions/updates_stream" - "#/definitions/users_stream" + - "#/definitions/workspaces_stream" check: stream_names: - - "users" + - "users" \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-monday/source_monday/schemas/boards.json b/airbyte-integrations/connectors/source-monday/source_monday/schemas/boards.json index 7eea49a9bd4b..9829d82e38d7 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/schemas/boards.json +++ b/airbyte-integrations/connectors/source-monday/source_monday/schemas/boards.json @@ -10,6 +10,7 @@ "additionalProperties": true, "properties": { "archived": { "type": ["null", "boolean"] }, + "description": { "type": ["null", "string"] }, "id": { "type": ["null", "string"] }, "settings_str": { "type": ["null", "string"] }, "title": { "type": ["null", "string"] }, @@ -37,7 +38,17 @@ }, "id": { "type": ["null", "string"] }, "name": { "type": ["null", "string"] }, - "owner": { + "owners": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { "type": ["null", "integer"] } + } + } + }, + "creator": { "type": ["null", "object"], "properties": { "id": { "type": ["null", "integer"] } @@ -89,7 +100,11 @@ "type": ["null", "object"], "additionalProperties": true, "properties": { - "id": { "type": ["null", "string"] } + "id": { "type": ["null", "string"] }, + "name": { "type": ["null", "string"] }, + "settings_str": { "type": ["null", "string"] }, + "type": { "type": ["null", "string"] }, + "view_specific_data_str": { "type": ["null", "string"] } } } }, diff --git a/airbyte-integrations/connectors/source-monday/source_monday/schemas/items.json b/airbyte-integrations/connectors/source-monday/source_monday/schemas/items.json index ccd2cc5ed005..61090df1d431 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/schemas/items.json +++ b/airbyte-integrations/connectors/source-monday/source_monday/schemas/items.json @@ -8,7 +8,21 @@ "type": ["null", "object"], "additionalProperties": true, "properties": { - "id": { "type": ["null", "integer"] } + "created_at": { "type": ["null", "string"], "format": "date-time" }, + "file_extension": { "type": ["null", "string"] }, + "file_size": { "type": ["null", "integer"] }, + "id": { "type": ["null", "string"] }, + "name": { "type": ["null", "string"] }, + "original_geometry": { "type": ["null", "string"] }, + "public_url": { "type": ["null", "string"] }, + "uploaded_by": { + "type": ["null", "object"], + "properties": { + "id": { "type": ["null", "integer"] } + } + }, + "url": { "type": ["null", "string"] }, + "url_thumbnail": { "type": ["null", "string"] } } } }, @@ -24,12 +38,13 @@ "type": ["null", "object"], "additionalProperties": true, "properties": { - "id": { "type": ["null", "string"] }, - "value": { "type": ["null", "string"] }, "additional_info": { "type": ["null", "string"] }, + "description": { "type": ["null", "string"] }, + "id": { "type": ["null", "string"] }, "text": { "type": ["null", "string"] }, "title": { "type": ["null", "string"] }, - "type": { "type": ["null", "string"] } + "type": { "type": ["null", "string"] }, + "value": { "type": ["null", "string"] } } } }, diff --git a/airbyte-integrations/connectors/source-monday/source_monday/schemas/tags.json b/airbyte-integrations/connectors/source-monday/source_monday/schemas/tags.json new file mode 100644 index 000000000000..08deffe7b8c1 --- /dev/null +++ b/airbyte-integrations/connectors/source-monday/source_monday/schemas/tags.json @@ -0,0 +1,9 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "color": { "type": ["null", "string"] }, + "id": { "type": ["null", "integer"] }, + "name": { "type": ["null", "string"] } + } +} \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-monday/source_monday/schemas/updates.json b/airbyte-integrations/connectors/source-monday/source_monday/schemas/updates.json index 2e52854b80e4..d0e004a69982 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/schemas/updates.json +++ b/airbyte-integrations/connectors/source-monday/source_monday/schemas/updates.json @@ -8,7 +8,21 @@ "type": ["null", "object"], "additionalProperties": true, "properties": { - "id": { "type": ["null", "integer"] } + "created_at": { "type": ["null", "string"], "format": "date-time" }, + "file_extension": { "type": ["null", "string"] }, + "file_size": { "type": ["null", "integer"] }, + "id": { "type": ["null", "string"] }, + "name": { "type": ["null", "string"] }, + "original_geometry": { "type": ["null", "string"] }, + "public_url": { "type": ["null", "string"] }, + "uploaded_by": { + "type": ["null", "object"], + "properties": { + "id": { "type": ["null", "integer"] } + } + }, + "url": { "type": ["null", "string"] }, + "url_thumbnail": { "type": ["null", "string"] } } } }, diff --git a/airbyte-integrations/connectors/source-monday/source_monday/schemas/workspaces.json b/airbyte-integrations/connectors/source-monday/source_monday/schemas/workspaces.json new file mode 100644 index 000000000000..891800eb2cbf --- /dev/null +++ b/airbyte-integrations/connectors/source-monday/source_monday/schemas/workspaces.json @@ -0,0 +1,73 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "created_at": { "type": ["null", "string"], "format": "date-time" }, + "description": { "type": ["null", "string"] }, + "id": { "type": ["null", "integer"] }, + "kind": { "type": ["null", "string"] }, + "name": { "type": ["null", "string"] }, + "state": { "type": ["null", "string"] }, + "account_product": { + "type": ["null", "object"], + "properties": { + "id": { "type": ["null", "integer"] }, + "kind": { "type": ["null", "string"] } + } + }, + "owners_subscribers": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { "type": ["null", "integer"] } + } + } + }, + "settings": { + "type": ["null", "object"], + "properties": { + "icon": { + "type": ["null", "object"], + "properties": { + "color": { "type": ["null", "string"] }, + "image": { "type": ["null", "string"] } + } + } + } + }, + "team_owners_subscribers": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { "type": ["null", "integer"] }, + "name": { "type": ["null", "string"] } + } + } + }, + "teams_subscribers": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { "type": ["null", "integer"] }, + "name": { "type": ["null", "string"] } + } + } + }, + "users_subscribers": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { "type": ["null", "integer"] } + } + } + } + } +} \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-monday/unit_tests/__init__.py b/airbyte-integrations/connectors/source-monday/unit_tests/__init__.py index 46b7376756ec..c941b3045795 100644 --- a/airbyte-integrations/connectors/source-monday/unit_tests/__init__.py +++ b/airbyte-integrations/connectors/source-monday/unit_tests/__init__.py @@ -1,3 +1,3 @@ # -# Copyright (c) 2021 Airbyte, Inc., all rights reserved. +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. # diff --git a/docs/integrations/sources/monday.md b/docs/integrations/sources/monday.md index c0b4fe52a2bc..3e4652e7b8a0 100644 --- a/docs/integrations/sources/monday.md +++ b/docs/integrations/sources/monday.md @@ -44,6 +44,16 @@ Several output streams are available from this source: * [Teams](https://developer.monday.com/api-reference/docs/teams-queries) * [Updates](https://developer.monday.com/api-reference/docs/updates-queries) * [Users](https://developer.monday.com/api-reference/docs/users-queries-1) +* [Tags](https://developer.monday.com/api-reference/docs/tags-queries) +* [Workspaces](https://developer.monday.com/api-reference/docs/workspaces) + +Important Notes: +* `Columns` are available from the `Boards` stream. By syncing the `Boards` stream you will get the `Columns` for each `Board` synced in the database +The typical name of the table depends on the `destination` you use like `boards.columns`, for instance. + +* `Column Values` are available from the `Items` stream. By syncing the `Items` stream you will get the `Column Values` for each `Item` (row) of the board. +The typical name of the table depends on the `destination` you use like `items.column_values`, for instance. + If there are more endpoints you'd like Airbyte to support, please [create an issue.](https://github.com/airbytehq/airbyte/issues/new/choose) @@ -55,17 +65,18 @@ The Monday connector should not run into Monday API limitations under normal usa ## Changelog -| Version | Date | Pull Request | Subject | -|:--------|:-----------|:---------------------------------------------------------|:------------------------------------------------| -| 0.2.6 | 2023-06-12 | [27244](https://github.com/airbytehq/airbyte/pull/27244) | Added http error handling for `403` and `500` HTTP errors | -| 0.2.5 | 2023-05-22 | [225881](https://github.com/airbytehq/airbyte/pull/25881) | Fix pagination for the items stream | -| 0.2.4 | 2023-04-26 | [25277](https://github.com/airbytehq/airbyte/pull/25277) | Increase row limit to 100 | -| 0.2.3 | 2023-03-06 | [23231](https://github.com/airbytehq/airbyte/pull/23231) | Publish using low-code CDK Beta version | -| 0.2.2 | 2023-01-04 | [20996](https://github.com/airbytehq/airbyte/pull/20996) | Fix json schema loader | -| 0.2.1 | 2022-12-15 | [20533](https://github.com/airbytehq/airbyte/pull/20533) | Bump CDK version | -| 0.2.0 | 2022-12-13 | [19586](https://github.com/airbytehq/airbyte/pull/19586) | Migrate to low-code | -| 0.1.4 | 2022-06-06 | [14443](https://github.com/airbytehq/airbyte/pull/14443) | Increase retry_factor for Items stream | -| 0.1.3 | 2021-12-23 | [8172](https://github.com/airbytehq/airbyte/pull/8172) | Add oauth2.0 support | -| 0.1.2 | 2021-12-07 | [8429](https://github.com/airbytehq/airbyte/pull/8429) | Update titles and descriptions | -| 0.1.1 | 2021-11-18 | [8016](https://github.com/airbytehq/airbyte/pull/8016) | 🐛 Source Monday: fix pagination and schema bug | -| 0.1.0 | 2021-11-07 | [7168](https://github.com/airbytehq/airbyte/pull/7168) | 🎉 New Source: Monday | +| Version | Date | Pull Request | Subject | +|:--------|:-----------|:---------------------------------------------------------|:------------------------------------------------------------------------| +| 1.0.0 | 2023-06-20 | [27410](https://github.com/airbytehq/airbyte/pull/27410) | Add new streams: Tags, Workspaces. Add new fields for existing streams. | +| 0.2.6 | 2023-06-12 | [27244](https://github.com/airbytehq/airbyte/pull/27244) | Added http error handling for `403` and `500` HTTP errors | +| 0.2.5 | 2023-05-22 | [225881](https://github.com/airbytehq/airbyte/pull/25881) | Fix pagination for the items stream | +| 0.2.4 | 2023-04-26 | [25277](https://github.com/airbytehq/airbyte/pull/25277) | Increase row limit to 100 | +| 0.2.3 | 2023-03-06 | [23231](https://github.com/airbytehq/airbyte/pull/23231) | Publish using low-code CDK Beta version | +| 0.2.2 | 2023-01-04 | [20996](https://github.com/airbytehq/airbyte/pull/20996) | Fix json schema loader | +| 0.2.1 | 2022-12-15 | [20533](https://github.com/airbytehq/airbyte/pull/20533) | Bump CDK version | +| 0.2.0 | 2022-12-13 | [19586](https://github.com/airbytehq/airbyte/pull/19586) | Migrate to low-code | +| 0.1.4 | 2022-06-06 | [14443](https://github.com/airbytehq/airbyte/pull/14443) | Increase retry_factor for Items stream | +| 0.1.3 | 2021-12-23 | [8172](https://github.com/airbytehq/airbyte/pull/8172) | Add oauth2.0 support | +| 0.1.2 | 2021-12-07 | [8429](https://github.com/airbytehq/airbyte/pull/8429) | Update titles and descriptions | +| 0.1.1 | 2021-11-18 | [8016](https://github.com/airbytehq/airbyte/pull/8016) | 🐛 Source Monday: fix pagination and schema bug | +| 0.1.0 | 2021-11-07 | [7168](https://github.com/airbytehq/airbyte/pull/7168) | 🎉 New Source: Monday | From 2a69ee5effddda97a65d28db5e132a62a93e0503 Mon Sep 17 00:00:00 2001 From: Eduard Tudenhoefner Date: Tue, 11 Jul 2023 18:50:18 +0200 Subject: [PATCH 21/63] =?UTF-8?q?=E2=9C=A8=20Destination=20Iceberg:=20Bump?= =?UTF-8?q?=20Iceberg=20from=201.0.0=20to=201.1.0=20(#23201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Destination Iceberg: Fix compilation * Iceberg Destination: Bump Iceberg from 1.0.0 to 1.1.0 * add icon and changelog entry * force aws dependencies used by iceberg * fix tests as MINIO runs without SSL * move icon --------- Co-authored-by: marcosmarxm Co-authored-by: Marcos Marx --- .../connectors/destination-iceberg/Dockerfile | 2 +- .../destination-iceberg/build.gradle | 21 +++++++++++++------ .../destination-iceberg/iceberg.svg | 1 + .../destination-iceberg/metadata.yaml | 2 +- .../destination/iceberg/IcebergConsumer.java | 4 ++-- .../resources/metastore-log4j.properties | 2 +- docs/integrations/destinations/iceberg.md | 1 + 7 files changed, 22 insertions(+), 11 deletions(-) create mode 100644 airbyte-integrations/connectors/destination-iceberg/iceberg.svg diff --git a/airbyte-integrations/connectors/destination-iceberg/Dockerfile b/airbyte-integrations/connectors/destination-iceberg/Dockerfile index 241e82f2adde..5692724d2d19 100644 --- a/airbyte-integrations/connectors/destination-iceberg/Dockerfile +++ b/airbyte-integrations/connectors/destination-iceberg/Dockerfile @@ -29,5 +29,5 @@ ENV JAVA_OPTS="--add-opens java.base/java.lang=ALL-UNNAMED \ COPY --from=build /airbyte /airbyte -LABEL io.airbyte.version=0.1.0 +LABEL io.airbyte.version=0.1.1 LABEL io.airbyte.name=airbyte/destination-iceberg diff --git a/airbyte-integrations/connectors/destination-iceberg/build.gradle b/airbyte-integrations/connectors/destination-iceberg/build.gradle index 8dcc5bb3c3f2..d50c0a1e1ed2 100644 --- a/airbyte-integrations/connectors/destination-iceberg/build.gradle +++ b/airbyte-integrations/connectors/destination-iceberg/build.gradle @@ -14,21 +14,30 @@ dependencies { implementation project(':airbyte-integrations:bases:base-java') implementation files(project(':airbyte-integrations:bases:base-java').airbyteDocker.outputs) - implementation('org.apache.spark:spark-sql_2.13:3.3.0') { + implementation('org.apache.spark:spark-sql_2.13:3.3.1') { exclude(group: 'org.apache.hadoop', module: 'hadoop-common') } - implementation('org.apache.spark:spark-hive_2.13:3.3.0') { + implementation('org.apache.spark:spark-hive_2.13:3.3.1') { exclude(group: 'org.apache.hadoop', module: 'hadoop-common') } - implementation 'org.apache.iceberg:iceberg-spark-runtime-3.3_2.13:1.0.0' - implementation "software.amazon.awssdk:bundle:2.17.131" - implementation "software.amazon.awssdk:url-connection-client:2.17.131" + implementation 'org.apache.iceberg:iceberg-spark-runtime-3.3_2.13:1.1.0' + + // force awssdk version required by Iceberg + implementation "software.amazon.awssdk:utils:2.17.257" + implementation "software.amazon.awssdk:url-connection-client:2.17.257" + implementation "software.amazon.awssdk:s3:2.17.257" + implementation "software.amazon.awssdk:glue:2.17.257" + implementation "software.amazon.awssdk:dynamodb:2.17.257" + implementation "software.amazon.awssdk:kms:2.17.257" + implementation "software.amazon.awssdk:sts:2.17.257" + implementation "software.amazon.awssdk:sdk-core:2.17.257" + implementation "software.amazon.awssdk:aws-core:2.17.257" + implementation "org.apache.hadoop:hadoop-aws:3.3.2" implementation "org.apache.hadoop:hadoop-client-api:3.3.2" implementation "org.apache.hadoop:hadoop-client-runtime:3.3.2" implementation "org.postgresql:postgresql:42.5.0" implementation "commons-collections:commons-collections:3.2.2" -// implementation "software.amazon.awssdk:utils:2.17.131" testImplementation libs.connectors.testcontainers.postgresql integrationTestJavaImplementation libs.connectors.testcontainers.postgresql diff --git a/airbyte-integrations/connectors/destination-iceberg/iceberg.svg b/airbyte-integrations/connectors/destination-iceberg/iceberg.svg new file mode 100644 index 000000000000..bed01742ad40 --- /dev/null +++ b/airbyte-integrations/connectors/destination-iceberg/iceberg.svg @@ -0,0 +1 @@ +iceberg \ No newline at end of file diff --git a/airbyte-integrations/connectors/destination-iceberg/metadata.yaml b/airbyte-integrations/connectors/destination-iceberg/metadata.yaml index 939304fa8afb..4d01dde02a2f 100644 --- a/airbyte-integrations/connectors/destination-iceberg/metadata.yaml +++ b/airbyte-integrations/connectors/destination-iceberg/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: database connectorType: destination definitionId: df65a8f3-9908-451b-aa9b-445462803560 - dockerImageTag: 0.1.0 + dockerImageTag: 0.1.1 dockerRepository: airbyte/destination-iceberg githubIssueLabel: destination-iceberg license: MIT diff --git a/airbyte-integrations/connectors/destination-iceberg/src/main/java/io/airbyte/integrations/destination/iceberg/IcebergConsumer.java b/airbyte-integrations/connectors/destination-iceberg/src/main/java/io/airbyte/integrations/destination/iceberg/IcebergConsumer.java index ffa2090d8cb2..709deab9811a 100644 --- a/airbyte-integrations/connectors/destination-iceberg/src/main/java/io/airbyte/integrations/destination/iceberg/IcebergConsumer.java +++ b/airbyte-integrations/connectors/destination-iceberg/src/main/java/io/airbyte/integrations/destination/iceberg/IcebergConsumer.java @@ -10,10 +10,10 @@ import static org.apache.logging.log4j.util.Strings.isNotBlank; import io.airbyte.commons.json.Jsons; -import io.airbyte.integrations.base.AirbyteStreamNameNamespacePair; import io.airbyte.integrations.base.CommitOnStateAirbyteMessageConsumer; import io.airbyte.integrations.destination.iceberg.config.WriteConfig; import io.airbyte.integrations.destination.iceberg.config.catalog.IcebergCatalogConfig; +import io.airbyte.protocol.models.v0.AirbyteStreamNameNamespacePair; import io.airbyte.protocol.models.v0.AirbyteMessage; import io.airbyte.protocol.models.v0.AirbyteMessage.Type; import io.airbyte.protocol.models.v0.AirbyteRecordMessage; @@ -93,7 +93,7 @@ protected void startTracked() throws Exception { throw new IllegalStateException("Undefined destination sync mode"); } final boolean isAppendMode = syncMode != DestinationSyncMode.OVERWRITE; - AirbyteStreamNameNamespacePair nameNamespacePair = AirbyteStreamNameNamespacePair.fromAirbyteSteam(stream.getStream()); + AirbyteStreamNameNamespacePair nameNamespacePair = AirbyteStreamNameNamespacePair.fromAirbyteStream(stream.getStream()); Integer flushBatchSize = catalogConfig.getFormatConfig().getFlushBatchSize(); WriteConfig writeConfig = new WriteConfig(namespace, streamName, isAppendMode, flushBatchSize); configs.put(nameNamespacePair, writeConfig); diff --git a/airbyte-integrations/connectors/destination-iceberg/src/test-integration/resources/metastore-log4j.properties b/airbyte-integrations/connectors/destination-iceberg/src/test-integration/resources/metastore-log4j.properties index c8e23faffb3f..52aca04c4e98 100644 --- a/airbyte-integrations/connectors/destination-iceberg/src/test-integration/resources/metastore-log4j.properties +++ b/airbyte-integrations/connectors/destination-iceberg/src/test-integration/resources/metastore-log4j.properties @@ -6,7 +6,7 @@ # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, diff --git a/docs/integrations/destinations/iceberg.md b/docs/integrations/destinations/iceberg.md index 75062620b371..8c03143c0ac9 100644 --- a/docs/integrations/destinations/iceberg.md +++ b/docs/integrations/destinations/iceberg.md @@ -57,4 +57,5 @@ specify the target size of compacted Iceberg data file. | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------- | +| 0.1.1 | 2023-02-27 | [23201](https://github.com/airbytehq/airbyte/pull/23301) | Bump Iceberg library to 1.1.0 | | 0.1.0 | 2022-11-01 | [18836](https://github.com/airbytehq/airbyte/pull/18836) | Initial Commit | From df2a6e50bb0b8634f7764fc6ce2c5b1748e0f111 Mon Sep 17 00:00:00 2001 From: Maxime Carbonneau-Leclerc Date: Tue, 11 Jul 2023 13:37:38 -0400 Subject: [PATCH 22/63] Issue 21014/oauth requests (#27973) * [ISSUE #27494] fix type issue caused by connector builder logging * [ISSUE #21014] log request/response for oauth as 'global_requests' * formatcdk * [ISSUE #21014] support DeclarativeOauth2Authenticator as well * [ISSUE #21014] improving message grouper tests * formatcdk * Test solution with logic in MessageRepository (#27990) * Test solution with logic in MessageRepository * Solution without creating a new ModelToComponentFactory * [ISSUE #21014] adding tests * [ISSUE #21014] add title and description to global requests * Revert "Solution without creating a new ModelToComponentFactory" This reverts commit f17799ecff03f411a103dcdfbe8252bd8f4c2518. * Automated Commit - Formatting Changes * [ISSUE #21014] code review * [ISSUE #21014] do not break on log appender conflict * Automated Commit - Formatting Changes * [ISSUE #21014] code review * formatcdk * [ISSUE #21014] moving is_global to is_auxiliary --- .../connector_builder/message_grouper.py | 125 ++++++---- .../airbyte_cdk/connector_builder/models.py | 9 + .../sources/declarative/auth/oauth.py | 10 + .../parsers/model_to_component_factory.py | 32 ++- .../retrievers/simple_retriever.py | 43 +--- .../python/airbyte_cdk/sources/http_logger.py | 47 ++++ .../airbyte_cdk/sources/message/__init__.py | 10 +- .../airbyte_cdk/sources/message/repository.py | 101 +++++++- .../requests_native_auth/abstract_oauth.py | 26 ++ .../http/requests_native_auth/oauth.py | 20 +- .../test_connector_builder_handler.py | 9 +- .../connector_builder/test_message_grouper.py | 186 +++++++++------ .../sources/declarative/auth/test_oauth.py | 4 + .../test_model_to_component_factory.py | 2 + .../retrievers/test_simple_retriever.py | 224 +----------------- .../sources/message/test_repository.py | 158 +++++++++--- .../test_requests_native_auth.py | 19 +- .../unit_tests/sources/test_http_logger.py | 176 ++++++++++++++ 18 files changed, 789 insertions(+), 412 deletions(-) create mode 100644 airbyte-cdk/python/airbyte_cdk/sources/http_logger.py create mode 100644 airbyte-cdk/python/unit_tests/sources/test_http_logger.py diff --git a/airbyte-cdk/python/airbyte_cdk/connector_builder/message_grouper.py b/airbyte-cdk/python/airbyte_cdk/connector_builder/message_grouper.py index 96661b511ee9..dd3ae40ba6a9 100644 --- a/airbyte-cdk/python/airbyte_cdk/connector_builder/message_grouper.py +++ b/airbyte-cdk/python/airbyte_cdk/connector_builder/message_grouper.py @@ -9,7 +9,15 @@ from typing import Any, Dict, Iterable, Iterator, List, Mapping, Optional, Union from urllib.parse import parse_qs, urlparse -from airbyte_cdk.connector_builder.models import HttpRequest, HttpResponse, LogMessage, StreamRead, StreamReadPages, StreamReadSlices +from airbyte_cdk.connector_builder.models import ( + AuxiliaryRequest, + HttpRequest, + HttpResponse, + LogMessage, + StreamRead, + StreamReadPages, + StreamReadSlices, +) from airbyte_cdk.entrypoint import AirbyteEntrypoint from airbyte_cdk.sources import AbstractSource from airbyte_cdk.sources.declarative.declarative_source import DeclarativeSource @@ -57,6 +65,7 @@ def get_message_groups( slices = [] log_messages = [] latest_config_update: AirbyteControlMessage = None + auxiliary_requests = [] for message_group in self._get_message_groups( self._read_stream(source, config, configured_catalog), schema_inferrer, @@ -72,6 +81,8 @@ def get_message_groups( elif isinstance(message_group, AirbyteControlMessage): if not latest_config_update or latest_config_update.emitted_at <= message_group.emitted_at: latest_config_update = message_group + elif isinstance(message_group, AuxiliaryRequest): + auxiliary_requests.append(message_group) else: slices.append(message_group) @@ -79,6 +90,7 @@ def get_message_groups( logs=log_messages, slices=slices, test_read_limit_reached=self._has_reached_limit(slices), + auxiliary_requests=auxiliary_requests, inferred_schema=schema_inferrer.get_stream_schema( configured_catalog.streams[0].stream.name ), # The connector builder currently only supports reading from a single stream at a time @@ -88,7 +100,7 @@ def get_message_groups( def _get_message_groups( self, messages: Iterator[AirbyteMessage], schema_inferrer: SchemaInferrer, datetime_format_inferrer: DatetimeFormatInferrer, limit: int - ) -> Iterable[Union[StreamReadPages, AirbyteControlMessage, AirbyteLogMessage, AirbyteTraceMessage]]: + ) -> Iterable[Union[StreamReadPages, AirbyteControlMessage, AirbyteLogMessage, AirbyteTraceMessage, AuxiliaryRequest]]: """ Message groups are partitioned according to when request log messages are received. Subsequent response log messages and record messages belong to the prior request log message and when we encounter another request, append the latest @@ -114,7 +126,8 @@ def _get_message_groups( had_error = False while records_count < limit and (message := next(messages, None)): - if self._need_to_close_page(at_least_one_page_in_group, message): + json_message = self._parse_json(message.log) if message.type == MessageType.LOG else None + if self._need_to_close_page(at_least_one_page_in_group, message, json_message): self._close_page(current_page_request, current_page_response, current_slice_pages, current_page_records, True) current_page_request = None current_page_response = None @@ -127,16 +140,26 @@ def _get_message_groups( elif message.type == MessageType.LOG and message.log.message.startswith(AbstractSource.SLICE_LOG_PREFIX): # parsing the first slice current_slice_descriptor = self._parse_slice_description(message.log.message) - elif message.type == MessageType.LOG and message.log.message.startswith("request:"): - if not at_least_one_page_in_group: - at_least_one_page_in_group = True - current_page_request = self._create_request_from_log_message(message.log) - elif message.type == MessageType.LOG and message.log.message.startswith("response:"): - current_page_response = self._create_response_from_log_message(message.log) elif message.type == MessageType.LOG: - if message.log.level == Level.ERROR: - had_error = True - yield message.log + if self._is_http_log(json_message): + if self._is_auxiliary_http_request(json_message): + title_prefix = ( + "Parent stream: " if json_message.get("airbyte_cdk", {}).get("stream", {}).get("is_substream", False) else "" + ) + yield AuxiliaryRequest( + title=title_prefix + json_message.get("http", {}).get("title", None), + description=json_message.get("http", {}).get("description", None), + request=self._create_request_from_log_message(json_message), + response=self._create_response_from_log_message(json_message), + ) + else: + at_least_one_page_in_group = True + current_page_request = self._create_request_from_log_message(json_message) + current_page_response = self._create_response_from_log_message(json_message) + else: + if message.log.level == Level.ERROR: + had_error = True + yield message.log elif message.type == MessageType.TRACE: if message.trace.type == TraceType.ERROR: had_error = True @@ -153,13 +176,35 @@ def _get_message_groups( yield StreamReadSlices(pages=current_slice_pages, slice_descriptor=current_slice_descriptor) @staticmethod - def _need_to_close_page(at_least_one_page_in_group: bool, message: AirbyteMessage) -> bool: + def _need_to_close_page(at_least_one_page_in_group: bool, message: AirbyteMessage, json_message: Optional[dict]) -> bool: return ( at_least_one_page_in_group and message.type == MessageType.LOG - and (message.log.message.startswith("request:") or message.log.message.startswith("slice:")) + and (MessageGrouper._is_page_http_request(json_message) or message.log.message.startswith("slice:")) ) + @staticmethod + def _is_page_http_request(json_message): + return MessageGrouper._is_http_log(json_message) and not MessageGrouper._is_auxiliary_http_request(json_message) + + @staticmethod + def _is_http_log(message: Optional[dict]) -> bool: + return message and bool(message.get("http", False)) + + @staticmethod + def _is_auxiliary_http_request(message: Optional[dict]) -> bool: + """ + A auxiliary request is a request that is performed and will not directly lead to record for the specific stream it is being queried. + A couple of examples are: + * OAuth authentication + * Substream slice generation + """ + if not message: + return False + + is_http = MessageGrouper._is_http_log(message) + return is_http and message.get("http", {}).get("is_auxiliary", False) + @staticmethod def _close_page(current_page_request, current_page_response, current_slice_pages, current_page_records, validate_page_complete: bool): """ @@ -184,39 +229,35 @@ def _read_stream(self, source: DeclarativeSource, config: Mapping[str, Any], con error_message = f"{e.args[0] if len(e.args) > 0 else str(e)}" yield AirbyteTracedException.from_exception(e, message=error_message).as_airbyte_message() - def _create_request_from_log_message(self, log_message: AirbyteLogMessage) -> Optional[HttpRequest]: - # TODO: As a temporary stopgap, the CDK emits request data as a log message string. Ideally this should come in the + @staticmethod + def _parse_json(log_message: AirbyteLogMessage): + # TODO: As a temporary stopgap, the CDK emits request/response data as a log message string. Ideally this should come in the # form of a custom message object defined in the Airbyte protocol, but this unblocks us in the immediate while the # protocol change is worked on. - raw_request = log_message.message.partition("request:")[2] try: - request = json.loads(raw_request) - url = urlparse(request.get("url", "")) - full_path = f"{url.scheme}://{url.hostname}{url.path}" if url else "" - parameters = parse_qs(url.query) or None - return HttpRequest( - url=full_path, - http_method=request.get("http_method", ""), - headers=request.get("headers"), - parameters=parameters, - body=request.get("body"), - ) - except JSONDecodeError as error: - self.logger.warning(f"Failed to parse log message into request object with error: {error}") + return json.loads(log_message.message) + except JSONDecodeError: return None - def _create_response_from_log_message(self, log_message: AirbyteLogMessage) -> Optional[HttpResponse]: - # TODO: As a temporary stopgap, the CDK emits response data as a log message string. Ideally this should come in the - # form of a custom message object defined in the Airbyte protocol, but this unblocks us in the immediate while the - # protocol change is worked on. - raw_response = log_message.message.partition("response:")[2] - try: - response = json.loads(raw_response) - body = response.get("body", "{}") - return HttpResponse(status=response.get("status_code"), body=body, headers=response.get("headers")) - except JSONDecodeError as error: - self.logger.warning(f"Failed to parse log message into response object with error: {error}") - return None + @staticmethod + def _create_request_from_log_message(json_http_message: dict) -> HttpRequest: + url = urlparse(json_http_message.get("url", {}).get("full", "")) + full_path = f"{url.scheme}://{url.hostname}{url.path}" if url else "" + request = json_http_message.get("http", {}).get("request", {}) + parameters = parse_qs(url.query) or None + return HttpRequest( + url=full_path, + http_method=request.get("method", ""), + headers=request.get("headers"), + parameters=parameters, + body=request.get("body", {}).get("content", ""), + ) + + @staticmethod + def _create_response_from_log_message(json_http_message: dict) -> HttpResponse: + response = json_http_message.get("http", {}).get("response", {}) + body = response.get("body", {}).get("content", "") + return HttpResponse(status=response.get("status_code"), body=body, headers=response.get("headers")) def _has_reached_limit(self, slices: List[StreamReadPages]): if len(slices) >= self._max_slices: diff --git a/airbyte-cdk/python/airbyte_cdk/connector_builder/models.py b/airbyte-cdk/python/airbyte_cdk/connector_builder/models.py index 7ebd4e4e65b9..5b09a60af308 100644 --- a/airbyte-cdk/python/airbyte_cdk/connector_builder/models.py +++ b/airbyte-cdk/python/airbyte_cdk/connector_builder/models.py @@ -42,11 +42,20 @@ class LogMessage: level: str +@dataclass +class AuxiliaryRequest: + title: str + description: str + request: HttpRequest + response: HttpResponse + + @dataclass class StreamRead(object): logs: List[LogMessage] slices: List[StreamReadSlices] test_read_limit_reached: bool + auxiliary_requests: List[AuxiliaryRequest] inferred_schema: Optional[Dict[str, Any]] inferred_datetime_formats: Optional[Dict[str, str]] latest_config_update: Optional[Dict[str, Any]] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/oauth.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/oauth.py index a7900e9ad693..a7621693f0a2 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/oauth.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/declarative/auth/oauth.py @@ -9,6 +9,7 @@ from airbyte_cdk.sources.declarative.auth.declarative_authenticator import DeclarativeAuthenticator from airbyte_cdk.sources.declarative.interpolation.interpolated_mapping import InterpolatedMapping from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString +from airbyte_cdk.sources.message import MessageRepository, NoopMessageRepository from airbyte_cdk.sources.streams.http.requests_native_auth.abstract_oauth import AbstractOauth2Authenticator from airbyte_cdk.sources.streams.http.requests_native_auth.oauth import SingleUseRefreshTokenOauth2Authenticator @@ -33,6 +34,7 @@ class DeclarativeOauth2Authenticator(AbstractOauth2Authenticator, DeclarativeAut token_expiry_date_format str: format of the datetime; provide it if expires_in is returned in datetime instead of seconds refresh_request_body (Optional[Mapping[str, Any]]): The request body to send in the refresh request grant_type: The grant_type to request for access_token. If set to refresh_token, the refresh_token parameter has to be provided + message_repository (MessageRepository): the message repository used to emit logs on HTTP requests """ token_refresh_endpoint: Union[InterpolatedString, str] @@ -49,6 +51,7 @@ class DeclarativeOauth2Authenticator(AbstractOauth2Authenticator, DeclarativeAut expires_in_name: Union[InterpolatedString, str] = "expires_in" refresh_request_body: Optional[Mapping[str, Any]] = None grant_type: Union[InterpolatedString, str] = "refresh_token" + message_repository: MessageRepository = NoopMessageRepository() def __post_init__(self, parameters: Mapping[str, Any]): self.token_refresh_endpoint = InterpolatedString.create(self.token_refresh_endpoint, parameters=parameters) @@ -135,6 +138,13 @@ def access_token(self) -> str: def access_token(self, value: str): self._access_token = value + @property + def _message_repository(self) -> MessageRepository: + """ + Overriding AbstractOauth2Authenticator._message_repository to allow for HTTP request logs + """ + return self.message_repository + @dataclass class DeclarativeSingleUseRefreshTokenOauth2Authenticator(SingleUseRefreshTokenOauth2Authenticator, DeclarativeAuthenticator): diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py index 1de091c4cb1e..6199f37915ac 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py @@ -9,6 +9,7 @@ import re from typing import Any, Callable, List, Literal, Mapping, Optional, Type, Union, get_args, get_origin, get_type_hints +from airbyte_cdk.models import Level from airbyte_cdk.sources.declarative.auth import DeclarativeOauth2Authenticator from airbyte_cdk.sources.declarative.auth.declarative_authenticator import NoAuth from airbyte_cdk.sources.declarative.auth.oauth import DeclarativeSingleUseRefreshTokenOauth2Authenticator @@ -106,7 +107,7 @@ from airbyte_cdk.sources.declarative.transformations import AddFields, RecordTransformation, RemoveFields from airbyte_cdk.sources.declarative.transformations.add_fields import AddedFieldDefinition from airbyte_cdk.sources.declarative.types import Config -from airbyte_cdk.sources.message import InMemoryMessageRepository +from airbyte_cdk.sources.message import InMemoryMessageRepository, LogAppenderMessageRepositoryDecorator, MessageRepository from pydantic import BaseModel ComponentDefinition: Union[Literal, Mapping, List] @@ -121,14 +122,17 @@ def __init__( limit_pages_fetched_per_slice: int = None, limit_slices_fetched: int = None, emit_connector_builder_messages: bool = False, - disable_retries=False, + disable_retries: bool = False, + message_repository: MessageRepository = None, ): self._init_mappings() self._limit_pages_fetched_per_slice = limit_pages_fetched_per_slice self._limit_slices_fetched = limit_slices_fetched self._emit_connector_builder_messages = emit_connector_builder_messages self._disable_retries = disable_retries - self._message_repository = InMemoryMessageRepository() + self._message_repository = message_repository or InMemoryMessageRepository( + self._evaluate_log_level(emit_connector_builder_messages) + ) def _init_mappings(self): self.PYDANTIC_MODEL_TO_CONSTRUCTOR: [Type[BaseModel], Callable] = { @@ -733,6 +737,7 @@ def create_oauth_authenticator(self, model: OAuthAuthenticatorModel, config: Con token_refresh_endpoint=model.token_refresh_endpoint, config=config, parameters=model.parameters, + message_repository=self._message_repository, ) @staticmethod @@ -838,6 +843,7 @@ def create_simple_retriever( maximum_number_of_slices=self._limit_slices_fetched, parameters=model.parameters, disable_retries=self._disable_retries, + message_repository=self._message_repository, ) return SimpleRetriever( name=name, @@ -850,6 +856,7 @@ def create_simple_retriever( config=config, parameters=model.parameters, disable_retries=self._disable_retries, + message_repository=self._message_repository, ) @staticmethod @@ -866,13 +873,27 @@ def create_substream_partition_router(self, model: SubstreamPartitionRouterModel if model.parent_stream_configs: parent_stream_configs.extend( [ - self._create_component_from_model(model=parent_stream_config, config=config) + self._create_message_repository_substream_wrapper(model=parent_stream_config, config=config) for parent_stream_config in model.parent_stream_configs ] ) return SubstreamPartitionRouter(parent_stream_configs=parent_stream_configs, parameters=model.parameters, config=config) + def _create_message_repository_substream_wrapper(self, model, config): + substream_factory = ModelToComponentFactory( + limit_pages_fetched_per_slice=self._limit_pages_fetched_per_slice, + limit_slices_fetched=self._limit_slices_fetched, + emit_connector_builder_messages=self._emit_connector_builder_messages, + disable_retries=self._disable_retries, + message_repository=LogAppenderMessageRepositoryDecorator( + {"airbyte_cdk": {"stream": {"is_substream": True}}, "http": {"is_auxiliary": True}}, + self._message_repository, + self._evaluate_log_level(self._emit_connector_builder_messages), + ), + ) + return substream_factory._create_component_from_model(model=model, config=config) + @staticmethod def create_wait_time_from_header(model: WaitTimeFromHeaderModel, config: Config, **kwargs) -> WaitTimeFromHeaderBackoffStrategy: return WaitTimeFromHeaderBackoffStrategy(header=model.header, parameters=model.parameters, config=config, regex=model.regex) @@ -887,3 +908,6 @@ def create_wait_until_time_from_header( def get_message_repository(self): return self._message_repository + + def _evaluate_log_level(self, emit_connector_builder_messages) -> Level: + return Level.DEBUG if emit_connector_builder_messages else Level.INFO diff --git a/airbyte-cdk/python/airbyte_cdk/sources/declarative/retrievers/simple_retriever.py b/airbyte-cdk/python/airbyte_cdk/sources/declarative/retrievers/simple_retriever.py index bb78f86f2220..55ce658873d4 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/declarative/retrievers/simple_retriever.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/declarative/retrievers/simple_retriever.py @@ -2,14 +2,12 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # -import json from dataclasses import InitVar, dataclass, field from itertools import islice from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Union import requests -from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, Level, SyncMode -from airbyte_cdk.models import Type as MessageType +from airbyte_cdk.models import AirbyteMessage, Level, SyncMode from airbyte_cdk.sources.declarative.exceptions import ReadException from airbyte_cdk.sources.declarative.extractors.http_selector import HttpSelector from airbyte_cdk.sources.declarative.incremental.cursor import Cursor @@ -22,9 +20,10 @@ from airbyte_cdk.sources.declarative.retrievers.retriever import Retriever from airbyte_cdk.sources.declarative.stream_slicers.stream_slicer import StreamSlicer from airbyte_cdk.sources.declarative.types import Config, Record, StreamSlice, StreamState +from airbyte_cdk.sources.http_logger import format_http_message +from airbyte_cdk.sources.message import MessageRepository, NoopMessageRepository from airbyte_cdk.sources.streams.core import StreamData from airbyte_cdk.sources.streams.http import HttpStream -from airbyte_cdk.utils.airbyte_secrets_utils import filter_secrets @dataclass @@ -64,8 +63,8 @@ class SimpleRetriever(Retriever, HttpStream): paginator: Optional[Paginator] = None stream_slicer: Optional[StreamSlicer] = SinglePartitionRouter(parameters={}) cursor: Optional[Cursor] = None - emit_connector_builder_messages: bool = False disable_retries: bool = False + message_repository: MessageRepository = NoopMessageRepository() def __post_init__(self, parameters: Mapping[str, Any]): self.paginator = self.paginator or NoPagination(parameters=parameters) @@ -501,29 +500,13 @@ def parse_records( stream_state: Mapping[str, Any], stream_slice: Mapping[str, Any], ) -> Iterable[StreamData]: - yield _prepared_request_to_airbyte_message(request) - yield _response_to_airbyte_message(response) + self.message_repository.log_message( + Level.DEBUG, + lambda: format_http_message( + response, + f"Stream '{self.name}' request", + f"Request performed in order to extract records for stream '{self.name}'", + self.name, + ), + ) yield from self.parse_response(response, stream_slice=stream_slice, stream_state=stream_state) - - -def _prepared_request_to_airbyte_message(request: requests.PreparedRequest) -> AirbyteMessage: - # FIXME: this should return some sort of trace message - request_dict = { - "url": request.url, - "http_method": request.method, - "headers": dict(request.headers), - "body": _normalize_body_string(request.body), - } - log_message = filter_secrets(f"request:{json.dumps(request_dict)}") - return AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=Level.INFO, message=log_message)) - - -def _normalize_body_string(body_str: Optional[Union[str, bytes]]) -> Optional[str]: - return body_str.decode() if isinstance(body_str, (bytes, bytearray)) else body_str - - -def _response_to_airbyte_message(response: requests.Response) -> AirbyteMessage: - # FIXME: this should return some sort of trace message - response_dict = {"body": response.text, "headers": dict(response.headers), "status_code": response.status_code} - log_message = filter_secrets(f"response:{json.dumps(response_dict)}") - return AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=Level.INFO, message=log_message)) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/http_logger.py b/airbyte-cdk/python/airbyte_cdk/sources/http_logger.py new file mode 100644 index 000000000000..7158c8003e5b --- /dev/null +++ b/airbyte-cdk/python/airbyte_cdk/sources/http_logger.py @@ -0,0 +1,47 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +from typing import Optional, Union + +import requests +from airbyte_cdk.sources.message import LogMessage + + +def format_http_message( + response: requests.Response, title: str, description: str, stream_name: Optional[str], is_auxiliary: bool = None +) -> LogMessage: + request = response.request + log_message = { + "http": { + "title": title, + "description": description, + "request": { + "method": request.method, + "body": { + "content": _normalize_body_string(request.body), + }, + "headers": dict(request.headers), + }, + "response": { + "body": { + "content": response.text, + }, + "headers": dict(response.headers), + "status_code": response.status_code, + }, + }, + "log": { + "level": "debug", + }, + "url": {"full": request.url}, + } + if is_auxiliary is not None: + log_message["http"]["is_auxiliary"] = is_auxiliary + if stream_name: + log_message["airbyte_cdk"] = {"stream": {"name": stream_name}} + return log_message + + +def _normalize_body_string(body_str: Optional[Union[str, bytes]]) -> Optional[str]: + return body_str.decode() if isinstance(body_str, (bytes, bytearray)) else body_str diff --git a/airbyte-cdk/python/airbyte_cdk/sources/message/__init__.py b/airbyte-cdk/python/airbyte_cdk/sources/message/__init__.py index 5dec9072fed3..c545c0d736ab 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/message/__init__.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/message/__init__.py @@ -2,6 +2,12 @@ # Copyright (c) 2021 Airbyte, Inc., all rights reserved. # -from .repository import InMemoryMessageRepository, MessageRepository +from .repository import ( + InMemoryMessageRepository, + LogAppenderMessageRepositoryDecorator, + LogMessage, + MessageRepository, + NoopMessageRepository, +) -__all__ = ["InMemoryMessageRepository", "MessageRepository"] +__all__ = ["InMemoryMessageRepository", "LogAppenderMessageRepositoryDecorator", "LogMessage", "MessageRepository", "NoopMessageRepository"] diff --git a/airbyte-cdk/python/airbyte_cdk/sources/message/repository.py b/airbyte-cdk/python/airbyte_cdk/sources/message/repository.py index 74866e610172..a389961ab0f5 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/message/repository.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/message/repository.py @@ -2,12 +2,42 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # +import json +import logging from abc import ABC, abstractmethod -from typing import Iterable +from collections import deque +from typing import Callable, Iterable, Union -from airbyte_cdk.models import AirbyteMessage, Type +from airbyte_cdk.models import AirbyteLogMessage, AirbyteMessage, Level, Type +from airbyte_cdk.utils.airbyte_secrets_utils import filter_secrets +_LOGGER = logging.getLogger("MessageRepository") _SUPPORTED_MESSAGE_TYPES = {Type.CONTROL, Type.LOG} +JsonType = Union[dict[str, "JsonType"], list["JsonType"], str, int, float, bool, None] +LogMessage = dict[str, JsonType] + +_SEVERITY_BY_LOG_LEVEL = { + Level.FATAL: 1, + Level.ERROR: 2, + Level.WARN: 3, + Level.INFO: 4, + Level.DEBUG: 5, + Level.TRACE: 5, +} + + +def _is_severe_enough(threshold: Level, level: Level): + if threshold not in _SEVERITY_BY_LOG_LEVEL: + _LOGGER.warning(f"Log level {threshold} for threshold is not supported. This is probably a CDK bug. Please contact Airbyte.") + return True + + if level not in _SEVERITY_BY_LOG_LEVEL: + _LOGGER.warning( + f"Log level {level} is not supported. This is probably a source bug. Please contact the owner of the source or Airbyte." + ) + return True + + return _SEVERITY_BY_LOG_LEVEL[threshold] >= _SEVERITY_BY_LOG_LEVEL[level] class MessageRepository(ABC): @@ -15,14 +45,34 @@ class MessageRepository(ABC): def emit_message(self, message: AirbyteMessage) -> None: raise NotImplementedError() + @abstractmethod + def log_message(self, level: Level, message_provider: Callable[[], LogMessage]) -> None: + """ + Computing messages can be resource consuming. This method is specialized for logging because we want to allow for lazy evaluation if + the log level is less severe than what is configured + """ + raise NotImplementedError() + @abstractmethod def consume_queue(self) -> Iterable[AirbyteMessage]: raise NotImplementedError() +class NoopMessageRepository(MessageRepository): + def emit_message(self, message: AirbyteMessage) -> None: + pass + + def log_message(self, level: Level, message_provider: Callable[[], LogMessage]) -> None: + pass + + def consume_queue(self) -> Iterable[AirbyteMessage]: + return [] + + class InMemoryMessageRepository(MessageRepository): - def __init__(self): - self._message_queue = [] + def __init__(self, log_level=Level.INFO): + self._message_queue = deque() + self._log_level = log_level def emit_message(self, message: AirbyteMessage) -> None: """ @@ -33,6 +83,47 @@ def emit_message(self, message: AirbyteMessage) -> None: raise ValueError(f"As of today, only {_SUPPORTED_MESSAGE_TYPES} are supported as part of the InMemoryMessageRepository") self._message_queue.append(message) + def log_message(self, level: Level, message_provider: Callable[[], LogMessage]) -> None: + if _is_severe_enough(self._log_level, level): + self.emit_message( + AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=level, message=filter_secrets(json.dumps(message_provider())))) + ) + def consume_queue(self) -> Iterable[AirbyteMessage]: while self._message_queue: - yield self._message_queue.pop(0) + yield self._message_queue.popleft() + + +class LogAppenderMessageRepositoryDecorator(MessageRepository): + def __init__(self, dict_to_append: LogMessage, decorated: MessageRepository, log_level=Level.INFO): + self._dict_to_append = dict_to_append + self._decorated = decorated + self._log_level = log_level + + def emit_message(self, message: AirbyteMessage) -> None: + self._decorated.emit_message(message) + + def log_message(self, level: Level, message_provider: Callable[[], LogMessage]) -> None: + if _is_severe_enough(self._log_level, level): + message = message_provider() + self._append_second_to_first(message, self._dict_to_append) + self._decorated.log_message(level, lambda: message) + + def consume_queue(self) -> Iterable[AirbyteMessage]: + return self._decorated.consume_queue() + + def _append_second_to_first(self, first, second, path=None): + if path is None: + path = [] + + for key in second: + if key in first: + if isinstance(first[key], dict) and isinstance(second[key], dict): + self._append_second_to_first(first[key], second[key], path + [str(key)]) + else: + if first[key] != second[key]: + _LOGGER.warning("Conflict at %s" % ".".join(path + [str(key)])) + first[key] = second[key] + else: + first[key] = second[key] + return first diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py index 642cdbf35a82..371f06b34d51 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/abstract_oauth.py @@ -9,11 +9,15 @@ import backoff import pendulum import requests +from airbyte_cdk.models import Level +from airbyte_cdk.sources.http_logger import format_http_message +from airbyte_cdk.sources.message import MessageRepository, NoopMessageRepository from requests.auth import AuthBase from ..exceptions import DefaultBackoffException logger = logging.getLogger("airbyte") +_NOOP_MESSAGE_REPOSITORY = NoopMessageRepository() class AbstractOauth2Authenticator(AuthBase): @@ -23,6 +27,8 @@ class AbstractOauth2Authenticator(AuthBase): delegating that behavior to the classes implementing the interface. """ + _NO_STREAM_NAME = None + def __call__(self, request: requests.Request) -> requests.Request: """Attach the HTTP headers required to authenticate on the HTTP request""" request.headers.update(self.get_auth_header()) @@ -80,6 +86,7 @@ def build_refresh_request_body(self) -> Mapping[str, Any]: def _get_refresh_access_token_response(self): try: response = requests.request(method="POST", url=self.get_token_refresh_endpoint(), data=self.build_refresh_request_body()) + self._log_response(response) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: @@ -151,3 +158,22 @@ def access_token(self) -> str: @abstractmethod def access_token(self, value: str) -> str: """Setter for the access token""" + + @property + def _message_repository(self) -> Optional[MessageRepository]: + """ + The implementation can define a message_repository if it wants debugging logs for HTTP requests + """ + return _NOOP_MESSAGE_REPOSITORY + + def _log_response(self, response: requests.Response): + self._message_repository.log_message( + Level.DEBUG, + lambda: format_http_message( + response, + "Refresh token", + "Obtains access token", + self._NO_STREAM_NAME, + is_auxiliary=True, + ), + ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py index 29e8a544b02d..d7a93157ed99 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/streams/http/requests_native_auth/oauth.py @@ -7,7 +7,7 @@ import dpath import pendulum from airbyte_cdk.config_observation import create_connector_config_control_message, emit_configuration_as_airbyte_control_message -from airbyte_cdk.sources.message import MessageRepository +from airbyte_cdk.sources.message import MessageRepository, NoopMessageRepository from airbyte_cdk.sources.streams.http.requests_native_auth.abstract_oauth import AbstractOauth2Authenticator @@ -116,7 +116,7 @@ def __init__( refresh_token_config_path: Sequence[str] = ("credentials", "refresh_token"), token_expiry_date_config_path: Sequence[str] = ("credentials", "token_expiry_date"), token_expiry_date_format: Optional[str] = None, - message_repository: MessageRepository = None, + message_repository: MessageRepository = NoopMessageRepository(), ): """ @@ -135,6 +135,7 @@ def __init__( refresh_token_config_path (Sequence[str]): Dpath to the refresh_token field in the connector configuration. Defaults to ("credentials", "refresh_token"). token_expiry_date_config_path (Sequence[str]): Dpath to the token_expiry_date field in the connector configuration. Defaults to ("credentials", "token_expiry_date"). token_expiry_date_format (Optional[str]): Date format of the token expiry date field (set by expires_in_name). If not specified the token expiry date is interpreted as number of seconds until expiration. + message_repository (MessageRepository): the message repository used to emit logs on HTTP requests and control message on config update """ self._client_id = client_id if client_id is not None else dpath.util.get(connector_config, ("credentials", "client_id")) self._client_secret = ( @@ -146,7 +147,7 @@ def __init__( self._token_expiry_date_format = token_expiry_date_format self._refresh_token_name = refresh_token_name self._connector_config = connector_config - self._message_repository = message_repository + self.__message_repository = message_repository super().__init__( token_refresh_endpoint, self.get_client_id(), @@ -214,10 +215,12 @@ def get_access_token(self) -> str: self.access_token = new_access_token self.set_refresh_token(new_refresh_token) self.set_token_expiry_date(new_token_expiry_date) - if self._message_repository: + # FIXME emit_configuration_as_airbyte_control_message as been deprecated in favor of package airbyte_cdk.sources.message + # Usually, a class shouldn't care about the implementation details but to keep backward compatibility where we print the + # message directly in the console, this is needed + if not isinstance(self._message_repository, NoopMessageRepository): self._message_repository.emit_message(create_connector_config_control_message(self._connector_config)) else: - # FIXME emit_configuration_as_airbyte_control_message as been deprecated in favor of package airbyte_cdk.sources.message emit_configuration_as_airbyte_control_message(self._connector_config) return self.access_token @@ -228,3 +231,10 @@ def refresh_access_token(self) -> Tuple[str, str, str]: response_json[self.get_expires_in_name()], response_json[self.get_refresh_token_name()], ) + + @property + def _message_repository(self) -> MessageRepository: + """ + Overriding AbstractOauth2Authenticator._message_repository to allow for HTTP request logs + """ + return self.__message_repository diff --git a/airbyte-cdk/python/unit_tests/connector_builder/test_connector_builder_handler.py b/airbyte-cdk/python/unit_tests/connector_builder/test_connector_builder_handler.py index b694bebb81db..4245ccc9d129 100644 --- a/airbyte-cdk/python/unit_tests/connector_builder/test_connector_builder_handler.py +++ b/airbyte-cdk/python/unit_tests/connector_builder/test_connector_builder_handler.py @@ -422,6 +422,7 @@ def test_read(): state=None, ) ], + auxiliary_requests=[], test_read_limit_reached=False, inferred_schema=None, inferred_datetime_formats=None, @@ -438,6 +439,7 @@ def test_read(): {"pages": [{"records": [real_record], "request": None, "response": None}], "slice_descriptor": None, "state": None} ], "test_read_limit_reached": False, + "auxiliary_requests": [], "inferred_schema": None, "inferred_datetime_formats": None, "latest_config_update": {} @@ -512,6 +514,7 @@ def check_config_against_spec(self): pages=[StreamReadPages(records=[], request=None, response=None)], slice_descriptor=None, state=None)], test_read_limit_reached=False, + auxiliary_requests=[], inferred_schema=None, inferred_datetime_formats={}, latest_config_update=None) @@ -690,16 +693,18 @@ def _create_request(): return requests.Request('POST', url, headers=headers, json={"key": "value"}).prepare() -def _create_response(body): +def _create_response(body, request): response = requests.Response() response.status_code = 200 response._content = bytes(json.dumps(body), "utf-8") response.headers["Content-Type"] = "application/json" + response.request = request return response def _create_page(response_body): - return _create_request(), _create_response(response_body) + request = _create_request() + return request, _create_response(response_body, request) @patch.object(HttpStream, "_fetch_next_page", side_effect=(_create_page({"result": [{"id": 0}, {"id": 1}],"_metadata": {"next": "next"}}), _create_page({"result": [{"id": 2}],"_metadata": {"next": "next"}})) * 10) diff --git a/airbyte-cdk/python/unit_tests/connector_builder/test_message_grouper.py b/airbyte-cdk/python/unit_tests/connector_builder/test_message_grouper.py index f5dda8fed77e..a9a2cc742b15 100644 --- a/airbyte-cdk/python/unit_tests/connector_builder/test_message_grouper.py +++ b/airbyte-cdk/python/unit_tests/connector_builder/test_message_grouper.py @@ -87,22 +87,22 @@ @patch('airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read') def test_get_grouped_messages(mock_entrypoint_read): + url = "https://demonslayers.com/api/v1/hashiras?era=taisho" request = { - "url": "https://demonslayers.com/api/v1/hashiras?era=taisho", "headers": {"Content-Type": "application/json"}, - "http_method": "GET", - "body": {"custom": "field"}, + "method": "GET", + "body": {"content": '{"custom": "field"}'}, } - response = {"status_code": 200, "headers": {"field": "value"}, "body": '{"name": "field"}', "http_method": "GET"} + response = {"status_code": 200, "headers": {"field": "value"}, "body": {"content": '{"name": "field"}'}} expected_schema = {"$schema": "http://json-schema.org/schema#", "properties": {"name": {"type": "string"}, "date": {"type": "string"}}, "type": "object"} - expected_datetime_fields = {"date":"%Y-%m-%d"} + expected_datetime_fields = {"date": "%Y-%m-%d"} expected_pages = [ StreamReadPages( request=HttpRequest( url="https://demonslayers.com/api/v1/hashiras", parameters={"era": ["taisho"]}, headers={"Content-Type": "application/json"}, - body={"custom": "field"}, + body='{"custom": "field"}', http_method="GET", ), response=HttpResponse(status=200, headers={"field": "value"}, body='{"name": "field"}'), @@ -113,7 +113,7 @@ def test_get_grouped_messages(mock_entrypoint_read): url="https://demonslayers.com/api/v1/hashiras", parameters={"era": ["taisho"]}, headers={"Content-Type": "application/json"}, - body={"custom": "field"}, + body='{"custom": "field"}', http_method="GET", ), response=HttpResponse(status=200, headers={"field": "value"}, body='{"name": "field"}'), @@ -123,12 +123,10 @@ def test_get_grouped_messages(mock_entrypoint_read): mock_source = make_mock_source(mock_entrypoint_read, iter( [ - request_log_message(request), - response_log_message(response), + request_response_log_message(request, response, url), record_message("hashiras", {"name": "Shinobu Kocho", "date": "2023-03-03"}), record_message("hashiras", {"name": "Muichiro Tokito", "date": "2023-03-04"}), - request_log_message(request), - response_log_message(response), + request_response_log_message(request, response, url), record_message("hashiras", {"name": "Mitsuri Kanroji", "date": "2023-03-05"}), ] )) @@ -148,20 +146,20 @@ def test_get_grouped_messages(mock_entrypoint_read): @patch('airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read') def test_get_grouped_messages_with_logs(mock_entrypoint_read): + url = "https://demonslayers.com/api/v1/hashiras?era=taisho" request = { - "url": "https://demonslayers.com/api/v1/hashiras?era=taisho", "headers": {"Content-Type": "application/json"}, - "body": {"custom": "field"}, - "http_method": "GET", + "method": "GET", + "body": {"content": '{"custom": "field"}'}, } - response = {"status_code": 200, "headers": {"field": "value"}, "body": '{"name": "field"}'} + response = {"status_code": 200, "headers": {"field": "value"}, "body": {"content": '{"name": "field"}'}} expected_pages = [ StreamReadPages( request=HttpRequest( url="https://demonslayers.com/api/v1/hashiras", parameters={"era": ["taisho"]}, headers={"Content-Type": "application/json"}, - body={"custom": "field"}, + body='{"custom": "field"}', http_method="GET", ), response=HttpResponse(status=200, headers={"field": "value"}, body='{"name": "field"}'), @@ -172,7 +170,7 @@ def test_get_grouped_messages_with_logs(mock_entrypoint_read): url="https://demonslayers.com/api/v1/hashiras", parameters={"era": ["taisho"]}, headers={"Content-Type": "application/json"}, - body={"custom": "field"}, + body='{"custom": "field"}', http_method="GET", ), response=HttpResponse(status=200, headers={"field": "value"}, body='{"name": "field"}'), @@ -188,8 +186,7 @@ def test_get_grouped_messages_with_logs(mock_entrypoint_read): mock_source = make_mock_source(mock_entrypoint_read, iter( [ AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=Level.INFO, message="log message before the request")), - request_log_message(request), - response_log_message(response), + request_response_log_message(request, response, url), record_message("hashiras", {"name": "Shinobu Kocho"}), AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=Level.INFO, message="log message during the page")), record_message("hashiras", {"name": "Muichiro Tokito"}), @@ -220,22 +217,20 @@ def test_get_grouped_messages_with_logs(mock_entrypoint_read): ) @patch('airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read') def test_get_grouped_messages_record_limit(mock_entrypoint_read, request_record_limit, max_record_limit): + url = "https://demonslayers.com/api/v1/hashiras?era=taisho" request = { - "url": "https://demonslayers.com/api/v1/hashiras?era=taisho", "headers": {"Content-Type": "application/json"}, - "body": {"custom": "field"}, + "method": "GET", + "body": {"content": '{"custom": "field"}'}, } - response = {"status_code": 200, "headers": {"field": "value"}, "body": '{"name": "field"}'} + response = {"status_code": 200, "headers": {"field": "value"}, "body": {"content": '{"name": "field"}'}} mock_source = make_mock_source(mock_entrypoint_read, iter( [ - request_log_message(request), - response_log_message(response), + request_response_log_message(request, response, url), record_message("hashiras", {"name": "Shinobu Kocho"}), record_message("hashiras", {"name": "Muichiro Tokito"}), - request_log_message(request), - response_log_message(response), + request_response_log_message(request, response, url), record_message("hashiras", {"name": "Mitsuri Kanroji"}), - response_log_message(response), ] ) ) @@ -262,22 +257,20 @@ def test_get_grouped_messages_record_limit(mock_entrypoint_read, request_record_ ) @patch('airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read') def test_get_grouped_messages_default_record_limit(mock_entrypoint_read, max_record_limit): + url = "https://demonslayers.com/api/v1/hashiras?era=taisho" request = { - "url": "https://demonslayers.com/api/v1/hashiras?era=taisho", "headers": {"Content-Type": "application/json"}, - "body": {"custom": "field"}, + "method": "GET", + "body": {"content": '{"custom": "field"}'}, } - response = {"status_code": 200, "headers": {"field": "value"}, "body": '{"name": "field"}'} + response = {"status_code": 200, "headers": {"field": "value"}, "body": {"content": '{"name": "field"}'}} mock_source = make_mock_source(mock_entrypoint_read, iter( [ - request_log_message(request), - response_log_message(response), + request_response_log_message(request, response, url), record_message("hashiras", {"name": "Shinobu Kocho"}), record_message("hashiras", {"name": "Muichiro Tokito"}), - request_log_message(request), - response_log_message(response), + request_response_log_message(request, response, url), record_message("hashiras", {"name": "Mitsuri Kanroji"}), - response_log_message(response), ] ) ) @@ -296,22 +289,20 @@ def test_get_grouped_messages_default_record_limit(mock_entrypoint_read, max_rec @patch('airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read') def test_get_grouped_messages_limit_0(mock_entrypoint_read): + url = "https://demonslayers.com/api/v1/hashiras?era=taisho" request = { - "url": "https://demonslayers.com/api/v1/hashiras?era=taisho", "headers": {"Content-Type": "application/json"}, - "body": {"custom": "field"}, + "method": "GET", + "body": {"content": '{"custom": "field"}'}, } - response = {"status_code": 200, "headers": {"field": "value"}, "body": '{"name": "field"}'} + response = {"status_code": 200, "headers": {"field": "value"}, "body": {"content": '{"name": "field"}'}} mock_source = make_mock_source(mock_entrypoint_read, iter( [ - request_log_message(request), - response_log_message(response), + request_response_log_message(request, response, url), record_message("hashiras", {"name": "Shinobu Kocho"}), record_message("hashiras", {"name": "Muichiro Tokito"}), - request_log_message(request), - response_log_message(response), + request_response_log_message(request, response, url), record_message("hashiras", {"name": "Mitsuri Kanroji"}), - response_log_message(response), ] ) ) @@ -323,20 +314,20 @@ def test_get_grouped_messages_limit_0(mock_entrypoint_read): @patch('airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read') def test_get_grouped_messages_no_records(mock_entrypoint_read): + url = "https://demonslayers.com/api/v1/hashiras?era=taisho" request = { - "url": "https://demonslayers.com/api/v1/hashiras?era=taisho", "headers": {"Content-Type": "application/json"}, - "body": {"custom": "field"}, - "http_method": "GET", + "method": "GET", + "body": {"content": '{"custom": "field"}'}, } - response = {"status_code": 200, "headers": {"field": "value"}, "body": '{"name": "field"}'} + response = {"status_code": 200, "headers": {"field": "value"}, "body": {"content": '{"name": "field"}'}} expected_pages = [ StreamReadPages( request=HttpRequest( url="https://demonslayers.com/api/v1/hashiras", parameters={"era": ["taisho"]}, headers={"Content-Type": "application/json"}, - body={"custom": "field"}, + body='{"custom": "field"}', http_method="GET", ), response=HttpResponse(status=200, headers={"field": "value"}, body='{"name": "field"}'), @@ -347,7 +338,7 @@ def test_get_grouped_messages_no_records(mock_entrypoint_read): url="https://demonslayers.com/api/v1/hashiras", parameters={"era": ["taisho"]}, headers={"Content-Type": "application/json"}, - body={"custom": "field"}, + body='{"custom": "field"}', http_method="GET", ), response=HttpResponse(status=200, headers={"field": "value"}, body='{"name": "field"}'), @@ -357,10 +348,8 @@ def test_get_grouped_messages_no_records(mock_entrypoint_read): mock_source = make_mock_source(mock_entrypoint_read, iter( [ - request_log_message(request), - response_log_message(response), - request_log_message(request), - response_log_message(response), + request_response_log_message(request, response, url), + request_response_log_message(request, response, url), ] ) ) @@ -399,25 +388,29 @@ def test_get_grouped_messages_invalid_group_format(mock_entrypoint_read): "log_message, expected_response", [ pytest.param( - {"status_code": 200, "headers": {"field": "name"}, "body": '{"id": "fire", "owner": "kyojuro_rengoku"}'}, + {"http": {"response": {"status_code": 200, "headers": {"field": "name"}, "body": {"content": '{"id": "fire", "owner": "kyojuro_rengoku"}'}}}}, HttpResponse(status=200, headers={"field": "name"}, body='{"id": "fire", "owner": "kyojuro_rengoku"}'), id="test_create_response_with_all_fields", ), pytest.param( - {"status_code": 200, "headers": {"field": "name"}}, - HttpResponse(status=200, headers={"field": "name"}, body="{}"), + {"http": {"response": {"status_code": 200, "headers": {"field": "name"}}}}, + HttpResponse(status=200, headers={"field": "name"}, body=""), id="test_create_response_with_no_body", ), pytest.param( - {"status_code": 200, "body": '{"id": "fire", "owner": "kyojuro_rengoku"}'}, + {"http": {"response": {"status_code": 200, "body": {"content": '{"id": "fire", "owner": "kyojuro_rengoku"}'}}}}, HttpResponse(status=200, body='{"id": "fire", "owner": "kyojuro_rengoku"}'), id="test_create_response_with_no_headers", ), pytest.param( { - "status_code": 200, - "headers": {"field": "name"}, - "body": '[{"id": "fire", "owner": "kyojuro_rengoku"}, {"id": "mist", "owner": "muichiro_tokito"}]', + "http": { + "response": { + "status_code": 200, + "headers": {"field": "name"}, + "body": {"content": '[{"id": "fire", "owner": "kyojuro_rengoku"}, {"id": "mist", "owner": "muichiro_tokito"}]'}, + } + } }, HttpResponse( status=200, @@ -427,48 +420,42 @@ def test_get_grouped_messages_invalid_group_format(mock_entrypoint_read): id="test_create_response_with_array", ), pytest.param( - {"status_code": 200, "body": "tomioka"}, + {"http": {"response": {"status_code": 200, "body": {"content": "tomioka"}}}}, HttpResponse(status=200, body="tomioka"), id="test_create_response_with_string", ), - pytest.param("request:{invalid_json: }", None, id="test_invalid_json_still_does_not_crash"), - pytest.param("just a regular log message", None, id="test_no_response:_prefix_does_not_crash"), ], ) def test_create_response_from_log_message(log_message, expected_response): if isinstance(log_message, str): - response_message = log_message + response_message = json.loads(log_message) else: - response_message = f"response:{json.dumps(log_message)}" + response_message = log_message - airbyte_log_message = AirbyteLogMessage(level=Level.INFO, message=response_message) connector_builder_handler = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) - actual_response = connector_builder_handler._create_response_from_log_message(airbyte_log_message) + actual_response = connector_builder_handler._create_response_from_log_message(response_message) assert actual_response == expected_response @patch('airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read') def test_get_grouped_messages_with_many_slices(mock_entrypoint_read): + url = "http://a-url.com" request = {} response = {"status_code": 200} mock_source = make_mock_source(mock_entrypoint_read, iter( [ slice_message('{"descriptor": "first_slice"}'), - request_log_message(request), - response_log_message(response), + request_response_log_message(request, response, url), record_message("hashiras", {"name": "Muichiro Tokito"}), slice_message('{"descriptor": "second_slice"}'), - request_log_message(request), - response_log_message(response), + request_response_log_message(request, response, url), record_message("hashiras", {"name": "Shinobu Kocho"}), record_message("hashiras", {"name": "Mitsuri Kanroji"}), - request_log_message(request), - response_log_message(response), + request_response_log_message(request, response, url), record_message("hashiras", {"name": "Obanai Iguro"}), - request_log_message(request), - response_log_message(response), + request_response_log_message(request, response, url), ] ) ) @@ -498,7 +485,7 @@ def test_get_grouped_messages_given_maximum_number_of_slices_then_test_read_limi maximum_number_of_slices = 5 request = {} response = {"status_code": 200} - mock_source = make_mock_source(mock_entrypoint_read, iter([slice_message(), request_log_message(request), response_log_message(response)] * maximum_number_of_slices)) + mock_source = make_mock_source(mock_entrypoint_read, iter([slice_message(), request_response_log_message(request, response, "a_url")] * maximum_number_of_slices)) api = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) @@ -514,7 +501,7 @@ def test_get_grouped_messages_given_maximum_number_of_pages_then_test_read_limit maximum_number_of_pages_per_slice = 5 request = {} response = {"status_code": 200} - mock_source = make_mock_source(mock_entrypoint_read, iter([slice_message()] + [request_log_message(request), response_log_message(response)] * maximum_number_of_pages_per_slice)) + mock_source = make_mock_source(mock_entrypoint_read, iter([slice_message()] + [request_response_log_message(request, response, "a_url")] * maximum_number_of_pages_per_slice)) api = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) @@ -598,6 +585,22 @@ def test_given_multiple_control_messages_with_same_timestamp_then_stream_read_ha assert stream_read.latest_config_update == latest_config +@patch('airbyte_cdk.connector_builder.message_grouper.AirbyteEntrypoint.read') +def test_given_auxiliary_requests_then_return_global_request(mock_entrypoint_read): + mock_source = make_mock_source(mock_entrypoint_read, iter( + any_request_and_response_with_a_record() + + [ + auxiliary_request_log_message() + ] + )) + connector_builder_handler = MessageGrouper(MAX_PAGES_PER_SLICE, MAX_SLICES) + stream_read: StreamRead = connector_builder_handler.get_message_groups( + source=mock_source, config=CONFIG, configured_catalog=create_configured_catalog("hashiras") + ) + + assert len(stream_read.auxiliary_requests) == 1 + + def make_mock_source(mock_entrypoint_read, return_value: Iterator) -> MagicMock: mock_source = MagicMock() mock_entrypoint_read.return_value = return_value @@ -631,9 +634,34 @@ def connector_configuration_control_message(emitted_at: float, config: dict) -> ) +def auxiliary_request_log_message(): + return AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=Level.INFO, message=json.dumps({ + "http": { + "is_auxiliary": True, + "title": "a title", + "description": "a description", + "request": {}, + "response": {}, + }, + "url": {"full": "https://a-url.com"} + }))) + + +def request_response_log_message(request: dict, response: dict, url: str): + return AirbyteMessage(type=MessageType.LOG, log=AirbyteLogMessage(level=Level.INFO, message=json.dumps({ + "airbyte_cdk": {"stream": {"name": "a stream name"}}, + "http": { + "title": "a title", + "description": "a description", + "request": request, + "response": response + }, + "url": {"full": url} + }))) + + def any_request_and_response_with_a_record(): return [ - request_log_message({"request": 1}), - response_log_message({"response": 2}), + request_response_log_message({"request": 1}, {"response": 2}, "http://any_url.com"), record_message("hashiras", {"name": "Shinobu Kocho"}), ] diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_oauth.py b/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_oauth.py index 93eaa02f178a..ff425380ed3c 100644 --- a/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_oauth.py +++ b/airbyte-cdk/python/unit_tests/sources/declarative/auth/test_oauth.py @@ -3,6 +3,7 @@ # import logging +from unittest.mock import Mock import freezegun import pendulum @@ -138,6 +139,7 @@ def test_refresh_access_token(self, mocker): def test_refresh_access_token_expire_format(self, mocker, expires_in_response, token_expiry_date_format): next_day = "2020-01-02T00:00:00Z" config.update({"token_expiry_date": pendulum.parse(next_day).subtract(days=2).to_rfc3339_string()}) + message_repository = Mock() oauth = DeclarativeOauth2Authenticator( token_refresh_endpoint="{{ config['refresh_endpoint'] }}", client_id="{{ config['client_id'] }}", @@ -152,6 +154,7 @@ def test_refresh_access_token_expire_format(self, mocker, expires_in_response, t "another_field": "{{ config['another_field'] }}", "scopes": ["no_override"], }, + message_repository=message_repository, parameters={}, ) @@ -161,6 +164,7 @@ def test_refresh_access_token_expire_format(self, mocker, expires_in_response, t token = oauth.get_access_token() assert "access_token" == token assert oauth.get_token_expiry_date() == pendulum.parse(next_day) + assert message_repository.log_message.call_count == 1 @pytest.mark.parametrize( "expires_in_response, next_day, raises", diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/parsers/test_model_to_component_factory.py b/airbyte-cdk/python/unit_tests/sources/declarative/parsers/test_model_to_component_factory.py index b6d960375511..c2eb0672f378 100644 --- a/airbyte-cdk/python/unit_tests/sources/declarative/parsers/test_model_to_component_factory.py +++ b/airbyte-cdk/python/unit_tests/sources/declarative/parsers/test_model_to_component_factory.py @@ -5,6 +5,7 @@ import datetime import pytest +from airbyte_cdk.models import Level from airbyte_cdk.sources.declarative.auth import DeclarativeOauth2Authenticator from airbyte_cdk.sources.declarative.auth.token import BasicHttpAuthenticator, BearerAuthenticator, SessionTokenAuthenticator from airbyte_cdk.sources.declarative.checks import CheckStream @@ -1478,6 +1479,7 @@ def test_simple_retriever_emit_log_messages(): ) assert isinstance(retriever, SimpleRetrieverTestReadDecorator) + assert connector_builder_factory._message_repository._log_level == Level.DEBUG def test_ignore_retry(): diff --git a/airbyte-cdk/python/unit_tests/sources/declarative/retrievers/test_simple_retriever.py b/airbyte-cdk/python/unit_tests/sources/declarative/retrievers/test_simple_retriever.py index 9c5bd0a6548d..f68e4ef63ce6 100644 --- a/airbyte-cdk/python/unit_tests/sources/declarative/retrievers/test_simple_retriever.py +++ b/airbyte-cdk/python/unit_tests/sources/declarative/retrievers/test_simple_retriever.py @@ -2,7 +2,6 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # -from typing import Mapping from unittest.mock import MagicMock, Mock, patch import airbyte_cdk.sources.declarative.requesters.error_handlers.response_status as response_status @@ -17,12 +16,7 @@ from airbyte_cdk.sources.declarative.requesters.error_handlers.response_status import ResponseStatus from airbyte_cdk.sources.declarative.requesters.request_option import RequestOptionType from airbyte_cdk.sources.declarative.requesters.requester import HttpMethod -from airbyte_cdk.sources.declarative.retrievers.simple_retriever import ( - SimpleRetriever, - SimpleRetrieverTestReadDecorator, - _prepared_request_to_airbyte_message, - _response_to_airbyte_message, -) +from airbyte_cdk.sources.declarative.retrievers.simple_retriever import SimpleRetriever, SimpleRetrieverTestReadDecorator from airbyte_cdk.sources.declarative.types import Record from airbyte_cdk.sources.streams.http.http import HttpStream @@ -513,198 +507,6 @@ def test_path(test_name, requester_path, paginator_path, expected_path): assert expected_path == actual_path -@pytest.mark.parametrize( - "test_name, http_method, url, headers, params, body_json, body_data, expected_airbyte_message", - [ - ( - "test_basic_get_request", - HttpMethod.GET, - "https://airbyte.io", - {}, - {}, - {}, - {}, - AirbyteMessage( - type=Type.LOG, - log=AirbyteLogMessage( - level=Level.INFO, message='request:{"url": "https://airbyte.io/", "http_method": "GET", "headers": {}, "body": null}' - ), - ), - ), - ( - "test_get_request_with_headers", - HttpMethod.GET, - "https://airbyte.io", - {"h1": "v1", "h2": "v2"}, - {}, - {}, - {}, - AirbyteMessage( - type=Type.LOG, - log=AirbyteLogMessage( - level=Level.INFO, - message='request:{"url": "https://airbyte.io/", "http_method": "GET", "headers": {"h1": "v1", "h2": "v2"}, "body": null}', - ), - ), - ), - ( - "test_get_request_with_request_params", - HttpMethod.GET, - "https://airbyte.io", - {}, - {"p1": "v1", "p2": "v2"}, - {}, - {}, - AirbyteMessage( - type=Type.LOG, - log=AirbyteLogMessage( - level=Level.INFO, - message='request:{"url": "https://airbyte.io/?p1=v1&p2=v2", "http_method": "GET", "headers": {}, "body": null}', - ), - ), - ), - ( - "test_get_request_with_request_body_json", - HttpMethod.GET, - "https://airbyte.io", - {"Content-Type": "application/json"}, - {}, - {"b1": "v1", "b2": "v2"}, - {}, - AirbyteMessage( - type=Type.LOG, - log=AirbyteLogMessage( - level=Level.INFO, - message='request:{"url": "https://airbyte.io/", "http_method": "GET", "headers": {"Content-Type": "application/json", "Content-Length": "24"}, "body": "{\\"b1\\": \\"v1\\", \\"b2\\": \\"v2\\"}"}', - ), - ), - ), - ( - "test_get_request_with_headers_params_and_body", - HttpMethod.GET, - "https://airbyte.io", - {"Content-Type": "application/json", "h1": "v1"}, - {"p1": "v1", "p2": "v2"}, - {"b1": "v1", "b2": "v2"}, - {}, - AirbyteMessage( - type=Type.LOG, - log=AirbyteLogMessage( - level=Level.INFO, - message='request:{"url": "https://airbyte.io/?p1=v1&p2=v2", "http_method": "GET", "headers": {"Content-Type": "application/json", "h1": "v1", "Content-Length": "24"}, "body": "{\\"b1\\": \\"v1\\", \\"b2\\": \\"v2\\"}"}', - ), - ), - ), - ( - "test_get_request_with_request_body_data", - HttpMethod.GET, - "https://airbyte.io", - {"Content-Type": "application/x-www-form-urlencoded"}, - {}, - {}, - {"b1": "v1", "b2": "v2"}, - AirbyteMessage( - type=Type.LOG, - log=AirbyteLogMessage( - level=Level.INFO, - message='request:{"url": "https://airbyte.io/", "http_method": "GET", "headers": {"Content-Type": "application/x-www-form-urlencoded", "Content-Length": "11"}, "body": "b1=v1&b2=v2"}', - ), - ), - ), - ( - "test_basic_post_request", - HttpMethod.POST, - "https://airbyte.io", - {}, - {}, - {}, - {}, - AirbyteMessage( - type=Type.LOG, - log=AirbyteLogMessage( - level=Level.INFO, - message='request:{"url": "https://airbyte.io/", "http_method": "POST", "headers": {"Content-Length": "0"}, "body": null}', - ), - ), - ), - ], -) -def test_prepared_request_to_airbyte_message(test_name, http_method, url, headers, params, body_json, body_data, expected_airbyte_message): - request = requests.Request(method=http_method.name, url=url, headers=headers, params=params) - if body_json: - request.json = body_json - if body_data: - request.data = body_data - prepared_request = request.prepare() - - actual_airbyte_message = _prepared_request_to_airbyte_message(prepared_request) - - assert expected_airbyte_message == actual_airbyte_message - - -@pytest.mark.parametrize( - "test_name, response_body, response_headers, status_code, expected_airbyte_message", - [ - ( - "test_response_no_body_no_headers", - b"", - {}, - 200, - AirbyteMessage( - type=Type.LOG, log=AirbyteLogMessage(level=Level.INFO, message='response:{"body": "", "headers": {}, "status_code": 200}') - ), - ), - ( - "test_response_no_body_with_headers", - b"", - {"h1": "v1", "h2": "v2"}, - 200, - AirbyteMessage( - type=Type.LOG, - log=AirbyteLogMessage( - level=Level.INFO, message='response:{"body": "", "headers": {"h1": "v1", "h2": "v2"}, "status_code": 200}' - ), - ), - ), - ( - "test_response_with_body_no_headers", - b'{"b1": "v1", "b2": "v2"}', - {}, - 200, - AirbyteMessage( - type=Type.LOG, - log=AirbyteLogMessage( - level=Level.INFO, - message='response:{"body": "{\\"b1\\": \\"v1\\", \\"b2\\": \\"v2\\"}", "headers": {}, "status_code": 200}', - ), - ), - ), - ( - "test_response_with_body_and_headers", - b'{"b1": "v1", "b2": "v2"}', - {"h1": "v1", "h2": "v2"}, - 200, - AirbyteMessage( - type=Type.LOG, - log=AirbyteLogMessage( - level=Level.INFO, - message='response:{"body": "{\\"b1\\": \\"v1\\", \\"b2\\": \\"v2\\"}", "headers": {"h1": "v1", "h2": "v2"}, "status_code": 200}', - ), - ), - ), - ], -) -def test_response_to_airbyte_message(test_name, response_body, response_headers, status_code, expected_airbyte_message): - response = requests.Response() - response.status_code = status_code - response.headers = response_headers - response._content = response_body - - actual_airbyte_message = _response_to_airbyte_message(response) - - assert expected_airbyte_message == actual_airbyte_message - - def test_limit_stream_slices(): maximum_number_of_slices = 4 stream_slicer = MagicMock() @@ -818,7 +620,7 @@ def test_given_state_selector_when_read_records_use_slice_state(http_stream_read http_stream_read_pages.assert_called_once_with(retriever.parse_records, A_STREAM_SLICE, A_SLICE_STATE) -def test_emit_log_request_response_messages(): +def test_emit_log_request_response_messages(mocker): record_selector = MagicMock() record_selector.select_records.return_value = records @@ -830,6 +632,8 @@ def test_emit_log_request_response_messages(): response.request = request response.status_code = 200 + format_http_message_mock = mocker.patch("airbyte_cdk.sources.declarative.retrievers.simple_retriever.format_http_message") + message_repository = Mock() retriever = SimpleRetrieverTestReadDecorator( name="stream_name", primary_key=primary_key, @@ -839,19 +643,11 @@ def test_emit_log_request_response_messages(): stream_slicer=SinglePartitionRouter(parameters={}), parameters={}, config={}, + message_repository=message_repository, ) - request_log_message, response_log_message, record_1, record_2 = [ - record for record in retriever.parse_records(request=request, response=response, stream_slice={}, stream_state={}) - ] - - assert isinstance(request_log_message, AirbyteMessage) - assert request_log_message.type == Type.LOG - assert "request:" in request_log_message.log.message - assert isinstance(response_log_message, AirbyteMessage) - assert response_log_message.type == Type.LOG - assert "response:" in response_log_message.log.message - assert isinstance(record_1, Mapping) - assert record_1 == records[0] - assert isinstance(record_1, Mapping) - assert record_2 == records[1] + list(retriever.parse_records(request=request, response=response, stream_slice={}, stream_state={})) + + assert len(message_repository.log_message.call_args_list) == 1 + assert message_repository.log_message.call_args_list[0].args[0] == Level.DEBUG + assert message_repository.log_message.call_args_list[0].args[1]() == format_http_message_mock.return_value diff --git a/airbyte-cdk/python/unit_tests/sources/message/test_repository.py b/airbyte-cdk/python/unit_tests/sources/message/test_repository.py index 59b907aa0de6..b8db5e08e53f 100644 --- a/airbyte-cdk/python/unit_tests/sources/message/test_repository.py +++ b/airbyte-cdk/python/unit_tests/sources/message/test_repository.py @@ -2,63 +2,165 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # +from unittest.mock import Mock + import pytest from airbyte_cdk.models import ( AirbyteControlConnectorConfigMessage, AirbyteControlMessage, AirbyteMessage, AirbyteStateMessage, + Level, OrchestratorType, Type, ) -from airbyte_cdk.sources.message import InMemoryMessageRepository +from airbyte_cdk.sources.message import ( + InMemoryMessageRepository, + LogAppenderMessageRepositoryDecorator, + MessageRepository, + NoopMessageRepository, +) +from pydantic.error_wrappers import ValidationError A_CONTROL = AirbyteControlMessage( type=OrchestratorType.CONNECTOR_CONFIG, emitted_at=0, connectorConfig=AirbyteControlConnectorConfigMessage(config={"a config": "value"}), ) +ANY_MESSAGE = AirbyteMessage(type=Type.CONTROL, control=AirbyteControlMessage( + type=OrchestratorType.CONNECTOR_CONFIG, + emitted_at=0, + connectorConfig=AirbyteControlConnectorConfigMessage(config={"any message": "value"}), +)) ANOTHER_CONTROL = AirbyteControlMessage( type=OrchestratorType.CONNECTOR_CONFIG, emitted_at=0, connectorConfig=AirbyteControlConnectorConfigMessage(config={"another config": "another value"}), ) +UNKNOWN_LEVEL = "potato" + + +class TestInMemoryMessageRepository: + def test_given_no_messages_when_consume_queue_then_return_empty(self): + repo = InMemoryMessageRepository() + messages = list(repo.consume_queue()) + assert messages == [] + + def test_given_messages_when_consume_queue_then_return_messages(self): + repo = InMemoryMessageRepository() + first_message = AirbyteMessage(type=Type.CONTROL, control=A_CONTROL) + repo.emit_message(first_message) + second_message = AirbyteMessage(type=Type.CONTROL, control=ANOTHER_CONTROL) + repo.emit_message(second_message) + + messages = repo.consume_queue() + + assert list(messages) == [first_message, second_message] + + def test_given_message_is_consumed_when_consume_queue_then_remove_message_from_queue(self): + repo = InMemoryMessageRepository() + first_message = AirbyteMessage(type=Type.CONTROL, control=A_CONTROL) + repo.emit_message(first_message) + second_message = AirbyteMessage(type=Type.CONTROL, control=ANOTHER_CONTROL) + repo.emit_message(second_message) + + message_generator = repo.consume_queue() + consumed_message = next(message_generator) + assert consumed_message == first_message + + second_message_generator = repo.consume_queue() + assert list(second_message_generator) == [second_message] + + def test_given_message_is_not_control_nor_log_message_when_emit_message_then_raise_error(self): + repo = InMemoryMessageRepository() + with pytest.raises(ValueError): + repo.emit_message(AirbyteMessage(type=Type.STATE, state=AirbyteStateMessage(data={"state": "state value"}))) + + def test_given_log_level_is_severe_enough_when_log_message_then_allow_message_to_be_consumed(self): + repo = InMemoryMessageRepository(Level.DEBUG) + repo.log_message(Level.INFO, lambda: "this is a log message") + assert list(repo.consume_queue()) + + def test_given_log_level_is_severe_enough_when_log_message_then_filter_secrets(self, mocker): + filtered_message = "a filtered message" + mocker.patch("airbyte_cdk.sources.message.repository.filter_secrets", return_value=filtered_message) + repo = InMemoryMessageRepository(Level.DEBUG) + + repo.log_message(Level.INFO, lambda: "this is a log message") + + assert list(repo.consume_queue())[0].log.message == filtered_message + + def test_given_log_level_not_severe_enough_when_log_message_then_do_not_allow_message_to_be_consumed(self): + repo = InMemoryMessageRepository(Level.ERROR) + repo.log_message(Level.INFO, lambda: "this is a log message") + assert not list(repo.consume_queue()) + + def test_given_unknown_log_level_as_threshold_when_log_message_then_allow_message_to_be_consumed(self): + repo = InMemoryMessageRepository(UNKNOWN_LEVEL) + repo.log_message(Level.DEBUG, lambda: "this is a log message") + assert list(repo.consume_queue()) + + def test_given_unknown_log_level_for_log_when_log_message_then_raise_error(self): + """ + Pydantic will fail if the log level is unknown but on our side, we should try to log at least + """ + repo = InMemoryMessageRepository(Level.ERROR) + with pytest.raises(ValidationError): + repo.log_message(UNKNOWN_LEVEL, lambda: "this is a log message") + + +class TestNoopMessageRepository: + def test_given_message_emitted_when_consume_queue_then_return_empty(self): + repo = NoopMessageRepository() + repo.emit_message(AirbyteMessage(type=Type.CONTROL, control=A_CONTROL)) + repo.log_message(Level.INFO, lambda: "this is a log message") + + assert not list(repo.consume_queue()) -def test_given_no_messages_when_consume_queue_then_return_empty(): - repo = InMemoryMessageRepository() - messages = list(repo.consume_queue()) - assert messages == [] +class TestLogAppenderMessageRepositoryDecorator: + _DICT_TO_APPEND = {"airbyte_cdk": {"stream": {"is_substream": False}}} -def test_given_messages_when_consume_queue_then_return_messages(): - repo = InMemoryMessageRepository() - first_message = AirbyteMessage(type=Type.CONTROL, control=A_CONTROL) - repo.emit_message(first_message) - second_message = AirbyteMessage(type=Type.CONTROL, control=ANOTHER_CONTROL) - repo.emit_message(second_message) + @pytest.fixture() + def decorated(self): + return Mock(spec=MessageRepository) - messages = repo.consume_queue() + def test_when_emit_message_then_delegate_call(self, decorated): + repo = LogAppenderMessageRepositoryDecorator(self._DICT_TO_APPEND, decorated, Level.DEBUG) + repo.emit_message(ANY_MESSAGE) + decorated.emit_message.assert_called_once_with(ANY_MESSAGE) - assert list(messages) == [first_message, second_message] + def test_when_log_message_then_append(self, decorated): + repo = LogAppenderMessageRepositoryDecorator({"a": {"dict_to_append": "appended value"}}, decorated, Level.DEBUG) + repo.log_message(Level.INFO, lambda: {"a": {"original": "original value"}}) + assert decorated.log_message.call_args_list[0].args[1]() == { + "a": { + "dict_to_append": "appended value", + "original": "original value" + } + } + def test_given_value_clash_when_log_message_then_overwrite_value(self, decorated): + repo = LogAppenderMessageRepositoryDecorator({"clash": "appended value"}, decorated, Level.DEBUG) + repo.log_message(Level.INFO, lambda: {"clash": "original value"}) + assert decorated.log_message.call_args_list[0].args[1]() == {"clash": "appended value"} -def test_given_message_is_consumed_when_consume_queue_then_remove_message_from_queue(): - repo = InMemoryMessageRepository() - first_message = AirbyteMessage(type=Type.CONTROL, control=A_CONTROL) - repo.emit_message(first_message) - second_message = AirbyteMessage(type=Type.CONTROL, control=ANOTHER_CONTROL) - repo.emit_message(second_message) + def test_given_log_level_is_severe_enough_when_log_message_then_allow_message_to_be_consumed(self, decorated): + repo = LogAppenderMessageRepositoryDecorator(self._DICT_TO_APPEND, decorated, Level.DEBUG) + repo.log_message(Level.INFO, lambda: {}) + assert decorated.log_message.call_count == 1 - message_generator = repo.consume_queue() - consumed_message = next(message_generator) - assert consumed_message == first_message + def test_given_log_level_not_severe_enough_when_log_message_then_do_not_allow_message_to_be_consumed(self, decorated): + repo = LogAppenderMessageRepositoryDecorator(self._DICT_TO_APPEND, decorated, Level.ERROR) + repo.log_message(Level.INFO, lambda: {}) + assert decorated.log_message.call_count == 0 - second_message_generator = repo.consume_queue() - assert list(second_message_generator) == [second_message] + def test_when_consume_queue_then_return_delegate_queue(self, decorated): + repo = LogAppenderMessageRepositoryDecorator(self._DICT_TO_APPEND, decorated, Level.DEBUG) + queue = [ANY_MESSAGE, ANY_MESSAGE, ANY_MESSAGE] + decorated.consume_queue.return_value = iter(queue) + result = list(repo.consume_queue()) -def test_given_message_is_not_control_nor_log_message_when_emit_message_then_raise_error(): - repo = InMemoryMessageRepository() - with pytest.raises(ValueError): - repo.emit_message(AirbyteMessage(type=Type.STATE, state=AirbyteStateMessage(data={"state": "state value"}))) + assert result == queue diff --git a/airbyte-cdk/python/unit_tests/sources/streams/http/requests_native_auth/test_requests_native_auth.py b/airbyte-cdk/python/unit_tests/sources/streams/http/requests_native_auth/test_requests_native_auth.py index 40fc087ab926..df2eb08e8464 100644 --- a/airbyte-cdk/python/unit_tests/sources/streams/http/requests_native_auth/test_requests_native_auth.py +++ b/airbyte-cdk/python/unit_tests/sources/streams/http/requests_native_auth/test_requests_native_auth.py @@ -272,7 +272,7 @@ def test_given_no_message_repository_get_access_token(self, test_name, expires_i assert not captured.out assert authenticator.access_token == access_token == "new_access_token" - def test_given_message_repository_when_get_access_token_emit_message(self, mocker, connector_config): + def test_given_message_repository_when_get_access_token_then_emit_message(self, mocker, connector_config): message_repository = Mock() authenticator = SingleUseRefreshTokenOauth2Authenticator( connector_config, @@ -296,6 +296,23 @@ def test_given_message_repository_when_get_access_token_emit_message(self, mocke assert emitted_message.control.connectorConfig.config["credentials"]["client_id"] == "my_client_id" assert emitted_message.control.connectorConfig.config["credentials"]["client_secret"] == "my_client_secret" + def test_given_message_repository_when_get_access_token_then_log_request(self, mocker, connector_config): + message_repository = Mock() + authenticator = SingleUseRefreshTokenOauth2Authenticator( + connector_config, + token_refresh_endpoint="foobar", + client_id=connector_config["credentials"]["client_id"], + client_secret=connector_config["credentials"]["client_secret"], + message_repository=message_repository, + ) + mocker.patch("airbyte_cdk.sources.streams.http.requests_native_auth.abstract_oauth.requests.request") + mocker.patch("airbyte_cdk.sources.streams.http.requests_native_auth.abstract_oauth.format_http_message", return_value="formatted json") + authenticator.token_has_expired = mocker.Mock(return_value=True) + + authenticator.get_access_token() + + assert message_repository.log_message.call_count == 1 + def test_refresh_access_token(self, mocker, connector_config): authenticator = SingleUseRefreshTokenOauth2Authenticator( connector_config, diff --git a/airbyte-cdk/python/unit_tests/sources/test_http_logger.py b/airbyte-cdk/python/unit_tests/sources/test_http_logger.py new file mode 100644 index 000000000000..a79a5216e2eb --- /dev/null +++ b/airbyte-cdk/python/unit_tests/sources/test_http_logger.py @@ -0,0 +1,176 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import pytest +import requests +from airbyte_cdk.sources.http_logger import format_http_message + +A_TITLE = "a title" +A_DESCRIPTION = "a description" +A_STREAM_NAME = "a stream name" +ANY_REQUEST = requests.Request(method="POST", url="http://a-url.com", headers={}, params={}).prepare() + + +class ResponseBuilder: + def __init__(self): + self._body_content = "" + self._headers = {} + self._request = ANY_REQUEST + self._status_code = 100 + + def body_content(self, body_content: bytes) -> "ResponseBuilder": + self._body_content = body_content + return self + + def headers(self, headers: dict) -> "ResponseBuilder": + self._headers = headers + return self + + def request(self, request: requests.PreparedRequest) -> "ResponseBuilder": + self._request = request + return self + + def status_code(self, status_code: int) -> "ResponseBuilder": + self._status_code = status_code + return self + + def build(self): + response = requests.Response() + response._content = self._body_content + response.headers = self._headers + response.request = self._request + response.status_code = self._status_code + return response + + +EMPTY_RESPONSE = {"body": {"content": ""}, "headers": {}, "status_code": 100} + + +@pytest.mark.parametrize( + "test_name, http_method, url, headers, params, body_json, body_data, expected_airbyte_message", + [ + ( + "test_basic_get_request", + "GET", + "https://airbyte.io", + {}, + {}, + {}, + {}, + {"airbyte_cdk": {"stream": {"name": A_STREAM_NAME}}, "http": {"title": A_TITLE, "description": A_DESCRIPTION, "request": {"method": "GET", "body": {"content": None}, "headers": {}}, "response": EMPTY_RESPONSE}, "log": {"level": "debug"}, "url": {"full": "https://airbyte.io/"}}, + ), + ( + "test_get_request_with_headers", + "GET", + "https://airbyte.io", + {"h1": "v1", "h2": "v2"}, + {}, + {}, + {}, + {"airbyte_cdk": {"stream": {"name": A_STREAM_NAME}}, "http": {"title": A_TITLE, "description": A_DESCRIPTION, "request": {"method": "GET", "body": {"content": None}, "headers": {"h1": "v1", "h2": "v2"}}, "response": EMPTY_RESPONSE}, "log": {"level": "debug"}, "url": {"full": "https://airbyte.io/"}}, + ), + ( + "test_get_request_with_request_params", + "GET", + "https://airbyte.io", + {}, + {"p1": "v1", "p2": "v2"}, + {}, + {}, + {"airbyte_cdk": {"stream": {"name": A_STREAM_NAME}}, "http": {"title": A_TITLE, "description": A_DESCRIPTION, "request": {"method": "GET", "body": {"content": None}, "headers": {}}, "response": EMPTY_RESPONSE}, "log": {"level": "debug"}, "url": {"full": "https://airbyte.io/?p1=v1&p2=v2"}}, + ), + ( + "test_get_request_with_request_body_json", + "GET", + "https://airbyte.io", + {"Content-Type": "application/json"}, + {}, + {"b1": "v1", "b2": "v2"}, + {}, + {"airbyte_cdk": {"stream": {"name": A_STREAM_NAME}}, "http": {"title": A_TITLE, "description": A_DESCRIPTION, "request": {"method": "GET", "body": {"content": '{"b1": "v1", "b2": "v2"}'}, "headers": {"Content-Type": "application/json", "Content-Length": "24"}}, "response": EMPTY_RESPONSE}, "log": {"level": "debug"}, "url": {"full": "https://airbyte.io/"}} + ), + ( + "test_get_request_with_headers_params_and_body", + "GET", + "https://airbyte.io", + {"Content-Type": "application/json", "h1": "v1"}, + {"p1": "v1", "p2": "v2"}, + {"b1": "v1", "b2": "v2"}, + {}, + {"airbyte_cdk": {"stream": {"name": A_STREAM_NAME}}, "http": {"title": A_TITLE, "description": A_DESCRIPTION, "request": {"method": "GET", "body": {"content": '{"b1": "v1", "b2": "v2"}'}, "headers": {"Content-Type": "application/json", "Content-Length": "24", "h1": "v1"}}, "response": EMPTY_RESPONSE}, "log": {"level": "debug"}, "url": {"full": "https://airbyte.io/?p1=v1&p2=v2"}}, + ), + ( + "test_get_request_with_request_body_data", + "GET", + "https://airbyte.io", + {"Content-Type": "application/x-www-form-urlencoded"}, + {}, + {}, + {"b1": "v1", "b2": "v2"}, + {"airbyte_cdk": {"stream": {"name": A_STREAM_NAME}}, "http": {"title": A_TITLE, "description": A_DESCRIPTION, "request": {"method": "GET", "body": {"content": "b1=v1&b2=v2"}, "headers": {"Content-Type": "application/x-www-form-urlencoded", "Content-Length": "11"}}, "response": EMPTY_RESPONSE}, "log": {"level": "debug"}, "url": {"full": "https://airbyte.io/"}}, + ), + ( + "test_basic_post_request", + "POST", + "https://airbyte.io", + {}, + {}, + {}, + {}, + {"airbyte_cdk": {"stream": {"name": A_STREAM_NAME}}, "http": {"title": A_TITLE, "description": A_DESCRIPTION, "request": {"method": "POST", "body": {"content": None}, "headers": {"Content-Length": "0"}}, "response": EMPTY_RESPONSE}, "log": {"level": "debug"}, "url": {"full": "https://airbyte.io/"}} + ), + ], +) +def test_prepared_request_to_airbyte_message(test_name, http_method, url, headers, params, body_json, body_data, expected_airbyte_message): + request = requests.Request(method=http_method, url=url, headers=headers, params=params) + if body_json: + request.json = body_json + if body_data: + request.data = body_data + prepared_request = request.prepare() + + actual_airbyte_message = format_http_message(ResponseBuilder().request(prepared_request).build(), A_TITLE, A_DESCRIPTION, A_STREAM_NAME) + + assert actual_airbyte_message == expected_airbyte_message + + +@pytest.mark.parametrize( + "test_name, response_body, response_headers, status_code, expected_airbyte_message", + [ + ( + "test_response_no_body_no_headers", + b"", + {}, + 200, + {"body": {"content": ""}, "headers": {}, "status_code": 200} + ), + ( + "test_response_no_body_with_headers", + b"", + {"h1": "v1", "h2": "v2"}, + 200, + {"body": {"content": ""}, "headers": {"h1": "v1", "h2": "v2"}, "status_code": 200} + ), + ( + "test_response_with_body_no_headers", + b'{"b1": "v1", "b2": "v2"}', + {}, + 200, + {"body": {"content": '{"b1": "v1", "b2": "v2"}'}, "headers": {}, "status_code": 200} + ), + ( + "test_response_with_body_and_headers", + b'{"b1": "v1", "b2": "v2"}', + {"h1": "v1", "h2": "v2"}, + 200, + {"body": {"content": '{"b1": "v1", "b2": "v2"}'}, "headers": {"h1": "v1", "h2": "v2"}, "status_code": 200} + ), + ], +) +def test_response_to_airbyte_message(test_name, response_body, response_headers, status_code, expected_airbyte_message): + response = ResponseBuilder().body_content(response_body).headers(response_headers).status_code(status_code).build() + + actual_airbyte_message = format_http_message(response, A_TITLE, A_DESCRIPTION, A_STREAM_NAME) + + assert actual_airbyte_message["http"]["response"] == expected_airbyte_message From 07da56914fa241e3f7023f4e511ee40f21267f0c Mon Sep 17 00:00:00 2001 From: maxi297 Date: Tue, 11 Jul 2023 17:43:50 +0000 Subject: [PATCH 23/63] =?UTF-8?q?=F0=9F=A4=96=20Bump=20patch=20version=20o?= =?UTF-8?q?f=20Airbyte=20CDK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- airbyte-cdk/python/.bumpversion.cfg | 2 +- airbyte-cdk/python/CHANGELOG.md | 3 +++ airbyte-cdk/python/Dockerfile | 4 ++-- airbyte-cdk/python/setup.py | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/airbyte-cdk/python/.bumpversion.cfg b/airbyte-cdk/python/.bumpversion.cfg index c17696a5f968..f99168016763 100644 --- a/airbyte-cdk/python/.bumpversion.cfg +++ b/airbyte-cdk/python/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.44.3 +current_version = 0.44.4 commit = False [bumpversion:file:setup.py] diff --git a/airbyte-cdk/python/CHANGELOG.md b/airbyte-cdk/python/CHANGELOG.md index 372a4e83cb8b..4a2890e08a16 100644 --- a/airbyte-cdk/python/CHANGELOG.md +++ b/airbyte-cdk/python/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## 0.44.4 +Connector builder: Show all request/responses as part of the testing panel + ## 0.44.3 [ISSUE #27494] allow for state to rely on transformed field diff --git a/airbyte-cdk/python/Dockerfile b/airbyte-cdk/python/Dockerfile index e58f12843187..933b5030834a 100644 --- a/airbyte-cdk/python/Dockerfile +++ b/airbyte-cdk/python/Dockerfile @@ -10,7 +10,7 @@ RUN apk --no-cache upgrade \ && apk --no-cache add tzdata build-base # install airbyte-cdk -RUN pip install --prefix=/install airbyte-cdk==0.44.3 +RUN pip install --prefix=/install airbyte-cdk==0.44.4 # build a clean environment FROM base @@ -32,5 +32,5 @@ ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] # needs to be the same as CDK -LABEL io.airbyte.version=0.44.3 +LABEL io.airbyte.version=0.44.4 LABEL io.airbyte.name=airbyte/source-declarative-manifest diff --git a/airbyte-cdk/python/setup.py b/airbyte-cdk/python/setup.py index c79904f514e7..15d763841cf7 100644 --- a/airbyte-cdk/python/setup.py +++ b/airbyte-cdk/python/setup.py @@ -17,7 +17,7 @@ name="airbyte-cdk", # The version of the airbyte-cdk package is used at runtime to validate manifests. That validation must be # updated if our semver format changes such as using release candidate versions. - version="0.44.3", + version="0.44.4", description="A framework for writing Airbyte Connectors.", long_description=README, long_description_content_type="text/markdown", From 0ca1c4bd05beed0447754d8b2658ffca23930fd5 Mon Sep 17 00:00:00 2001 From: Maxime Carbonneau-Leclerc Date: Tue, 11 Jul 2023 13:50:20 -0400 Subject: [PATCH 24/63] =?UTF-8?q?=F0=9F=90=9B=20Source=20Apple=20Search=20?= =?UTF-8?q?Ads:=20manifest.yaml=20duplicate=20key=20error=20(#28153)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix source-apple-search-ads manifest.yaml duplicate key error * version bump --- .../connectors/source-apple-search-ads/Dockerfile | 2 +- .../connectors/source-apple-search-ads/metadata.yaml | 2 +- .../source_apple_search_ads/manifest.yaml | 1 - docs/integrations/sources/apple-search-ads.md | 3 ++- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/airbyte-integrations/connectors/source-apple-search-ads/Dockerfile b/airbyte-integrations/connectors/source-apple-search-ads/Dockerfile index 2f1b015660a1..f82a8effc8e4 100644 --- a/airbyte-integrations/connectors/source-apple-search-ads/Dockerfile +++ b/airbyte-integrations/connectors/source-apple-search-ads/Dockerfile @@ -34,5 +34,5 @@ COPY source_apple_search_ads ./source_apple_search_ads ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=0.1.0 +LABEL io.airbyte.version=0.1.1 LABEL io.airbyte.name=airbyte/source-apple-search-ads diff --git a/airbyte-integrations/connectors/source-apple-search-ads/metadata.yaml b/airbyte-integrations/connectors/source-apple-search-ads/metadata.yaml index 98fbc20ceb44..854fc52e4120 100644 --- a/airbyte-integrations/connectors/source-apple-search-ads/metadata.yaml +++ b/airbyte-integrations/connectors/source-apple-search-ads/metadata.yaml @@ -2,7 +2,7 @@ data: connectorSubtype: api connectorType: source definitionId: e59c8416-c2fa-4bd3-9e95-52677ea281c1 - dockerImageTag: 0.1.0 + dockerImageTag: 0.1.1 dockerRepository: airbyte/source-apple-search-ads githubIssueLabel: source-apple-search-ads icon: apple.svg diff --git a/airbyte-integrations/connectors/source-apple-search-ads/source_apple_search_ads/manifest.yaml b/airbyte-integrations/connectors/source-apple-search-ads/source_apple_search_ads/manifest.yaml index 8df0dc8934a1..d0ff359a64c4 100644 --- a/airbyte-integrations/connectors/source-apple-search-ads/source_apple_search_ads/manifest.yaml +++ b/airbyte-integrations/connectors/source-apple-search-ads/source_apple_search_ads/manifest.yaml @@ -94,7 +94,6 @@ definitions: cursor_granularity: "P1D" cursor_field: "date" lookback_window: "P30D" - datetime_format: "%Y-%m-%d" report_stream: selector: diff --git a/docs/integrations/sources/apple-search-ads.md b/docs/integrations/sources/apple-search-ads.md index f1c6e9ea9580..cf1423033a52 100644 --- a/docs/integrations/sources/apple-search-ads.md +++ b/docs/integrations/sources/apple-search-ads.md @@ -46,5 +46,6 @@ However, at this moment and as indicated in the stream names, the connector only ## Changelog | Version | Date | Pull Request | Subject | -| :------ |:-----------|:--------------------------------------------------------|:-------------------------------------------------------------------------------------| +|:--------|:-----------|:--------------------------------------------------------|:-------------------------------------------------------------------------------------| +| 0.1.1 | 2023-07-11 | [28153](https://github.com/airbytehq/airbyte/pull/28153) | Fix manifest duplicate key (no change in behavior for the syncs) | | 0.1.0 | 2022-11-17 | [19557](https://github.com/airbytehq/airbyte/pull/19557) | Initial release with campaigns, adgroups & keywords streams (base and daily reports) | From 98d175c7a92087f973ef140b560f376a955cf52f Mon Sep 17 00:00:00 2001 From: Arsen Losenko <20901439+arsenlosenko@users.noreply.github.com> Date: Tue, 11 Jul 2023 21:13:19 +0300 Subject: [PATCH 25/63] Source Faker: update expected records (#28146) --- .../source-faker/integration_tests/expected_records.jsonl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/airbyte-integrations/connectors/source-faker/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-faker/integration_tests/expected_records.jsonl index 9a171b604f7b..ac354808125f 100644 --- a/airbyte-integrations/connectors/source-faker/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-faker/integration_tests/expected_records.jsonl @@ -1,9 +1,9 @@ {"stream": "users", "data": {"id": 1, "created_at": "2004-10-28T02:16:07+00:00", "updated_at": "2014-08-21T12:50:13+00:00", "name": "Rudolf", "title": "M.Des", "age": 66, "email": "wisconsin1930+1@yandex.com", "telephone": "(483) 676-2851", "gender": "Fluid", "language": "Arabic", "academic_degree": "Bachelor", "nationality": "Argentinian", "occupation": "Valve Technician", "height": "1.50", "blood_type": "B\u2212", "weight": 81, "address": {"street_number": "276", "street_name": "Yukon", "city": "Wooster", "state": "Wisconsin", "province": "California", "postal_code": "24467", "country_code": "BI"}}, "emitted_at": 1683605758599} {"stream": "users", "data": {"id": 2, "created_at": "2000-12-15T08:46:51+00:00", "updated_at": "2015-01-29T12:27:38+00:00", "name": "Orville", "title": "Miss", "age": 30, "email": "recipes2070+2@yahoo.com", "telephone": "994.991.6727", "gender": "Other", "language": "Montenegrin", "academic_degree": "PhD", "nationality": "Costa Rican", "occupation": "Optical Advisor", "height": "1.64", "blood_type": "AB\u2212", "weight": 70, "address": {"street_number": "1000", "street_name": "Avenue E", "city": "Wilkinsburg", "state": "Missouri", "province": "Nevada", "postal_code": "67628", "country_code": "MT"}}, "emitted_at": 1683605758599} {"stream": "users", "data": {"id": 3, "created_at": "2017-01-31T12:43:13+00:00", "updated_at": "2018-02-11T00:01:01+00:00", "name": "Rachell", "title": "M.A.", "age": 21, "email": "assets1924+3@protonmail.com", "telephone": "+1-(118)-374-3865", "gender": "Female", "language": "Dutch", "academic_degree": "PhD", "nationality": "Danish", "occupation": "Aeronautical Engineer", "height": "1.89", "blood_type": "AB+", "weight": 63, "address": {"street_number": "210", "street_name": "Lysette", "city": "Arlington Heights", "state": "Alaska", "province": "Alaska", "postal_code": "60869", "country_code": "QA"}}, "emitted_at": 1683605758599} -{"stream": "purchases", "data": {"id": 1, "product_id": 8, "user_id": 1, "added_to_cart_at": "2003-02-23T11:53:10+00:00", "purchased_at": "2011-03-30T11:53:10+00:00", "returned_at": null}, "emitted_at": 1683605758786} -{"stream": "purchases", "data": {"id": 2, "product_id": 95, "user_id": 2, "added_to_cart_at": "2023-05-20T13:40:25+00:00", "purchased_at": null, "returned_at": null}, "emitted_at": 1683605758786} -{"stream": "purchases", "data": {"id": 3, "product_id": 40, "user_id": 3, "added_to_cart_at": "2013-09-18T00:23:29+00:00", "purchased_at": null, "returned_at": null}, "emitted_at": 1683605758786} +{"stream": "purchases", "data": {"id": 1, "product_id": 8, "user_id": 1, "created_at": "2001-02-03T11:53:10.771720", "updated_at": "2023-07-11T12:21:28+00:00", "added_to_cart_at": "2005-03-14T11:53:10+00:00", "purchased_at": "2013-04-18T11:53:10+00:00", "returned_at": null}, "emitted_at": 1689067288181} +{"stream": "purchases", "data": {"id": 2, "product_id": 95, "user_id": 2, "created_at": "2018-11-06T13:40:25.842708", "updated_at": "2023-07-11T12:21:28+00:00", "added_to_cart_at": "2023-05-20T13:40:25+00:00", "purchased_at": null, "returned_at": null}, "emitted_at": 1689067288181} +{"stream": "purchases", "data": {"id": 3, "product_id": 40, "user_id": 3, "created_at": "2008-01-28T00:23:29.977111", "updated_at": "2023-07-11T12:21:28+00:00", "added_to_cart_at": "2013-09-18T00:23:29+00:00", "purchased_at": null, "returned_at": null}, "emitted_at": 1689067288181} {"stream": "products", "data": {"id": 1, "make": "Mazda", "model": "MX-5", "year": 2008, "price": 2869, "created_at": "2022-02-01T17:02:19+00:00"}, "emitted_at": 1682937993845} {"stream": "products", "data": {"id": 2, "make": "Mercedes-Benz", "model": "C-Class", "year": 2009, "price": 42397, "created_at": "2021-01-25T14:31:33+00:00"}, "emitted_at": 1682937993846} {"stream": "products", "data": {"id": 3, "make": "Honda", "model": "Accord Crosstour", "year": 2011, "price": 63293, "created_at": "2021-02-11T05:36:03+00:00"}, "emitted_at": 1682937993846} From 9cd5ee701c63ccd1262f3bf37ed047d567c98eb5 Mon Sep 17 00:00:00 2001 From: Arsen Losenko <20901439+arsenlosenko@users.noreply.github.com> Date: Tue, 11 Jul 2023 21:13:36 +0300 Subject: [PATCH 26/63] =?UTF-8?q?=F0=9F=90=9B=20Source=20Github:=20update?= =?UTF-8?q?=20schema=20for=20Organizations=20stream=20(#28144)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Source Github: update schema for Organizations stream * Update changelog --- airbyte-integrations/connectors/source-github/Dockerfile | 2 +- .../source-github/integration_tests/expected_records.jsonl | 4 ++-- airbyte-integrations/connectors/source-github/metadata.yaml | 2 +- .../source-github/source_github/schemas/organizations.json | 4 ++++ docs/integrations/sources/github.md | 1 + 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/airbyte-integrations/connectors/source-github/Dockerfile b/airbyte-integrations/connectors/source-github/Dockerfile index 34031d113a8c..f7a3137e9d29 100644 --- a/airbyte-integrations/connectors/source-github/Dockerfile +++ b/airbyte-integrations/connectors/source-github/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=1.0.1 +LABEL io.airbyte.version=1.0.2 LABEL io.airbyte.name=airbyte/source-github diff --git a/airbyte-integrations/connectors/source-github/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-github/integration_tests/expected_records.jsonl index 422d84fc85bc..29cd3d9ba4a7 100644 --- a/airbyte-integrations/connectors/source-github/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-github/integration_tests/expected_records.jsonl @@ -12,7 +12,7 @@ {"stream":"issue_milestones","data":{"url":"https://api.github.com/repos/airbytehq/integration-test/milestones/1","html_url":"https://github.com/airbytehq/integration-test/milestone/1","labels_url":"https://api.github.com/repos/airbytehq/integration-test/milestones/1/labels","id":7097357,"node_id":"MI_kwDOF9hP9c4AbEwN","number":1,"title":"main","description":null,"creator":{"login":"gaart","id":743901,"node_id":"MDQ6VXNlcjc0MzkwMQ==","avatar_url":"https://avatars.githubusercontent.com/u/743901?v=4","gravatar_id":"","url":"https://api.github.com/users/gaart","html_url":"https://github.com/gaart","followers_url":"https://api.github.com/users/gaart/followers","following_url":"https://api.github.com/users/gaart/following{/other_user}","gists_url":"https://api.github.com/users/gaart/gists{/gist_id}","starred_url":"https://api.github.com/users/gaart/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gaart/subscriptions","organizations_url":"https://api.github.com/users/gaart/orgs","repos_url":"https://api.github.com/users/gaart/repos","events_url":"https://api.github.com/users/gaart/events{/privacy}","received_events_url":"https://api.github.com/users/gaart/received_events","type":"User","site_admin":false},"open_issues":3,"closed_issues":1,"state":"open","created_at":"2021-08-27T15:43:44Z","updated_at":"2021-08-27T16:02:49Z","due_on":null,"closed_at":null,"repository":"airbytehq/integration-test"},"emitted_at":1677668751023} {"stream":"issue_reactions","data":{"node_id":"MDEzOklzc3VlUmVhY3Rpb24xMjcwNDg0NTY=","id":127048456,"content":"ROCKET","created_at":"2021-09-06T11:13:32Z","user":{"node_id":"MDQ6VXNlcjM0MTAzMTI1","id":34103125,"login":"yevhenii-ldv","avatar_url":"https://avatars.githubusercontent.com/u/34103125?u=3e49bb73177a9f70896e3d49b34656ab659c70a5&v=4","html_url":"https://github.com/yevhenii-ldv","site_admin":false,"type":"User"},"repository":"airbytehq/integration-test","issue_number":11},"emitted_at":1677668751465} {"stream":"issues","data":{"url":"https://api.github.com/repos/airbytehq/integration-test/issues/14","repository_url":"https://api.github.com/repos/airbytehq/integration-test","labels_url":"https://api.github.com/repos/airbytehq/integration-test/issues/14/labels{/name}","comments_url":"https://api.github.com/repos/airbytehq/integration-test/issues/14/comments","events_url":"https://api.github.com/repos/airbytehq/integration-test/issues/14/events","html_url":"https://github.com/airbytehq/integration-test/pull/14","id":1291262400,"node_id":"PR_kwDOF9hP9c46s2Qa","number":14,"title":"New PR from feature/branch_5","user":{"login":"grubberr","id":195743,"node_id":"MDQ6VXNlcjE5NTc0Mw==","avatar_url":"https://avatars.githubusercontent.com/u/195743?v=4","gravatar_id":"","url":"https://api.github.com/users/grubberr","html_url":"https://github.com/grubberr","followers_url":"https://api.github.com/users/grubberr/followers","following_url":"https://api.github.com/users/grubberr/following{/other_user}","gists_url":"https://api.github.com/users/grubberr/gists{/gist_id}","starred_url":"https://api.github.com/users/grubberr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/grubberr/subscriptions","organizations_url":"https://api.github.com/users/grubberr/orgs","repos_url":"https://api.github.com/users/grubberr/repos","events_url":"https://api.github.com/users/grubberr/events{/privacy}","received_events_url":"https://api.github.com/users/grubberr/received_events","type":"User","site_admin":false},"labels":[{"id":3984065862,"node_id":"LA_kwDOF9hP9c7teAVG","url":"https://api.github.com/repos/airbytehq/integration-test/labels/labeler","name":"labeler","color":"ededed","default":false,"description":null}],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2022-07-01T11:05:28Z","updated_at":"2022-10-04T17:41:29Z","closed_at":null,"author_association":"MEMBER","active_lock_reason":null,"draft":false,"pull_request":{"url":"https://api.github.com/repos/airbytehq/integration-test/pulls/14","html_url":"https://github.com/airbytehq/integration-test/pull/14","diff_url":"https://github.com/airbytehq/integration-test/pull/14.diff","patch_url":"https://github.com/airbytehq/integration-test/pull/14.patch","merged_at":null},"body":"Signed-off-by: Sergey Chvalyuk ","reactions":{"url":"https://api.github.com/repos/airbytehq/integration-test/issues/14/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"timeline_url":"https://api.github.com/repos/airbytehq/integration-test/issues/14/timeline","performed_via_github_app":null,"state_reason":null,"repository":"airbytehq/integration-test"},"emitted_at":1677668752186} -{"stream":"organizations","data":{"login":"airbytehq","id":59758427,"node_id":"MDEyOk9yZ2FuaXphdGlvbjU5NzU4NDI3","url":"https://api.github.com/orgs/airbytehq","repos_url":"https://api.github.com/orgs/airbytehq/repos","events_url":"https://api.github.com/orgs/airbytehq/events","hooks_url":"https://api.github.com/orgs/airbytehq/hooks","issues_url":"https://api.github.com/orgs/airbytehq/issues","members_url":"https://api.github.com/orgs/airbytehq/members{/member}","public_members_url":"https://api.github.com/orgs/airbytehq/public_members{/member}","avatar_url":"https://avatars.githubusercontent.com/u/59758427?v=4","description":"Simple & extensible open-source data integration","name":"Airbyte","company":null,"blog":"https://airbyte.io","location":"United States of America","email":"contact@airbyte.io","twitter_username":"AirbyteHQ","is_verified":true,"has_organization_projects":true,"has_repository_projects":true,"public_repos":34,"public_gists":0,"followers":199,"following":0,"html_url":"https://github.com/airbytehq","created_at":"2020-01-11T06:27:48Z","updated_at":"2023-02-06T21:57:02Z","type":"Organization","total_private_repos":43,"owned_private_repos":41,"private_gists":null,"disk_usage":null,"collaborators":null,"billing_email":null,"default_repository_permission":null,"members_can_create_repositories":true,"two_factor_requirement_enabled":null,"members_allowed_repository_creation_type":"all","members_can_create_public_repositories":true,"members_can_create_private_repositories":true,"members_can_create_internal_repositories":false,"members_can_create_pages":true,"members_can_fork_private_repositories":false,"web_commit_signoff_required":false,"members_can_create_public_pages":true,"members_can_create_private_pages":true,"plan":{"name":"team","space":976562499,"private_repos":999999,"filled_seats":125,"seats":135}},"emitted_at":1677668752546} +{"stream": "organizations", "data": {"login": "airbytehq", "id": 59758427, "node_id": "MDEyOk9yZ2FuaXphdGlvbjU5NzU4NDI3", "url": "https://api.github.com/orgs/airbytehq", "repos_url": "https://api.github.com/orgs/airbytehq/repos", "events_url": "https://api.github.com/orgs/airbytehq/events", "hooks_url": "https://api.github.com/orgs/airbytehq/hooks", "issues_url": "https://api.github.com/orgs/airbytehq/issues", "members_url": "https://api.github.com/orgs/airbytehq/members{/member}", "public_members_url": "https://api.github.com/orgs/airbytehq/public_members{/member}", "avatar_url": "https://avatars.githubusercontent.com/u/59758427?v=4", "description": "Simple & extensible open-source data integration", "name": "Airbyte", "company": null, "blog": "https://airbyte.io", "location": "United States of America", "email": "contact@airbyte.io", "twitter_username": "AirbyteHQ", "is_verified": true, "has_organization_projects": true, "has_repository_projects": true, "public_repos": 46, "public_gists": 0, "followers": 267, "following": 0, "html_url": "https://github.com/airbytehq", "created_at": "2020-01-11T06:27:48Z", "updated_at": "2023-05-03T17:28:12Z", "archived_at": null, "type": "Organization", "total_private_repos": 57, "owned_private_repos": 55, "private_gists": null, "disk_usage": null, "collaborators": null, "billing_email": null, "default_repository_permission": null, "members_can_create_repositories": true, "two_factor_requirement_enabled": null, "members_allowed_repository_creation_type": "all", "members_can_create_public_repositories": true, "members_can_create_private_repositories": true, "members_can_create_internal_repositories": false, "members_can_create_pages": true, "members_can_fork_private_repositories": false, "web_commit_signoff_required": false, "members_can_create_public_pages": true, "members_can_create_private_pages": true, "plan": {"name": "team", "space": 976562499, "private_repos": 999999, "filled_seats": 116, "seats": 118}}, "emitted_at": 1689065014314} {"stream":"project_cards","data":{"url":"https://api.github.com/projects/columns/cards/77859890","project_url":"https://api.github.com/projects/13167124","id":77859890,"node_id":"PRC_lALOF9hP9c4AyOoUzgSkDDI","note":"note_1","archived":false,"creator":{"login":"grubberr","id":195743,"node_id":"MDQ6VXNlcjE5NTc0Mw==","avatar_url":"https://avatars.githubusercontent.com/u/195743?v=4","gravatar_id":"","url":"https://api.github.com/users/grubberr","html_url":"https://github.com/grubberr","followers_url":"https://api.github.com/users/grubberr/followers","following_url":"https://api.github.com/users/grubberr/following{/other_user}","gists_url":"https://api.github.com/users/grubberr/gists{/gist_id}","starred_url":"https://api.github.com/users/grubberr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/grubberr/subscriptions","organizations_url":"https://api.github.com/users/grubberr/orgs","repos_url":"https://api.github.com/users/grubberr/repos","events_url":"https://api.github.com/users/grubberr/events{/privacy}","received_events_url":"https://api.github.com/users/grubberr/received_events","type":"User","site_admin":false},"created_at":"2022-02-17T09:56:51Z","updated_at":"2022-02-17T09:56:51Z","column_url":"https://api.github.com/projects/columns/17807006","repository":"airbytehq/integration-test","project_id":13167124,"column_id":17807006},"emitted_at":1677668754200} {"stream":"project_columns","data":{"url":"https://api.github.com/projects/columns/17807092","project_url":"https://api.github.com/projects/13167124","cards_url":"https://api.github.com/projects/columns/17807092/cards","id":17807092,"node_id":"PC_lATOF9hP9c4AyOoUzgEPtvQ","name":"column_2","created_at":"2022-02-17T09:57:27Z","updated_at":"2022-02-17T09:57:27Z","repository":"airbytehq/integration-test","project_id":13167124},"emitted_at":1677668754456} {"stream":"projects","data":{"owner_url":"https://api.github.com/repos/airbytehq/integration-test","url":"https://api.github.com/projects/13167124","html_url":"https://github.com/airbytehq/integration-test/projects/3","columns_url":"https://api.github.com/projects/13167124/columns","id":13167124,"node_id":"PRO_kwLOF9hP9c4AyOoU","name":"project_3","body":null,"number":3,"state":"open","creator":{"login":"gaart","id":743901,"node_id":"MDQ6VXNlcjc0MzkwMQ==","avatar_url":"https://avatars.githubusercontent.com/u/743901?v=4","gravatar_id":"","url":"https://api.github.com/users/gaart","html_url":"https://github.com/gaart","followers_url":"https://api.github.com/users/gaart/followers","following_url":"https://api.github.com/users/gaart/following{/other_user}","gists_url":"https://api.github.com/users/gaart/gists{/gist_id}","starred_url":"https://api.github.com/users/gaart/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gaart/subscriptions","organizations_url":"https://api.github.com/users/gaart/orgs","repos_url":"https://api.github.com/users/gaart/repos","events_url":"https://api.github.com/users/gaart/events{/privacy}","received_events_url":"https://api.github.com/users/gaart/received_events","type":"User","site_admin":false},"created_at":"2021-08-27T15:43:57Z","updated_at":"2022-02-17T12:16:56Z","repository":"airbytehq/integration-test"},"emitted_at":1677668754468} @@ -21,7 +21,7 @@ {"stream":"pull_request_stats","data":{"node_id":"MDExOlB1bGxSZXF1ZXN0NzIxNDM1NTA2","id":721435506,"number":5,"updated_at":"2021-08-27T15:53:14Z","changed_files":5,"deletions":0,"additions":5,"merged":false,"mergeable":"MERGEABLE","can_be_rebased":true,"maintainer_can_modify":false,"merge_state_status":"BLOCKED","comments":0,"commits":5,"review_comments":0,"merged_by":null,"repository":"airbytehq/integration-test"},"emitted_at":1677668759962} {"stream": "pull_requests", "data": {"url": "https://api.github.com/repos/airbytehq/integration-test/pulls/5", "id": 721435506, "node_id": "MDExOlB1bGxSZXF1ZXN0NzIxNDM1NTA2", "html_url": "https://github.com/airbytehq/integration-test/pull/5", "diff_url": "https://github.com/airbytehq/integration-test/pull/5.diff", "patch_url": "https://github.com/airbytehq/integration-test/pull/5.patch", "issue_url": "https://api.github.com/repos/airbytehq/integration-test/issues/5", "number": 5, "state": "open", "locked": false, "title": "New PR from feature/branch_4", "user": {"login": "gaart", "id": 743901, "node_id": "MDQ6VXNlcjc0MzkwMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/743901?v=4", "gravatar_id": "", "url": "https://api.github.com/users/gaart", "html_url": "https://github.com/gaart", "followers_url": "https://api.github.com/users/gaart/followers", "following_url": "https://api.github.com/users/gaart/following{/other_user}", "gists_url": "https://api.github.com/users/gaart/gists{/gist_id}", "starred_url": "https://api.github.com/users/gaart/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/gaart/subscriptions", "organizations_url": "https://api.github.com/users/gaart/orgs", "repos_url": "https://api.github.com/users/gaart/repos", "events_url": "https://api.github.com/users/gaart/events{/privacy}", "received_events_url": "https://api.github.com/users/gaart/received_events", "type": "User", "site_admin": false}, "body": null, "created_at": "2021-08-27T15:43:40Z", "updated_at": "2021-08-27T15:53:14Z", "closed_at": null, "merged_at": null, "merge_commit_sha": "191309e3da8b36705156348ae73f4dca836533f9", "assignee": null, "assignees": [], "requested_reviewers": [], "requested_teams": [], "labels": [{"id": 3295756566, "node_id": "MDU6TGFiZWwzMjk1NzU2NTY2", "url": "https://api.github.com/repos/airbytehq/integration-test/labels/bug", "name": "bug", "color": "d73a4a", "default": true, "description": "Something isn't working"}, {"id": 3300346197, "node_id": "MDU6TGFiZWwzMzAwMzQ2MTk3", "url": "https://api.github.com/repos/airbytehq/integration-test/labels/critical", "name": "critical", "color": "ededed", "default": false, "description": null}], "milestone": null, "draft": false, "commits_url": "https://api.github.com/repos/airbytehq/integration-test/pulls/5/commits", "review_comments_url": "https://api.github.com/repos/airbytehq/integration-test/pulls/5/comments", "review_comment_url": "https://api.github.com/repos/airbytehq/integration-test/pulls/comments{/number}", "comments_url": "https://api.github.com/repos/airbytehq/integration-test/issues/5/comments", "statuses_url": "https://api.github.com/repos/airbytehq/integration-test/statuses/31a3e3f19fefce60fba6bfc69dd2b3fb5195a083", "head": {"label": "airbytehq:feature/branch_4", "ref": "feature/branch_4", "sha": "31a3e3f19fefce60fba6bfc69dd2b3fb5195a083", "user": {"login": "airbytehq", "id": 59758427, "node_id": "MDEyOk9yZ2FuaXphdGlvbjU5NzU4NDI3", "avatar_url": "https://avatars.githubusercontent.com/u/59758427?v=4", "gravatar_id": "", "url": "https://api.github.com/users/airbytehq", "html_url": "https://github.com/airbytehq", "followers_url": "https://api.github.com/users/airbytehq/followers", "following_url": "https://api.github.com/users/airbytehq/following{/other_user}", "gists_url": "https://api.github.com/users/airbytehq/gists{/gist_id}", "starred_url": "https://api.github.com/users/airbytehq/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/airbytehq/subscriptions", "organizations_url": "https://api.github.com/users/airbytehq/orgs", "repos_url": "https://api.github.com/users/airbytehq/repos", "events_url": "https://api.github.com/users/airbytehq/events{/privacy}", "received_events_url": "https://api.github.com/users/airbytehq/received_events", "type": "Organization", "site_admin": false}, "repo_id": 400052213}, "base": {"label": "airbytehq:master", "ref": "master", "sha": "978753aeb56f7b49872279d1b491411a6235aa90", "user": {"login": "airbytehq", "id": 59758427, "node_id": "MDEyOk9yZ2FuaXphdGlvbjU5NzU4NDI3", "avatar_url": "https://avatars.githubusercontent.com/u/59758427?v=4", "gravatar_id": "", "url": "https://api.github.com/users/airbytehq", "html_url": "https://github.com/airbytehq", "followers_url": "https://api.github.com/users/airbytehq/followers", "following_url": "https://api.github.com/users/airbytehq/following{/other_user}", "gists_url": "https://api.github.com/users/airbytehq/gists{/gist_id}", "starred_url": "https://api.github.com/users/airbytehq/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/airbytehq/subscriptions", "organizations_url": "https://api.github.com/users/airbytehq/orgs", "repos_url": "https://api.github.com/users/airbytehq/repos", "events_url": "https://api.github.com/users/airbytehq/events{/privacy}", "received_events_url": "https://api.github.com/users/airbytehq/received_events", "type": "Organization", "site_admin": false}, "repo": {"id": 400052213, "node_id": "MDEwOlJlcG9zaXRvcnk0MDAwNTIyMTM=", "name": "integration-test", "full_name": "airbytehq/integration-test", "private": false, "owner": {"login": "airbytehq", "id": 59758427, "node_id": "MDEyOk9yZ2FuaXphdGlvbjU5NzU4NDI3", "avatar_url": "https://avatars.githubusercontent.com/u/59758427?v=4", "gravatar_id": "", "url": "https://api.github.com/users/airbytehq", "html_url": "https://github.com/airbytehq", "followers_url": "https://api.github.com/users/airbytehq/followers", "following_url": "https://api.github.com/users/airbytehq/following{/other_user}", "gists_url": "https://api.github.com/users/airbytehq/gists{/gist_id}", "starred_url": "https://api.github.com/users/airbytehq/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/airbytehq/subscriptions", "organizations_url": "https://api.github.com/users/airbytehq/orgs", "repos_url": "https://api.github.com/users/airbytehq/repos", "events_url": "https://api.github.com/users/airbytehq/events{/privacy}", "received_events_url": "https://api.github.com/users/airbytehq/received_events", "type": "Organization", "site_admin": false}, "html_url": "https://github.com/airbytehq/integration-test", "description": "Used for integration testing the Github source connector", "fork": false, "url": "https://api.github.com/repos/airbytehq/integration-test", "forks_url": "https://api.github.com/repos/airbytehq/integration-test/forks", "keys_url": "https://api.github.com/repos/airbytehq/integration-test/keys{/key_id}", "collaborators_url": "https://api.github.com/repos/airbytehq/integration-test/collaborators{/collaborator}", "teams_url": "https://api.github.com/repos/airbytehq/integration-test/teams", "hooks_url": "https://api.github.com/repos/airbytehq/integration-test/hooks", "issue_events_url": "https://api.github.com/repos/airbytehq/integration-test/issues/events{/number}", "events_url": "https://api.github.com/repos/airbytehq/integration-test/events", "assignees_url": "https://api.github.com/repos/airbytehq/integration-test/assignees{/user}", "branches_url": "https://api.github.com/repos/airbytehq/integration-test/branches{/branch}", "tags_url": "https://api.github.com/repos/airbytehq/integration-test/tags", "blobs_url": "https://api.github.com/repos/airbytehq/integration-test/git/blobs{/sha}", "git_tags_url": "https://api.github.com/repos/airbytehq/integration-test/git/tags{/sha}", "git_refs_url": "https://api.github.com/repos/airbytehq/integration-test/git/refs{/sha}", "trees_url": "https://api.github.com/repos/airbytehq/integration-test/git/trees{/sha}", "statuses_url": "https://api.github.com/repos/airbytehq/integration-test/statuses/{sha}", "languages_url": "https://api.github.com/repos/airbytehq/integration-test/languages", "stargazers_url": "https://api.github.com/repos/airbytehq/integration-test/stargazers", "contributors_url": "https://api.github.com/repos/airbytehq/integration-test/contributors", "subscribers_url": "https://api.github.com/repos/airbytehq/integration-test/subscribers", "subscription_url": "https://api.github.com/repos/airbytehq/integration-test/subscription", "commits_url": "https://api.github.com/repos/airbytehq/integration-test/commits{/sha}", "git_commits_url": "https://api.github.com/repos/airbytehq/integration-test/git/commits{/sha}", "comments_url": "https://api.github.com/repos/airbytehq/integration-test/comments{/number}", "issue_comment_url": "https://api.github.com/repos/airbytehq/integration-test/issues/comments{/number}", "contents_url": "https://api.github.com/repos/airbytehq/integration-test/contents/{+path}", "compare_url": "https://api.github.com/repos/airbytehq/integration-test/compare/{base}...{head}", "merges_url": "https://api.github.com/repos/airbytehq/integration-test/merges", "archive_url": "https://api.github.com/repos/airbytehq/integration-test/{archive_format}{/ref}", "downloads_url": "https://api.github.com/repos/airbytehq/integration-test/downloads", "issues_url": "https://api.github.com/repos/airbytehq/integration-test/issues{/number}", "pulls_url": "https://api.github.com/repos/airbytehq/integration-test/pulls{/number}", "milestones_url": "https://api.github.com/repos/airbytehq/integration-test/milestones{/number}", "notifications_url": "https://api.github.com/repos/airbytehq/integration-test/notifications{?since,all,participating}", "labels_url": "https://api.github.com/repos/airbytehq/integration-test/labels{/name}", "releases_url": "https://api.github.com/repos/airbytehq/integration-test/releases{/id}", "deployments_url": "https://api.github.com/repos/airbytehq/integration-test/deployments", "created_at": "2021-08-26T05:32:43Z", "updated_at": "2022-07-08T01:27:13Z", "pushed_at": "2023-05-03T16:40:56Z", "git_url": "git://github.com/airbytehq/integration-test.git", "ssh_url": "git@github.com:airbytehq/integration-test.git", "clone_url": "https://github.com/airbytehq/integration-test.git", "svn_url": "https://github.com/airbytehq/integration-test", "homepage": null, "size": 11, "stargazers_count": 4, "watchers_count": 4, "language": null, "has_issues": true, "has_projects": true, "has_downloads": true, "has_wiki": true, "has_pages": false, "has_discussions": false, "forks_count": 2, "mirror_url": null, "archived": false, "disabled": false, "open_issues_count": 10, "license": null, "allow_forking": true, "is_template": false, "web_commit_signoff_required": false, "topics": [], "visibility": "public", "forks": 2, "open_issues": 10, "watchers": 4, "default_branch": "master"}, "repo_id": null}, "_links": {"self": {"href": "https://api.github.com/repos/airbytehq/integration-test/pulls/5"}, "html": {"href": "https://github.com/airbytehq/integration-test/pull/5"}, "issue": {"href": "https://api.github.com/repos/airbytehq/integration-test/issues/5"}, "comments": {"href": "https://api.github.com/repos/airbytehq/integration-test/issues/5/comments"}, "review_comments": {"href": "https://api.github.com/repos/airbytehq/integration-test/pulls/5/comments"}, "review_comment": {"href": "https://api.github.com/repos/airbytehq/integration-test/pulls/comments{/number}"}, "commits": {"href": "https://api.github.com/repos/airbytehq/integration-test/pulls/5/commits"}, "statuses": {"href": "https://api.github.com/repos/airbytehq/integration-test/statuses/31a3e3f19fefce60fba6bfc69dd2b3fb5195a083"}}, "author_association": "CONTRIBUTOR", "auto_merge": null, "active_lock_reason": null, "repository": "airbytehq/integration-test"}, "emitted_at": 1685698519242} {"stream":"releases","data":{"url":"https://api.github.com/repos/airbytehq/integration-test/releases/48581586","assets_url":"https://api.github.com/repos/airbytehq/integration-test/releases/48581586/assets","upload_url":"https://uploads.github.com/repos/airbytehq/integration-test/releases/48581586/assets{?name,label}","html_url":"https://github.com/airbytehq/integration-test/releases/tag/dev-0.9","id":48581586,"author":{"login":"gaart","id":743901,"node_id":"MDQ6VXNlcjc0MzkwMQ==","avatar_url":"https://avatars.githubusercontent.com/u/743901?v=4","gravatar_id":"","url":"https://api.github.com/users/gaart","html_url":"https://github.com/gaart","followers_url":"https://api.github.com/users/gaart/followers","following_url":"https://api.github.com/users/gaart/following{/other_user}","gists_url":"https://api.github.com/users/gaart/gists{/gist_id}","starred_url":"https://api.github.com/users/gaart/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gaart/subscriptions","organizations_url":"https://api.github.com/users/gaart/orgs","repos_url":"https://api.github.com/users/gaart/repos","events_url":"https://api.github.com/users/gaart/events{/privacy}","received_events_url":"https://api.github.com/users/gaart/received_events","type":"User","site_admin":false},"node_id":"MDc6UmVsZWFzZTQ4NTgxNTg2","tag_name":"dev-0.9","target_commitish":"master","name":"9 global release","draft":false,"prerelease":false,"created_at":"2021-08-27T07:03:09Z","published_at":"2021-08-27T15:43:53Z","assets":[],"tarball_url":"https://api.github.com/repos/airbytehq/integration-test/tarball/dev-0.9","zipball_url":"https://api.github.com/repos/airbytehq/integration-test/zipball/dev-0.9","body":"","repository":"airbytehq/integration-test"},"emitted_at":1677668760424} -{"stream":"repositories","data":{"id":283046497,"node_id":"MDEwOlJlcG9zaXRvcnkyODMwNDY0OTc=","name":"airbyte","full_name":"airbytehq/airbyte","private":false,"owner":{"login":"airbytehq","id":59758427,"node_id":"MDEyOk9yZ2FuaXphdGlvbjU5NzU4NDI3","avatar_url":"https://avatars.githubusercontent.com/u/59758427?v=4","gravatar_id":"","url":"https://api.github.com/users/airbytehq","html_url":"https://github.com/airbytehq","followers_url":"https://api.github.com/users/airbytehq/followers","following_url":"https://api.github.com/users/airbytehq/following{/other_user}","gists_url":"https://api.github.com/users/airbytehq/gists{/gist_id}","starred_url":"https://api.github.com/users/airbytehq/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/airbytehq/subscriptions","organizations_url":"https://api.github.com/users/airbytehq/orgs","repos_url":"https://api.github.com/users/airbytehq/repos","events_url":"https://api.github.com/users/airbytehq/events{/privacy}","received_events_url":"https://api.github.com/users/airbytehq/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/airbytehq/airbyte","description":"Data integration platform for ELT pipelines from APIs, databases & files to warehouses & lakes.","fork":false,"url":"https://api.github.com/repos/airbytehq/airbyte","forks_url":"https://api.github.com/repos/airbytehq/airbyte/forks","keys_url":"https://api.github.com/repos/airbytehq/airbyte/keys{/key_id}","collaborators_url":"https://api.github.com/repos/airbytehq/airbyte/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/airbytehq/airbyte/teams","hooks_url":"https://api.github.com/repos/airbytehq/airbyte/hooks","issue_events_url":"https://api.github.com/repos/airbytehq/airbyte/issues/events{/number}","events_url":"https://api.github.com/repos/airbytehq/airbyte/events","assignees_url":"https://api.github.com/repos/airbytehq/airbyte/assignees{/user}","branches_url":"https://api.github.com/repos/airbytehq/airbyte/branches{/branch}","tags_url":"https://api.github.com/repos/airbytehq/airbyte/tags","blobs_url":"https://api.github.com/repos/airbytehq/airbyte/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/airbytehq/airbyte/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/airbytehq/airbyte/git/refs{/sha}","trees_url":"https://api.github.com/repos/airbytehq/airbyte/git/trees{/sha}","statuses_url":"https://api.github.com/repos/airbytehq/airbyte/statuses/{sha}","languages_url":"https://api.github.com/repos/airbytehq/airbyte/languages","stargazers_url":"https://api.github.com/repos/airbytehq/airbyte/stargazers","contributors_url":"https://api.github.com/repos/airbytehq/airbyte/contributors","subscribers_url":"https://api.github.com/repos/airbytehq/airbyte/subscribers","subscription_url":"https://api.github.com/repos/airbytehq/airbyte/subscription","commits_url":"https://api.github.com/repos/airbytehq/airbyte/commits{/sha}","git_commits_url":"https://api.github.com/repos/airbytehq/airbyte/git/commits{/sha}","comments_url":"https://api.github.com/repos/airbytehq/airbyte/comments{/number}","issue_comment_url":"https://api.github.com/repos/airbytehq/airbyte/issues/comments{/number}","contents_url":"https://api.github.com/repos/airbytehq/airbyte/contents/{+path}","compare_url":"https://api.github.com/repos/airbytehq/airbyte/compare/{base}...{head}","merges_url":"https://api.github.com/repos/airbytehq/airbyte/merges","archive_url":"https://api.github.com/repos/airbytehq/airbyte/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/airbytehq/airbyte/downloads","issues_url":"https://api.github.com/repos/airbytehq/airbyte/issues{/number}","pulls_url":"https://api.github.com/repos/airbytehq/airbyte/pulls{/number}","milestones_url":"https://api.github.com/repos/airbytehq/airbyte/milestones{/number}","notifications_url":"https://api.github.com/repos/airbytehq/airbyte/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/airbytehq/airbyte/labels{/name}","releases_url":"https://api.github.com/repos/airbytehq/airbyte/releases{/id}","deployments_url":"https://api.github.com/repos/airbytehq/airbyte/deployments","created_at":"2020-07-27T23:55:54Z","updated_at":"2023-06-30T09:20:50Z","pushed_at":"2023-06-30T10:14:51Z","git_url":"git://github.com/airbytehq/airbyte.git","ssh_url":"git@github.com:airbytehq/airbyte.git","clone_url":"https://github.com/airbytehq/airbyte.git","svn_url":"https://github.com/airbytehq/airbyte","homepage":"https://airbyte.com","size":3554496,"stargazers_count":11029,"watchers_count":11029,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"has_discussions":false,"forks_count":2848,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":4711,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":["airbyte","bigquery","change-data-capture","data","data-analysis","data-collection","data-engineering","data-ingestion","data-integration","elt","etl","java","pipeline","python","redshift","snowflake"],"visibility":"public","forks":2848,"open_issues":4711,"watchers":11029,"default_branch":"master","permissions":{"admin":true,"maintain":true,"push":true,"triage":true,"pull":true},"security_and_analysis":{"secret_scanning":{"status":"disabled"},"secret_scanning_push_protection":{"status":"disabled"},"dependabot_security_updates":{"status":"enabled"}},"organization":"airbytehq"},"emitted_at":1688121076307} +{"stream": "repositories", "data": {"id": 283046497, "node_id": "MDEwOlJlcG9zaXRvcnkyODMwNDY0OTc=", "name": "airbyte", "full_name": "airbytehq/airbyte", "private": false, "owner": {"login": "airbytehq", "id": 59758427, "node_id": "MDEyOk9yZ2FuaXphdGlvbjU5NzU4NDI3", "avatar_url": "https://avatars.githubusercontent.com/u/59758427?v=4", "gravatar_id": "", "url": "https://api.github.com/users/airbytehq", "html_url": "https://github.com/airbytehq", "followers_url": "https://api.github.com/users/airbytehq/followers", "following_url": "https://api.github.com/users/airbytehq/following{/other_user}", "gists_url": "https://api.github.com/users/airbytehq/gists{/gist_id}", "starred_url": "https://api.github.com/users/airbytehq/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/airbytehq/subscriptions", "organizations_url": "https://api.github.com/users/airbytehq/orgs", "repos_url": "https://api.github.com/users/airbytehq/repos", "events_url": "https://api.github.com/users/airbytehq/events{/privacy}", "received_events_url": "https://api.github.com/users/airbytehq/received_events", "type": "Organization", "site_admin": false}, "html_url": "https://github.com/airbytehq/airbyte", "description": "Data integration platform for ELT pipelines from APIs, databases & files to warehouses & lakes.", "fork": false, "url": "https://api.github.com/repos/airbytehq/airbyte", "forks_url": "https://api.github.com/repos/airbytehq/airbyte/forks", "keys_url": "https://api.github.com/repos/airbytehq/airbyte/keys{/key_id}", "collaborators_url": "https://api.github.com/repos/airbytehq/airbyte/collaborators{/collaborator}", "teams_url": "https://api.github.com/repos/airbytehq/airbyte/teams", "hooks_url": "https://api.github.com/repos/airbytehq/airbyte/hooks", "issue_events_url": "https://api.github.com/repos/airbytehq/airbyte/issues/events{/number}", "events_url": "https://api.github.com/repos/airbytehq/airbyte/events", "assignees_url": "https://api.github.com/repos/airbytehq/airbyte/assignees{/user}", "branches_url": "https://api.github.com/repos/airbytehq/airbyte/branches{/branch}", "tags_url": "https://api.github.com/repos/airbytehq/airbyte/tags", "blobs_url": "https://api.github.com/repos/airbytehq/airbyte/git/blobs{/sha}", "git_tags_url": "https://api.github.com/repos/airbytehq/airbyte/git/tags{/sha}", "git_refs_url": "https://api.github.com/repos/airbytehq/airbyte/git/refs{/sha}", "trees_url": "https://api.github.com/repos/airbytehq/airbyte/git/trees{/sha}", "statuses_url": "https://api.github.com/repos/airbytehq/airbyte/statuses/{sha}", "languages_url": "https://api.github.com/repos/airbytehq/airbyte/languages", "stargazers_url": "https://api.github.com/repos/airbytehq/airbyte/stargazers", "contributors_url": "https://api.github.com/repos/airbytehq/airbyte/contributors", "subscribers_url": "https://api.github.com/repos/airbytehq/airbyte/subscribers", "subscription_url": "https://api.github.com/repos/airbytehq/airbyte/subscription", "commits_url": "https://api.github.com/repos/airbytehq/airbyte/commits{/sha}", "git_commits_url": "https://api.github.com/repos/airbytehq/airbyte/git/commits{/sha}", "comments_url": "https://api.github.com/repos/airbytehq/airbyte/comments{/number}", "issue_comment_url": "https://api.github.com/repos/airbytehq/airbyte/issues/comments{/number}", "contents_url": "https://api.github.com/repos/airbytehq/airbyte/contents/{+path}", "compare_url": "https://api.github.com/repos/airbytehq/airbyte/compare/{base}...{head}", "merges_url": "https://api.github.com/repos/airbytehq/airbyte/merges", "archive_url": "https://api.github.com/repos/airbytehq/airbyte/{archive_format}{/ref}", "downloads_url": "https://api.github.com/repos/airbytehq/airbyte/downloads", "issues_url": "https://api.github.com/repos/airbytehq/airbyte/issues{/number}", "pulls_url": "https://api.github.com/repos/airbytehq/airbyte/pulls{/number}", "milestones_url": "https://api.github.com/repos/airbytehq/airbyte/milestones{/number}", "notifications_url": "https://api.github.com/repos/airbytehq/airbyte/notifications{?since,all,participating}", "labels_url": "https://api.github.com/repos/airbytehq/airbyte/labels{/name}", "releases_url": "https://api.github.com/repos/airbytehq/airbyte/releases{/id}", "deployments_url": "https://api.github.com/repos/airbytehq/airbyte/deployments", "created_at": "2020-07-27T23:55:54Z", "updated_at": "2023-07-11T04:02:27Z", "pushed_at": "2023-07-11T08:47:50Z", "git_url": "git://github.com/airbytehq/airbyte.git", "ssh_url": "git@github.com:airbytehq/airbyte.git", "clone_url": "https://github.com/airbytehq/airbyte.git", "svn_url": "https://github.com/airbytehq/airbyte", "homepage": "https://airbyte.com", "size": 3671239, "stargazers_count": 11137, "watchers_count": 11137, "language": "Python", "has_issues": true, "has_projects": true, "has_downloads": true, "has_wiki": false, "has_pages": true, "has_discussions": true, "forks_count": 2881, "mirror_url": null, "archived": false, "disabled": false, "open_issues_count": 4723, "license": {"key": "other", "name": "Other", "spdx_id": "NOASSERTION", "url": null, "node_id": "MDc6TGljZW5zZTA="}, "allow_forking": true, "is_template": false, "web_commit_signoff_required": false, "topics": ["airbyte", "bigquery", "change-data-capture", "data", "data-analysis", "data-collection", "data-engineering", "data-ingestion", "data-integration", "elt", "etl", "java", "pipeline", "python", "redshift", "snowflake"], "visibility": "public", "forks": 2881, "open_issues": 4723, "watchers": 11137, "default_branch": "master", "permissions": {"admin": true, "maintain": true, "push": true, "triage": true, "pull": true}, "security_and_analysis": {"secret_scanning": {"status": "disabled"}, "secret_scanning_push_protection": {"status": "disabled"}, "dependabot_security_updates": {"status": "enabled"}}, "organization": "airbytehq"}, "emitted_at": 1689065865611} {"stream":"review_comments","data":{"url":"https://api.github.com/repos/airbytehq/integration-test/pulls/comments/699253726","pull_request_review_id":742633128,"id":699253726,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDY5OTI1MzcyNg==","diff_hunk":"@@ -0,0 +1 @@\n+text_for_file_","path":"github_sources/file_1.txt","position":1,"original_position":1,"commit_id":"da5fa314f9b3a272d0aa47a453aec0f68a80cbae","original_commit_id":"da5fa314f9b3a272d0aa47a453aec0f68a80cbae","user":{"login":"yevhenii-ldv","id":34103125,"node_id":"MDQ6VXNlcjM0MTAzMTI1","avatar_url":"https://avatars.githubusercontent.com/u/34103125?v=4","gravatar_id":"","url":"https://api.github.com/users/yevhenii-ldv","html_url":"https://github.com/yevhenii-ldv","followers_url":"https://api.github.com/users/yevhenii-ldv/followers","following_url":"https://api.github.com/users/yevhenii-ldv/following{/other_user}","gists_url":"https://api.github.com/users/yevhenii-ldv/gists{/gist_id}","starred_url":"https://api.github.com/users/yevhenii-ldv/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/yevhenii-ldv/subscriptions","organizations_url":"https://api.github.com/users/yevhenii-ldv/orgs","repos_url":"https://api.github.com/users/yevhenii-ldv/repos","events_url":"https://api.github.com/users/yevhenii-ldv/events{/privacy}","received_events_url":"https://api.github.com/users/yevhenii-ldv/received_events","type":"User","site_admin":false},"body":"Good point","created_at":"2021-08-31T12:01:15Z","updated_at":"2021-08-31T12:01:15Z","html_url":"https://github.com/airbytehq/integration-test/pull/4#discussion_r699253726","pull_request_url":"https://api.github.com/repos/airbytehq/integration-test/pulls/4","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/airbytehq/integration-test/pulls/comments/699253726"},"html":{"href":"https://github.com/airbytehq/integration-test/pull/4#discussion_r699253726"},"pull_request":{"href":"https://api.github.com/repos/airbytehq/integration-test/pulls/4"}},"reactions":{"url":"https://api.github.com/repos/airbytehq/integration-test/pulls/comments/699253726/reactions","total_count":1,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":1,"rocket":0,"eyes":0},"start_line":null,"original_start_line":null,"start_side":null,"line":1,"original_line":1,"side":"RIGHT","subject_type": "line","repository":"airbytehq/integration-test"},"emitted_at":1677668764426} {"stream":"reviews","data":{"node_id":"MDE3OlB1bGxSZXF1ZXN0UmV2aWV3NzQwNjU5Nzk4","id":740659798,"body":"Review commit for branch feature/branch_4","state":"COMMENTED","html_url":"https://github.com/airbytehq/integration-test/pull/5#pullrequestreview-740659798","author_association":"CONTRIBUTOR","submitted_at":"2021-08-27T15:43:42Z","created_at":"2021-08-27T15:43:42Z","updated_at":"2021-08-27T15:43:42Z","user":{"node_id":"MDQ6VXNlcjc0MzkwMQ==","id":743901,"login":"gaart","avatar_url":"https://avatars.githubusercontent.com/u/743901?v=4","html_url":"https://github.com/gaart","site_admin":false,"type":"User"},"repository":"airbytehq/integration-test","pull_request_url":"https://github.com/airbytehq/integration-test/pull/5","commit_id":"31a3e3f19fefce60fba6bfc69dd2b3fb5195a083","_links":{"html":{"href":"https://github.com/airbytehq/integration-test/pull/5#pullrequestreview-740659798"},"pull_request":{"href":"https://github.com/airbytehq/integration-test/pull/5"}}},"emitted_at":1677668764954} {"stream":"stargazers","data":{"starred_at":"2021-08-27T16:23:34Z","user":{"login":"VasylLazebnyk","id":68591643,"node_id":"MDQ6VXNlcjY4NTkxNjQz","avatar_url":"https://avatars.githubusercontent.com/u/68591643?v=4","gravatar_id":"","url":"https://api.github.com/users/VasylLazebnyk","html_url":"https://github.com/VasylLazebnyk","followers_url":"https://api.github.com/users/VasylLazebnyk/followers","following_url":"https://api.github.com/users/VasylLazebnyk/following{/other_user}","gists_url":"https://api.github.com/users/VasylLazebnyk/gists{/gist_id}","starred_url":"https://api.github.com/users/VasylLazebnyk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/VasylLazebnyk/subscriptions","organizations_url":"https://api.github.com/users/VasylLazebnyk/orgs","repos_url":"https://api.github.com/users/VasylLazebnyk/repos","events_url":"https://api.github.com/users/VasylLazebnyk/events{/privacy}","received_events_url":"https://api.github.com/users/VasylLazebnyk/received_events","type":"User","site_admin":false},"repository":"airbytehq/integration-test","user_id":68591643},"emitted_at":1677668765231} diff --git a/airbyte-integrations/connectors/source-github/metadata.yaml b/airbyte-integrations/connectors/source-github/metadata.yaml index 0f99717be32b..3351bab45998 100644 --- a/airbyte-integrations/connectors/source-github/metadata.yaml +++ b/airbyte-integrations/connectors/source-github/metadata.yaml @@ -5,7 +5,7 @@ data: connectorSubtype: api connectorType: source definitionId: ef69ef6e-aa7f-4af1-a01d-ef775033524e - dockerImageTag: 1.0.1 + dockerImageTag: 1.0.2 maxSecondsBetweenMessages: 5400 dockerRepository: airbyte/source-github githubIssueLabel: source-github diff --git a/airbyte-integrations/connectors/source-github/source_github/schemas/organizations.json b/airbyte-integrations/connectors/source-github/source_github/schemas/organizations.json index e0a3f1f73797..cab08b9532ce 100644 --- a/airbyte-integrations/connectors/source-github/source_github/schemas/organizations.json +++ b/airbyte-integrations/connectors/source-github/source_github/schemas/organizations.json @@ -88,6 +88,10 @@ "type": "string", "format": "date-time" }, + "archived_at": { + "type": ["null", "string"], + "format": "date-time" + }, "type": { "type": ["null", "string"] }, diff --git a/docs/integrations/sources/github.md b/docs/integrations/sources/github.md index 5e42ebeb5605..3e1d81ec05ed 100644 --- a/docs/integrations/sources/github.md +++ b/docs/integrations/sources/github.md @@ -163,6 +163,7 @@ The GitHub connector should not run into GitHub API limitations under normal usa | Version | Date | Pull Request | Subject | |:--------|:-----------|:------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 1.0.2 | 2023-07-11 | [28144](https://github.com/airbytehq/airbyte/pull/28144) | Add `archived_at` property to `Organizations` schema parameter | | 1.0.1 | 2023-05-22 | [25838](https://github.com/airbytehq/airbyte/pull/25838) | Deprecate "page size" input parameter | | 1.0.0 | 2023-05-19 | [25778](https://github.com/airbytehq/airbyte/pull/25778) | Improve repo(s) name validation on UI | | 0.5.0 | 2023-05-16 | [25793](https://github.com/airbytehq/airbyte/pull/25793) | Implement client-side throttling of requests | From ff868ee983017e1361237f83298391a418de803d Mon Sep 17 00:00:00 2001 From: Marcos Marx Date: Tue, 11 Jul 2023 15:16:21 -0300 Subject: [PATCH 27/63] Source Google Sheets: fix several reported vulnerabilities (#28085) * Fixes several reported vulnerabilities, total - 25, critical - 1, high - 17, medium - 6, low - 1 Upgraded alpine from 3.15 to 3.18 CVE-2022-37434 CVE-2022-42898 CVE-2022-28391 CVE-2022-1271 CVE-2022-40674 CVE-2023-29491 CVE-2022-1304 CVE-2023-2650 CVE-2023-0464 CVE-2023-0215 CVE-2022-4450 * Updated Changelog with PR number. * Leave pip installed as its required by our pipeline --------- Co-authored-by: Mauricio A Co-authored-by: Ben Church --- .../source-google-sheets/Dockerfile | 8 +- .../source-google-sheets/metadata.yaml | 2 +- docs/integrations/sources/google-sheets.md | 75 ++++++++++--------- 3 files changed, 44 insertions(+), 41 deletions(-) diff --git a/airbyte-integrations/connectors/source-google-sheets/Dockerfile b/airbyte-integrations/connectors/source-google-sheets/Dockerfile index c08fa909cdfc..4f1889631a31 100644 --- a/airbyte-integrations/connectors/source-google-sheets/Dockerfile +++ b/airbyte-integrations/connectors/source-google-sheets/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9.11-alpine3.15 as base +FROM python:3.9.16-alpine3.18 as base # build and load all requirements FROM base as builder @@ -25,7 +25,9 @@ COPY --from=builder /usr/share/zoneinfo/Etc/UTC /etc/localtime RUN echo "Etc/UTC" > /etc/timezone # bash is installed for more convenient debugging. -RUN apk --no-cache add bash +RUN apk --no-cache add bash && \ + # upgrading openssl due to https://nvd.nist.gov/vuln/detail/CVE-2023-2650 + apk upgrade # copy payload code only COPY main.py ./ @@ -34,5 +36,5 @@ COPY source_google_sheets ./source_google_sheets ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=0.3.0 +LABEL io.airbyte.version=0.3.1 LABEL io.airbyte.name=airbyte/source-google-sheets diff --git a/airbyte-integrations/connectors/source-google-sheets/metadata.yaml b/airbyte-integrations/connectors/source-google-sheets/metadata.yaml index 209fa3c35047..27a5ff93828b 100644 --- a/airbyte-integrations/connectors/source-google-sheets/metadata.yaml +++ b/airbyte-integrations/connectors/source-google-sheets/metadata.yaml @@ -5,7 +5,7 @@ data: connectorSubtype: file connectorType: source definitionId: 71607ba1-c0ac-4799-8049-7f4b90dd50f7 - dockerImageTag: 0.3.0 + dockerImageTag: 0.3.1 dockerRepository: airbyte/source-google-sheets githubIssueLabel: source-google-sheets icon: google-sheets.svg diff --git a/docs/integrations/sources/google-sheets.md b/docs/integrations/sources/google-sheets.md index 79c5c05f9435..e1db0f830968 100644 --- a/docs/integrations/sources/google-sheets.md +++ b/docs/integrations/sources/google-sheets.md @@ -74,42 +74,43 @@ The [Google API rate limit](https://developers.google.com/sheets/api/limits) is ## Changelog -| Version | Date | Pull Request | Subject | -| ------- | ---------- | -------------------------------------------------------- | ----------------------------------------------------------------------------- | -| 0.3.0 | 2023-06-26 | [27738](https://github.com/airbytehq/airbyte/pull/27738) | License Update: Elv2 | -| 0.2.39 | 2023-05-31 | [26833](https://github.com/airbytehq/airbyte/pull/26833) | Remove authSpecification in favour of advancedAuth in specification | -| 0.2.38 | 2023-05-16 | [26097](https://github.com/airbytehq/airbyte/pull/26097) | Refactor config error | -| 0.2.37 | 2023-02-21 | [23292](https://github.com/airbytehq/airbyte/pull/23292) | Skip non grid sheets. | -| 0.2.36 | 2023-02-21 | [23272](https://github.com/airbytehq/airbyte/pull/23272) | Handle empty sheets gracefully. | -| 0.2.35 | 2023-02-23 | [23057](https://github.com/airbytehq/airbyte/pull/23057) | Slugify column names | -| 0.2.34 | 2023-02-15 | [23071](https://github.com/airbytehq/airbyte/pull/23071) | Change min spreadsheet id size to 20 symbols | -| 0.2.33 | 2023-02-13 | [23278](https://github.com/airbytehq/airbyte/pull/23278) | Handle authentication errors | -| 0.2.32 | 2023-02-13 | [22884](https://github.com/airbytehq/airbyte/pull/22884) | Do not consume http spreadsheets. | -| 0.2.31 | 2022-10-09 | [19574](https://github.com/airbytehq/airbyte/pull/19574) | Revert 'Add row_id to rows and use as primary key' | -| 0.2.30 | 2022-10-09 | [19215](https://github.com/airbytehq/airbyte/pull/19215) | Add row_id to rows and use as primary key | -| 0.2.21 | 2022-10-04 | [15591](https://github.com/airbytehq/airbyte/pull/15591) | Clean instantiation of AirbyteStream | -| 0.2.20 | 2022-10-10 | [17766](https://github.com/airbytehq/airbyte/pull/17766) | Fix null pointer exception when parsing the spreadsheet id. | -| 0.2.19 | 2022-09-29 | [17410](https://github.com/airbytehq/airbyte/pull/17410) | Use latest CDK. | -| 0.2.18 | 2022-09-28 | [17326](https://github.com/airbytehq/airbyte/pull/17326) | Migrate to per-stream states. | -| 0.2.17 | 2022-08-03 | [15107](https://github.com/airbytehq/airbyte/pull/15107) | Expose Row Batch Size in Connector Specification | -| 0.2.16 | 2022-07-07 | [13729](https://github.com/airbytehq/airbyte/pull/13729) | Improve configuration field description | -| 0.2.15 | 2022-06-02 | [13446](https://github.com/airbytehq/airbyte/pull/13446) | Retry requests resulting in a server error | -| 0.2.13 | 2022-05-06 | [12685](https://github.com/airbytehq/airbyte/pull/12685) | Update CDK to v0.1.56 to emit an `AirbyeTraceMessage` on uncaught exceptions | -| 0.2.12 | 2022-04-20 | [12230](https://github.com/airbytehq/airbyte/pull/12230) | Update connector to use a `spec.yaml` | -| 0.2.11 | 2022-04-13 | [11977](https://github.com/airbytehq/airbyte/pull/11977) | Replace leftover print statement with airbyte logger | -| 0.2.10 | 2022-03-25 | [11404](https://github.com/airbytehq/airbyte/pull/11404) | Allow using Spreadsheet Link/URL instead of Spreadsheet ID | -| 0.2.9 | 2022-01-25 | [9208](https://github.com/airbytehq/airbyte/pull/9208) | Update title and descriptions | -| 0.2.7 | 2021-09-27 | [8470](https://github.com/airbytehq/airbyte/pull/8470) | Migrate to the CDK | -| 0.2.6 | 2021-09-27 | [6354](https://github.com/airbytehq/airbyte/pull/6354) | Support connecting via Oauth webflow | -| 0.2.5 | 2021-09-12 | [5972](https://github.com/airbytehq/airbyte/pull/5972) | Fix full_refresh test by adding supported_sync_modes to Stream initialization | -| 0.2.4 | 2021-08-05 | [5233](https://github.com/airbytehq/airbyte/pull/5233) | Fix error during listing sheets with diagram only | -| 0.2.3 | 2021-06-09 | [3973](https://github.com/airbytehq/airbyte/pull/3973) | Add AIRBYTE_ENTRYPOINT for Kubernetes support | -| 0.2.2 | 2021-04-20 | [2994](https://github.com/airbytehq/airbyte/pull/2994) | Formatting spec | -| 0.2.1 | 2021-04-03 | [2726](https://github.com/airbytehq/airbyte/pull/2726) | Fix base connector versioning | -| 0.2.0 | 2021-03-09 | [2238](https://github.com/airbytehq/airbyte/pull/2238) | Protocol allows future/unknown properties | -| 0.1.7 | 2021-01-21 | [1762](https://github.com/airbytehq/airbyte/pull/1762) | Fix issue large spreadsheet | -| 0.1.6 | 2021-01-27 | [1668](https://github.com/airbytehq/airbyte/pull/1668) | Adopt connector best practices | -| 0.1.5 | 2020-12-30 | [1438](https://github.com/airbytehq/airbyte/pull/1438) | Implement backoff | -| 0.1.4 | 2020-11-30 | [1046](https://github.com/airbytehq/airbyte/pull/1046) | Add connectors using an index YAML file | +| Version | Date | Pull Request | Subject | +|---------|------------|----------------------------------------------------------|------------------------------------------------------------------------------------| +| 0.3.1 | 2023-07-06 | [28033](https://github.com/airbytehq/airbyte/pull/28033) | Fixed several reported vulnerabilities (25 total), CVE-2022-37434, CVE-2022-42898 | +| 0.3.0 | 2023-06-26 | [27738](https://github.com/airbytehq/airbyte/pull/27738) | License Update: Elv2 | +| 0.2.39 | 2023-05-31 | [26833](https://github.com/airbytehq/airbyte/pull/26833) | Remove authSpecification in favour of advancedAuth in specification | +| 0.2.38 | 2023-05-16 | [26097](https://github.com/airbytehq/airbyte/pull/26097) | Refactor config error | +| 0.2.37 | 2023-02-21 | [23292](https://github.com/airbytehq/airbyte/pull/23292) | Skip non grid sheets. | +| 0.2.36 | 2023-02-21 | [23272](https://github.com/airbytehq/airbyte/pull/23272) | Handle empty sheets gracefully. | +| 0.2.35 | 2023-02-23 | [23057](https://github.com/airbytehq/airbyte/pull/23057) | Slugify column names | +| 0.2.34 | 2023-02-15 | [23071](https://github.com/airbytehq/airbyte/pull/23071) | Change min spreadsheet id size to 20 symbols | +| 0.2.33 | 2023-02-13 | [23278](https://github.com/airbytehq/airbyte/pull/23278) | Handle authentication errors | +| 0.2.32 | 2023-02-13 | [22884](https://github.com/airbytehq/airbyte/pull/22884) | Do not consume http spreadsheets. | +| 0.2.31 | 2022-10-09 | [19574](https://github.com/airbytehq/airbyte/pull/19574) | Revert 'Add row_id to rows and use as primary key' | +| 0.2.30 | 2022-10-09 | [19215](https://github.com/airbytehq/airbyte/pull/19215) | Add row_id to rows and use as primary key | +| 0.2.21 | 2022-10-04 | [15591](https://github.com/airbytehq/airbyte/pull/15591) | Clean instantiation of AirbyteStream | +| 0.2.20 | 2022-10-10 | [17766](https://github.com/airbytehq/airbyte/pull/17766) | Fix null pointer exception when parsing the spreadsheet id. | +| 0.2.19 | 2022-09-29 | [17410](https://github.com/airbytehq/airbyte/pull/17410) | Use latest CDK. | +| 0.2.18 | 2022-09-28 | [17326](https://github.com/airbytehq/airbyte/pull/17326) | Migrate to per-stream states. | +| 0.2.17 | 2022-08-03 | [15107](https://github.com/airbytehq/airbyte/pull/15107) | Expose Row Batch Size in Connector Specification | +| 0.2.16 | 2022-07-07 | [13729](https://github.com/airbytehq/airbyte/pull/13729) | Improve configuration field description | +| 0.2.15 | 2022-06-02 | [13446](https://github.com/airbytehq/airbyte/pull/13446) | Retry requests resulting in a server error | +| 0.2.13 | 2022-05-06 | [12685](https://github.com/airbytehq/airbyte/pull/12685) | Update CDK to v0.1.56 to emit an `AirbyeTraceMessage` on uncaught exceptions | +| 0.2.12 | 2022-04-20 | [12230](https://github.com/airbytehq/airbyte/pull/12230) | Update connector to use a `spec.yaml` | +| 0.2.11 | 2022-04-13 | [11977](https://github.com/airbytehq/airbyte/pull/11977) | Replace leftover print statement with airbyte logger | +| 0.2.10 | 2022-03-25 | [11404](https://github.com/airbytehq/airbyte/pull/11404) | Allow using Spreadsheet Link/URL instead of Spreadsheet ID | +| 0.2.9 | 2022-01-25 | [9208](https://github.com/airbytehq/airbyte/pull/9208) | Update title and descriptions | +| 0.2.7 | 2021-09-27 | [8470](https://github.com/airbytehq/airbyte/pull/8470) | Migrate to the CDK | +| 0.2.6 | 2021-09-27 | [6354](https://github.com/airbytehq/airbyte/pull/6354) | Support connecting via Oauth webflow | +| 0.2.5 | 2021-09-12 | [5972](https://github.com/airbytehq/airbyte/pull/5972) | Fix full_refresh test by adding supported_sync_modes to Stream initialization | +| 0.2.4 | 2021-08-05 | [5233](https://github.com/airbytehq/airbyte/pull/5233) | Fix error during listing sheets with diagram only | +| 0.2.3 | 2021-06-09 | [3973](https://github.com/airbytehq/airbyte/pull/3973) | Add AIRBYTE_ENTRYPOINT for Kubernetes support | +| 0.2.2 | 2021-04-20 | [2994](https://github.com/airbytehq/airbyte/pull/2994) | Formatting spec | +| 0.2.1 | 2021-04-03 | [2726](https://github.com/airbytehq/airbyte/pull/2726) | Fix base connector versioning | +| 0.2.0 | 2021-03-09 | [2238](https://github.com/airbytehq/airbyte/pull/2238) | Protocol allows future/unknown properties | +| 0.1.7 | 2021-01-21 | [1762](https://github.com/airbytehq/airbyte/pull/1762) | Fix issue large spreadsheet | +| 0.1.6 | 2021-01-27 | [1668](https://github.com/airbytehq/airbyte/pull/1668) | Adopt connector best practices | +| 0.1.5 | 2020-12-30 | [1438](https://github.com/airbytehq/airbyte/pull/1438) | Implement backoff | +| 0.1.4 | 2020-11-30 | [1046](https://github.com/airbytehq/airbyte/pull/1046) | Add connectors using an index YAML file | From af4b0d7244ef1002c13b8c267326be3e9973f6f7 Mon Sep 17 00:00:00 2001 From: simonbutt-datatonic <67054747+simonbutt-datatonic@users.noreply.github.com> Date: Tue, 11 Jul 2023 21:01:41 +0100 Subject: [PATCH 28/63] Update google-analytics-data-api.md (#28081) Updating the "Full Refresh - Overwrite" link in `google-analytics-data-api.md` as currently it sends to a page not found link (https://docs.airbyte.com/understanding-airbyte/glossary#full-refresh-sync). --- docs/integrations/sources/google-analytics-data-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/integrations/sources/google-analytics-data-api.md b/docs/integrations/sources/google-analytics-data-api.md index b478d605f5d0..397790541234 100644 --- a/docs/integrations/sources/google-analytics-data-api.md +++ b/docs/integrations/sources/google-analytics-data-api.md @@ -65,7 +65,7 @@ Use the service account email address to [add a user](https://support.google.com The Google Analytics source connector supports the following [sync modes](https://docs.airbyte.com/cloud/core-concepts#connection-sync-modes): -- [Full Refresh - Overwrite](https://docs.airbyte.com/understanding-airbyte/glossary#full-refresh-sync) +- [Full Refresh - Overwrite](https://docs.airbyte.com/understanding-airbyte/connections/full-refresh-overwrite) - [Full Refresh - Append](https://docs.airbyte.com/understanding-airbyte/connections/full-refresh-append) - [Incremental - Append](https://docs.airbyte.com/understanding-airbyte/connections/incremental-append) - [Incremental - Deduped History](https://docs.airbyte.com/understanding-airbyte/connections/incremental-deduped-history) From 8ff7e580776a657a5e87cf8db9f3a7deab833811 Mon Sep 17 00:00:00 2001 From: markortleb-dice <136358713+markortleb-dice@users.noreply.github.com> Date: Tue, 11 Jul 2023 16:49:07 -0400 Subject: [PATCH 29/63] Source Salesloft: Added new streams (call data records, call dispositions, call sentiments, custom fields, meetings, searches) (#27505) * adding new Salesloft streams * change the version to 1.1.1 * increment the patch version * fixing typo in meetings * fix another typo * making corrections requested by reviewer * increment version in salesloft metadata to 1.2.0 * reformating files * fix expected records * Source Salesloft: change Call Dispositions, Call Sentiments, and Custom Fields to full refresh. Use created_at instead of updated_at for timestamp field for Meetings. * changing meetings cursor field to created_at * Source Salesloft: Convert meetings to a non-incremental stream, since there is no viable cursor field option. * fix schemas and update tests --------- Co-authored-by: sh4sh <6833405+sh4sh@users.noreply.github.com> Co-authored-by: Mal Hancock --- .../connectors/source-salesloft/Dockerfile | 2 +- .../acceptance-test-config.yml | 6 + .../integration_tests/abnormal_state.json | 21 ++ .../integration_tests/configured_catalog.json | 106 ++++++++ .../integration_tests/expected_records.jsonl | 245 +++++------------- .../incremental_catalog.json | 42 +++ .../connectors/source-salesloft/metadata.yaml | 2 +- .../schemas/call_data_records.json | 90 +++++++ .../schemas/call_dispositions.json | 21 ++ .../schemas/call_sentiments.json | 21 ++ .../schemas/custom_fields.json | 27 ++ .../source_salesloft/schemas/meetings.json | 192 ++++++++++++++ .../source_salesloft/schemas/searches.json | 124 +++++++++ .../source_salesloft/source.py | 46 ++++ .../unit_tests/test_source.py | 2 +- docs/integrations/sources/salesloft.md | 7 + 16 files changed, 776 insertions(+), 178 deletions(-) create mode 100644 airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/call_data_records.json create mode 100644 airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/call_dispositions.json create mode 100644 airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/call_sentiments.json create mode 100644 airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/custom_fields.json create mode 100644 airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/meetings.json create mode 100644 airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/searches.json diff --git a/airbyte-integrations/connectors/source-salesloft/Dockerfile b/airbyte-integrations/connectors/source-salesloft/Dockerfile index a687aa3a440c..b927379a10a7 100644 --- a/airbyte-integrations/connectors/source-salesloft/Dockerfile +++ b/airbyte-integrations/connectors/source-salesloft/Dockerfile @@ -34,5 +34,5 @@ COPY source_salesloft ./source_salesloft ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=1.1.1 +LABEL io.airbyte.version=1.2.0 LABEL io.airbyte.name=airbyte/source-salesloft diff --git a/airbyte-integrations/connectors/source-salesloft/acceptance-test-config.yml b/airbyte-integrations/connectors/source-salesloft/acceptance-test-config.yml index ee463e829ecb..fa9271151623 100644 --- a/airbyte-integrations/connectors/source-salesloft/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-salesloft/acceptance-test-config.yml @@ -15,10 +15,16 @@ acceptance_tests: - name: locale_utc_offset bypass_reason: volatile data fail_on_extra_columns: false + empty_streams: + - name: call_data_records + bypass_reason: "no records" - config_path: secrets/config_oauth.json expect_records: path: integration_tests/expected_records.jsonl fail_on_extra_columns: false + empty_streams: + - name: call_data_records + bypass_reason: "no records" connection: tests: - config_path: secrets/config.json diff --git a/airbyte-integrations/connectors/source-salesloft/integration_tests/abnormal_state.json b/airbyte-integrations/connectors/source-salesloft/integration_tests/abnormal_state.json index 81a81225bad3..5a8875fd2e05 100644 --- a/airbyte-integrations/connectors/source-salesloft/integration_tests/abnormal_state.json +++ b/airbyte-integrations/connectors/source-salesloft/integration_tests/abnormal_state.json @@ -89,5 +89,26 @@ "stream_state": { "updated_at": "2122-01-18T21:18:20.000Z" }, "stream_descriptor": { "name": "email_templates" } } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "updated_at": "2122-01-18T21:18:20.000Z" }, + "stream_descriptor": { "name": "call_data_records" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "updated_at": "2122-01-18T21:18:20.000Z" }, + "stream_descriptor": { "name": "meetings" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "updated_at": "2122-01-18T21:18:20.000Z" }, + "stream_descriptor": { "name": "searches" } + } } ] diff --git a/airbyte-integrations/connectors/source-salesloft/integration_tests/configured_catalog.json b/airbyte-integrations/connectors/source-salesloft/integration_tests/configured_catalog.json index 99a5e4c4847d..5879c74639fc 100644 --- a/airbyte-integrations/connectors/source-salesloft/integration_tests/configured_catalog.json +++ b/airbyte-integrations/connectors/source-salesloft/integration_tests/configured_catalog.json @@ -420,6 +420,112 @@ }, "destination_sync_mode": "overwrite", "sync_mode": "full_refresh" + }, + { + "stream": { + "name": "custom_fields", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ], + "source_defined_primary_key": [ + [ + "id" + ] + ] + }, + "destination_sync_mode": "overwrite", + "sync_mode": "full_refresh" + }, + { + "stream": { + "name": "call_data_records", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh", + "incremental" + ], + "source_defined_cursor": true, + "default_cursor_field": [ + "updated_at" + ], + "source_defined_primary_key": [ + [ + "id" + ] + ] + }, + "destination_sync_mode": "overwrite", + "sync_mode": "full_refresh" + }, + { + "stream": { + "name": "call_dispositions", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ], + "source_defined_primary_key": [ + [ + "id" + ] + ] + }, + "destination_sync_mode": "overwrite", + "sync_mode": "full_refresh" + }, + { + "stream": { + "name": "call_sentiments", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ], + "source_defined_primary_key": [ + [ + "id" + ] + ] + }, + "destination_sync_mode": "overwrite", + "sync_mode": "full_refresh" + }, + { + "stream": { + "name": "meetings", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ], + "source_defined_primary_key": [ + [ + "id" + ] + ] + }, + "destination_sync_mode": "overwrite", + "sync_mode": "full_refresh" + }, + { + "stream": { + "name": "searches", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh", + "incremental" + ], + "source_defined_cursor": true, + "default_cursor_field": [ + "updated_at" + ], + "source_defined_primary_key": [ + [ + "id" + ] + ] + }, + "destination_sync_mode": "overwrite", + "sync_mode": "full_refresh" } ] } diff --git a/airbyte-integrations/connectors/source-salesloft/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-salesloft/integration_tests/expected_records.jsonl index 7eee65ef39ab..37483885ed62 100644 --- a/airbyte-integrations/connectors/source-salesloft/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-salesloft/integration_tests/expected_records.jsonl @@ -1,175 +1,70 @@ -{"stream": "cadences", "data": {"id": 340821, "created_at": "2023-03-07T12:47:07.697191-05:00", "updated_at": "2023-03-07T12:47:07.697191-05:00", "archived_at": null, "latest_active_date": null, "team_cadence": false, "shared": true, "remove_bounces_enabled": false, "remove_replies_enabled": false, "opt_out_link_included": false, "draft": false, "override_contact_restrictions": null, "cadence_framework_id": null, "cadence_function": "outbound", "name": "Cadence 1", "external_identifier": null, "tags": [], "creator": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "bounced_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10147", "id": 10147}, "replied_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "added_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10149", "id": 10149}, "finished_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10151", "id": 10151}, "cadence_priority": null, "groups": [], "counts": {"cadence_people": null, "people_acted_on_count": 0, "target_daily_people": 0, "opportunities_created": 0, "meetings_booked": 0}}, "emitted_at": 1684327170434} -{"stream": "cadences", "data": {"id": 25591, "created_at": "2021-09-16T08:20:08.485246-04:00", "updated_at": "2023-03-07T12:43:17.450246-05:00", "archived_at": null, "latest_active_date": null, "team_cadence": false, "shared": true, "remove_bounces_enabled": false, "remove_replies_enabled": false, "opt_out_link_included": true, "draft": false, "override_contact_restrictions": null, "cadence_framework_id": null, "cadence_function": "event", "name": "New Cadence", "external_identifier": null, "tags": ["opt-out"], "creator": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "bounced_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "replied_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "added_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "finished_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10149", "id": 10149}, "cadence_priority": {"_href": "https://api.salesloft.com/v2/cadence_priorities", "id": 3385}, "groups": [], "counts": {"cadence_people": 11, "people_acted_on_count": 0, "target_daily_people": 0, "opportunities_created": 0, "meetings_booked": 0}}, "emitted_at": 1684327170434} -{"stream": "cadence_memberships", "data": {"id": 71245543, "added_at": "2023-03-07T12:12:53.179454-05:00", "created_at": "2023-03-07T12:12:53.186833-05:00", "updated_at": "2023-03-07T12:12:53.210155-05:00", "person_deleted": false, "currently_on_cadence": true, "current_state": "staged", "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "person": {"_href": "https://api.salesloft.com/v2/people/103358221", "id": 103358221}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "latest_action": {"id": 343305169}, "counts": {"views": 0, "clicks": 0, "replies": 0, "calls": 0, "sent_emails": 0, "bounces": 0}}, "emitted_at": 1682600550188} -{"stream": "cadence_memberships", "data": {"id": 71245540, "added_at": "2023-03-07T12:12:53.104252-05:00", "created_at": "2023-03-07T12:12:53.111202-05:00", "updated_at": "2023-03-07T12:12:53.140663-05:00", "person_deleted": false, "currently_on_cadence": true, "current_state": "staged", "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "person": {"_href": "https://api.salesloft.com/v2/people/103358220", "id": 103358220}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "latest_action": {"id": 343305164}, "counts": {"views": 0, "clicks": 0, "replies": 0, "calls": 0, "sent_emails": 0, "bounces": 0}}, "emitted_at": 1682600550189} -{"stream": "cadence_memberships", "data": {"id": 71245537, "added_at": "2023-03-07T12:12:53.034821-05:00", "created_at": "2023-03-07T12:12:53.043064-05:00", "updated_at": "2023-03-07T12:12:53.064853-05:00", "person_deleted": false, "currently_on_cadence": true, "current_state": "staged", "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "person": {"_href": "https://api.salesloft.com/v2/people/103358219", "id": 103358219}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "latest_action": {"id": 343305158}, "counts": {"views": 0, "clicks": 0, "replies": 0, "calls": 0, "sent_emails": 0, "bounces": 0}}, "emitted_at": 1682600550190} -{"stream": "cadence_memberships", "data": {"id": 71245536, "added_at": "2023-03-07T12:12:52.968153-05:00", "created_at": "2023-03-07T12:12:52.976764-05:00", "updated_at": "2023-03-07T12:12:53.000579-05:00", "person_deleted": false, "currently_on_cadence": true, "current_state": "staged", "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "person": {"_href": "https://api.salesloft.com/v2/people/103358218", "id": 103358218}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "latest_action": {"id": 343305154}, "counts": {"views": 0, "clicks": 0, "replies": 0, "calls": 0, "sent_emails": 0, "bounces": 0}}, "emitted_at": 1682600550190} -{"stream": "cadence_memberships", "data": {"id": 71245534, "added_at": "2023-03-07T12:12:52.912138-05:00", "created_at": "2023-03-07T12:12:52.918424-05:00", "updated_at": "2023-03-07T12:12:52.935680-05:00", "person_deleted": false, "currently_on_cadence": true, "current_state": "staged", "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "person": {"_href": "https://api.salesloft.com/v2/people/103358217", "id": 103358217}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "latest_action": {"id": 343305151}, "counts": {"views": 0, "clicks": 0, "replies": 0, "calls": 0, "sent_emails": 0, "bounces": 0}}, "emitted_at": 1682600550190} -{"stream": "cadence_memberships", "data": {"id": 71245530, "added_at": "2023-03-07T12:12:52.849515-05:00", "created_at": "2023-03-07T12:12:52.857286-05:00", "updated_at": "2023-03-07T12:12:52.881880-05:00", "person_deleted": false, "currently_on_cadence": true, "current_state": "staged", "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "person": {"_href": "https://api.salesloft.com/v2/people/103358215", "id": 103358215}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "latest_action": {"id": 343305142}, "counts": {"views": 0, "clicks": 0, "replies": 0, "calls": 0, "sent_emails": 0, "bounces": 0}}, "emitted_at": 1682600550191} -{"stream": "cadence_memberships", "data": {"id": 71245528, "added_at": "2023-03-07T12:12:52.772223-05:00", "created_at": "2023-03-07T12:12:52.780135-05:00", "updated_at": "2023-03-07T12:12:52.808970-05:00", "person_deleted": false, "currently_on_cadence": true, "current_state": "staged", "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "person": {"_href": "https://api.salesloft.com/v2/people/103358214", "id": 103358214}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "latest_action": {"id": 343305138}, "counts": {"views": 0, "clicks": 0, "replies": 0, "calls": 0, "sent_emails": 0, "bounces": 0}}, "emitted_at": 1682600550191} -{"stream": "cadence_memberships", "data": {"id": 71245525, "added_at": "2023-03-07T12:12:52.695686-05:00", "created_at": "2023-03-07T12:12:52.702356-05:00", "updated_at": "2023-03-07T12:12:52.721273-05:00", "person_deleted": false, "currently_on_cadence": true, "current_state": "staged", "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "person": {"_href": "https://api.salesloft.com/v2/people/103358213", "id": 103358213}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "latest_action": {"id": 343305133}, "counts": {"views": 0, "clicks": 0, "replies": 0, "calls": 0, "sent_emails": 0, "bounces": 0}}, "emitted_at": 1682600550191} -{"stream": "cadence_memberships", "data": {"id": 71245522, "added_at": "2023-03-07T12:12:52.625165-05:00", "created_at": "2023-03-07T12:12:52.631608-05:00", "updated_at": "2023-03-07T12:12:52.652336-05:00", "person_deleted": false, "currently_on_cadence": true, "current_state": "staged", "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "person": {"_href": "https://api.salesloft.com/v2/people/103358212", "id": 103358212}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "latest_action": {"id": 343305126}, "counts": {"views": 0, "clicks": 0, "replies": 0, "calls": 0, "sent_emails": 0, "bounces": 0}}, "emitted_at": 1682600550192} -{"stream": "cadence_memberships", "data": {"id": 71245520, "added_at": "2023-03-07T12:12:52.510254-05:00", "created_at": "2023-03-07T12:12:52.522770-05:00", "updated_at": "2023-03-07T12:12:52.558480-05:00", "person_deleted": false, "currently_on_cadence": true, "current_state": "staged", "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "person": {"_href": "https://api.salesloft.com/v2/people/103358211", "id": 103358211}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "latest_action": {"id": 343305124}, "counts": {"views": 0, "clicks": 0, "replies": 0, "calls": 0, "sent_emails": 0, "bounces": 0}}, "emitted_at": 1682600550192} -{"stream": "cadence_memberships", "data": {"id": 4482611, "added_at": "2021-09-16T10:22:15.874489-04:00", "created_at": "2021-09-16T10:22:15.886276-04:00", "updated_at": "2021-09-16T10:22:15.920756-04:00", "person_deleted": false, "currently_on_cadence": true, "current_state": "staged", "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "person": {"_href": "https://api.salesloft.com/v2/people/6509414", "id": 6509414}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "latest_action": {"id": 19115635}, "counts": {"views": 0, "clicks": 0, "replies": 0, "calls": 0, "sent_emails": 0, "bounces": 0}}, "emitted_at": 1682600550192} -{"stream": "people", "data": {"id": 103358219, "created_at": "2023-03-07T12:12:52.362090-05:00", "updated_at": "2023-03-07T12:49:27.205203-05:00", "last_contacted_at": null, "last_replied_at": null, "first_name": "User8", "last_name": "Sample", "display_name": "User8 Sample", "email_address": "user8.sample.airbyte@outlook.com", "full_email_address": "\"User8 Sample\" ", "secondary_email_address": null, "personal_email_address": null, "phone": null, "phone_extension": null, "home_phone": null, "mobile_phone": "16205829403", "linkedin_url": null, "title": "Manager", "city": "San Francisco, CA, US", "state": "CA", "country": null, "work_city": null, "work_state": null, "work_country": null, "crm_url": null, "crm_id": null, "crm_object_type": null, "owner_crm_id": null, "person_company_name": "Company 8", "person_company_website": "http://outlook.com", "person_company_industry": null, "do_not_contact": false, "bouncing": false, "locale": "US/Pacific", "locale_utc_offset": -420, "eu_resident": false, "personal_website": null, "twitter_handle": null, "last_contacted_type": null, "job_seniority": "manager", "custom_fields": {}, "tags": [], "contact_restrictions": [], "success_count": 0, "starred": false, "untouched": false, "counts": {"emails_sent": 0, "emails_viewed": 0, "emails_clicked": 0, "emails_replied_to": 0, "emails_bounced": 0, "calls": 0}, "account": {"_href": "https://api.salesloft.com/v2/accounts/35092358", "id": 35092358}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "import": {"_href": "https://api.salesloft.com/v2/imports/5174826", "id": 5174826}, "person_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "most_recent_cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "last_completed_step_cadence": null, "last_completed_step": null, "cadences": [{"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}]}, "emitted_at": 1682600550999} -{"stream": "people", "data": {"id": 103358220, "created_at": "2023-03-07T12:12:52.405367-05:00", "updated_at": "2023-03-07T12:49:12.464381-05:00", "last_contacted_at": null, "last_replied_at": null, "first_name": "User9", "last_name": "Sample", "display_name": "User9 Sample", "email_address": "user9.sample.airbyte@outlook.com", "full_email_address": "\"User9 Sample\" ", "secondary_email_address": null, "personal_email_address": null, "phone": null, "phone_extension": null, "home_phone": null, "mobile_phone": "19125901057", "linkedin_url": null, "title": "Manager", "city": "San Francisco, CA, US", "state": "CA", "country": null, "work_city": null, "work_state": null, "work_country": null, "crm_url": null, "crm_id": null, "crm_object_type": null, "owner_crm_id": null, "person_company_name": "Company 9", "person_company_website": "http://outlook.com", "person_company_industry": null, "do_not_contact": false, "bouncing": false, "locale": "US/Pacific", "locale_utc_offset": -420, "eu_resident": false, "personal_website": null, "twitter_handle": null, "last_contacted_type": null, "job_seniority": "manager", "custom_fields": {}, "tags": [], "contact_restrictions": [], "success_count": 0, "starred": false, "untouched": false, "counts": {"emails_sent": 0, "emails_viewed": 0, "emails_clicked": 0, "emails_replied_to": 0, "emails_bounced": 0, "calls": 0}, "account": {"_href": "https://api.salesloft.com/v2/accounts/35092358", "id": 35092358}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "import": {"_href": "https://api.salesloft.com/v2/imports/5174826", "id": 5174826}, "person_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "most_recent_cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "last_completed_step_cadence": null, "last_completed_step": null, "cadences": [{"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}]}, "emitted_at": 1682600551000} -{"stream": "people", "data": {"id": 103358221, "created_at": "2023-03-07T12:12:52.433805-05:00", "updated_at": "2023-03-07T12:48:51.576983-05:00", "last_contacted_at": null, "last_replied_at": null, "first_name": "User10", "last_name": "Sample", "display_name": "User10 Sample", "email_address": "user10.sample.airbyte@outlook.com", "full_email_address": "\"User10 Sample\" ", "secondary_email_address": null, "personal_email_address": null, "phone": null, "phone_extension": null, "home_phone": null, "mobile_phone": "14246220939", "linkedin_url": null, "title": "Manager", "city": "San Francisco, CA, US", "state": "CA", "country": null, "work_city": null, "work_state": null, "work_country": null, "crm_url": null, "crm_id": null, "crm_object_type": null, "owner_crm_id": null, "person_company_name": "Company 10", "person_company_website": "http://outlook.com", "person_company_industry": null, "do_not_contact": false, "bouncing": false, "locale": "US/Pacific", "locale_utc_offset": -420, "eu_resident": false, "personal_website": null, "twitter_handle": null, "last_contacted_type": null, "job_seniority": "manager", "custom_fields": {}, "tags": [], "contact_restrictions": [], "success_count": 0, "starred": false, "untouched": false, "counts": {"emails_sent": 0, "emails_viewed": 0, "emails_clicked": 0, "emails_replied_to": 0, "emails_bounced": 0, "calls": 0}, "account": {"_href": "https://api.salesloft.com/v2/accounts/35092358", "id": 35092358}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "import": {"_href": "https://api.salesloft.com/v2/imports/5174826", "id": 5174826}, "person_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "most_recent_cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "last_completed_step_cadence": null, "last_completed_step": null, "cadences": [{"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}]}, "emitted_at": 1682600551000} -{"stream": "people", "data": {"id": 103358218, "created_at": "2023-03-07T12:12:52.332996-05:00", "updated_at": "2023-03-07T12:21:29.512819-05:00", "last_contacted_at": null, "last_replied_at": null, "first_name": "User7", "last_name": "Sample", "display_name": "User7 Sample", "email_address": "user7.sample.airbyte@outlook.com", "full_email_address": "\"User7 Sample\" ", "secondary_email_address": null, "personal_email_address": null, "phone": null, "phone_extension": null, "home_phone": null, "mobile_phone": null, "linkedin_url": null, "title": "Manager", "city": "San Francisco, CA, US", "state": "CA", "country": null, "work_city": null, "work_state": null, "work_country": null, "crm_url": null, "crm_id": null, "crm_object_type": null, "owner_crm_id": null, "person_company_name": "Company 7", "person_company_website": "http://outlook.com", "person_company_industry": null, "do_not_contact": false, "bouncing": false, "locale": "US/Pacific", "locale_utc_offset": -420, "eu_resident": false, "personal_website": null, "twitter_handle": null, "last_contacted_type": null, "job_seniority": "manager", "custom_fields": {}, "tags": [], "contact_restrictions": [], "success_count": 0, "starred": false, "untouched": false, "counts": {"emails_sent": 0, "emails_viewed": 0, "emails_clicked": 0, "emails_replied_to": 0, "emails_bounced": 0, "calls": 0}, "account": {"_href": "https://api.salesloft.com/v2/accounts/35092358", "id": 35092358}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "import": {"_href": "https://api.salesloft.com/v2/imports/5174826", "id": 5174826}, "person_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "most_recent_cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "last_completed_step_cadence": null, "last_completed_step": null, "cadences": [{"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}]}, "emitted_at": 1682600551001} -{"stream": "people", "data": {"id": 103358217, "created_at": "2023-03-07T12:12:52.304206-05:00", "updated_at": "2023-03-07T12:21:29.493399-05:00", "last_contacted_at": null, "last_replied_at": null, "first_name": "User6", "last_name": "Sample", "display_name": "User6 Sample", "email_address": "user6.sample.airbyte@outlook.com", "full_email_address": "\"User6 Sample\" ", "secondary_email_address": null, "personal_email_address": null, "phone": null, "phone_extension": null, "home_phone": null, "mobile_phone": null, "linkedin_url": null, "title": "Manager", "city": "San Francisco, CA, US", "state": "CA", "country": null, "work_city": null, "work_state": null, "work_country": null, "crm_url": null, "crm_id": null, "crm_object_type": null, "owner_crm_id": null, "person_company_name": "Company 6", "person_company_website": "http://outlook.com", "person_company_industry": null, "do_not_contact": false, "bouncing": false, "locale": "US/Pacific", "locale_utc_offset": -420, "eu_resident": false, "personal_website": null, "twitter_handle": null, "last_contacted_type": null, "job_seniority": "manager", "custom_fields": {}, "tags": [], "contact_restrictions": [], "success_count": 0, "starred": false, "untouched": false, "counts": {"emails_sent": 0, "emails_viewed": 0, "emails_clicked": 0, "emails_replied_to": 0, "emails_bounced": 0, "calls": 0}, "account": {"_href": "https://api.salesloft.com/v2/accounts/35092358", "id": 35092358}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "import": {"_href": "https://api.salesloft.com/v2/imports/5174826", "id": 5174826}, "person_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "most_recent_cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "last_completed_step_cadence": null, "last_completed_step": null, "cadences": [{"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}]}, "emitted_at": 1682600551001} -{"stream": "people", "data": {"id": 103358215, "created_at": "2023-03-07T12:12:52.273260-05:00", "updated_at": "2023-03-07T12:21:29.483727-05:00", "last_contacted_at": null, "last_replied_at": null, "first_name": "User5", "last_name": "Sample", "display_name": "User5 Sample", "email_address": "user5.sample.airbyte@outlook.com", "full_email_address": "\"User5 Sample\" ", "secondary_email_address": null, "personal_email_address": null, "phone": null, "phone_extension": null, "home_phone": null, "mobile_phone": null, "linkedin_url": null, "title": "Manager", "city": "San Francisco, CA, US", "state": "CA", "country": null, "work_city": null, "work_state": null, "work_country": null, "crm_url": null, "crm_id": null, "crm_object_type": null, "owner_crm_id": null, "person_company_name": "Company 5", "person_company_website": "http://outlook.com", "person_company_industry": null, "do_not_contact": false, "bouncing": false, "locale": "US/Pacific", "locale_utc_offset": -420, "eu_resident": false, "personal_website": null, "twitter_handle": null, "last_contacted_type": null, "job_seniority": "manager", "custom_fields": {}, "tags": [], "contact_restrictions": [], "success_count": 0, "starred": false, "untouched": false, "counts": {"emails_sent": 0, "emails_viewed": 0, "emails_clicked": 0, "emails_replied_to": 0, "emails_bounced": 0, "calls": 0}, "account": {"_href": "https://api.salesloft.com/v2/accounts/35092358", "id": 35092358}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "import": {"_href": "https://api.salesloft.com/v2/imports/5174826", "id": 5174826}, "person_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "most_recent_cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "last_completed_step_cadence": null, "last_completed_step": null, "cadences": [{"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}]}, "emitted_at": 1682600551002} -{"stream": "people", "data": {"id": 103358214, "created_at": "2023-03-07T12:12:52.241485-05:00", "updated_at": "2023-03-07T12:21:29.478054-05:00", "last_contacted_at": null, "last_replied_at": null, "first_name": "User4", "last_name": "Sample", "display_name": "User4 Sample", "email_address": "user4.sample.airbyte@outlook.com", "full_email_address": "\"User4 Sample\" ", "secondary_email_address": null, "personal_email_address": null, "phone": null, "phone_extension": null, "home_phone": null, "mobile_phone": null, "linkedin_url": null, "title": "Manager", "city": "San Francisco, CA, US", "state": "CA", "country": null, "work_city": null, "work_state": null, "work_country": null, "crm_url": null, "crm_id": null, "crm_object_type": null, "owner_crm_id": null, "person_company_name": "Company 4", "person_company_website": "http://outlook.com", "person_company_industry": null, "do_not_contact": false, "bouncing": false, "locale": "US/Pacific", "locale_utc_offset": -420, "eu_resident": false, "personal_website": null, "twitter_handle": null, "last_contacted_type": null, "job_seniority": "manager", "custom_fields": {}, "tags": [], "contact_restrictions": [], "success_count": 0, "starred": false, "untouched": false, "counts": {"emails_sent": 0, "emails_viewed": 0, "emails_clicked": 0, "emails_replied_to": 0, "emails_bounced": 0, "calls": 0}, "account": {"_href": "https://api.salesloft.com/v2/accounts/35092358", "id": 35092358}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "import": {"_href": "https://api.salesloft.com/v2/imports/5174826", "id": 5174826}, "person_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "most_recent_cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "last_completed_step_cadence": null, "last_completed_step": null, "cadences": [{"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}]}, "emitted_at": 1682600551002} -{"stream": "people", "data": {"id": 103358213, "created_at": "2023-03-07T12:12:52.209832-05:00", "updated_at": "2023-03-07T12:21:29.467289-05:00", "last_contacted_at": null, "last_replied_at": null, "first_name": "User3", "last_name": "Sample", "display_name": "User3 Sample", "email_address": "user3.sample.airbyte@outlook.com", "full_email_address": "\"User3 Sample\" ", "secondary_email_address": null, "personal_email_address": null, "phone": null, "phone_extension": null, "home_phone": null, "mobile_phone": null, "linkedin_url": null, "title": "Manager", "city": "San Francisco, CA, US", "state": "CA", "country": null, "work_city": null, "work_state": null, "work_country": null, "crm_url": null, "crm_id": null, "crm_object_type": null, "owner_crm_id": null, "person_company_name": "Company 3", "person_company_website": "http://outlook.com", "person_company_industry": null, "do_not_contact": false, "bouncing": false, "locale": "US/Pacific", "locale_utc_offset": -420, "eu_resident": false, "personal_website": null, "twitter_handle": null, "last_contacted_type": null, "job_seniority": "manager", "custom_fields": {}, "tags": [], "contact_restrictions": [], "success_count": 0, "starred": false, "untouched": false, "counts": {"emails_sent": 0, "emails_viewed": 0, "emails_clicked": 0, "emails_replied_to": 0, "emails_bounced": 0, "calls": 0}, "account": {"_href": "https://api.salesloft.com/v2/accounts/35092358", "id": 35092358}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "import": {"_href": "https://api.salesloft.com/v2/imports/5174826", "id": 5174826}, "person_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "most_recent_cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "last_completed_step_cadence": null, "last_completed_step": null, "cadences": [{"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}]}, "emitted_at": 1682600551002} -{"stream": "people", "data": {"id": 103358212, "created_at": "2023-03-07T12:12:52.173789-05:00", "updated_at": "2023-03-07T12:21:29.435970-05:00", "last_contacted_at": null, "last_replied_at": null, "first_name": "User2", "last_name": "Sample", "display_name": "User2 Sample", "email_address": "user2.sample.airbyte@gmail.com", "full_email_address": "\"User2 Sample\" ", "secondary_email_address": null, "personal_email_address": null, "phone": null, "phone_extension": null, "home_phone": null, "mobile_phone": null, "linkedin_url": null, "title": "Manager", "city": "San Francisco, CA, US", "state": "CA", "country": null, "work_city": null, "work_state": null, "work_country": null, "crm_url": null, "crm_id": null, "crm_object_type": null, "owner_crm_id": null, "person_company_name": "Company 2", "person_company_website": "http://gmail.com", "person_company_industry": null, "do_not_contact": false, "bouncing": false, "locale": "US/Pacific", "locale_utc_offset": -420, "eu_resident": false, "personal_website": null, "twitter_handle": null, "last_contacted_type": null, "job_seniority": "manager", "custom_fields": {}, "tags": [], "contact_restrictions": [], "success_count": 0, "starred": false, "untouched": false, "counts": {"emails_sent": 0, "emails_viewed": 0, "emails_clicked": 0, "emails_replied_to": 0, "emails_bounced": 0, "calls": 0}, "account": {"_href": "https://api.salesloft.com/v2/accounts/35092357", "id": 35092357}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "import": {"_href": "https://api.salesloft.com/v2/imports/5174826", "id": 5174826}, "person_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "most_recent_cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "last_completed_step_cadence": null, "last_completed_step": null, "cadences": [{"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}]}, "emitted_at": 1682600551003} -{"stream": "people", "data": {"id": 103358211, "created_at": "2023-03-07T12:12:52.141355-05:00", "updated_at": "2023-03-07T12:21:29.433659-05:00", "last_contacted_at": null, "last_replied_at": null, "first_name": "User1", "last_name": "Sample", "display_name": "User1 Sample", "email_address": "user1.sample@zohomail.eu", "full_email_address": "\"User1 Sample\" ", "secondary_email_address": null, "personal_email_address": null, "phone": null, "phone_extension": null, "home_phone": null, "mobile_phone": null, "linkedin_url": null, "title": "Manager", "city": "San Francisco, CA, US", "state": "CA", "country": null, "work_city": null, "work_state": null, "work_country": null, "crm_url": null, "crm_id": null, "crm_object_type": null, "owner_crm_id": null, "person_company_name": "Company 1", "person_company_website": "http://zohomail.eu", "person_company_industry": null, "do_not_contact": false, "bouncing": false, "locale": "US/Pacific", "locale_utc_offset": -420, "eu_resident": false, "personal_website": null, "twitter_handle": null, "last_contacted_type": null, "job_seniority": "manager", "custom_fields": {}, "tags": [], "contact_restrictions": [], "success_count": 0, "starred": false, "untouched": false, "counts": {"emails_sent": 0, "emails_viewed": 0, "emails_clicked": 0, "emails_replied_to": 0, "emails_bounced": 0, "calls": 0}, "account": {"_href": "https://api.salesloft.com/v2/accounts/35092356", "id": 35092356}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "import": {"_href": "https://api.salesloft.com/v2/imports/5174826", "id": 5174826}, "person_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "most_recent_cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "last_completed_step_cadence": null, "last_completed_step": null, "cadences": [{"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}]}, "emitted_at": 1682600551003} -{"stream": "people", "data": {"id": 6509414, "created_at": "2021-09-16T09:54:45.082693-04:00", "updated_at": "2021-09-16T11:03:46.660816-04:00", "last_contacted_at": "2021-09-16T11:02:51.405506-04:00", "last_replied_at": null, "first_name": "Kelly", "last_name": "Irish", "display_name": "Kelly Irish", "email_address": "kellyirish@google.com", "full_email_address": "\"Kelly Irish\" ", "secondary_email_address": null, "personal_email_address": null, "phone": "+1234445556", "phone_extension": null, "home_phone": null, "mobile_phone": "+1234445557", "linkedin_url": null, "title": "seller", "city": null, "state": null, "country": null, "work_city": null, "work_state": null, "work_country": null, "crm_url": null, "crm_id": null, "crm_object_type": null, "owner_crm_id": null, "person_company_name": null, "person_company_website": "http://google.com", "person_company_industry": null, "do_not_contact": false, "bouncing": true, "locale": "US/Pacific", "locale_utc_offset": -420, "eu_resident": false, "personal_website": null, "twitter_handle": null, "last_contacted_type": "email", "job_seniority": "unknown", "custom_fields": {}, "tags": [], "contact_restrictions": [], "success_count": 0, "starred": false, "untouched": false, "counts": {"emails_sent": 1, "emails_viewed": 0, "emails_clicked": 0, "emails_replied_to": 0, "emails_bounced": 1, "calls": 1}, "account": {"_href": "https://api.salesloft.com/v2/accounts/2366578", "id": 2366578}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "import": null, "person_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "most_recent_cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "last_completed_step_cadence": null, "last_completed_step": null, "cadences": [{"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}]}, "emitted_at": 1682600551004} -{"stream": "people", "data": {"id": 6502956, "created_at": "2021-09-16T07:02:46.804979-04:00", "updated_at": "2021-09-16T10:26:17.103697-04:00", "last_contacted_at": "2021-09-16T09:31:12.895350-04:00", "last_replied_at": null, "first_name": "Karina", "last_name": "Kuznietsova", "display_name": "Karina Kuznietsova", "email_address": "karina.kuznietsova@zazmc.com", "full_email_address": "\"Karina Kuznietsova\" ", "secondary_email_address": null, "personal_email_address": null, "phone": "+12345678900", "phone_extension": null, "home_phone": null, "mobile_phone": "+12334567778", "linkedin_url": null, "title": "QA", "city": "San Francisco", "state": "CA", "country": "US", "work_city": "Los Angeles", "work_state": "CA", "work_country": "US", "crm_url": null, "crm_id": null, "crm_object_type": null, "owner_crm_id": null, "person_company_name": null, "person_company_website": "http://zazmc.com", "person_company_industry": "engineering", "do_not_contact": false, "bouncing": true, "locale": "US/Pacific", "locale_utc_offset": -420, "eu_resident": false, "personal_website": null, "twitter_handle": null, "last_contacted_type": "email", "job_seniority": "individual_contributor", "custom_fields": {}, "tags": ["airbyte"], "contact_restrictions": [], "success_count": 1, "starred": false, "untouched": false, "counts": {"emails_sent": 3, "emails_viewed": 0, "emails_clicked": 0, "emails_replied_to": 0, "emails_bounced": 3, "calls": 1}, "account": null, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "import": null, "person_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "most_recent_cadence": null, "last_completed_step_cadence": null, "last_completed_step": null, "cadences": []}, "emitted_at": 1682600551004} -{"stream": "people", "data": {"id": 6503685, "created_at": "2021-09-16T07:24:03.591827-04:00", "updated_at": "2021-09-16T07:24:46.650636-04:00", "last_contacted_at": null, "last_replied_at": null, "first_name": "Tailor", "last_name": "Moon", "display_name": "Tailor Moon", "email_address": "tailormoon@yhoo.com", "full_email_address": "\"Tailor Moon\" ", "secondary_email_address": null, "personal_email_address": null, "phone": "+12345543210", "phone_extension": null, "home_phone": null, "mobile_phone": null, "linkedin_url": null, "title": "Manager", "city": "San Francisco", "state": "CA", "country": "US", "work_city": null, "work_state": null, "work_country": null, "crm_url": null, "crm_id": null, "crm_object_type": null, "owner_crm_id": null, "person_company_name": null, "person_company_website": "http://yhoo.com", "person_company_industry": null, "do_not_contact": false, "bouncing": false, "locale": "US/Pacific", "locale_utc_offset": -420, "eu_resident": false, "personal_website": null, "twitter_handle": null, "last_contacted_type": null, "job_seniority": "manager", "custom_fields": {}, "tags": [], "contact_restrictions": [], "success_count": 0, "starred": false, "untouched": true, "counts": {"emails_sent": 0, "emails_viewed": 0, "emails_clicked": 0, "emails_replied_to": 0, "emails_bounced": 0, "calls": 0}, "account": {"_href": "https://api.salesloft.com/v2/accounts/2364729", "id": 2364729}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "import": null, "person_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "most_recent_cadence": null, "last_completed_step_cadence": null, "last_completed_step": null, "cadences": []}, "emitted_at": 1682600551005} -{"stream": "users", "data": {"id": 52180, "guid": "58d151f8-9b0b-4422-858a-40ea165edc46", "created_at": "2023-03-07T12:28:31.354490-05:00", "updated_at": "2023-03-07T13:10:23.281437-05:00", "name": "User11 Sample", "first_name": "User11", "last_name": "Sample", "job_role": "Operations", "active": true, "time_zone": "US/Eastern", "locale_utc_offset": -240, "slack_username": "iryna.grankova", "twitter_handle": null, "email": "iryna.grankova@airbyte.io", "email_client_email_address": "iryna.grankova@airbyte.io", "sending_email_address": "iryna.grankova@airbyte.io", "from_address": null, "full_email_address": "\"User11 Sample\" ", "bcc_email_address": null, "work_country": "UA", "seat_package": "prospect", "email_signature": "", "email_signature_type": "html", "email_signature_click_tracking_disabled": false, "team_admin": false, "local_dial_enabled": true, "click_to_call_enabled": false, "email_client_configured": false, "crm_connected": false, "external_feature_flags": {"ma_enabled": true, "ma_live_feed": true, "ma_recent_activities_update": true, "ma_person_page": true, "ma_push_notifications": true, "ma_meetings_push_notifications": true, "ma_websockets": true, "ma_edit_person": true, "ma_dev_qa_tools": false, "ma_cadences": false, "hot_leads": true, "people_crud_allow_create": true, "people_crud_allow_delete": true, "ma_mobile_workflow": true, "linkedin_oauth_flow": true}, "_private_fields": {}, "phone_client": {"id": 53219}, "phone_number_assignment": {"_href": "https://api.salesloft.com/v2/phone_number_assignments/34936", "id": 34936}, "group": null, "team": {"_href": "https://api.salesloft.com/v2/team", "id": 104779}, "role": {"id": "User"}}, "emitted_at": 1682600551673} -{"stream": "users", "data": {"id": 6970, "guid": "54713f8f-6283-453f-84da-e27e28223e8c", "created_at": "2021-09-03T12:04:02.458089-04:00", "updated_at": "2023-03-09T14:50:58.222994-05:00", "name": "Airbyte Team", "first_name": "Airbyte", "last_name": "Team", "job_role": "Account Executive / Account Manager", "active": true, "time_zone": "US/Eastern", "locale_utc_offset": -240, "slack_username": "integration-test", "twitter_handle": null, "email": "integration-test@airbyte.io", "email_client_email_address": "karina.kuznietsova@zazmic.com", "sending_email_address": "karina.kuznietsova@zazmic.com", "from_address": null, "full_email_address": "\"Airbyte Team\" ", "bcc_email_address": null, "work_country": "US", "seat_package": "admin", "email_signature": "", "email_signature_type": "html", "email_signature_click_tracking_disabled": false, "team_admin": true, "local_dial_enabled": true, "click_to_call_enabled": false, "email_client_configured": true, "crm_connected": true, "external_feature_flags": {"ma_enabled": true, "ma_live_feed": true, "ma_recent_activities_update": true, "ma_person_page": true, "ma_push_notifications": true, "ma_meetings_push_notifications": true, "ma_websockets": true, "ma_edit_person": true, "ma_dev_qa_tools": false, "ma_cadences": false, "hot_leads": true, "people_crud_allow_create": true, "people_crud_allow_delete": true, "ma_mobile_workflow": true, "linkedin_oauth_flow": true}, "_private_fields": {}, "phone_client": {"id": 7593}, "phone_number_assignment": {"_href": "https://api.salesloft.com/v2/phone_number_assignments/34935", "id": 34935}, "group": null, "team": {"_href": "https://api.salesloft.com/v2/team", "id": 104779}, "role": {"id": "Admin"}}, "emitted_at": 1682600551674} -{"stream": "emails", "data": {"id": 8202787, "created_at": "2021-09-16T10:02:20.479210-04:00", "updated_at": "2021-09-16T11:03:06.789805-04:00", "recipient_email_address": "kellyirish@google.com", "status": "sent", "bounced": true, "send_after": "2021-09-16T11:02:21.934859-04:00", "sent_at": "2021-09-16T11:02:51.405506-04:00", "view_tracking": true, "click_tracking": false, "headers": {}, "personalization": "100.0", "counts": {"clicks": 0, "views": 0, "replies": 0, "unique_devices": 0, "unique_locations": 0, "attachments": 0}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "recipient": {"_href": "https://api.salesloft.com/v2/people/6509414", "id": 6509414}, "mailing": {"id": 3124568}, "action": null, "task": null, "crm_activity": {"_href": "https://api.salesloft.com/v2/crm_activities/11367506", "id": 11367506}, "cadence": null, "step": null, "email_template": null}, "emitted_at": 1682600552239} -{"stream": "emails", "data": {"id": 8194214, "created_at": "2021-09-16T09:30:13.172463-04:00", "updated_at": "2021-09-16T09:31:23.363226-04:00", "recipient_email_address": "karina.kuznietsova@zazmc.com", "status": "sent", "bounced": true, "send_after": "2021-09-16T09:30:27.343687-04:00", "sent_at": "2021-09-16T09:31:12.895350-04:00", "view_tracking": true, "click_tracking": false, "headers": {}, "personalization": "100.0", "counts": {"clicks": 0, "views": 0, "replies": 0, "unique_devices": 0, "unique_locations": 0, "attachments": 0}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "recipient": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "mailing": {"id": 3122753}, "action": null, "task": null, "crm_activity": {"_href": "https://api.salesloft.com/v2/crm_activities/11334017", "id": 11334017}, "cadence": null, "step": null, "email_template": null}, "emitted_at": 1682600552240} -{"stream": "emails", "data": {"id": 8190809, "created_at": "2021-09-16T09:04:44.160528-04:00", "updated_at": "2021-09-16T09:05:48.392667-04:00", "recipient_email_address": "karina.kuznietsova@zazmc.com", "status": "sent", "bounced": true, "send_after": "2021-09-16T09:05:06.374217-04:00", "sent_at": "2021-09-16T09:05:39.849349-04:00", "view_tracking": true, "click_tracking": false, "headers": {}, "personalization": "100.0", "counts": {"clicks": 0, "views": 0, "replies": 0, "unique_devices": 0, "unique_locations": 0, "attachments": 0}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "recipient": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "mailing": {"id": 3121331}, "action": null, "task": null, "crm_activity": {"_href": "https://api.salesloft.com/v2/crm_activities/11324527", "id": 11324527}, "cadence": null, "step": null, "email_template": null}, "emitted_at": 1682600552240} -{"stream": "emails", "data": {"id": 8182634, "created_at": "2021-09-16T07:17:40.583164-04:00", "updated_at": "2021-09-16T07:18:16.263040-04:00", "recipient_email_address": "karina.kuznietsova@zazmc.com", "status": "sent", "bounced": true, "send_after": "2021-09-16T07:17:42.594827-04:00", "sent_at": "2021-09-16T07:18:07.913740-04:00", "view_tracking": true, "click_tracking": false, "headers": {}, "personalization": "100.0", "counts": {"clicks": 0, "views": 0, "replies": 0, "unique_devices": 0, "unique_locations": 0, "attachments": 0}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "recipient": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "mailing": {"id": 3118814}, "action": null, "task": null, "crm_activity": {"_href": "https://api.salesloft.com/v2/crm_activities/11305642", "id": 11305642}, "cadence": null, "step": null, "email_template": null}, "emitted_at": 1682600552240} -{"stream": "calls", "data": {"id": 2117241, "to": "+1234445556", "duration": null, "sentiment": "Customer", "disposition": "No Answer", "created_at": "2021-09-16T10:04:58.125490-04:00", "updated_at": "2021-09-16T10:04:58.295640-04:00", "recordings": [], "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "action": null, "called_person": {"_href": "https://api.salesloft.com/v2/people/6509414", "id": 6509414}, "crm_activity": {"_href": "https://api.salesloft.com/v2/crm_activities/11346104", "id": 11346104}, "note": {"_href": "https://api.salesloft.com/v2/notes/1029422", "id": 1029422}, "cadence": null, "step": null}, "emitted_at": 1682600552756} -{"stream": "calls", "data": {"id": 2113993, "to": "+12345678900", "duration": null, "sentiment": null, "disposition": null, "created_at": "2021-09-16T07:17:57.430595-04:00", "updated_at": "2021-09-16T07:17:57.499713-04:00", "recordings": [], "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "action": null, "called_person": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "crm_activity": {"_href": "https://api.salesloft.com/v2/crm_activities/11305624", "id": 11305624}, "note": null, "cadence": null, "step": null}, "emitted_at": 1682600552756} -{"stream": "account_stages", "data": {"id": 5006, "name": "Disqualified", "created_at": "2021-09-03T12:03:15.863631-04:00", "updated_at": "2021-09-03T12:03:15.863631-04:00", "order": 3}, "emitted_at": 1682600553230} -{"stream": "account_stages", "data": {"id": 5005, "name": "Completed", "created_at": "2021-09-03T12:03:15.850021-04:00", "updated_at": "2021-09-03T12:03:15.850021-04:00", "order": 2}, "emitted_at": 1682600553231} -{"stream": "account_stages", "data": {"id": 5004, "name": "Working", "created_at": "2021-09-03T12:03:15.835536-04:00", "updated_at": "2021-09-03T12:03:15.835536-04:00", "order": 1}, "emitted_at": 1682600553231} -{"stream": "account_stages", "data": {"id": 5003, "name": "Open", "created_at": "2021-09-03T12:03:15.817610-04:00", "updated_at": "2021-09-03T12:03:15.817610-04:00", "order": 0}, "emitted_at": 1682600553231} -{"stream": "account_tiers", "data": {"id": 3469, "name": "Tier 3", "order": 2, "created_at": "2021-09-03T12:03:16.281412-04:00", "updated_at": "2021-09-03T12:03:16.281412-04:00"}, "emitted_at": 1682600553715} -{"stream": "account_tiers", "data": {"id": 3468, "name": "Tier 2", "order": 1, "created_at": "2021-09-03T12:03:16.270440-04:00", "updated_at": "2021-09-03T12:03:16.270440-04:00"}, "emitted_at": 1682600553716} -{"stream": "account_tiers", "data": {"id": 3467, "name": "Tier 1", "order": 0, "created_at": "2021-09-03T12:03:16.235256-04:00", "updated_at": "2021-09-03T12:03:16.235256-04:00"}, "emitted_at": 1682600553716} -{"stream": "accounts", "data": {"id": 35092356, "created_at": "2023-03-07T12:12:53.353476-05:00", "updated_at": "2023-03-07T12:42:45.816560-05:00", "archived_at": null, "name": "Company 1", "domain": "zohomail.eu", "conversational_name": null, "description": null, "phone": null, "website": null, "linkedin_url": null, "twitter_handle": null, "street": null, "city": null, "state": null, "postal_code": null, "country": null, "locale": null, "industry": null, "company_type": null, "founded": null, "revenue_range": null, "size": null, "crm_id": null, "crm_url": null, "crm_object_type": "account", "owner_crm_id": null, "last_contacted_at": null, "last_contacted_type": null, "do_not_contact": false, "custom_fields": {}, "user_relationships": [], "tags": [], "counts": {"people": 1}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "creator": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "last_contacted_person": null, "company_stage": null, "account_tier": null}, "emitted_at": 1682600554256} -{"stream": "accounts", "data": {"id": 35092358, "created_at": "2023-03-07T12:12:53.436918-05:00", "updated_at": "2023-03-07T12:42:45.540331-05:00", "archived_at": null, "name": "Company 4", "domain": "outlook.com", "conversational_name": null, "description": null, "phone": null, "website": null, "linkedin_url": null, "twitter_handle": null, "street": null, "city": null, "state": null, "postal_code": null, "country": null, "locale": null, "industry": null, "company_type": null, "founded": null, "revenue_range": null, "size": null, "crm_id": null, "crm_url": null, "crm_object_type": "account", "owner_crm_id": null, "last_contacted_at": null, "last_contacted_type": null, "do_not_contact": false, "custom_fields": {}, "user_relationships": [], "tags": [], "counts": {"people": 8}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "creator": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "last_contacted_person": null, "company_stage": null, "account_tier": null}, "emitted_at": 1682600554257} -{"stream": "accounts", "data": {"id": 35092357, "created_at": "2023-03-07T12:12:53.393425-05:00", "updated_at": "2023-03-07T12:42:42.384044-05:00", "archived_at": null, "name": "Company 2", "domain": "gmail.com", "conversational_name": null, "description": null, "phone": null, "website": null, "linkedin_url": null, "twitter_handle": null, "street": null, "city": null, "state": null, "postal_code": null, "country": null, "locale": null, "industry": null, "company_type": null, "founded": null, "revenue_range": null, "size": null, "crm_id": null, "crm_url": null, "crm_object_type": "account", "owner_crm_id": null, "last_contacted_at": null, "last_contacted_type": null, "do_not_contact": false, "custom_fields": {}, "user_relationships": [], "tags": [], "counts": {"people": 1}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "creator": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "last_contacted_person": null, "company_stage": null, "account_tier": null}, "emitted_at": 1682600554258} -{"stream": "accounts", "data": {"id": 2366578, "created_at": "2021-09-16T09:39:28.916301-04:00", "updated_at": "2021-09-16T11:02:51.482085-04:00", "archived_at": null, "name": "Karina Testing", "domain": "karina.io", "conversational_name": null, "description": null, "phone": null, "website": null, "linkedin_url": null, "twitter_handle": null, "street": null, "city": null, "state": null, "postal_code": null, "country": null, "locale": null, "industry": null, "company_type": null, "founded": null, "revenue_range": null, "size": null, "crm_id": null, "crm_url": null, "crm_object_type": "account", "owner_crm_id": null, "last_contacted_at": "2021-09-16T11:02:51.405506-04:00", "last_contacted_type": "email", "do_not_contact": false, "custom_fields": {}, "user_relationships": [], "tags": ["salesloft"], "counts": {"people": 1}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "creator": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_person": {"_href": "https://api.salesloft.com/v2/people/6509414", "id": 6509414}, "company_stage": null, "account_tier": null}, "emitted_at": 1682600554258} -{"stream": "accounts", "data": {"id": 2364729, "created_at": "2021-09-16T06:57:53.029439-04:00", "updated_at": "2021-09-16T09:38:36.386606-04:00", "archived_at": null, "name": "Airbyte Testing", "domain": "airbyte.io", "conversational_name": "Karina", "description": "Test account", "phone": "14088669100", "website": "https://airbyte.io/", "linkedin_url": null, "twitter_handle": null, "street": "29th Avenue", "city": "San Francisco", "state": "CA", "postal_code": "94121", "country": "US", "locale": "US/Pacific", "industry": "engineering", "company_type": "Main", "founded": "2020", "revenue_range": "5000000", "size": "14", "crm_id": null, "crm_url": null, "crm_object_type": "account", "owner_crm_id": null, "last_contacted_at": null, "last_contacted_type": null, "do_not_contact": false, "custom_fields": {}, "user_relationships": [], "tags": ["airbyte", "salesloft"], "counts": {"people": 1}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "creator": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "last_contacted_person": null, "company_stage": {"_href": "https://api.salesloft.com/v2/account_stages/5004", "id": 5004}, "account_tier": {"_href": "https://api.salesloft.com/v2/account_tiers/3467", "id": 3467}}, "emitted_at": 1682600554258} -{"stream":"actions","data":{"id":343305169,"due":true,"created_at":"2023-03-07T12:12:53.201684-05:00","updated_at":"2023-06-17T09:53:56.994997-04:00","type":"email","status":"in_progress","due_on":"2023-03-07T00:00:00.000000+00:00","multitouch_group_id":null,"action_details":{"_href":"https://api.salesloft.com/v2/action_details/email_details/198394","id":198394},"user":{"_href":"https://api.salesloft.com/v2/users/6970","id":6970},"person":{"_href":"https://api.salesloft.com/v2/people/103358221","id":103358221},"cadence":{"_href":"https://api.salesloft.com/v2/cadences/25591","id":25591},"step":{"_href":"https://api.salesloft.com/v2/steps/198394","id":198394}},"emitted_at":1687198842250} -{"stream":"actions","data":{"id":343305164,"due":true,"created_at":"2023-03-07T12:12:53.128204-05:00","updated_at":"2023-06-17T09:53:56.950542-04:00","type":"email","status":"in_progress","due_on":"2023-03-07T00:00:00.000000+00:00","multitouch_group_id":null,"action_details":{"_href":"https://api.salesloft.com/v2/action_details/email_details/198394","id":198394},"user":{"_href":"https://api.salesloft.com/v2/users/6970","id":6970},"person":{"_href":"https://api.salesloft.com/v2/people/103358220","id":103358220},"cadence":{"_href":"https://api.salesloft.com/v2/cadences/25591","id":25591},"step":{"_href":"https://api.salesloft.com/v2/steps/198394","id":198394}},"emitted_at":1687198842251} -{"stream":"actions","data":{"id":343305158,"due":true,"created_at":"2023-03-07T12:12:53.058448-05:00","updated_at":"2023-06-17T09:53:56.891992-04:00","type":"email","status":"in_progress","due_on":"2023-03-07T00:00:00.000000+00:00","multitouch_group_id":null,"action_details":{"_href":"https://api.salesloft.com/v2/action_details/email_details/198394","id":198394},"user":{"_href":"https://api.salesloft.com/v2/users/6970","id":6970},"person":{"_href":"https://api.salesloft.com/v2/people/103358219","id":103358219},"cadence":{"_href":"https://api.salesloft.com/v2/cadences/25591","id":25591},"step":{"_href":"https://api.salesloft.com/v2/steps/198394","id":198394}},"emitted_at":1687198842251} -{"stream":"actions","data":{"id":343305154,"due":true,"created_at":"2023-03-07T12:12:52.993213-05:00","updated_at":"2023-06-17T09:53:56.847111-04:00","type":"email","status":"in_progress","due_on":"2023-03-07T00:00:00.000000+00:00","multitouch_group_id":null,"action_details":{"_href":"https://api.salesloft.com/v2/action_details/email_details/198394","id":198394},"user":{"_href":"https://api.salesloft.com/v2/users/6970","id":6970},"person":{"_href":"https://api.salesloft.com/v2/people/103358218","id":103358218},"cadence":{"_href":"https://api.salesloft.com/v2/cadences/25591","id":25591},"step":{"_href":"https://api.salesloft.com/v2/steps/198394","id":198394}},"emitted_at":1687198842252} -{"stream":"actions","data":{"id":343305151,"due":true,"created_at":"2023-03-07T12:12:52.930479-05:00","updated_at":"2023-06-17T09:53:56.787126-04:00","type":"email","status":"in_progress","due_on":"2023-03-07T00:00:00.000000+00:00","multitouch_group_id":null,"action_details":{"_href":"https://api.salesloft.com/v2/action_details/email_details/198394","id":198394},"user":{"_href":"https://api.salesloft.com/v2/users/6970","id":6970},"person":{"_href":"https://api.salesloft.com/v2/people/103358217","id":103358217},"cadence":{"_href":"https://api.salesloft.com/v2/cadences/25591","id":25591},"step":{"_href":"https://api.salesloft.com/v2/steps/198394","id":198394}},"emitted_at":1687198842252} -{"stream":"actions","data":{"id":343305142,"due":true,"created_at":"2023-03-07T12:12:52.876008-05:00","updated_at":"2023-06-17T09:53:56.745470-04:00","type":"email","status":"in_progress","due_on":"2023-03-07T00:00:00.000000+00:00","multitouch_group_id":null,"action_details":{"_href":"https://api.salesloft.com/v2/action_details/email_details/198394","id":198394},"user":{"_href":"https://api.salesloft.com/v2/users/6970","id":6970},"person":{"_href":"https://api.salesloft.com/v2/people/103358215","id":103358215},"cadence":{"_href":"https://api.salesloft.com/v2/cadences/25591","id":25591},"step":{"_href":"https://api.salesloft.com/v2/steps/198394","id":198394}},"emitted_at":1687198842252} -{"stream":"actions","data":{"id":343305138,"due":true,"created_at":"2023-03-07T12:12:52.799215-05:00","updated_at":"2023-06-17T09:53:56.686735-04:00","type":"email","status":"in_progress","due_on":"2023-03-07T00:00:00.000000+00:00","multitouch_group_id":null,"action_details":{"_href":"https://api.salesloft.com/v2/action_details/email_details/198394","id":198394},"user":{"_href":"https://api.salesloft.com/v2/users/6970","id":6970},"person":{"_href":"https://api.salesloft.com/v2/people/103358214","id":103358214},"cadence":{"_href":"https://api.salesloft.com/v2/cadences/25591","id":25591},"step":{"_href":"https://api.salesloft.com/v2/steps/198394","id":198394}},"emitted_at":1687198842252} -{"stream":"actions","data":{"id":343305133,"due":true,"created_at":"2023-03-07T12:12:52.715735-05:00","updated_at":"2023-06-17T09:53:56.642664-04:00","type":"email","status":"in_progress","due_on":"2023-03-07T00:00:00.000000+00:00","multitouch_group_id":null,"action_details":{"_href":"https://api.salesloft.com/v2/action_details/email_details/198394","id":198394},"user":{"_href":"https://api.salesloft.com/v2/users/6970","id":6970},"person":{"_href":"https://api.salesloft.com/v2/people/103358213","id":103358213},"cadence":{"_href":"https://api.salesloft.com/v2/cadences/25591","id":25591},"step":{"_href":"https://api.salesloft.com/v2/steps/198394","id":198394}},"emitted_at":1687198842253} -{"stream":"actions","data":{"id":343305126,"due":true,"created_at":"2023-03-07T12:12:52.646430-05:00","updated_at":"2023-06-17T09:53:56.582732-04:00","type":"email","status":"in_progress","due_on":"2023-03-07T00:00:00.000000+00:00","multitouch_group_id":null,"action_details":{"_href":"https://api.salesloft.com/v2/action_details/email_details/198394","id":198394},"user":{"_href":"https://api.salesloft.com/v2/users/6970","id":6970},"person":{"_href":"https://api.salesloft.com/v2/people/103358212","id":103358212},"cadence":{"_href":"https://api.salesloft.com/v2/cadences/25591","id":25591},"step":{"_href":"https://api.salesloft.com/v2/steps/198394","id":198394}},"emitted_at":1687198842253} -{"stream":"actions","data":{"id":343305124,"due":true,"created_at":"2023-03-07T12:12:52.543926-05:00","updated_at":"2023-06-17T09:53:56.530095-04:00","type":"email","status":"in_progress","due_on":"2023-03-07T00:00:00.000000+00:00","multitouch_group_id":null,"action_details":{"_href":"https://api.salesloft.com/v2/action_details/email_details/198394","id":198394},"user":{"_href":"https://api.salesloft.com/v2/users/6970","id":6970},"person":{"_href":"https://api.salesloft.com/v2/people/103358211","id":103358211},"cadence":{"_href":"https://api.salesloft.com/v2/cadences/25591","id":25591},"step":{"_href":"https://api.salesloft.com/v2/steps/198394","id":198394}},"emitted_at":1687198842253} -{"stream":"actions","data":{"id":19115635,"due":true,"created_at":"2021-09-16T10:22:15.911633-04:00","updated_at":"2023-06-17T09:53:56.474756-04:00","type":"email","status":"in_progress","due_on":"2021-09-16T00:00:00.000000+00:00","multitouch_group_id":null,"action_details":{"_href":"https://api.salesloft.com/v2/action_details/email_details/198394","id":198394},"user":{"_href":"https://api.salesloft.com/v2/users/6970","id":6970},"person":{"_href":"https://api.salesloft.com/v2/people/6509414","id":6509414},"cadence":{"_href":"https://api.salesloft.com/v2/cadences/25591","id":25591},"step":{"_href":"https://api.salesloft.com/v2/steps/198394","id":198394}},"emitted_at":1687198842254} -{"stream": "email_templates", "data": {"id": 6605423, "title": "Team Template 6", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:28:31.552863-05:00", "updated_at": "2023-03-07T12:28:31.552863-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6605423"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/353f478c-c5dd-4c36-8417-3ad5bb88c927", "id": "353f478c-c5dd-4c36-8417-3ad5bb88c927"}, "groups": []}, "emitted_at": 1682600555791} -{"stream": "email_templates", "data": {"id": 6605422, "title": "Team Template 7", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:28:31.526620-05:00", "updated_at": "2023-03-07T12:28:31.526620-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6605422"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/cb3c0c27-95a5-4d06-bc2a-6a1d81859d6f", "id": "cb3c0c27-95a5-4d06-bc2a-6a1d81859d6f"}, "groups": []}, "emitted_at": 1682600555792} -{"stream": "email_templates", "data": {"id": 6605421, "title": "Team Template 10", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:28:31.524798-05:00", "updated_at": "2023-03-07T12:28:31.524798-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6605421"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/75621893-cf7f-41d3-bb45-6d31afc8914c", "id": "75621893-cf7f-41d3-bb45-6d31afc8914c"}, "groups": []}, "emitted_at": 1682600555792} -{"stream": "email_templates", "data": {"id": 6605420, "title": "Team Template 9", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:28:31.518429-05:00", "updated_at": "2023-03-07T12:28:31.518429-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6605420"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/858de732-204b-4a58-a870-f3b551d2d6f3", "id": "858de732-204b-4a58-a870-f3b551d2d6f3"}, "groups": []}, "emitted_at": 1682600555793} -{"stream": "email_templates", "data": {"id": 6605419, "title": "Team Template 8", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:28:31.515791-05:00", "updated_at": "2023-03-07T12:28:31.515791-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6605419"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/d90faaf7-903c-4f1d-b3c1-973c7fa9531d", "id": "d90faaf7-903c-4f1d-b3c1-973c7fa9531d"}, "groups": []}, "emitted_at": 1682600555793} -{"stream": "email_templates", "data": {"id": 6605418, "title": "Team Template 1", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:28:31.505073-05:00", "updated_at": "2023-03-07T12:28:31.505073-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6605418"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/2ae537a5-a2fe-48c5-a2f2-df3d110c3af3", "id": "2ae537a5-a2fe-48c5-a2f2-df3d110c3af3"}, "groups": []}, "emitted_at": 1682600555793} -{"stream": "email_templates", "data": {"id": 6605416, "title": "Team Template 4", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:28:31.497559-05:00", "updated_at": "2023-03-07T12:28:31.497559-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6605416"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/c9cb00f1-0c63-4440-80fd-a58b68affe5d", "id": "c9cb00f1-0c63-4440-80fd-a58b68affe5d"}, "groups": []}, "emitted_at": 1682600555793} -{"stream": "email_templates", "data": {"id": 6605415, "title": "Team Template 5", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:28:31.495168-05:00", "updated_at": "2023-03-07T12:28:31.495168-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6605415"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/2e31b292-dcd1-48fd-b4df-4b788090d487", "id": "2e31b292-dcd1-48fd-b4df-4b788090d487"}, "groups": []}, "emitted_at": 1682600555794} -{"stream": "email_templates", "data": {"id": 6605414, "title": "Team Template 3", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:28:31.489992-05:00", "updated_at": "2023-03-07T12:28:31.489992-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6605414"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/c2d18470-2c55-4dd0-a421-c69f993c0487", "id": "c2d18470-2c55-4dd0-a421-c69f993c0487"}, "groups": []}, "emitted_at": 1682600555794} -{"stream": "email_templates", "data": {"id": 6605413, "title": "Team Template 2", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:28:31.483018-05:00", "updated_at": "2023-03-07T12:28:31.483018-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6605413"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/0d7e1891-893d-47ed-aa4c-9b30dd484a35", "id": "0d7e1891-893d-47ed-aa4c-9b30dd484a35"}, "groups": []}, "emitted_at": 1682600555795} -{"stream": "email_templates", "data": {"id": 6602890, "title": "Test Email Template 9", "subject": "Test Subject", "body": "
\n
Tag9
\n
\"\"Test body
\n
 
\n
Best Regards,
\n
Test signature
\n
", "body_preview": "Tag9 \nTest body \n\u00a0 \nBest Regards, \nTest signature", "created_at": "2023-03-07T11:05:57.501642-05:00", "updated_at": "2023-03-07T12:21:55.154868-05:00", "last_used_at": null, "archived_at": null, "shared": true, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": false, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6602890"}, "tags": ["Tag9"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": null, "groups": []}, "emitted_at": 1682600555795} -{"stream": "email_templates", "data": {"id": 6604896, "title": "Team Template 10", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:19:43.204612-05:00", "updated_at": "2023-03-07T12:19:50.648106-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6604896"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/75621893-cf7f-41d3-bb45-6d31afc8914c", "id": "75621893-cf7f-41d3-bb45-6d31afc8914c"}, "groups": []}, "emitted_at": 1682600555795} -{"stream": "email_templates", "data": {"id": 6604894, "title": "Team Template 9", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:19:31.910224-05:00", "updated_at": "2023-03-07T12:19:37.960137-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6604894"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/858de732-204b-4a58-a870-f3b551d2d6f3", "id": "858de732-204b-4a58-a870-f3b551d2d6f3"}, "groups": []}, "emitted_at": 1682600555795} -{"stream": "email_templates", "data": {"id": 6604779, "title": "Team Template 8", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:19:21.638522-05:00", "updated_at": "2023-03-07T12:19:26.970641-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6604779"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/d90faaf7-903c-4f1d-b3c1-973c7fa9531d", "id": "d90faaf7-903c-4f1d-b3c1-973c7fa9531d"}, "groups": []}, "emitted_at": 1682600555796} -{"stream": "email_templates", "data": {"id": 6604723, "title": "Team Template 7", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:19:10.650378-05:00", "updated_at": "2023-03-07T12:19:16.419317-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6604723"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/cb3c0c27-95a5-4d06-bc2a-6a1d81859d6f", "id": "cb3c0c27-95a5-4d06-bc2a-6a1d81859d6f"}, "groups": []}, "emitted_at": 1682600555796} -{"stream": "email_templates", "data": {"id": 6604722, "title": "Team Template 6", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:18:56.781108-05:00", "updated_at": "2023-03-07T12:19:05.569243-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6604722"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/353f478c-c5dd-4c36-8417-3ad5bb88c927", "id": "353f478c-c5dd-4c36-8417-3ad5bb88c927"}, "groups": []}, "emitted_at": 1682600555796} -{"stream": "email_templates", "data": {"id": 6604721, "title": "Team Template 5", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:18:45.877812-05:00", "updated_at": "2023-03-07T12:18:51.721623-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6604721"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/2e31b292-dcd1-48fd-b4df-4b788090d487", "id": "2e31b292-dcd1-48fd-b4df-4b788090d487"}, "groups": []}, "emitted_at": 1682600555797} -{"stream": "email_templates", "data": {"id": 6604719, "title": "Team Template 4", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:18:35.440122-05:00", "updated_at": "2023-03-07T12:18:40.690325-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6604719"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/c9cb00f1-0c63-4440-80fd-a58b68affe5d", "id": "c9cb00f1-0c63-4440-80fd-a58b68affe5d"}, "groups": []}, "emitted_at": 1682600555797} -{"stream": "email_templates", "data": {"id": 6604714, "title": "Team Template 3", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:18:25.251366-05:00", "updated_at": "2023-03-07T12:18:30.509891-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6604714"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/c2d18470-2c55-4dd0-a421-c69f993c0487", "id": "c2d18470-2c55-4dd0-a421-c69f993c0487"}, "groups": []}, "emitted_at": 1682600555797} -{"stream": "email_templates", "data": {"id": 6604713, "title": "Team Template 2", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:18:14.459208-05:00", "updated_at": "2023-03-07T12:18:20.397620-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6604713"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/0d7e1891-893d-47ed-aa4c-9b30dd484a35", "id": "0d7e1891-893d-47ed-aa4c-9b30dd484a35"}, "groups": []}, "emitted_at": 1682600555797} -{"stream": "email_templates", "data": {"id": 6604711, "title": "Team Template 1", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:18:08.212272-05:00", "updated_at": "2023-03-07T12:18:08.212272-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6604711"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/2ae537a5-a2fe-48c5-a2f2-df3d110c3af3", "id": "2ae537a5-a2fe-48c5-a2f2-df3d110c3af3"}, "groups": []}, "emitted_at": 1682600555798} -{"stream": "email_templates", "data": {"id": 6602865, "title": "Test Email Template 3", "subject": "Test Subject", "body": "
\n
\"\"Test body
\n
 
\n
Best Regards,
\n
Test signature
\n
", "body_preview": "Test body \n\u00a0 \nBest Regards, \nTest signature", "created_at": "2023-03-07T11:04:10.975386-05:00", "updated_at": "2023-03-07T11:10:53.197963-05:00", "last_used_at": null, "archived_at": null, "shared": true, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": false, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6602865"}, "tags": ["Tag3"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": null, "groups": []}, "emitted_at": 1682600555798} -{"stream": "email_templates", "data": {"id": 6602856, "title": "Test Email Template 1", "subject": "Test Subject", "body": "
\n
\"\"Test body
\n
 
\n
Best Regards,
\n
Test signature
\n
", "body_preview": "Test body \n\u00a0 \nBest Regards, \nTest signature", "created_at": "2023-03-07T11:03:47.663912-05:00", "updated_at": "2023-03-07T11:10:35.000495-05:00", "last_used_at": null, "archived_at": null, "shared": true, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": false, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6602856"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": null, "groups": []}, "emitted_at": 1682600555798} -{"stream": "email_templates", "data": {"id": 6602891, "title": "Test Email Template 10", "subject": "Test Subject", "body": "
\n
\"\"Test body
\n
 
\n
Best Regards,
\n
Test signature
\n
", "body_preview": "Test body \n\u00a0 \nBest Regards, \nTest signature", "created_at": "2023-03-07T11:06:09.023206-05:00", "updated_at": "2023-03-07T11:06:15.975470-05:00", "last_used_at": null, "archived_at": null, "shared": true, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": false, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6602891"}, "tags": ["Tag10", "Tag2"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": null, "groups": []}, "emitted_at": 1682600555799} -{"stream": "email_templates", "data": {"id": 6602889, "title": "Test Email Template 8", "subject": "Test Subject", "body": "
\n
\"\"Test body
\n
 
\n
Best Regards,
\n
Test signature
\n
", "body_preview": "Test body \n\u00a0 \nBest Regards, \nTest signature", "created_at": "2023-03-07T11:05:46.915871-05:00", "updated_at": "2023-03-07T11:05:52.679742-05:00", "last_used_at": null, "archived_at": null, "shared": true, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": false, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6602889"}, "tags": ["Tag8"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": null, "groups": []}, "emitted_at": 1682600555799} -{"stream": "email_templates", "data": {"id": 6602887, "title": "Test Email Template 7", "subject": "Test Subject", "body": "
\n
\"\"Test body
\n
 
\n
Best Regards,
\n
Test signature
\n
", "body_preview": "Test body \n\u00a0 \nBest Regards, \nTest signature", "created_at": "2023-03-07T11:05:35.470980-05:00", "updated_at": "2023-03-07T11:05:41.102561-05:00", "last_used_at": null, "archived_at": null, "shared": true, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": false, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6602887"}, "tags": ["Tag7"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": null, "groups": []}, "emitted_at": 1682600555799} -{"stream": "email_templates", "data": {"id": 6602885, "title": "Test Email Template 6", "subject": "Test Subject", "body": "
\n
\"\"Test body
\n
 
\n
Best Regards,
\n
Test signature
\n
", "body_preview": "Test body \n\u00a0 \nBest Regards, \nTest signature", "created_at": "2023-03-07T11:05:22.964779-05:00", "updated_at": "2023-03-07T11:05:29.509996-05:00", "last_used_at": null, "archived_at": null, "shared": true, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": false, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6602885"}, "tags": ["Tag6"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": null, "groups": []}, "emitted_at": 1682600555799} -{"stream": "email_templates", "data": {"id": 6602883, "title": "Test Email Template 5", "subject": "Test Subject", "body": "
\n
\"\"Test body
\n
 
\n
Best Regards,
\n
Test signature
\n
", "body_preview": "Test body \n\u00a0 \nBest Regards, \nTest signature", "created_at": "2023-03-07T11:05:12.722084-05:00", "updated_at": "2023-03-07T11:05:18.659351-05:00", "last_used_at": null, "archived_at": null, "shared": true, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": false, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6602883"}, "tags": ["Tag5"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": null, "groups": []}, "emitted_at": 1682600555800} -{"stream": "email_templates", "data": {"id": 6602880, "title": "Test Email Template 4", "subject": "Test Subject", "body": "
\n
\"\"Test body
\n
 
\n
Best Regards,
\n
Test signature
\n
", "body_preview": "Test body \n\u00a0 \nBest Regards, \nTest signature", "created_at": "2023-03-07T11:05:01.756029-05:00", "updated_at": "2023-03-07T11:05:07.264650-05:00", "last_used_at": null, "archived_at": null, "shared": true, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": false, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6602880"}, "tags": ["Tag4"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": null, "groups": []}, "emitted_at": 1682600555800} -{"stream": "email_templates", "data": {"id": 6602857, "title": "Test Email Template 2", "subject": "Test Subject", "body": "
\n
Test body
\n
 
\n
Best Regards,
\n
Test signature
\n
", "body_preview": "Test body \n\u00a0 \nBest Regards, \nTest signature", "created_at": "2023-03-07T11:03:57.182749-05:00", "updated_at": "2023-03-07T11:04:04.381615-05:00", "last_used_at": null, "archived_at": null, "shared": true, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": false, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6602857"}, "tags": ["Tag2"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "team_template": null, "groups": []}, "emitted_at": 1682600555800} -{"stream": "import", "data": {"id": 5174826, "created_at": "2023-03-07T12:12:52.105709-05:00", "updated_at": "2023-03-07T12:12:52.105709-05:00", "name": "People_Salesloft.csv", "current_people_count": 10, "imported_people_count": 10}, "emitted_at": 1682600556324} -{"stream": "notes", "data": {"id": 1029422, "content": "missed call", "created_at": "2021-09-16T10:04:58.109554-04:00", "updated_at": "2021-09-16T10:04:58.109554-04:00", "associated_type": "person", "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "associated_with": {"_href": "https://api.salesloft.com/v2/people/6509414", "id": 6509414}, "call": {"_href": "https://api.salesloft.com/v2/activities/calls/2117241", "id": 2117241}}, "emitted_at": 1682600556828} -{"stream": "notes", "data": {"id": 1028798, "content": "this is a new note", "created_at": "2021-09-16T09:37:38.057127-04:00", "updated_at": "2021-09-16T09:38:08.829201-04:00", "associated_type": "account", "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "associated_with": {"_href": "https://api.salesloft.com/v2/accounts/2364729", "id": 2364729}, "call": null}, "emitted_at": 1682600556829} -{"stream": "notes", "data": {"id": 1027747, "content": "Test Note", "created_at": "2021-09-16T07:18:35.368918-04:00", "updated_at": "2021-09-16T07:18:35.368918-04:00", "associated_type": "person", "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "associated_with": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "call": null}, "emitted_at": 1682600556829} -{"stream": "person_stages", "data": {"id": 10154, "name": "Replied", "created_at": "2021-09-03T12:03:15.801147-04:00", "updated_at": "2021-09-03T12:03:15.801147-04:00", "order": 7}, "emitted_at": 1682600557293} -{"stream": "person_stages", "data": {"id": 10153, "name": "Completed", "created_at": "2021-09-03T12:03:15.784892-04:00", "updated_at": "2021-09-03T12:03:15.784892-04:00", "order": 6}, "emitted_at": 1682600557294} -{"stream": "person_stages", "data": {"id": 10152, "name": "Do Not Contact", "created_at": "2021-09-03T12:03:15.771896-04:00", "updated_at": "2021-09-03T12:03:15.771896-04:00", "order": 5}, "emitted_at": 1682600557294} -{"stream": "person_stages", "data": {"id": 10151, "name": "Bounced", "created_at": "2021-09-03T12:03:15.757535-04:00", "updated_at": "2021-09-03T12:03:15.757535-04:00", "order": 4}, "emitted_at": 1682600557294} -{"stream": "person_stages", "data": {"id": 10150, "name": "Closed- Not Converted", "created_at": "2021-09-03T12:03:15.735123-04:00", "updated_at": "2021-09-03T12:03:15.735123-04:00", "order": 3}, "emitted_at": 1682600557294} -{"stream": "person_stages", "data": {"id": 10149, "name": "Closed- Converted", "created_at": "2021-09-03T12:03:15.690611-04:00", "updated_at": "2021-09-03T12:03:15.690611-04:00", "order": 2}, "emitted_at": 1682600557294} -{"stream": "person_stages", "data": {"id": 10148, "name": "Working", "created_at": "2021-09-03T12:03:15.669008-04:00", "updated_at": "2021-09-03T12:03:15.669008-04:00", "order": 1}, "emitted_at": 1682600557294} -{"stream": "person_stages", "data": {"id": 10147, "name": "Open", "created_at": "2021-09-03T12:03:15.642239-04:00", "updated_at": "2021-09-03T12:03:15.642239-04:00", "order": 0}, "emitted_at": 1682600557295} -{"stream": "phone_number_assignments", "data": {"id": 34936, "number": "+13807775869", "user": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}}, "emitted_at": 1682600557789} -{"stream": "phone_number_assignments", "data": {"id": 34935, "number": "+13803335311", "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600557790} -{"stream": "steps", "data": {"id": 198394, "created_at": "2021-09-16T10:12:17.764130-04:00", "updated_at": "2023-03-07T12:43:13.069452-05:00", "disabled": false, "type": "email", "name": "Sandbox Account", "display_name": "Day 1: Step 1 - Email", "day": 1, "step_number": 1, "multitouch_enabled": false, "details": {"_href": "https://api.salesloft.com/v2/action_details/email_details/198394", "id": 198394}, "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}}, "emitted_at": 1682600558324} -{"stream": "steps", "data": {"id": 198448, "created_at": "2021-09-16T10:19:08.732399-04:00", "updated_at": "2021-09-16T10:19:08.732399-04:00", "disabled": false, "type": "email", "name": "About company", "display_name": "Day 3: Step 2 - Email", "day": 3, "step_number": 2, "multitouch_enabled": false, "details": {"_href": "https://api.salesloft.com/v2/action_details/email_details/198448", "id": 198448}, "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}}, "emitted_at": 1682600558325} -{"stream": "team_templates", "data": {"id": "75621893-cf7f-41d3-bb45-6d31afc8914c", "title": "Team Template 10", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:19:43.083542-05:00", "updated_at": "2023-03-07T12:19:50.995059-05:00", "last_used_at": null, "archived_at": null, "last_modified_at": "2023-03-07T12:19:50.579224-05:00", "open_tracking_enabled": true, "click_tracking_enabled": false, "_links": {"attachments": "https://api.salesloft.com/v2/team_template_attachments?team_template_id%5B%5D=75621893-cf7f-41d3-bb45-6d31afc8914c"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "last_modified_user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600558969} -{"stream": "team_templates", "data": {"id": "858de732-204b-4a58-a870-f3b551d2d6f3", "title": "Team Template 9", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:19:31.825973-05:00", "updated_at": "2023-03-07T12:19:38.280673-05:00", "last_used_at": null, "archived_at": null, "last_modified_at": "2023-03-07T12:19:37.878579-05:00", "open_tracking_enabled": true, "click_tracking_enabled": false, "_links": {"attachments": "https://api.salesloft.com/v2/team_template_attachments?team_template_id%5B%5D=858de732-204b-4a58-a870-f3b551d2d6f3"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "last_modified_user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600558969} -{"stream": "team_templates", "data": {"id": "d90faaf7-903c-4f1d-b3c1-973c7fa9531d", "title": "Team Template 8", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:19:21.558099-05:00", "updated_at": "2023-03-07T12:19:27.352314-05:00", "last_used_at": null, "archived_at": null, "last_modified_at": "2023-03-07T12:19:26.901056-05:00", "open_tracking_enabled": true, "click_tracking_enabled": false, "_links": {"attachments": "https://api.salesloft.com/v2/team_template_attachments?team_template_id%5B%5D=d90faaf7-903c-4f1d-b3c1-973c7fa9531d"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "last_modified_user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600558969} -{"stream": "team_templates", "data": {"id": "cb3c0c27-95a5-4d06-bc2a-6a1d81859d6f", "title": "Team Template 7", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:19:10.501230-05:00", "updated_at": "2023-03-07T12:19:16.796639-05:00", "last_used_at": null, "archived_at": null, "last_modified_at": "2023-03-07T12:19:16.334281-05:00", "open_tracking_enabled": true, "click_tracking_enabled": false, "_links": {"attachments": "https://api.salesloft.com/v2/team_template_attachments?team_template_id%5B%5D=cb3c0c27-95a5-4d06-bc2a-6a1d81859d6f"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "last_modified_user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600558970} -{"stream": "team_templates", "data": {"id": "353f478c-c5dd-4c36-8417-3ad5bb88c927", "title": "Team Template 6", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:18:56.710041-05:00", "updated_at": "2023-03-07T12:19:05.988093-05:00", "last_used_at": null, "archived_at": null, "last_modified_at": "2023-03-07T12:19:05.462518-05:00", "open_tracking_enabled": true, "click_tracking_enabled": false, "_links": {"attachments": "https://api.salesloft.com/v2/team_template_attachments?team_template_id%5B%5D=353f478c-c5dd-4c36-8417-3ad5bb88c927"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "last_modified_user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600558970} -{"stream": "team_templates", "data": {"id": "2e31b292-dcd1-48fd-b4df-4b788090d487", "title": "Team Template 5", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:18:45.801760-05:00", "updated_at": "2023-03-07T12:18:52.064748-05:00", "last_used_at": null, "archived_at": null, "last_modified_at": "2023-03-07T12:18:51.662511-05:00", "open_tracking_enabled": true, "click_tracking_enabled": false, "_links": {"attachments": "https://api.salesloft.com/v2/team_template_attachments?team_template_id%5B%5D=2e31b292-dcd1-48fd-b4df-4b788090d487"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "last_modified_user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600558970} -{"stream": "team_templates", "data": {"id": "c9cb00f1-0c63-4440-80fd-a58b68affe5d", "title": "Team Template 4", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:18:35.339790-05:00", "updated_at": "2023-03-07T12:18:41.088563-05:00", "last_used_at": null, "archived_at": null, "last_modified_at": "2023-03-07T12:18:40.613109-05:00", "open_tracking_enabled": true, "click_tracking_enabled": false, "_links": {"attachments": "https://api.salesloft.com/v2/team_template_attachments?team_template_id%5B%5D=c9cb00f1-0c63-4440-80fd-a58b68affe5d"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "last_modified_user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600558970} -{"stream": "team_templates", "data": {"id": "c2d18470-2c55-4dd0-a421-c69f993c0487", "title": "Team Template 3", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:18:25.166835-05:00", "updated_at": "2023-03-07T12:18:30.886758-05:00", "last_used_at": null, "archived_at": null, "last_modified_at": "2023-03-07T12:18:30.432862-05:00", "open_tracking_enabled": true, "click_tracking_enabled": false, "_links": {"attachments": "https://api.salesloft.com/v2/team_template_attachments?team_template_id%5B%5D=c2d18470-2c55-4dd0-a421-c69f993c0487"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "last_modified_user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600558971} -{"stream": "team_templates", "data": {"id": "0d7e1891-893d-47ed-aa4c-9b30dd484a35", "title": "Team Template 2", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:18:14.371691-05:00", "updated_at": "2023-03-07T12:18:20.762914-05:00", "last_used_at": null, "archived_at": null, "last_modified_at": "2023-03-07T12:18:20.340839-05:00", "open_tracking_enabled": true, "click_tracking_enabled": false, "_links": {"attachments": "https://api.salesloft.com/v2/team_template_attachments?team_template_id%5B%5D=0d7e1891-893d-47ed-aa4c-9b30dd484a35"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "last_modified_user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600558971} -{"stream": "team_templates", "data": {"id": "2ae537a5-a2fe-48c5-a2f2-df3d110c3af3", "title": "Team Template 1", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:18:08.123679-05:00", "updated_at": "2023-03-07T12:18:08.690684-05:00", "last_used_at": null, "archived_at": null, "last_modified_at": "2023-03-07T12:18:08.074973-05:00", "open_tracking_enabled": true, "click_tracking_enabled": false, "_links": {"attachments": "https://api.salesloft.com/v2/team_template_attachments?team_template_id%5B%5D=2ae537a5-a2fe-48c5-a2f2-df3d110c3af3"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "last_modified_user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600558971} -{"stream": "team_template_attachments", "data": {"id": 4825, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/2ae537a5-a2fe-48c5-a2f2-df3d110c3af3", "id": "2ae537a5-a2fe-48c5-a2f2-df3d110c3af3"}}, "emitted_at": 1682600560611} -{"stream": "team_template_attachments", "data": {"id": 4826, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/0d7e1891-893d-47ed-aa4c-9b30dd484a35", "id": "0d7e1891-893d-47ed-aa4c-9b30dd484a35"}}, "emitted_at": 1682600560612} -{"stream": "team_template_attachments", "data": {"id": 4827, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/c2d18470-2c55-4dd0-a421-c69f993c0487", "id": "c2d18470-2c55-4dd0-a421-c69f993c0487"}}, "emitted_at": 1682600560612} -{"stream": "team_template_attachments", "data": {"id": 4828, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/c9cb00f1-0c63-4440-80fd-a58b68affe5d", "id": "c9cb00f1-0c63-4440-80fd-a58b68affe5d"}}, "emitted_at": 1682600560613} -{"stream": "team_template_attachments", "data": {"id": 4829, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/2e31b292-dcd1-48fd-b4df-4b788090d487", "id": "2e31b292-dcd1-48fd-b4df-4b788090d487"}}, "emitted_at": 1682600560613} -{"stream": "team_template_attachments", "data": {"id": 4830, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/353f478c-c5dd-4c36-8417-3ad5bb88c927", "id": "353f478c-c5dd-4c36-8417-3ad5bb88c927"}}, "emitted_at": 1682600560613} -{"stream": "team_template_attachments", "data": {"id": 4831, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/cb3c0c27-95a5-4d06-bc2a-6a1d81859d6f", "id": "cb3c0c27-95a5-4d06-bc2a-6a1d81859d6f"}}, "emitted_at": 1682600560613} -{"stream": "team_template_attachments", "data": {"id": 4832, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/d90faaf7-903c-4f1d-b3c1-973c7fa9531d", "id": "d90faaf7-903c-4f1d-b3c1-973c7fa9531d"}}, "emitted_at": 1682600560613} -{"stream": "team_template_attachments", "data": {"id": 4833, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/858de732-204b-4a58-a870-f3b551d2d6f3", "id": "858de732-204b-4a58-a870-f3b551d2d6f3"}}, "emitted_at": 1682600560614} -{"stream": "team_template_attachments", "data": {"id": 4834, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/75621893-cf7f-41d3-bb45-6d31afc8914c", "id": "75621893-cf7f-41d3-bb45-6d31afc8914c"}}, "emitted_at": 1682600560614} -{"stream": "crm_activities", "data": {"id": 11367506, "created_at": "2021-09-16T11:02:51.541557-04:00", "updated_at": "2021-09-16T11:03:06.798971-04:00", "subject": "Email: ", "description": "To: \"Kelly Irish\" \n\nSubject: \nBody:\n\n\u00a0 \nhi", "crm_id": null, "activity_type": "email", "error": "Not connected to your CRM", "custom_crm_fields": {"email_message_id": "", "direction": "outbound", "bounced": true}, "person": {"_href": "https://api.salesloft.com/v2/people/6509414", "id": 6509414}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600561128} -{"stream": "crm_activities", "data": {"id": 11346104, "created_at": "2021-09-16T10:04:58.277547-04:00", "updated_at": "2021-09-16T10:04:58.326349-04:00", "subject": "Call: No Answer | Customer", "description": "missed call", "crm_id": null, "activity_type": "phone", "error": "Not connected to your CRM", "custom_crm_fields": {"call_sentiment": "Customer", "call_disposition": "No Answer", "direction": "unknown", "call_to": "+1234445556", "metadata": {}}, "person": {"_href": "https://api.salesloft.com/v2/people/6509414", "id": 6509414}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600561129} -{"stream": "crm_activities", "data": {"id": 11334017, "created_at": "2021-09-16T09:31:13.059842-04:00", "updated_at": "2021-09-16T09:31:23.374677-04:00", "subject": "Email: test 2", "description": "To: \"Karina Kuznietsova\" \n\nSubject: test 2\nBody:\n\n\u00a0 \ntest 2 email", "crm_id": null, "activity_type": "email", "error": "Not connected to your CRM", "custom_crm_fields": {"email_message_id": "", "direction": "outbound", "bounced": true}, "person": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600561129} -{"stream": "crm_activities", "data": {"id": 11329207, "created_at": "2021-09-16T09:18:09.092324-04:00", "updated_at": "2021-09-16T09:18:09.238934-04:00", "subject": "Meeting Booked: Meeting with Karina Kuznietsova", "description": null, "crm_id": null, "activity_type": "meeting_event", "error": "Not connected to your CRM", "custom_crm_fields": {"meeting_assigned_to": "Karina Kuznietsova", "meeting_name": "Meeting with Karina Kuznietsova", "meeting_duration": 30, "meeting_date": "2021-09-16", "meeting_start_time": "2021-09-16T13:30:00+00:00", "meeting_location": "", "meeting_description": "", "meeting_booked_by": "Karina Kuznietsova", "meeting_type": "Default Personal Meeting", "meeting_guests": [], "meeting_attendees": [], "meeting_all_day": false, "meeting_source": "Booked in SalesLoft", "meeting_no_show": false}, "person": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600561130} -{"stream": "crm_activities", "data": {"id": 11328442, "created_at": "2021-09-16T09:16:01.712378-04:00", "updated_at": "2021-09-16T09:16:01.769654-04:00", "subject": "Meeting Booked: Meeting with Karina Kuznietsova", "description": null, "crm_id": null, "activity_type": "meeting_event", "error": "Not connected to your CRM", "custom_crm_fields": {"meeting_assigned_to": "Karina Kuznietsova", "meeting_name": "Meeting with Karina Kuznietsova", "meeting_duration": 30, "meeting_date": "2021-09-17", "meeting_start_time": "2021-09-17T07:15:00+00:00", "meeting_location": "", "meeting_description": "", "meeting_booked_by": "Karina Kuznietsova", "meeting_type": "Default Personal Meeting", "meeting_guests": [], "meeting_attendees": [], "meeting_all_day": false, "meeting_source": "Booked in SalesLoft", "meeting_no_show": false}, "person": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600561130} -{"stream": "crm_activities", "data": {"id": 11324527, "created_at": "2021-09-16T09:05:40.168912-04:00", "updated_at": "2021-09-16T09:05:48.403036-04:00", "subject": "Email: test ", "description": "To: \"Karina Kuznietsova\" \n\nSubject: test \nBody:\n\ntest email \n\u00a0", "crm_id": null, "activity_type": "email", "error": "Not connected to your CRM", "custom_crm_fields": {"email_message_id": "", "direction": "outbound", "bounced": true}, "person": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600561130} -{"stream": "crm_activities", "data": {"id": 11305693, "created_at": "2021-09-16T07:18:35.435230-04:00", "updated_at": "2021-09-16T07:18:35.484403-04:00", "subject": "Note", "description": "Test Note", "crm_id": null, "activity_type": null, "error": "Not connected to your CRM", "custom_crm_fields": {}, "person": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600561131} -{"stream": "crm_activities", "data": {"id": 11305642, "created_at": "2021-09-16T07:18:08.100954-04:00", "updated_at": "2021-09-16T07:18:16.273222-04:00", "subject": "Email: test ", "description": "To: \"Karina Kuznietsova\" \n\nSubject: test \nBody:\n\ntest email \n\u00a0", "crm_id": null, "activity_type": "email", "error": "Not connected to your CRM", "custom_crm_fields": {"email_message_id": "", "direction": "outbound", "bounced": true}, "person": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600561131} -{"stream": "crm_activities", "data": {"id": 11305624, "created_at": "2021-09-16T07:17:57.487992-04:00", "updated_at": "2021-09-16T07:17:57.538224-04:00", "subject": "Call", "description": "", "crm_id": null, "activity_type": "phone", "error": "Not connected to your CRM", "custom_crm_fields": {"direction": "unknown", "call_to": "+12345678900", "metadata": {}}, "person": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600561131} -{"stream": "crm_users", "data": {"id": 41009, "crm_id": "0055e000005ubSNAAY", "created_at": "2023-03-07T12:32:43.804976-05:00", "updated_at": "2023-03-07T12:32:43.804976-05:00", "first_name": "User11", "last_name": "Sample", "name": "User11 Sample", "user": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}}, "emitted_at": 1682600561623} -{"stream": "crm_users", "data": {"id": 41008, "crm_id": "00505000001npKKAAY", "created_at": "2023-03-07T12:32:22.065502-05:00", "updated_at": "2023-03-07T12:32:22.065502-05:00", "first_name": "Airbyte", "last_name": "Team", "name": "Airbyte Team", "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1682600561624} -{"stream": "groups", "data": {"id": 11820, "name": "Group3", "parent_id": null, "accessible_groups": [{"_href": "https://api.salesloft.com/v2/groups/11820", "id": 11820}, {"_href": "https://api.salesloft.com/v2/groups/11827", "id": 11827}]}, "emitted_at": 1682600562427} -{"stream": "groups", "data": {"id": 11827, "name": "Group10", "parent_id": 11820, "accessible_groups": [{"_href": "https://api.salesloft.com/v2/groups/11827", "id": 11827}]}, "emitted_at": 1682600562428} -{"stream": "groups", "data": {"id": 11818, "name": "Group1", "parent_id": null, "accessible_groups": [{"_href": "https://api.salesloft.com/v2/groups/11818", "id": 11818}, {"_href": "https://api.salesloft.com/v2/groups/11821", "id": 11821}, {"_href": "https://api.salesloft.com/v2/groups/11823", "id": 11823}, {"_href": "https://api.salesloft.com/v2/groups/11826", "id": 11826}]}, "emitted_at": 1682600562429} -{"stream": "groups", "data": {"id": 11823, "name": "Group6", "parent_id": 11818, "accessible_groups": [{"_href": "https://api.salesloft.com/v2/groups/11823", "id": 11823}, {"_href": "https://api.salesloft.com/v2/groups/11826", "id": 11826}]}, "emitted_at": 1682600562429} -{"stream": "groups", "data": {"id": 11826, "name": "Group9", "parent_id": 11823, "accessible_groups": [{"_href": "https://api.salesloft.com/v2/groups/11826", "id": 11826}]}, "emitted_at": 1682600562429} -{"stream": "groups", "data": {"id": 11822, "name": "Group5", "parent_id": null, "accessible_groups": [{"_href": "https://api.salesloft.com/v2/groups/11822", "id": 11822}, {"_href": "https://api.salesloft.com/v2/groups/11825", "id": 11825}]}, "emitted_at": 1682600562429} -{"stream": "groups", "data": {"id": 11825, "name": "Group8", "parent_id": 11822, "accessible_groups": [{"_href": "https://api.salesloft.com/v2/groups/11825", "id": 11825}]}, "emitted_at": 1682600562430} -{"stream": "groups", "data": {"id": 11824, "name": "Group7", "parent_id": null, "accessible_groups": [{"_href": "https://api.salesloft.com/v2/groups/11824", "id": 11824}]}, "emitted_at": 1682600562430} -{"stream": "groups", "data": {"id": 11821, "name": "Group4", "parent_id": 11818, "accessible_groups": [{"_href": "https://api.salesloft.com/v2/groups/11821", "id": 11821}]}, "emitted_at": 1682600562430} -{"stream": "groups", "data": {"id": 11819, "name": "Group2", "parent_id": null, "accessible_groups": [{"_href": "https://api.salesloft.com/v2/groups/11819", "id": 11819}]}, "emitted_at": 1682600562430} -{"stream": "successes", "data": {"id": 34605, "created_at": "2021-09-16T09:18:30.667051-04:00", "updated_at": "2021-09-16T09:18:30.667051-04:00", "succeeded_at": "2021-09-16T09:18:30.667051-04:00", "success_window_started_at": "2021-09-16T07:20:01.801041-04:00", "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "person": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "latest_email": null, "latest_call": {"_href": "https://api.salesloft.com/v2/activities/calls/2113993", "id": 2113993}, "latest_action": null, "latest_cadence": null, "latest_step": null, "counts": {"total_emails": 0, "total_calls": 0, "total_other_touches": 0}}, "emitted_at": 1682600562923} -{"stream": "successes", "data": {"id": 34569, "created_at": "2021-09-16T07:20:01.801041-04:00", "updated_at": "2021-09-16T07:20:01.801041-04:00", "succeeded_at": "2021-09-16T07:20:01.801041-04:00", "success_window_started_at": "2021-09-16T07:02:46.804979-04:00", "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "person": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "latest_email": null, "latest_call": {"_href": "https://api.salesloft.com/v2/activities/calls/2113993", "id": 2113993}, "latest_action": null, "latest_cadence": null, "latest_step": null, "counts": {"total_emails": 0, "total_calls": 1, "total_other_touches": 0}}, "emitted_at": 1682600562924} -{"stream": "email_template_attachments", "data": {"id": 255134, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6604711", "id": 6604711}}, "emitted_at": 1682600567092} -{"stream": "email_template_attachments", "data": {"id": 255135, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6604713", "id": 6604713}}, "emitted_at": 1682600567093} -{"stream": "email_template_attachments", "data": {"id": 255136, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6604714", "id": 6604714}}, "emitted_at": 1682600567093} -{"stream": "email_template_attachments", "data": {"id": 255137, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6604719", "id": 6604719}}, "emitted_at": 1682600567093} -{"stream": "email_template_attachments", "data": {"id": 255138, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6604721", "id": 6604721}}, "emitted_at": 1682600567093} -{"stream": "email_template_attachments", "data": {"id": 255139, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6604722", "id": 6604722}}, "emitted_at": 1682600567093} -{"stream": "email_template_attachments", "data": {"id": 255140, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6604723", "id": 6604723}}, "emitted_at": 1682600567094} -{"stream": "email_template_attachments", "data": {"id": 255141, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6604779", "id": 6604779}}, "emitted_at": 1682600567094} -{"stream": "email_template_attachments", "data": {"id": 255142, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6604894", "id": 6604894}}, "emitted_at": 1682600567094} -{"stream": "email_template_attachments", "data": {"id": 255143, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6604896", "id": 6604896}}, "emitted_at": 1682600567094} -{"stream": "email_template_attachments", "data": {"id": 255144, "attachment_id": 597204, "name": "Airbyte logo 120x30.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/e27974daab648ebd7f83f7c51e3ce7300dd52968/Airbyte_logo_120x30.png?1678209646", "attachment_file_size": 3361, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "e97f514cc3453d54b8758058723732c7fda2dee3", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6602856", "id": 6602856}}, "emitted_at": 1682600567094} -{"stream": "email_template_attachments", "data": {"id": 255145, "attachment_id": 597204, "name": "Airbyte logo 120x30.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/e27974daab648ebd7f83f7c51e3ce7300dd52968/Airbyte_logo_120x30.png?1678209646", "attachment_file_size": 3361, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "e97f514cc3453d54b8758058723732c7fda2dee3", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6602891", "id": 6602891}}, "emitted_at": 1682600567094} -{"stream": "email_template_attachments", "data": {"id": 255146, "attachment_id": 597204, "name": "Airbyte logo 120x30.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/e27974daab648ebd7f83f7c51e3ce7300dd52968/Airbyte_logo_120x30.png?1678209646", "attachment_file_size": 3361, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "e97f514cc3453d54b8758058723732c7fda2dee3", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6602857", "id": 6602857}}, "emitted_at": 1682600567094} -{"stream": "email_template_attachments", "data": {"id": 255147, "attachment_id": 597204, "name": "Airbyte logo 120x30.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/e27974daab648ebd7f83f7c51e3ce7300dd52968/Airbyte_logo_120x30.png?1678209646", "attachment_file_size": 3361, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "e97f514cc3453d54b8758058723732c7fda2dee3", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6602865", "id": 6602865}}, "emitted_at": 1682600567095} -{"stream": "email_template_attachments", "data": {"id": 255148, "attachment_id": 597204, "name": "Airbyte logo 120x30.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/e27974daab648ebd7f83f7c51e3ce7300dd52968/Airbyte_logo_120x30.png?1678209646", "attachment_file_size": 3361, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "e97f514cc3453d54b8758058723732c7fda2dee3", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6602880", "id": 6602880}}, "emitted_at": 1682600567095} -{"stream": "email_template_attachments", "data": {"id": 255149, "attachment_id": 597204, "name": "Airbyte logo 120x30.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/e27974daab648ebd7f83f7c51e3ce7300dd52968/Airbyte_logo_120x30.png?1678209646", "attachment_file_size": 3361, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "e97f514cc3453d54b8758058723732c7fda2dee3", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6602885", "id": 6602885}}, "emitted_at": 1682600567095} -{"stream": "email_template_attachments", "data": {"id": 255150, "attachment_id": 597204, "name": "Airbyte logo 120x30.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/e27974daab648ebd7f83f7c51e3ce7300dd52968/Airbyte_logo_120x30.png?1678209646", "attachment_file_size": 3361, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "e97f514cc3453d54b8758058723732c7fda2dee3", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6602889", "id": 6602889}}, "emitted_at": 1682600567095} -{"stream": "email_template_attachments", "data": {"id": 255151, "attachment_id": 597204, "name": "Airbyte logo 120x30.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/e27974daab648ebd7f83f7c51e3ce7300dd52968/Airbyte_logo_120x30.png?1678209646", "attachment_file_size": 3361, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "e97f514cc3453d54b8758058723732c7fda2dee3", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6602890", "id": 6602890}}, "emitted_at": 1682600567095} -{"stream": "email_template_attachments", "data": {"id": 255152, "attachment_id": 597204, "name": "Airbyte logo 120x30.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/e27974daab648ebd7f83f7c51e3ce7300dd52968/Airbyte_logo_120x30.png?1678209646", "attachment_file_size": 3361, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "e97f514cc3453d54b8758058723732c7fda2dee3", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6602883", "id": 6602883}}, "emitted_at": 1682600567095} -{"stream": "email_template_attachments", "data": {"id": 255158, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6605413", "id": 6605413}}, "emitted_at": 1682600567095} -{"stream": "email_template_attachments", "data": {"id": 255159, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6605414", "id": 6605414}}, "emitted_at": 1682600567096} -{"stream": "email_template_attachments", "data": {"id": 255160, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6605415", "id": 6605415}}, "emitted_at": 1682600567096} -{"stream": "email_template_attachments", "data": {"id": 255161, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6605416", "id": 6605416}}, "emitted_at": 1682600567096} -{"stream": "email_template_attachments", "data": {"id": 255162, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6605419", "id": 6605419}}, "emitted_at": 1682600567096} -{"stream": "email_template_attachments", "data": {"id": 255163, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6605420", "id": 6605420}}, "emitted_at": 1682600567096} -{"stream": "email_template_attachments", "data": {"id": 255164, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6605418", "id": 6605418}}, "emitted_at": 1682600567096} -{"stream": "email_template_attachments", "data": {"id": 255165, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6605421", "id": 6605421}}, "emitted_at": 1682600567096} -{"stream": "email_template_attachments", "data": {"id": 255166, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6605422", "id": 6605422}}, "emitted_at": 1682600567097} -{"stream": "email_template_attachments", "data": {"id": 255167, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6605423", "id": 6605423}}, "emitted_at": 1682600567097} +{"stream": "emails", "data": {"id": 8202787, "created_at": "2021-09-16T10:02:20.479210-04:00", "updated_at": "2021-09-16T11:03:06.789805-04:00", "recipient_email_address": "kellyirish@google.com", "status": "sent", "bounced": true, "send_after": "2021-09-16T11:02:21.934859-04:00", "sent_at": "2021-09-16T11:02:51.405506-04:00", "view_tracking": true, "click_tracking": false, "headers": {}, "personalization": "100.0", "counts": {"clicks": 0, "views": 0, "replies": 0, "unique_devices": 0, "unique_locations": 0, "attachments": 0}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "recipient": {"_href": "https://api.salesloft.com/v2/people/6509414", "id": 6509414}, "mailing": {"id": 3124568}, "action": null, "task": null, "crm_activity": {"_href": "https://api.salesloft.com/v2/crm_activities/11367506", "id": 11367506}, "cadence": null, "step": null, "email_template": null}, "emitted_at": 1688663044626} +{"stream": "emails", "data": {"id": 8194214, "created_at": "2021-09-16T09:30:13.172463-04:00", "updated_at": "2021-09-16T09:31:23.363226-04:00", "recipient_email_address": "karina.kuznietsova@zazmc.com", "status": "sent", "bounced": true, "send_after": "2021-09-16T09:30:27.343687-04:00", "sent_at": "2021-09-16T09:31:12.895350-04:00", "view_tracking": true, "click_tracking": false, "headers": {}, "personalization": "100.0", "counts": {"clicks": 0, "views": 0, "replies": 0, "unique_devices": 0, "unique_locations": 0, "attachments": 0}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "recipient": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "mailing": {"id": 3122753}, "action": null, "task": null, "crm_activity": {"_href": "https://api.salesloft.com/v2/crm_activities/11334017", "id": 11334017}, "cadence": null, "step": null, "email_template": null}, "emitted_at": 1688663044627} +{"stream": "emails", "data": {"id": 8190809, "created_at": "2021-09-16T09:04:44.160528-04:00", "updated_at": "2021-09-16T09:05:48.392667-04:00", "recipient_email_address": "karina.kuznietsova@zazmc.com", "status": "sent", "bounced": true, "send_after": "2021-09-16T09:05:06.374217-04:00", "sent_at": "2021-09-16T09:05:39.849349-04:00", "view_tracking": true, "click_tracking": false, "headers": {}, "personalization": "100.0", "counts": {"clicks": 0, "views": 0, "replies": 0, "unique_devices": 0, "unique_locations": 0, "attachments": 0}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "recipient": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "mailing": {"id": 3121331}, "action": null, "task": null, "crm_activity": {"_href": "https://api.salesloft.com/v2/crm_activities/11324527", "id": 11324527}, "cadence": null, "step": null, "email_template": null}, "emitted_at": 1688663044627} +{"stream": "searches", "data": {"id": 4002, "user_slug": "karinakuznietsova", "primary_calendar_id": "karina.kuznietsova@zazmic.com", "primary_calendar_name": "Airbyte Team", "email_address": "karina.kuznietsova@zazmic.com", "user_details": {}, "calendar_type": "gmail", "title": null, "description": null, "location": null, "default_meeting_length": 30, "availability_limit_enabled": false, "availability_limit": 0, "schedule_delay": 0, "buffer_time_duration": 0, "schedule_buffer_enabled": false, "times_available": {"Sunday": {"start_time": "09:00", "end_time": "17:00", "enabled": false}, "Monday": {"start_time": "09:00", "end_time": "17:00", "enabled": true}, "Tuesday": {"start_time": "09:00", "end_time": "17:00", "enabled": true}, "Wednesday": {"start_time": "09:00", "end_time": "17:00", "enabled": true}, "Thursday": {"start_time": "09:00", "end_time": "17:00", "enabled": true}, "Friday": {"start_time": "09:00", "end_time": "17:00", "enabled": true}, "Saturday": {"start_time": "09:00", "end_time": "17:00", "enabled": false}}, "allow_booking_on_behalf": true, "allow_booking_overtime": true, "allow_event_overlap": false, "share_event_detail": false, "enable_dynamic_location": false, "created_at": "2021-09-16T11:20:22.900750Z", "updated_at": "2023-03-07T16:01:09.172091Z", "time_zone": "US/Eastern", "primary_calendar_connection_failed": true, "enable_calendar_sync": false, "reschedule_meetings_enabled": true, "user": {"_href": "https://api.salesloft.com/v2/users/54713f8f-6283-453f-84da-e27e28223e8c", "id": "54713f8f-6283-453f-84da-e27e28223e8c"}, "active_meeting_url": {"url": "https://meetings.salesloft.com/airbytedeveloperlicense/karinakuznietsova", "created_at": "2021-09-16T11:20:23.071018Z", "updated_at": "2021-09-16T11:20:27.648100Z"}}, "emitted_at": 1688663058815} +{"stream": "groups", "data": {"id": 11820, "name": "Group3", "parent_id": null, "accessible_groups": [{"_href": "https://api.salesloft.com/v2/groups/11820", "id": 11820}, {"_href": "https://api.salesloft.com/v2/groups/11827", "id": 11827}]}, "emitted_at": 1688663052134} +{"stream": "groups", "data": {"id": 11827, "name": "Group10", "parent_id": 11820, "accessible_groups": [{"_href": "https://api.salesloft.com/v2/groups/11827", "id": 11827}]}, "emitted_at": 1688663052135} +{"stream": "groups", "data": {"id": 11818, "name": "Group1", "parent_id": null, "accessible_groups": [{"_href": "https://api.salesloft.com/v2/groups/11818", "id": 11818}, {"_href": "https://api.salesloft.com/v2/groups/11821", "id": 11821}, {"_href": "https://api.salesloft.com/v2/groups/11823", "id": 11823}, {"_href": "https://api.salesloft.com/v2/groups/11826", "id": 11826}]}, "emitted_at": 1688663052136} +{"stream": "successes", "data": {"id": 34605, "created_at": "2021-09-16T09:18:30.667051-04:00", "updated_at": "2021-09-16T09:18:30.667051-04:00", "succeeded_at": "2021-09-16T09:18:30.667051-04:00", "success_window_started_at": "2021-09-16T07:20:01.801041-04:00", "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "person": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "latest_email": null, "latest_call": {"_href": "https://api.salesloft.com/v2/activities/calls/2113993", "id": 2113993}, "latest_action": null, "latest_cadence": null, "latest_step": null, "counts": {"total_emails": 0, "total_calls": 0, "total_other_touches": 0}}, "emitted_at": 1688663052494} +{"stream": "successes", "data": {"id": 34569, "created_at": "2021-09-16T07:20:01.801041-04:00", "updated_at": "2021-09-16T07:20:01.801041-04:00", "succeeded_at": "2021-09-16T07:20:01.801041-04:00", "success_window_started_at": "2021-09-16T07:02:46.804979-04:00", "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "person": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "latest_email": null, "latest_call": {"_href": "https://api.salesloft.com/v2/activities/calls/2113993", "id": 2113993}, "latest_action": null, "latest_cadence": null, "latest_step": null, "counts": {"total_emails": 0, "total_calls": 1, "total_other_touches": 0}}, "emitted_at": 1688663052495} +{"stream": "notes", "data": {"id": 1029422, "content": "missed call", "created_at": "2021-09-16T10:04:58.109554-04:00", "updated_at": "2021-09-16T10:04:58.109554-04:00", "associated_type": "person", "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "associated_with": {"_href": "https://api.salesloft.com/v2/people/6509414", "id": 6509414}, "call": {"_href": "https://api.salesloft.com/v2/activities/calls/2117241", "id": 2117241}}, "emitted_at": 1688663047921} +{"stream": "notes", "data": {"id": 1028798, "content": "this is a new note", "created_at": "2021-09-16T09:37:38.057127-04:00", "updated_at": "2021-09-16T09:38:08.829201-04:00", "associated_type": "account", "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "associated_with": {"_href": "https://api.salesloft.com/v2/accounts/2364729", "id": 2364729}, "call": null}, "emitted_at": 1688663047922} +{"stream": "notes", "data": {"id": 1027747, "content": "Test Note", "created_at": "2021-09-16T07:18:35.368918-04:00", "updated_at": "2021-09-16T07:18:35.368918-04:00", "associated_type": "person", "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "associated_with": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "call": null}, "emitted_at": 1688663047922} +{"stream": "steps", "data": {"id": 198394, "created_at": "2021-09-16T10:12:17.764130-04:00", "updated_at": "2023-03-07T12:43:13.069452-05:00", "disabled": false, "type": "email", "name": "Sandbox Account", "display_name": "Day 1: Step 1 - Email", "day": 1, "step_number": 1, "multitouch_enabled": false, "details": {"_href": "https://api.salesloft.com/v2/action_details/email_details/198394", "id": 198394}, "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}}, "emitted_at": 1688663049025} +{"stream": "steps", "data": {"id": 198448, "created_at": "2021-09-16T10:19:08.732399-04:00", "updated_at": "2021-09-16T10:19:08.732399-04:00", "disabled": false, "type": "email", "name": "About company", "display_name": "Day 3: Step 2 - Email", "day": 3, "step_number": 2, "multitouch_enabled": false, "details": {"_href": "https://api.salesloft.com/v2/action_details/email_details/198448", "id": 198448}, "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}}, "emitted_at": 1688663049026} +{"stream": "account_stages", "data": {"id": 5006, "name": "Disqualified", "created_at": "2021-09-03T12:03:15.863631-04:00", "updated_at": "2021-09-03T12:03:15.863631-04:00", "order": 3}, "emitted_at": 1688663045341} +{"stream": "account_stages", "data": {"id": 5005, "name": "Completed", "created_at": "2021-09-03T12:03:15.850021-04:00", "updated_at": "2021-09-03T12:03:15.850021-04:00", "order": 2}, "emitted_at": 1688663045341} +{"stream": "account_stages", "data": {"id": 5004, "name": "Working", "created_at": "2021-09-03T12:03:15.835536-04:00", "updated_at": "2021-09-03T12:03:15.835536-04:00", "order": 1}, "emitted_at": 1688663045341} +{"stream": "account_tiers", "data": {"id": 3469, "name": "Tier 3", "order": 2, "created_at": "2021-09-03T12:03:16.281412-04:00", "updated_at": "2021-09-03T12:03:16.281412-04:00"}, "emitted_at": 1688663045681} +{"stream": "account_tiers", "data": {"id": 3468, "name": "Tier 2", "order": 1, "created_at": "2021-09-03T12:03:16.270440-04:00", "updated_at": "2021-09-03T12:03:16.270440-04:00"}, "emitted_at": 1688663045682} +{"stream": "account_tiers", "data": {"id": 3467, "name": "Tier 1", "order": 0, "created_at": "2021-09-03T12:03:16.235256-04:00", "updated_at": "2021-09-03T12:03:16.235256-04:00"}, "emitted_at": 1688663045682} +{"stream": "people", "data": {"id": 103358219, "created_at": "2023-03-07T12:12:52.362090-05:00", "updated_at": "2023-03-07T12:49:27.205203-05:00", "last_contacted_at": null, "last_replied_at": null, "first_name": "User8", "last_name": "Sample", "display_name": "User8 Sample", "email_address": "user8.sample.airbyte@outlook.com", "full_email_address": "\"User8 Sample\" ", "secondary_email_address": null, "personal_email_address": null, "phone": null, "phone_extension": null, "home_phone": null, "mobile_phone": "16205829403", "linkedin_url": null, "title": "Manager", "city": "San Francisco, CA, US", "state": "CA", "country": null, "work_city": null, "work_state": null, "work_country": null, "crm_url": null, "crm_id": null, "crm_object_type": null, "owner_crm_id": null, "person_company_name": "Company 8", "person_company_website": "http://outlook.com", "person_company_industry": null, "do_not_contact": false, "bouncing": false, "locale": "US/Pacific", "locale_utc_offset": -420, "eu_resident": false, "personal_website": null, "twitter_handle": null, "last_contacted_type": null, "job_seniority": "manager", "custom_fields": {}, "tags": [], "contact_restrictions": [], "success_count": 0, "starred": false, "untouched": false, "counts": {"emails_sent": 0, "emails_viewed": 0, "emails_clicked": 0, "emails_replied_to": 0, "emails_bounced": 0, "calls": 0}, "account": {"_href": "https://api.salesloft.com/v2/accounts/35092358", "id": 35092358}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "import": {"_href": "https://api.salesloft.com/v2/imports/5174826", "id": 5174826}, "person_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "most_recent_cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "last_completed_step_cadence": null, "last_completed_step": null, "cadences": [{"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}]}, "emitted_at": 1688663043752} +{"stream": "people", "data": {"id": 103358220, "created_at": "2023-03-07T12:12:52.405367-05:00", "updated_at": "2023-03-07T12:49:12.464381-05:00", "last_contacted_at": null, "last_replied_at": null, "first_name": "User9", "last_name": "Sample", "display_name": "User9 Sample", "email_address": "user9.sample.airbyte@outlook.com", "full_email_address": "\"User9 Sample\" ", "secondary_email_address": null, "personal_email_address": null, "phone": null, "phone_extension": null, "home_phone": null, "mobile_phone": "19125901057", "linkedin_url": null, "title": "Manager", "city": "San Francisco, CA, US", "state": "CA", "country": null, "work_city": null, "work_state": null, "work_country": null, "crm_url": null, "crm_id": null, "crm_object_type": null, "owner_crm_id": null, "person_company_name": "Company 9", "person_company_website": "http://outlook.com", "person_company_industry": null, "do_not_contact": false, "bouncing": false, "locale": "US/Pacific", "locale_utc_offset": -420, "eu_resident": false, "personal_website": null, "twitter_handle": null, "last_contacted_type": null, "job_seniority": "manager", "custom_fields": {}, "tags": [], "contact_restrictions": [], "success_count": 0, "starred": false, "untouched": false, "counts": {"emails_sent": 0, "emails_viewed": 0, "emails_clicked": 0, "emails_replied_to": 0, "emails_bounced": 0, "calls": 0}, "account": {"_href": "https://api.salesloft.com/v2/accounts/35092358", "id": 35092358}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "import": {"_href": "https://api.salesloft.com/v2/imports/5174826", "id": 5174826}, "person_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "most_recent_cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "last_completed_step_cadence": null, "last_completed_step": null, "cadences": [{"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}]}, "emitted_at": 1688663043753} +{"stream": "people", "data": {"id": 103358221, "created_at": "2023-03-07T12:12:52.433805-05:00", "updated_at": "2023-03-07T12:48:51.576983-05:00", "last_contacted_at": null, "last_replied_at": null, "first_name": "User10", "last_name": "Sample", "display_name": "User10 Sample", "email_address": "user10.sample.airbyte@outlook.com", "full_email_address": "\"User10 Sample\" ", "secondary_email_address": null, "personal_email_address": null, "phone": null, "phone_extension": null, "home_phone": null, "mobile_phone": "14246220939", "linkedin_url": null, "title": "Manager", "city": "San Francisco, CA, US", "state": "CA", "country": null, "work_city": null, "work_state": null, "work_country": null, "crm_url": null, "crm_id": null, "crm_object_type": null, "owner_crm_id": null, "person_company_name": "Company 10", "person_company_website": "http://outlook.com", "person_company_industry": null, "do_not_contact": false, "bouncing": false, "locale": "US/Pacific", "locale_utc_offset": -420, "eu_resident": false, "personal_website": null, "twitter_handle": null, "last_contacted_type": null, "job_seniority": "manager", "custom_fields": {}, "tags": [], "contact_restrictions": [], "success_count": 0, "starred": false, "untouched": false, "counts": {"emails_sent": 0, "emails_viewed": 0, "emails_clicked": 0, "emails_replied_to": 0, "emails_bounced": 0, "calls": 0}, "account": {"_href": "https://api.salesloft.com/v2/accounts/35092358", "id": 35092358}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "import": {"_href": "https://api.salesloft.com/v2/imports/5174826", "id": 5174826}, "person_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "most_recent_cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "last_completed_step_cadence": null, "last_completed_step": null, "cadences": [{"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}]}, "emitted_at": 1688663043754} +{"stream": "team_template_attachments", "data": {"id": 4825, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/2ae537a5-a2fe-48c5-a2f2-df3d110c3af3", "id": "2ae537a5-a2fe-48c5-a2f2-df3d110c3af3"}}, "emitted_at": 1688663051076} +{"stream": "team_template_attachments", "data": {"id": 4826, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/0d7e1891-893d-47ed-aa4c-9b30dd484a35", "id": "0d7e1891-893d-47ed-aa4c-9b30dd484a35"}}, "emitted_at": 1688663051077} +{"stream": "team_template_attachments", "data": {"id": 4827, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/c2d18470-2c55-4dd0-a421-c69f993c0487", "id": "c2d18470-2c55-4dd0-a421-c69f993c0487"}}, "emitted_at": 1688663051077} +{"stream": "phone_number_assignments", "data": {"id": 34936, "number": "+13807775869", "user": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}}, "emitted_at": 1688663048585} +{"stream": "phone_number_assignments", "data": {"id": 34935, "number": "+13803335311", "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1688663048586} +{"stream": "email_templates", "data": {"id": 6605423, "title": "Team Template 6", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:28:31.552863-05:00", "updated_at": "2023-03-07T12:28:31.552863-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6605423"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/353f478c-c5dd-4c36-8417-3ad5bb88c927", "id": "353f478c-c5dd-4c36-8417-3ad5bb88c927"}, "groups": []}, "emitted_at": 1688663047202} +{"stream": "email_templates", "data": {"id": 6605422, "title": "Team Template 7", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:28:31.526620-05:00", "updated_at": "2023-03-07T12:28:31.526620-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6605422"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/cb3c0c27-95a5-4d06-bc2a-6a1d81859d6f", "id": "cb3c0c27-95a5-4d06-bc2a-6a1d81859d6f"}, "groups": []}, "emitted_at": 1688663047202} +{"stream": "email_templates", "data": {"id": 6605421, "title": "Team Template 10", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:28:31.524798-05:00", "updated_at": "2023-03-07T12:28:31.524798-05:00", "last_used_at": null, "archived_at": null, "shared": false, "open_tracking_enabled": true, "click_tracking_enabled": false, "cadence_template": null, "_links": {"attachments": "https://api.salesloft.com/v2/email_template_attachments?email_template_id%5B%5D=6605421"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "template_owner": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}, "team_template": {"_href": "https://api.salesloft.com/v2/team_templates/75621893-cf7f-41d3-bb45-6d31afc8914c", "id": "75621893-cf7f-41d3-bb45-6d31afc8914c"}, "groups": []}, "emitted_at": 1688663047202} +{"stream": "import", "data": {"id": 5174826, "created_at": "2023-03-07T12:12:52.105709-05:00", "updated_at": "2023-03-07T12:12:52.105709-05:00", "name": "People_Salesloft.csv", "current_people_count": 10, "imported_people_count": 10}, "emitted_at": 1688663047572} +{"stream": "team_templates", "data": {"id": "75621893-cf7f-41d3-bb45-6d31afc8914c", "title": "Team Template 10", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:19:43.083542-05:00", "updated_at": "2023-03-07T12:19:50.995059-05:00", "last_used_at": null, "archived_at": null, "last_modified_at": "2023-03-07T12:19:50.579224-05:00", "open_tracking_enabled": true, "click_tracking_enabled": false, "_links": {"attachments": "https://api.salesloft.com/v2/team_template_attachments?team_template_id%5B%5D=75621893-cf7f-41d3-bb45-6d31afc8914c"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "last_modified_user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1688663049578} +{"stream": "team_templates", "data": {"id": "858de732-204b-4a58-a870-f3b551d2d6f3", "title": "Team Template 9", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:19:31.825973-05:00", "updated_at": "2023-03-07T12:19:38.280673-05:00", "last_used_at": null, "archived_at": null, "last_modified_at": "2023-03-07T12:19:37.878579-05:00", "open_tracking_enabled": true, "click_tracking_enabled": false, "_links": {"attachments": "https://api.salesloft.com/v2/team_template_attachments?team_template_id%5B%5D=858de732-204b-4a58-a870-f3b551d2d6f3"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "last_modified_user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1688663049578} +{"stream": "team_templates", "data": {"id": "d90faaf7-903c-4f1d-b3c1-973c7fa9531d", "title": "Team Template 8", "subject": "Test Team Template", "body": "
\n
Test Team Template Description
\n
", "body_preview": "Test Team Template Description", "created_at": "2023-03-07T12:19:21.558099-05:00", "updated_at": "2023-03-07T12:19:27.352314-05:00", "last_used_at": null, "archived_at": null, "last_modified_at": "2023-03-07T12:19:26.901056-05:00", "open_tracking_enabled": true, "click_tracking_enabled": false, "_links": {"attachments": "https://api.salesloft.com/v2/team_template_attachments?team_template_id%5B%5D=d90faaf7-903c-4f1d-b3c1-973c7fa9531d"}, "tags": ["Tag1"], "counts": {"sent_emails": 0, "views": 0, "clicks": 0, "replies": 0, "bounces": 0}, "last_modified_user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1688663049579} +{"stream": "cadence_memberships", "data": {"id": 71245543, "added_at": "2023-03-07T12:12:53.179454-05:00", "created_at": "2023-03-07T12:12:53.186833-05:00", "updated_at": "2023-03-07T12:12:53.210155-05:00", "person_deleted": false, "currently_on_cadence": true, "current_state": "staged", "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "person": {"_href": "https://api.salesloft.com/v2/people/103358221", "id": 103358221}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "latest_action": {"id": 343305169}, "counts": {"views": 0, "clicks": 0, "replies": 0, "calls": 0, "sent_emails": 0, "bounces": 0}}, "emitted_at": 1688663043136} +{"stream": "cadence_memberships", "data": {"id": 71245540, "added_at": "2023-03-07T12:12:53.104252-05:00", "created_at": "2023-03-07T12:12:53.111202-05:00", "updated_at": "2023-03-07T12:12:53.140663-05:00", "person_deleted": false, "currently_on_cadence": true, "current_state": "staged", "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "person": {"_href": "https://api.salesloft.com/v2/people/103358220", "id": 103358220}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "latest_action": {"id": 343305164}, "counts": {"views": 0, "clicks": 0, "replies": 0, "calls": 0, "sent_emails": 0, "bounces": 0}}, "emitted_at": 1688663043136} +{"stream": "cadence_memberships", "data": {"id": 71245537, "added_at": "2023-03-07T12:12:53.034821-05:00", "created_at": "2023-03-07T12:12:53.043064-05:00", "updated_at": "2023-03-07T12:12:53.064853-05:00", "person_deleted": false, "currently_on_cadence": true, "current_state": "staged", "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "person": {"_href": "https://api.salesloft.com/v2/people/103358219", "id": 103358219}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "latest_action": {"id": 343305158}, "counts": {"views": 0, "clicks": 0, "replies": 0, "calls": 0, "sent_emails": 0, "bounces": 0}}, "emitted_at": 1688663043136} +{"stream": "person_stages", "data": {"id": 10154, "name": "Replied", "created_at": "2021-09-03T12:03:15.801147-04:00", "updated_at": "2021-09-03T12:03:15.801147-04:00", "order": 7}, "emitted_at": 1688663048246} +{"stream": "person_stages", "data": {"id": 10153, "name": "Completed", "created_at": "2021-09-03T12:03:15.784892-04:00", "updated_at": "2021-09-03T12:03:15.784892-04:00", "order": 6}, "emitted_at": 1688663048246} +{"stream": "person_stages", "data": {"id": 10152, "name": "Do Not Contact", "created_at": "2021-09-03T12:03:15.771896-04:00", "updated_at": "2021-09-03T12:03:15.771896-04:00", "order": 5}, "emitted_at": 1688663048247} +{"stream": "accounts", "data": {"id": 35092356, "created_at": "2023-03-07T12:12:53.353476-05:00", "updated_at": "2023-03-07T12:42:45.816560-05:00", "archived_at": null, "name": "Company 1", "domain": "zohomail.eu", "conversational_name": null, "description": null, "phone": null, "website": null, "linkedin_url": null, "twitter_handle": null, "street": null, "city": null, "state": null, "postal_code": null, "country": null, "locale": null, "industry": null, "company_type": null, "founded": null, "revenue_range": null, "size": null, "crm_id": null, "crm_url": null, "crm_object_type": "account", "owner_crm_id": null, "last_contacted_at": null, "last_contacted_type": null, "do_not_contact": false, "custom_fields": {}, "user_relationships": [], "tags": [], "counts": {"people": 1}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "creator": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "last_contacted_person": null, "company_stage": null, "account_tier": null}, "emitted_at": 1688663046098} +{"stream": "accounts", "data": {"id": 35092358, "created_at": "2023-03-07T12:12:53.436918-05:00", "updated_at": "2023-03-07T12:42:45.540331-05:00", "archived_at": null, "name": "Company 4", "domain": "outlook.com", "conversational_name": null, "description": null, "phone": null, "website": null, "linkedin_url": null, "twitter_handle": null, "street": null, "city": null, "state": null, "postal_code": null, "country": null, "locale": null, "industry": null, "company_type": null, "founded": null, "revenue_range": null, "size": null, "crm_id": null, "crm_url": null, "crm_object_type": "account", "owner_crm_id": null, "last_contacted_at": null, "last_contacted_type": null, "do_not_contact": false, "custom_fields": {}, "user_relationships": [], "tags": [], "counts": {"people": 8}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "creator": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "last_contacted_person": null, "company_stage": null, "account_tier": null}, "emitted_at": 1688663046099} +{"stream": "accounts", "data": {"id": 35092357, "created_at": "2023-03-07T12:12:53.393425-05:00", "updated_at": "2023-03-07T12:42:42.384044-05:00", "archived_at": null, "name": "Company 2", "domain": "gmail.com", "conversational_name": null, "description": null, "phone": null, "website": null, "linkedin_url": null, "twitter_handle": null, "street": null, "city": null, "state": null, "postal_code": null, "country": null, "locale": null, "industry": null, "company_type": null, "founded": null, "revenue_range": null, "size": null, "crm_id": null, "crm_url": null, "crm_object_type": "account", "owner_crm_id": null, "last_contacted_at": null, "last_contacted_type": null, "do_not_contact": false, "custom_fields": {}, "user_relationships": [], "tags": [], "counts": {"people": 1}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "creator": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "last_contacted_by": null, "last_contacted_person": null, "company_stage": null, "account_tier": null}, "emitted_at": 1688663046099} +{"stream": "cadences", "data": {"id": 340821, "created_at": "2023-03-07T12:47:07.697191-05:00", "updated_at": "2023-03-07T12:47:07.697191-05:00", "archived_at": null, "latest_active_date": null, "team_cadence": false, "shared": true, "remove_bounces_enabled": false, "remove_replies_enabled": false, "opt_out_link_included": false, "draft": false, "override_contact_restrictions": null, "cadence_framework_id": null, "cadence_function": "outbound", "name": "Cadence 1", "external_identifier": null, "tags": [], "creator": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "bounced_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10147", "id": 10147}, "replied_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "added_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10149", "id": 10149}, "finished_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10151", "id": 10151}, "cadence_priority": null, "groups": [], "counts": {"cadence_people": null, "people_acted_on_count": 0, "target_daily_people": 0, "opportunities_created": 0, "meetings_booked": 0}}, "emitted_at": 1688663042778} +{"stream": "cadences", "data": {"id": 25591, "created_at": "2021-09-16T08:20:08.485246-04:00", "updated_at": "2023-03-07T12:43:17.450246-05:00", "archived_at": null, "latest_active_date": null, "team_cadence": false, "shared": true, "remove_bounces_enabled": false, "remove_replies_enabled": false, "opt_out_link_included": true, "draft": false, "override_contact_restrictions": null, "cadence_framework_id": null, "cadence_function": "event", "name": "New Cadence", "external_identifier": null, "tags": ["opt-out"], "creator": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "owner": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "bounced_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "replied_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "added_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10148", "id": 10148}, "finished_stage": {"_href": "https://api.salesloft.com/v2/person_stages/10149", "id": 10149}, "cadence_priority": {"_href": "https://api.salesloft.com/v2/cadence_priorities", "id": 3385}, "groups": [], "counts": {"cadence_people": 11, "people_acted_on_count": 0, "target_daily_people": 0, "opportunities_created": 0, "meetings_booked": 0}}, "emitted_at": 1688663042779} +{"stream": "call_dispositions", "data": {"id": 8740, "created_at": "2021-09-03T12:03:16.028383-04:00", "updated_at": "2021-09-03T12:03:16.028383-04:00", "name": "Busy"}, "emitted_at": 1688663057513} +{"stream": "call_dispositions", "data": {"id": 8741, "created_at": "2021-09-03T12:03:16.052231-04:00", "updated_at": "2021-09-03T12:03:16.052231-04:00", "name": "Connected"}, "emitted_at": 1688663057515} +{"stream": "call_dispositions", "data": {"id": 8745, "created_at": "2021-09-03T12:03:16.107806-04:00", "updated_at": "2021-09-03T12:03:16.107806-04:00", "name": "Left Voicemail"}, "emitted_at": 1688663057515} +{"stream": "crm_users", "data": {"id": 41009, "crm_id": "0055e000005ubSNAAY", "created_at": "2023-03-07T12:32:43.804976-05:00", "updated_at": "2023-03-07T12:32:43.804976-05:00", "first_name": "User11", "last_name": "Sample", "name": "User11 Sample", "user": {"_href": "https://api.salesloft.com/v2/users/52180", "id": 52180}}, "emitted_at": 1688663051796} +{"stream": "crm_users", "data": {"id": 41008, "crm_id": "00505000001npKKAAY", "created_at": "2023-03-07T12:32:22.065502-05:00", "updated_at": "2023-03-07T12:32:22.065502-05:00", "first_name": "Airbyte", "last_name": "Team", "name": "Airbyte Team", "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1688663051797} +{"stream": "email_template_attachments", "data": {"id": 255134, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6604711", "id": 6604711}}, "emitted_at": 1688663056384} +{"stream": "email_template_attachments", "data": {"id": 255135, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6604713", "id": 6604713}}, "emitted_at": 1688663056385} +{"stream": "email_template_attachments", "data": {"id": 255136, "attachment_id": 597193, "name": "Airbyte logo 75x75.png", "download_url": "https://sdr-scanii-prod-us3.storage.googleapis.com/attachments/da400c613af3917b3d510b3f9152e0a338d51554/Airbyte_logo_75x75.png?1678209474", "attachment_file_size": 6132, "scanned": true, "attachment_content_type": "image/png", "attachment_fingerprint": "0050641c170ca71780863dc0cdaa63cae7b4101a", "email_template": {"_href": "https://api.salesloft.com/v2/email_templates/6604714", "id": 6604714}}, "emitted_at": 1688663056386} +{"stream": "crm_activities", "data": {"id": 11367506, "created_at": "2021-09-16T11:02:51.541557-04:00", "updated_at": "2021-09-16T11:03:06.798971-04:00", "subject": "Email: ", "description": "To: \"Kelly Irish\" \n\nSubject: \nBody:\n\n\u00a0 \nhi", "crm_id": null, "activity_type": "email", "error": "Not connected to your CRM", "custom_crm_fields": {"email_message_id": "", "direction": "outbound", "bounced": true}, "person": {"_href": "https://api.salesloft.com/v2/people/6509414", "id": 6509414}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1688663051444} +{"stream": "crm_activities", "data": {"id": 11346104, "created_at": "2021-09-16T10:04:58.277547-04:00", "updated_at": "2021-09-16T10:04:58.326349-04:00", "subject": "Call: No Answer | Customer", "description": "missed call", "crm_id": null, "activity_type": "phone", "error": "Not connected to your CRM", "custom_crm_fields": {"call_sentiment": "Customer", "call_disposition": "No Answer", "direction": "unknown", "call_to": "+1234445556", "metadata": {}}, "person": {"_href": "https://api.salesloft.com/v2/people/6509414", "id": 6509414}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1688663051445} +{"stream": "crm_activities", "data": {"id": 11334017, "created_at": "2021-09-16T09:31:13.059842-04:00", "updated_at": "2021-09-16T09:31:23.374677-04:00", "subject": "Email: test 2", "description": "To: \"Karina Kuznietsova\" \n\nSubject: test 2\nBody:\n\n\u00a0 \ntest 2 email", "crm_id": null, "activity_type": "email", "error": "Not connected to your CRM", "custom_crm_fields": {"email_message_id": "", "direction": "outbound", "bounced": true}, "person": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}}, "emitted_at": 1688663051446} +{"stream": "call_sentiments", "data": {"id": 15076, "created_at": "2021-09-03T12:03:15.893251-04:00", "updated_at": "2021-09-03T12:03:15.893251-04:00", "name": "Company - Bad Fit"}, "emitted_at": 1688663057904} +{"stream": "call_sentiments", "data": {"id": 15077, "created_at": "2021-09-03T12:03:15.903392-04:00", "updated_at": "2021-09-03T12:03:15.903392-04:00", "name": "Contact - Bad Fit"}, "emitted_at": 1688663057905} +{"stream": "call_sentiments", "data": {"id": 15079, "created_at": "2021-09-03T12:03:15.927346-04:00", "updated_at": "2021-09-03T12:03:15.927346-04:00", "name": "Customer"}, "emitted_at": 1688663057905} +{"stream": "meetings", "data": {"id": 66445, "title": "Meeting with Karina Kuznietsova", "start_time": "2021-09-17T07:15:00.000000Z", "end_time": "2021-09-17T07:45:00.000000Z", "calendar_id": "karina.kuznietsova@zazmic.com", "calendar_type": "gmail", "meeting_type": null, "recipient_name": "Karina Kuznietsova", "recipient_email": "karina.kuznietsova@zazmc.com", "location": "", "description": "", "event_id": "rf641atglm8tt4hkbu91kv1p6c", "account_id": null, "task_id": 123599, "created_at": "2021-09-16T13:15:56.122269Z", "updated_at": "2022-07-27T09:09:28.112086Z", "guests": [], "crm_references": null, "event_source": "internal", "canceled_at": null, "all_day": false, "no_show": false, "crm_custom_fields": null, "strict_attribution": false, "i_cal_uid": "rf641atglm8tt4hkbu91kv1p6c@google.com", "status": "booked", "reschedule_status": null, "attendees": [], "person": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "cadence": null, "step": null, "booked_by_user": {"_href": "https://api.salesloft.com/v2/users/54713f8f-6283-453f-84da-e27e28223e8c", "id": "54713f8f-6283-453f-84da-e27e28223e8c"}}, "emitted_at": 1688663058393} +{"stream": "meetings", "data": {"id": 66450, "title": "Meeting with Karina Kuznietsova", "start_time": "2021-09-16T13:30:00.000000Z", "end_time": "2021-09-16T14:00:00.000000Z", "calendar_id": "karina.kuznietsova@zazmic.com", "calendar_type": "gmail", "meeting_type": null, "recipient_name": "Karina Kuznietsova", "recipient_email": "karina.kuznietsova@zazmc.com", "location": "", "description": "", "event_id": "9qqo8mlb1llolnp2g1dgrh339c", "account_id": null, "task_id": 123608, "created_at": "2021-09-16T13:18:00.421729Z", "updated_at": "2022-07-27T09:09:28.156604Z", "guests": [], "crm_references": null, "event_source": "internal", "canceled_at": null, "all_day": false, "no_show": false, "crm_custom_fields": null, "strict_attribution": false, "i_cal_uid": "9qqo8mlb1llolnp2g1dgrh339c@google.com", "status": "booked", "reschedule_status": null, "attendees": [], "person": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "cadence": null, "step": null, "booked_by_user": {"_href": "https://api.salesloft.com/v2/users/54713f8f-6283-453f-84da-e27e28223e8c", "id": "54713f8f-6283-453f-84da-e27e28223e8c"}}, "emitted_at": 1688663058394} +{"stream": "actions", "data": {"id": 343305169, "due": true, "created_at": "2023-03-07T12:12:53.201684-05:00", "updated_at": "2023-06-17T09:53:56.994997-04:00", "type": "email", "status": "in_progress", "due_on": "2023-03-07T00:00:00.000000+00:00", "multitouch_group_id": null, "action_details": {"_href": "https://api.salesloft.com/v2/action_details/email_details/198394", "id": 198394}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "person": {"_href": "https://api.salesloft.com/v2/people/103358221", "id": 103358221}, "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "step": {"_href": "https://api.salesloft.com/v2/steps/198394", "id": 198394}}, "emitted_at": 1688663046502} +{"stream": "actions", "data": {"id": 343305164, "due": true, "created_at": "2023-03-07T12:12:53.128204-05:00", "updated_at": "2023-06-17T09:53:56.950542-04:00", "type": "email", "status": "in_progress", "due_on": "2023-03-07T00:00:00.000000+00:00", "multitouch_group_id": null, "action_details": {"_href": "https://api.salesloft.com/v2/action_details/email_details/198394", "id": 198394}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "person": {"_href": "https://api.salesloft.com/v2/people/103358220", "id": 103358220}, "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "step": {"_href": "https://api.salesloft.com/v2/steps/198394", "id": 198394}}, "emitted_at": 1688663046505} +{"stream": "actions", "data": {"id": 343305158, "due": true, "created_at": "2023-03-07T12:12:53.058448-05:00", "updated_at": "2023-06-17T09:53:56.891992-04:00", "type": "email", "status": "in_progress", "due_on": "2023-03-07T00:00:00.000000+00:00", "multitouch_group_id": null, "action_details": {"_href": "https://api.salesloft.com/v2/action_details/email_details/198394", "id": 198394}, "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "person": {"_href": "https://api.salesloft.com/v2/people/103358219", "id": 103358219}, "cadence": {"_href": "https://api.salesloft.com/v2/cadences/25591", "id": 25591}, "step": {"_href": "https://api.salesloft.com/v2/steps/198394", "id": 198394}}, "emitted_at": 1688663046505} +{"stream": "users", "data": {"id": 52180, "guid": "58d151f8-9b0b-4422-858a-40ea165edc46", "created_at": "2023-03-07T12:28:31.354490-05:00", "updated_at": "2023-03-07T13:10:23.281437-05:00", "name": "User11 Sample", "first_name": "User11", "last_name": "Sample", "job_role": "Operations", "active": true, "time_zone": "US/Eastern", "locale_utc_offset": -240, "slack_username": "iryna.grankova", "twitter_handle": null, "email": "iryna.grankova@airbyte.io", "email_client_email_address": "iryna.grankova@airbyte.io", "sending_email_address": "iryna.grankova@airbyte.io", "from_address": null, "full_email_address": "\"User11 Sample\" ", "bcc_email_address": null, "work_country": "UA", "seat_package": "prospect", "email_signature": "", "email_signature_type": "html", "email_signature_click_tracking_disabled": false, "team_admin": false, "local_dial_enabled": true, "click_to_call_enabled": false, "email_client_configured": false, "crm_connected": false, "external_feature_flags": {"ma_enabled": true, "ma_live_feed": true, "ma_recent_activities_update": true, "ma_person_page": true, "ma_push_notifications": true, "ma_meetings_push_notifications": true, "ma_websockets": true, "ma_edit_person": true, "ma_dev_qa_tools": false, "ma_cadences": false, "hot_leads": true, "people_crud_allow_create": true, "people_crud_allow_delete": true, "ma_mobile_workflow": true, "linkedin_oauth_flow": true}, "_private_fields": {}, "phone_client": {"id": 53219}, "phone_number_assignment": {"_href": "https://api.salesloft.com/v2/phone_number_assignments/34936", "id": 34936}, "group": null, "team": {"_href": "https://api.salesloft.com/v2/team", "id": 104779}, "role": {"id": "User"}}, "emitted_at": 1688663044216} +{"stream": "users", "data": {"id": 6970, "guid": "54713f8f-6283-453f-84da-e27e28223e8c", "created_at": "2021-09-03T12:04:02.458089-04:00", "updated_at": "2023-03-09T14:50:58.222994-05:00", "name": "Airbyte Team", "first_name": "Airbyte", "last_name": "Team", "job_role": "Account Executive / Account Manager", "active": true, "time_zone": "US/Eastern", "locale_utc_offset": -240, "slack_username": "integration-test", "twitter_handle": null, "email": "integration-test@airbyte.io", "email_client_email_address": "karina.kuznietsova@zazmic.com", "sending_email_address": "karina.kuznietsova@zazmic.com", "from_address": null, "full_email_address": "\"Airbyte Team\" ", "bcc_email_address": null, "work_country": "US", "seat_package": "admin", "email_signature": "", "email_signature_type": "html", "email_signature_click_tracking_disabled": false, "team_admin": true, "local_dial_enabled": true, "click_to_call_enabled": false, "email_client_configured": true, "crm_connected": true, "external_feature_flags": {"ma_enabled": true, "ma_live_feed": true, "ma_recent_activities_update": true, "ma_person_page": true, "ma_push_notifications": true, "ma_meetings_push_notifications": true, "ma_websockets": true, "ma_edit_person": true, "ma_dev_qa_tools": false, "ma_cadences": false, "hot_leads": true, "people_crud_allow_create": true, "people_crud_allow_delete": true, "ma_mobile_workflow": true, "linkedin_oauth_flow": true}, "_private_fields": {}, "phone_client": {"id": 7593}, "phone_number_assignment": {"_href": "https://api.salesloft.com/v2/phone_number_assignments/34935", "id": 34935}, "group": null, "team": {"_href": "https://api.salesloft.com/v2/team", "id": 104779}, "role": {"id": "Admin"}}, "emitted_at": 1688663044217} +{"stream": "calls", "data": {"id": 2117241, "to": "+1234445556", "duration": null, "sentiment": "Customer", "disposition": "No Answer", "created_at": "2021-09-16T10:04:58.125490-04:00", "updated_at": "2021-09-16T10:04:58.295640-04:00", "recordings": [], "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "action": null, "called_person": {"_href": "https://api.salesloft.com/v2/people/6509414", "id": 6509414}, "crm_activity": {"_href": "https://api.salesloft.com/v2/crm_activities/11346104", "id": 11346104}, "note": {"_href": "https://api.salesloft.com/v2/notes/1029422", "id": 1029422}, "cadence": null, "step": null}, "emitted_at": 1688663045010} +{"stream": "calls", "data": {"id": 2113993, "to": "+12345678900", "duration": null, "sentiment": null, "disposition": null, "created_at": "2021-09-16T07:17:57.430595-04:00", "updated_at": "2021-09-16T07:17:57.499713-04:00", "recordings": [], "user": {"_href": "https://api.salesloft.com/v2/users/6970", "id": 6970}, "action": null, "called_person": {"_href": "https://api.salesloft.com/v2/people/6502956", "id": 6502956}, "crm_activity": {"_href": "https://api.salesloft.com/v2/crm_activities/11305624", "id": 11305624}, "note": null, "cadence": null, "step": null}, "emitted_at": 1688663045010} +{"stream": "custom_fields", "data": {"id": 37515, "name": "airbyte", "field_type": "company", "value_type": "text", "created_at": "2023-07-11T14:07:59.517241-04:00", "updated_at": "2023-07-11T14:07:59.517241-04:00"}, "emitted_at": 1689099854082} diff --git a/airbyte-integrations/connectors/source-salesloft/integration_tests/incremental_catalog.json b/airbyte-integrations/connectors/source-salesloft/integration_tests/incremental_catalog.json index 0998800674d1..23b38071a106 100644 --- a/airbyte-integrations/connectors/source-salesloft/integration_tests/incremental_catalog.json +++ b/airbyte-integrations/connectors/source-salesloft/integration_tests/incremental_catalog.json @@ -260,6 +260,48 @@ }, "destination_sync_mode": "overwrite", "sync_mode": "incremental" + }, + { + "stream": { + "name": "call_data_records", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh", + "incremental" + ], + "source_defined_cursor": true, + "default_cursor_field": [ + "updated_at" + ], + "source_defined_primary_key": [ + [ + "id" + ] + ] + }, + "destination_sync_mode": "overwrite", + "sync_mode": "incremental" + }, + { + "stream": { + "name": "searches", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh", + "incremental" + ], + "source_defined_cursor": true, + "default_cursor_field": [ + "updated_at" + ], + "source_defined_primary_key": [ + [ + "id" + ] + ] + }, + "destination_sync_mode": "overwrite", + "sync_mode": "incremental" } ] } diff --git a/airbyte-integrations/connectors/source-salesloft/metadata.yaml b/airbyte-integrations/connectors/source-salesloft/metadata.yaml index 7225c25065db..5bfb9aca1332 100644 --- a/airbyte-integrations/connectors/source-salesloft/metadata.yaml +++ b/airbyte-integrations/connectors/source-salesloft/metadata.yaml @@ -5,7 +5,7 @@ data: connectorSubtype: api connectorType: source definitionId: 41991d12-d4b5-439e-afd0-260a31d4c53f - dockerImageTag: 1.1.1 + dockerImageTag: 1.2.0 dockerRepository: airbyte/source-salesloft githubIssueLabel: source-salesloft icon: salesloft.svg diff --git a/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/call_data_records.json b/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/call_data_records.json new file mode 100644 index 000000000000..568c45ac8c83 --- /dev/null +++ b/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/call_data_records.json @@ -0,0 +1,90 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "integer"] + }, + "created_at": { + "type": ["null", "string"], + "format": "date-time" + }, + "updated_at": { + "type": ["null", "string"], + "format": "date-time" + }, + "to": { + "type": ["null", "string"] + }, + "from": { + "type": ["null", "string"] + }, + "duration": { + "type": ["null", "integer"] + }, + "direction": { + "type": ["null", "string"] + }, + "status": { + "type": ["null", "string"] + }, + "call_type": { + "type": ["null", "string"] + }, + "call_uuid": { + "type": ["null", "string"] + }, + "recording": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "url": { + "type": ["null", "string"] + }, + "status": { + "type": ["null", "string"] + }, + "recording_status": { + "type": ["null", "string"] + } + } + }, + "call": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "integer"] + }, + "_href": { + "type": ["null", "string"] + } + } + }, + "user": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "integer"] + }, + "_href": { + "type": ["null", "string"] + } + } + }, + "called_person": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "integer"] + }, + "_href": { + "type": ["null", "string"] + } + } + } + } +} diff --git a/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/call_dispositions.json b/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/call_dispositions.json new file mode 100644 index 000000000000..17bd429d1d27 --- /dev/null +++ b/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/call_dispositions.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "integer"] + }, + "created_at": { + "type": ["null", "string"], + "format": "date-time" + }, + "updated_at": { + "type": ["null", "string"], + "format": "date-time" + }, + "name": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/call_sentiments.json b/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/call_sentiments.json new file mode 100644 index 000000000000..17bd429d1d27 --- /dev/null +++ b/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/call_sentiments.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "integer"] + }, + "created_at": { + "type": ["null", "string"], + "format": "date-time" + }, + "updated_at": { + "type": ["null", "string"], + "format": "date-time" + }, + "name": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/custom_fields.json b/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/custom_fields.json new file mode 100644 index 000000000000..9d4b6742c00d --- /dev/null +++ b/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/custom_fields.json @@ -0,0 +1,27 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "integer"] + }, + "name": { + "type": ["null", "string"] + }, + "field_type": { + "type": ["null", "string"] + }, + "value_type": { + "type": ["null", "string"] + }, + "created_at": { + "type": ["null", "string"], + "format": "date-time" + }, + "updated_at": { + "type": ["null", "string"], + "format": "date-time" + } + } +} diff --git a/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/meetings.json b/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/meetings.json new file mode 100644 index 000000000000..071e51cc1398 --- /dev/null +++ b/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/meetings.json @@ -0,0 +1,192 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "integer"] + }, + "title": { + "type": ["null", "string"] + }, + "start_time": { + "type": ["null", "string"], + "format": "date-time" + }, + "end_time": { + "type": ["null", "string"], + "format": "date-time" + }, + "calendar_id": { + "type": ["null", "string"] + }, + "calendar_type": { + "type": ["null", "string"] + }, + "meeting_type": { + "type": ["null", "string"] + }, + "recipient_name": { + "type": ["null", "string"] + }, + "recipient_email": { + "type": ["null", "string"] + }, + "location": { + "type": ["null", "string"] + }, + "description": { + "type": ["null", "string"] + }, + "event_id": { + "type": ["null", "string"] + }, + "account_id": { + "type": ["null", "string"] + }, + "task_id": { + "type": ["null", "integer"] + }, + "created_at": { + "type": ["null", "string"], + "format": "date-time" + }, + "updated_at": { + "type": ["null", "string"], + "format": "date-time" + }, + "guests": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "attendees": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "email": { + "type": ["null", "string"] + }, + "name": { + "type": ["null", "string"] + }, + "organizer": { + "type": ["null", "boolean"] + }, + "status": { + "type": ["null", "string"] + }, + "status_changed": { + "type": ["null", "boolean"] + }, + "deleted_at": { + "type": ["null", "string"], + "format": "date-time" + } + } + } + }, + "person": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "integer"] + }, + "_href": { + "type": ["null", "string"] + } + } + }, + "cadence": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "integer"] + }, + "_href": { + "type": ["null", "string"] + } + } + }, + "step": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "integer"] + }, + "_href": { + "type": ["null", "string"] + } + } + }, + "booked_by_user": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "string"] + }, + "_href": { + "type": ["null", "string"] + } + } + }, + "crm_references": { + "type": ["null", "object"], + "additionalProperties": true + }, + "event_source": { + "type": ["null", "string"] + }, + "canceled_at": { + "type": ["null", "string"], + "format": "date-time" + }, + "all_day": { + "type": ["null", "boolean"] + }, + "no_show": { + "type": ["null", "boolean"] + }, + "crm_custom_fields": { + "type": ["null", "object"], + "additionalProperties": true + }, + "strict_attribution": { + "type": ["null", "boolean"] + }, + "i_cal_uid": { + "type": ["null", "string"] + }, + "status": { + "type": ["null", "string"] + }, + "reschedule_status": { + "type": ["null", "string"] + }, + "owned_by_meetings_settings": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { + "email_address": ["null", "string"] + } + } + }, + "booked_by_meetings_settings": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { + "email_address": ["null", "string"] + } + } + } + } +} diff --git a/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/searches.json b/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/searches.json new file mode 100644 index 000000000000..1ae0c6d07651 --- /dev/null +++ b/airbyte-integrations/connectors/source-salesloft/source_salesloft/schemas/searches.json @@ -0,0 +1,124 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "integer"] + }, + "user": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "string"] + }, + "_href": { + "type": ["null", "string"] + } + } + }, + "user_slug": { + "type": ["null", "string"] + }, + "primary_calendar_id": { + "type": ["null", "string"] + }, + "primary_calendar_name": { + "type": ["null", "string"] + }, + "email_address": { + "type": ["null", "string"] + }, + "user_details": { + "type": ["null", "object"], + "additionalProperties": true + }, + "calendar_type": { + "type": ["null", "string"] + }, + "title": { + "type": ["null", "string"] + }, + "description": { + "type": ["null", "string"] + }, + "location": { + "type": ["null", "string"] + }, + "default_meeting_length": { + "type": ["null", "integer"] + }, + "availability_limit_enabled": { + "type": ["null", "boolean"] + }, + "availability_limit": { + "type": ["null", "integer"] + }, + "schedule_delay": { + "type": ["null", "integer"] + }, + "buffer_time_duration": { + "type": ["null", "integer"] + }, + "schedule_buffer_enabled": { + "type": ["null", "boolean"] + }, + "times_available": { + "type": ["null", "object"], + "additionalProperties": true + }, + "allow_booking_on_behalf": { + "type": ["null", "boolean"] + }, + "allow_booking_overtime": { + "type": ["null", "boolean"] + }, + "allow_event_overlap": { + "type": ["null", "boolean"] + }, + "allow_event_detail": { + "type": ["null", "boolean"] + }, + "enable_dynamic_location": { + "type": ["null", "boolean"] + }, + "created_at": { + "type": ["null", "string"], + "format": "date-time" + }, + "updated_at": { + "type": ["null", "string"], + "format": "date-time" + }, + "time_zone": { + "type": ["null", "string"] + }, + "primary_calendar_connection_failed": { + "type": ["null", "boolean"] + }, + "enable_calendar_sync": { + "type": ["null", "boolean"] + }, + "reschedule_meetings_enabled": { + "type": ["null", "boolean"] + }, + "active_meeting_url": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "url": { + "type": ["null", "string"] + }, + "created_at": { + "type": ["null", "string"], + "format": "date-time" + }, + "updated_at": { + "type": ["null", "string"], + "format": "date-time" + } + } + } + } +} diff --git a/airbyte-integrations/connectors/source-salesloft/source_salesloft/source.py b/airbyte-integrations/connectors/source-salesloft/source_salesloft/source.py index 51136a94e6db..b784fb98e5e6 100644 --- a/airbyte-integrations/connectors/source-salesloft/source_salesloft/source.py +++ b/airbyte-integrations/connectors/source-salesloft/source_salesloft/source.py @@ -226,6 +226,46 @@ def path(self, **kwargs) -> str: return "groups" +class CustomFields(SalesloftStream): + def path(self, **kwargs) -> str: + return "custom_fields" + + +class CallDataRecords(IncrementalSalesloftStream): + created_at_field = "updated_at" + + def path(self, **kwargs) -> str: + return "call_data_records" + + +class CallDispositions(SalesloftStream): + def path(self, **kwargs) -> str: + return "call_dispositions" + + +class CallSentiments(SalesloftStream): + def path(self, **kwargs) -> str: + return "call_sentiments" + + +class Meetings(SalesloftStream): + created_at_field = "created_at" + + def path(self, **kwargs) -> str: + return "meetings" + + +class Searches(IncrementalSalesloftStream): + created_at_field = "updated_at" + + def path(self, **kwargs) -> str: + return "meetings/settings/searches" + + @property + def http_method(self) -> str: + return "POST" + + # Source class SourceSalesloft(AbstractSource): def _create_authenticator(self, config) -> AuthBase: @@ -272,4 +312,10 @@ def streams(self, config: Mapping[str, Any]) -> List[Stream]: Groups(*args), Successes(*args), EmailTemplateAttachments(*args), + CustomFields(*args), + CallDataRecords(*args), + CallDispositions(*args), + CallSentiments(*args), + Meetings(*args), + Searches(*args), ] diff --git a/airbyte-integrations/connectors/source-salesloft/unit_tests/test_source.py b/airbyte-integrations/connectors/source-salesloft/unit_tests/test_source.py index 9664728482da..06efdbbaf2b8 100644 --- a/airbyte-integrations/connectors/source-salesloft/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-salesloft/unit_tests/test_source.py @@ -9,7 +9,7 @@ def test_streams(config): source = SourceSalesloft() streams = source.streams(config) - expected_streams_number = 23 + expected_streams_number = 29 assert len(streams) == expected_streams_number diff --git a/docs/integrations/sources/salesloft.md b/docs/integrations/sources/salesloft.md index bb677006301d..2b25039436e2 100644 --- a/docs/integrations/sources/salesloft.md +++ b/docs/integrations/sources/salesloft.md @@ -82,6 +82,12 @@ This connector outputs the following streams: * [CRM Users](https://developers.salesloft.com/api.html#!/Crm_Users/get_v2_crm_users_json) * [Groups](https://developers.salesloft.com/api.html#!/Groups/get_v2_groups_json) * [Successes](https://developers.salesloft.com/api.html#!/Successes/get_v2_successes_json) +* [Call Data Records](https://developers.salesloft.com/api.html#!/Call_Data_Records/get_v2_call_data_records_json) +* [Call Dispositions](https://developers.salesloft.com/api.html#!/Call_Dispositions/get_v2_call_dispositions_json) +* [Call Sentiments](https://developers.salesloft.com/api.html#!/Call_Sentiments/get_v2_call_sentiments_json) +* [Custom Fields](https://developers.salesloft.com/api.html#!/Custom_Fields/get_v2_custom_fields_json) +* [Meetings](https://developers.salesloft.com/api.html#!/Meetings/get_v2_meetings_json) +* [Searches](https://developers.salesloft.com/api.html#!/Searches/post_v2_searches_json) ## Performance considerations @@ -91,6 +97,7 @@ Salesloft has the [rate limits](hhttps://developers.salesloft.com/api.html#!/Top | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:------------------------------------------------------------------| +| 1.2.0 | 2023-06-20 | [27505](https://github.com/airbytehq/airbyte/pull/27505) | Added new streams (Call Data Records, Call Dispositions, ... ) | | 1.1.1 | 2023-06-17 | [27484](https://github.com/airbytehq/airbyte/pull/27484) | Bump version on py files updates | | 1.1.0 | 2023-05-17 | [26188](https://github.com/airbytehq/airbyte/pull/26188) | Added `latest_active_date` field to the `Cadences` stream schema. | | 1.0.0 | 2023-03-08 | [23937](https://github.com/airbytehq/airbyte/pull/23937) | Certify to Beta | From 679d475caed8cb6ceb4a3364066bcf2fa10d32f6 Mon Sep 17 00:00:00 2001 From: Ben Church Date: Tue, 11 Jul 2023 15:25:13 -0600 Subject: [PATCH 30/63] Break resources into dependency trees (#28166) --- .../orchestrator/.env.template | 5 +- .../orchestrator/orchestrator/__init__.py | 53 ++++++++++++++----- 2 files changed, 43 insertions(+), 15 deletions(-) diff --git a/airbyte-ci/connectors/metadata_service/orchestrator/.env.template b/airbyte-ci/connectors/metadata_service/orchestrator/.env.template index 4199ce966092..e0c860e3041a 100644 --- a/airbyte-ci/connectors/metadata_service/orchestrator/.env.template +++ b/airbyte-ci/connectors/metadata_service/orchestrator/.env.template @@ -1,4 +1,7 @@ -METADATA_BUCKET="ben-ab-test-bucket" +METADATA_BUCKET="dev-airbyte-cloud-connector-metadata-service" CI_REPORT_BUCKET="airbyte-ci-reports" GITHUB_METADATA_SERVICE_TOKEN="" NIGHTLY_REPORT_SLACK_WEBHOOK_URL="" +# METADATA_CDN_BASE_URL="https://connectors.airbyte.com/files" +DOCKER_HUB_USERNAME="" +DOCKER_HUB_PASSWORD="" \ No newline at end of file diff --git a/airbyte-ci/connectors/metadata_service/orchestrator/orchestrator/__init__.py b/airbyte-ci/connectors/metadata_service/orchestrator/orchestrator/__init__.py index 97dda8ed541c..d909456f2a0b 100644 --- a/airbyte-ci/connectors/metadata_service/orchestrator/orchestrator/__init__.py +++ b/airbyte-ci/connectors/metadata_service/orchestrator/orchestrator/__init__.py @@ -49,8 +49,7 @@ ] ) - -RESOURCES = { +GITHUB_RESOURCE_TREE = { "github_client": github_client.configured({"github_token": {"env": "GITHUB_METADATA_SERVICE_TOKEN"}}), "github_connector_repo": github_connector_repo.configured({"connector_repo_name": CONNECTOR_REPO_NAME}), "github_connectors_directory": github_connectors_directory.configured({"connectors_path": CONNECTORS_PATH}), @@ -61,6 +60,9 @@ "status": "success", } ), +} + +GCS_RESOURCE_TREE = { "gcp_gcs_client": gcp_gcs_client.configured( { "gcp_gcs_cred_string": {"env": "GCS_CREDENTIALS"}, @@ -69,24 +71,41 @@ "registry_directory_manager": gcs_file_manager.configured({"gcs_bucket": {"env": "METADATA_BUCKET"}, "prefix": REGISTRIES_FOLDER}), "registry_report_directory_manager": gcs_file_manager.configured({"gcs_bucket": {"env": "METADATA_BUCKET"}, "prefix": REPORT_FOLDER}), "root_metadata_directory_manager": gcs_file_manager.configured({"gcs_bucket": {"env": "METADATA_BUCKET"}, "prefix": ""}), +} + +METADATA_RESOURCE_TREE = { + **GCS_RESOURCE_TREE, "all_metadata_file_blobs": gcs_directory_blobs.configured( {"gcs_bucket": {"env": "METADATA_BUCKET"}, "prefix": METADATA_FOLDER, "match_regex": f".*/{METADATA_FILE_NAME}$"} ), "latest_metadata_file_blobs": gcs_directory_blobs.configured( {"gcs_bucket": {"env": "METADATA_BUCKET"}, "prefix": METADATA_FOLDER, "match_regex": f".*latest/{METADATA_FILE_NAME}$"} ), - "latest_cloud_registry_entries_file_blobs": gcs_directory_blobs.configured( - {"gcs_bucket": {"env": "METADATA_BUCKET"}, "prefix": METADATA_FOLDER, "match_regex": f".*latest/cloud.json$"} - ), - "latest_oss_registry_entries_file_blobs": gcs_directory_blobs.configured( - {"gcs_bucket": {"env": "METADATA_BUCKET"}, "prefix": METADATA_FOLDER, "match_regex": f".*latest/oss.json$"} - ), +} + +REGISTRY_RESOURCE_TREE = { + **GCS_RESOURCE_TREE, "latest_oss_registry_gcs_blob": gcs_file_blob.configured( {"gcs_bucket": {"env": "METADATA_BUCKET"}, "prefix": REGISTRIES_FOLDER, "gcs_filename": "oss_registry.json"} ), "latest_cloud_registry_gcs_blob": gcs_file_blob.configured( {"gcs_bucket": {"env": "METADATA_BUCKET"}, "prefix": REGISTRIES_FOLDER, "gcs_filename": "cloud_registry.json"} ), +} + +REGISTRY_ENTRY_RESOURCE_TREE = { + **GCS_RESOURCE_TREE, + "latest_cloud_registry_entries_file_blobs": gcs_directory_blobs.configured( + {"gcs_bucket": {"env": "METADATA_BUCKET"}, "prefix": METADATA_FOLDER, "match_regex": f".*latest/cloud.json$"} + ), + "latest_oss_registry_entries_file_blobs": gcs_directory_blobs.configured( + {"gcs_bucket": {"env": "METADATA_BUCKET"}, "prefix": METADATA_FOLDER, "match_regex": f".*latest/oss.json$"} + ), +} + +CONNECTOR_TEST_REPORT_RESOURCE_TREE = { + **GITHUB_RESOURCE_TREE, + **GCS_RESOURCE_TREE, "latest_nightly_complete_file_blobs": gcs_directory_blobs.configured( {"gcs_bucket": {"env": "CI_REPORT_BUCKET"}, "prefix": NIGHTLY_FOLDER, "match_regex": f".*{NIGHTLY_COMPLETE_REPORT_FILE_NAME}$"} ), @@ -102,37 +121,43 @@ ), } +RESOURCES = { + **METADATA_RESOURCE_TREE, + **REGISTRY_RESOURCE_TREE, + **REGISTRY_ENTRY_RESOURCE_TREE, + **CONNECTOR_TEST_REPORT_RESOURCE_TREE, +} + SENSORS = [ registry_updated_sensor(job=generate_registry_reports, resources_def=RESOURCES), new_gcs_blobs_sensor( job=generate_oss_registry, - resources_def=RESOURCES, + resources_def=REGISTRY_ENTRY_RESOURCE_TREE, gcs_blobs_resource_key="latest_oss_registry_entries_file_blobs", interval=30, ), new_gcs_blobs_sensor( job=generate_cloud_registry, - resources_def=RESOURCES, + resources_def=REGISTRY_ENTRY_RESOURCE_TREE, gcs_blobs_resource_key="latest_cloud_registry_entries_file_blobs", interval=30, ), new_gcs_blobs_sensor( job=generate_nightly_reports, - resources_def=RESOURCES, + resources_def=CONNECTOR_TEST_REPORT_RESOURCE_TREE, gcs_blobs_resource_key="latest_nightly_complete_file_blobs", interval=(1 * 60 * 60), ), new_gcs_blobs_partition_sensor( job=generate_registry_entry, - resources_def=RESOURCES, + resources_def=METADATA_RESOURCE_TREE, partitions_def=registry_entry.metadata_partitions_def, gcs_blobs_resource_key="all_metadata_file_blobs", interval=(10 * 60 * 60), - ), new_gcs_blobs_partition_sensor( job=generate_registry_entry, - resources_def=RESOURCES, + resources_def=METADATA_RESOURCE_TREE, partitions_def=registry_entry.metadata_partitions_def, gcs_blobs_resource_key="latest_metadata_file_blobs", interval=60, From f92d833d8d4f0533e77280ddbaa3eba647d66a3b Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Tue, 11 Jul 2023 17:30:40 -0700 Subject: [PATCH 31/63] [Source-Postgres] Switch over to user-defined-cursor after CTID initial sync (#27809) * Separated Standard vs Xmin categorization Added StandardCtidUtilsTest Added versions to StandardStatus * WIP incremental read test * Added PostgresStandardStateManager to write state_type key to stream state Added sync to verify state messages and cursor records on running multiple syncs of the same streams * Isolate tables used for ctid test and enable checkpointing records to 1 for just CTID test * Moved ctid cursor test to its own file CtidEnabledPostgresSourceTest * Gracefully handle case where there is no statetype Update all "standard" to "cursorBased" --- .../jdbc/test/JdbcSourceAcceptanceTest.java | 43 +-- .../source/postgres/PostgresQueryUtils.java | 109 +++++- .../source/postgres/PostgresSource.java | 179 ++++++--- .../postgres/ctid/CtidFeatureFlags.java | 33 ++ .../source/postgres/ctid/CtidUtils.java | 51 +++ .../cursor_based/CursorBasedCtidUtils.java | 91 +++++ .../PostgresCursorBasedStateManager.java | 112 ++++++ .../postgres/xmin/PostgresXminHandler.java | 2 +- .../source/postgres/xmin/XminCtidUtils.java | 41 +-- .../postgres/xmin/XminStateManager.java | 9 +- .../internal_models/internal_models.yaml | 14 + .../CtidEnabledCdcPostgresSourceTest.java | 3 +- .../CtidEnabledPostgresSourceTest.java | 345 ++++++++++++++++++ .../PostgresJdbcSourceAcceptanceTest.java | 4 + .../postgres/XminPostgresSourceTest.java | 12 +- .../CursorBasedCtidUtilsTest.java | 120 ++++++ .../postgres/utils/PostgresUnitTestsUtil.java | 41 +++ .../postgres/xmin/XminCtidUtilsTest.java | 19 +- 18 files changed, 1083 insertions(+), 145 deletions(-) create mode 100644 airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/ctid/CtidFeatureFlags.java create mode 100644 airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/ctid/CtidUtils.java create mode 100644 airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/cursor_based/CursorBasedCtidUtils.java create mode 100644 airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/cursor_based/PostgresCursorBasedStateManager.java create mode 100644 airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/CtidEnabledPostgresSourceTest.java create mode 100644 airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/cursor_based/CursorBasedCtidUtilsTest.java diff --git a/airbyte-integrations/connectors/source-jdbc/src/testFixtures/java/io/airbyte/integrations/source/jdbc/test/JdbcSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-jdbc/src/testFixtures/java/io/airbyte/integrations/source/jdbc/test/JdbcSourceAcceptanceTest.java index bba9eca3db41..3f4c420cac77 100644 --- a/airbyte-integrations/connectors/source-jdbc/src/testFixtures/java/io/airbyte/integrations/source/jdbc/test/JdbcSourceAcceptanceTest.java +++ b/airbyte-integrations/connectors/source-jdbc/src/testFixtures/java/io/airbyte/integrations/source/jdbc/test/JdbcSourceAcceptanceTest.java @@ -944,7 +944,7 @@ public void testIncrementalWithConcurrentInsertion() throws Exception { } - private JsonNode getStateData(final AirbyteMessage airbyteMessage, final String streamName) { + protected JsonNode getStateData(final AirbyteMessage airbyteMessage, final String streamName) { for (final JsonNode stream : airbyteMessage.getState().getData().get("streams")) { if (stream.get("stream_name").asText().equals(streamName)) { return stream; @@ -965,13 +965,13 @@ private void incrementalCursorCheck( getConfiguredCatalogWithOneStream(getDefaultNamespace()).getStreams().get(0)); } - private void incrementalCursorCheck( - final String initialCursorField, - final String cursorField, - final String initialCursorValue, - final String endCursorValue, - final List expectedRecordMessages, - final ConfiguredAirbyteStream airbyteStream) + protected void incrementalCursorCheck( + final String initialCursorField, + final String cursorField, + final String initialCursorValue, + final String endCursorValue, + final List expectedRecordMessages, + final ConfiguredAirbyteStream airbyteStream) throws Exception { airbyteStream.setSyncMode(SyncMode.INCREMENTAL); airbyteStream.setCursorField(List.of(cursorField)); @@ -980,25 +980,15 @@ private void incrementalCursorCheck( final ConfiguredAirbyteCatalog configuredCatalog = new ConfiguredAirbyteCatalog() .withStreams(List.of(airbyteStream)); - final DbStreamState dbStreamState = new DbStreamState() - .withStreamName(airbyteStream.getStream().getName()) - .withStreamNamespace(airbyteStream.getStream().getNamespace()) - .withCursorField(List.of(initialCursorField)) - .withCursor(initialCursorValue) - .withCursorRecordCount(1L); + final DbStreamState dbStreamState = buildStreamState(airbyteStream, initialCursorField, initialCursorValue); final List actualMessages = MoreIterators .toList(source.read(config, configuredCatalog, Jsons.jsonNode(createState(List.of(dbStreamState))))); setEmittedAtToNull(actualMessages); - final List expectedStreams = List.of( - new DbStreamState() - .withStreamName(airbyteStream.getStream().getName()) - .withStreamNamespace(airbyteStream.getStream().getNamespace()) - .withCursorField(List.of(cursorField)) - .withCursor(endCursorValue) - .withCursorRecordCount(1L)); + final List expectedStreams = List.of(buildStreamState(airbyteStream, cursorField, endCursorValue)); + final List expectedMessages = new ArrayList<>(expectedRecordMessages); expectedMessages.addAll(createExpectedTestMessages(expectedStreams)); @@ -1007,6 +997,17 @@ private void incrementalCursorCheck( assertTrue(actualMessages.containsAll(expectedMessages)); } + protected DbStreamState buildStreamState(final ConfiguredAirbyteStream configuredAirbyteStream, + final String cursorField, + final String cursorValue) { + return new DbStreamState() + .withStreamName(configuredAirbyteStream.getStream().getName()) + .withStreamNamespace(configuredAirbyteStream.getStream().getNamespace()) + .withCursorField(List.of(cursorField)) + .withCursor(cursorValue) + .withCursorRecordCount(1L); + } + // get catalog and perform a defensive copy. protected ConfiguredAirbyteCatalog getConfiguredCatalogWithOneStream(final String defaultNamespace) { final ConfiguredAirbyteCatalog catalog = CatalogHelpers.toDefaultConfiguredCatalog(getCatalog(defaultNamespace)); diff --git a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresQueryUtils.java b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresQueryUtils.java index 39ca956dc30a..c9874bd2aaf0 100644 --- a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresQueryUtils.java +++ b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresQueryUtils.java @@ -9,17 +9,25 @@ import com.fasterxml.jackson.databind.JsonNode; import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; import io.airbyte.db.jdbc.JdbcDatabase; import io.airbyte.db.jdbc.JdbcUtils; +import io.airbyte.integrations.source.postgres.ctid.CtidUtils.CtidStreams; +import io.airbyte.integrations.source.postgres.internal.models.CursorBasedStatus; import io.airbyte.integrations.source.postgres.internal.models.InternalModels.StateType; import io.airbyte.integrations.source.postgres.internal.models.XminStatus; +import io.airbyte.integrations.source.relationaldb.CursorInfo; +import io.airbyte.integrations.source.relationaldb.state.StateManager; import io.airbyte.protocol.models.AirbyteStreamNameNamespacePair; +import io.airbyte.protocol.models.v0.AirbyteStateMessage; +import io.airbyte.protocol.models.v0.AirbyteStreamState; import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,7 +36,7 @@ */ public class PostgresQueryUtils { - public record TableBlockSize(Long tableSize, Long blockSize) { } + public record TableBlockSize(Long tableSize, Long blockSize) {} private static final Logger LOGGER = LoggerFactory.getLogger(PostgresQueryUtils.class); @@ -62,6 +70,10 @@ public record TableBlockSize(Long tableSize, Long blockSize) { } (txid_snapshot_xmin(txid_current_snapshot()) % (2^32)::bigint) AS xmin_xid_value, txid_snapshot_xmin(txid_current_snapshot()) AS xmin_raw_value; """; + public static final String MAX_CURSOR_VALUE_QUERY = + """ + SELECT %s FROM %s WHERE %s = (SELECT MAX(%s) FROM %s); + """; public static final String CTID_FULL_VACUUM_IN_PROGRESS_QUERY = """ @@ -82,14 +94,14 @@ SELECT pg_relation_filenode('%s') public static final String TOTAL_BYTES_RESULT_COL = "totalbytes"; /** - * Query returns the size table data takes on DB server disk (not incling any index or other metadata) - * And the size of each page used in (page, tuple) ctid. - * This helps us evaluate how many pages we need to read to traverse the entire table. + * Query returns the size table data takes on DB server disk (not incling any index or other + * metadata) And the size of each page used in (page, tuple) ctid. This helps us evaluate how many + * pages we need to read to traverse the entire table. */ public static final String CTID_TABLE_BLOCK_SIZE = - """ - WITH block_sz AS (SELECT current_setting('block_size')::int), rel_sz AS (select pg_relation_size('%s')) SELECT * from block_sz, rel_sz - """; + """ + WITH block_sz AS (SELECT current_setting('block_size')::int), rel_sz AS (select pg_relation_size('%s')) SELECT * from block_sz, rel_sz + """; /** * Logs the current xmin status : 1. The number of wraparounds the source DB has undergone. (These @@ -112,9 +124,63 @@ public static XminStatus getXminStatus(final JdbcDatabase database) throws SQLEx .withStateType(StateType.XMIN); } + /** + * Iterates through each stream and find the max cursor value and the record count which has that + * value based on each cursor field provided by the customer per stream This information is saved in + * a Hashmap with the mapping being the AirbyteStreamNameNamespacepair -> CursorBasedStatus + * + * @param database the source db + * @param streams streams to be synced + * @param stateManager stream stateManager + * @return + */ + public static Map getCursorBasedSyncStatusForStreams(final JdbcDatabase database, + final List streams, + final StateManager stateManager) { + + final Map cursorBasedStatusMap = new HashMap<>(); + streams.forEach(stream -> { + try { + final String name = stream.getStream().getName(); + final String namespace = stream.getStream().getNamespace(); + final Optional cursorInfoOptional = + stateManager.getCursorInfo(new io.airbyte.protocol.models.v0.AirbyteStreamNameNamespacePair(name, namespace)); + if (cursorInfoOptional.isEmpty()) { + throw new RuntimeException(String.format("Stream %s was not provided with an appropriate cursor", stream.getStream().getName())); + } + + final String cursorField = cursorInfoOptional.get().getCursorField(); + final String cursorBasedSyncStatusQuery = String.format(MAX_CURSOR_VALUE_QUERY, + cursorField, + name, + cursorField, + cursorField, + name); + final List jsonNodes = database.bufferedResultSetQuery(conn -> conn.prepareStatement(cursorBasedSyncStatusQuery).executeQuery(), + resultSet -> JdbcUtils.getDefaultSourceOperations().rowToJson(resultSet)); + final JsonNode result = jsonNodes.get(0); + final CursorBasedStatus cursorBasedStatus = new CursorBasedStatus(); + + cursorBasedStatus.setStateType(StateType.CURSOR_BASED); + cursorBasedStatus.setVersion(2L); + cursorBasedStatus.setCursorField(ImmutableList.of(cursorField)); + cursorBasedStatus.setCursor(result.get(cursorField).asText()); + cursorBasedStatus.setCursorRecordCount((long) jsonNodes.size()); + cursorBasedStatus.setStreamName(name); + cursorBasedStatus.setStreamNamespace(namespace); + + cursorBasedStatusMap.put(new AirbyteStreamNameNamespacePair(name, namespace), cursorBasedStatus); + } catch (final SQLException e) { + throw new RuntimeException(e); + } + }); + + return cursorBasedStatusMap; + } + public static Map fileNodeForStreams(final JdbcDatabase database, - final List streams, - final String quoteString) { + final List streams, + final String quoteString) { final Map fileNodes = new HashMap<>(); streams.forEach(stream -> { final AirbyteStreamNameNamespacePair namespacePair = @@ -171,8 +237,8 @@ public static List } public static Map getTableBlockSizeForStream(final JdbcDatabase database, - final List streams, - final String quoteString) { + final List streams, + final String quoteString) { final Map tableBlockSizes = new HashMap<>(); streams.forEach(stream -> { final AirbyteStreamNameNamespacePair namespacePair = @@ -183,9 +249,10 @@ public static Map getTableBlockS return tableBlockSizes; } + public static TableBlockSize getTableBlockSizeForStream(final JdbcDatabase database, - final AirbyteStreamNameNamespacePair stream, - final String quoteString) { + final AirbyteStreamNameNamespacePair stream, + final String quoteString) { try { final String streamName = stream.getName(); final String schemaName = stream.getNamespace(); @@ -203,4 +270,20 @@ public static TableBlockSize getTableBlockSizeForStream(final JdbcDatabase datab throw new RuntimeException(e); } } + + /** + * Filter out streams that are currently under vacuum from being synced via Ctid + * + * @param streamsUnderVacuum streams that are currently under vacuum + * @param ctidStreams preliminary streams to be synced via Ctid + * @return ctid streams that are not under vacuum + */ + public static List filterStreamsUnderVacuumForCtidSync(final List streamsUnderVacuum, + final CtidStreams ctidStreams) { + return streamsUnderVacuum.isEmpty() ? ctidStreams.streamsForCtidSync() + : ctidStreams.streamsForCtidSync().stream() + .filter(c -> !streamsUnderVacuum.contains(io.airbyte.protocol.models.v0.AirbyteStreamNameNamespacePair.fromConfiguredAirbyteSteam(c))) + .toList(); + } + } diff --git a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresSource.java b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresSource.java index 8e8c4efea074..6847974f3241 100644 --- a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresSource.java +++ b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresSource.java @@ -20,9 +20,12 @@ import static io.airbyte.integrations.source.postgres.PostgresQueryUtils.ROW_COUNT_RESULT_COL; import static io.airbyte.integrations.source.postgres.PostgresQueryUtils.TABLE_ESTIMATE_QUERY; import static io.airbyte.integrations.source.postgres.PostgresQueryUtils.TOTAL_BYTES_RESULT_COL; +import static io.airbyte.integrations.source.postgres.PostgresQueryUtils.filterStreamsUnderVacuumForCtidSync; +import static io.airbyte.integrations.source.postgres.PostgresQueryUtils.getCursorBasedSyncStatusForStreams; import static io.airbyte.integrations.source.postgres.PostgresQueryUtils.streamsUnderVacuum; import static io.airbyte.integrations.source.postgres.PostgresUtils.isIncrementalSyncMode; import static io.airbyte.integrations.source.postgres.cdc.PostgresCdcCtidInitializer.cdcCtidIteratorsCombined; +import static io.airbyte.integrations.source.postgres.cursor_based.CursorBasedCtidUtils.categoriseStreams; import static io.airbyte.integrations.source.postgres.xmin.XminCtidUtils.categoriseStreams; import static io.airbyte.integrations.source.relationaldb.RelationalDbQueryUtils.getFullyQualifiedTableNameWithQuoting; import static io.airbyte.integrations.util.PostgresSslConnectionUtils.PARAM_SSL_MODE; @@ -59,18 +62,23 @@ import io.airbyte.integrations.source.jdbc.JdbcSSLConnectionUtils; import io.airbyte.integrations.source.jdbc.JdbcSSLConnectionUtils.SslMode; import io.airbyte.integrations.source.jdbc.dto.JdbcPrivilegeDto; +import io.airbyte.integrations.source.postgres.PostgresQueryUtils.TableBlockSize; import io.airbyte.integrations.source.postgres.cdc.PostgresCdcConnectorMetadataInjector; import io.airbyte.integrations.source.postgres.cdc.PostgresCdcProperties; import io.airbyte.integrations.source.postgres.cdc.PostgresCdcSavedInfoFetcher; import io.airbyte.integrations.source.postgres.cdc.PostgresCdcStateHandler; -import io.airbyte.integrations.source.postgres.PostgresQueryUtils.TableBlockSize; -import io.airbyte.integrations.source.postgres.ctid.CtidPostgresSourceOperations; +import io.airbyte.integrations.source.postgres.ctid.CtidFeatureFlags; import io.airbyte.integrations.source.postgres.ctid.CtidPerStreamStateManager; +import io.airbyte.integrations.source.postgres.ctid.CtidPostgresSourceOperations; import io.airbyte.integrations.source.postgres.ctid.CtidStateManager; +import io.airbyte.integrations.source.postgres.ctid.CtidUtils.StreamsCategorised; import io.airbyte.integrations.source.postgres.ctid.PostgresCtidHandler; +import io.airbyte.integrations.source.postgres.cursor_based.CursorBasedCtidUtils.CursorBasedStreams; +import io.airbyte.integrations.source.postgres.cursor_based.PostgresCursorBasedStateManager; +import io.airbyte.integrations.source.postgres.internal.models.CursorBasedStatus; import io.airbyte.integrations.source.postgres.internal.models.XminStatus; import io.airbyte.integrations.source.postgres.xmin.PostgresXminHandler; -import io.airbyte.integrations.source.postgres.xmin.XminCtidUtils.StreamsCategorised; +import io.airbyte.integrations.source.postgres.xmin.XminCtidUtils.XminStreams; import io.airbyte.integrations.source.postgres.xmin.XminStateManager; import io.airbyte.integrations.source.relationaldb.TableInfo; import io.airbyte.integrations.source.relationaldb.state.StateManager; @@ -278,7 +286,8 @@ public AirbyteCatalog discover(final JsonNode config) throws Exception { // Xmin replication has a source-defined cursor (the xmin column). This is done to prevent the user // from being able to pick their own cursor. final List streams = catalog.getStreams().stream() - // We want to make sure every stream can be synced in INCREMENTAL mode and never in FULL_REFRESH mode for xmin. + // We want to make sure every stream can be synced in INCREMENTAL mode and never in FULL_REFRESH + // mode for xmin. .map(PostgresCatalogHelper::overrideSyncModesForXmin) .map(PostgresCatalogHelper::setIncrementalToSourceDefined) .collect(toList()); @@ -405,6 +414,7 @@ public List> getIncrementalIterators(final final StateManager stateManager, final Instant emittedAt) { final JsonNode sourceConfig = database.getSourceConfig(); + final CtidFeatureFlags ctidFeatureFlags = new CtidFeatureFlags(sourceConfig); if (PostgresUtils.isCdc(sourceConfig) && shouldUseCDC(catalog)) { if (sourceConfig.has("cdc_via_ctid") && sourceConfig.get("cdc_via_ctid").asBoolean()) { LOGGER.info("Using ctid + CDC"); @@ -418,8 +428,9 @@ public List> getIncrementalIterators(final final PostgresDebeziumStateUtil postgresDebeziumStateUtil = new PostgresDebeziumStateUtil(); final JsonNode state = - (stateManager.getCdcStateManager().getCdcState() == null || stateManager.getCdcStateManager().getCdcState().getState() == null) ? null - : Jsons.clone(stateManager.getCdcStateManager().getCdcState().getState()); + (stateManager.getCdcStateManager().getCdcState() == null || + stateManager.getCdcStateManager().getCdcState().getState() == null) ? null + : Jsons.clone(stateManager.getCdcStateManager().getCdcState().getState()); final OptionalLong savedOffset = postgresDebeziumStateUtil.savedOffset( Jsons.clone(PostgresCdcProperties.getDebeziumDefaultProperties(database)), @@ -452,16 +463,22 @@ public List> getIncrementalIterators(final } final AirbyteDebeziumHandler handler = new AirbyteDebeziumHandler<>(sourceConfig, - PostgresCdcTargetPosition.targetPosition(database), false, firstRecordWaitTime, queueSize); + PostgresCdcTargetPosition.targetPosition(database), + false, + firstRecordWaitTime, + queueSize); final PostgresCdcStateHandler postgresCdcStateHandler = new PostgresCdcStateHandler(stateManager); final List streamsToSnapshot = identifyStreamsToSnapshot(catalog, stateManager); - final Supplier> incrementalIteratorSupplier = () -> handler.getIncrementalIterators(catalog, - new PostgresCdcSavedInfoFetcher(savedOffsetAfterReplicationSlotLSN ? stateManager.getCdcStateManager().getCdcState() : null), - postgresCdcStateHandler, - new PostgresCdcConnectorMetadataInjector(), - PostgresCdcProperties.getDebeziumDefaultProperties(database), - emittedAt, - false); + final Supplier> incrementalIteratorSupplier = + () -> handler.getIncrementalIterators(catalog, + new PostgresCdcSavedInfoFetcher( + savedOffsetAfterReplicationSlotLSN ? stateManager.getCdcStateManager().getCdcState() + : null), + postgresCdcStateHandler, + new PostgresCdcConnectorMetadataInjector(), + PostgresCdcProperties.getDebeziumDefaultProperties(database), + emittedAt, + false); if (!savedOffsetAfterReplicationSlotLSN || streamsToSnapshot.isEmpty()) { return Collections.singletonList(incrementalIteratorSupplier.get()); } @@ -473,60 +490,118 @@ public List> getIncrementalIterators(final AutoCloseableIterators.concatWithEagerClose(AirbyteTraceMessageUtility::emitStreamStatusTrace, snapshotIterator, AutoCloseableIterators.lazyIterator(incrementalIteratorSupplier, null))); - } else if (PostgresUtils.isXmin(sourceConfig) && isIncrementalSyncMode(catalog)) { - final StreamsCategorised streamsCategorised = categoriseStreams(stateManager, catalog, xminStatus); + } - final List> ctidIterator = new ArrayList<>(); - final List> xminIterator = new ArrayList<>(); + if (isIncrementalSyncMode(catalog) && PostgresUtils.isXmin(sourceConfig)) { + final StreamsCategorised streamsCategorised = categoriseStreams(stateManager, catalog, xminStatus); + final List streamsUnderVacuum = streamsUnderVacuum(database, + streamsCategorised.ctidStreams().streamsForCtidSync(), + getQuoteString()); + final List finalListOfStreamsToBeSyncedViaCtid = + filterStreamsUnderVacuumForCtidSync(streamsUnderVacuum, streamsCategorised.ctidStreams()); + final Map fileNodes = + PostgresQueryUtils.fileNodeForStreams(database, + finalListOfStreamsToBeSyncedViaCtid, + getQuoteString()); + final CtidStateManager ctidStateManager = new CtidPerStreamStateManager(streamsCategorised.ctidStreams().statesFromCtidSync(), fileNodes); + final Map tableBlockSizes = + PostgresQueryUtils.getTableBlockSizeForStream( + database, + finalListOfStreamsToBeSyncedViaCtid, + getQuoteString()); if (!streamsCategorised.ctidStreams().streamsForCtidSync().isEmpty()) { - final List streamsUnderVacuum = streamsUnderVacuum(database, - streamsCategorised.ctidStreams().streamsForCtidSync(), getQuoteString()); - - final List finalListOfStreamsToBeSyncedViaCtid = - streamsUnderVacuum.isEmpty() ? streamsCategorised.ctidStreams().streamsForCtidSync() - : streamsCategorised.ctidStreams().streamsForCtidSync().stream() - .filter(c -> !streamsUnderVacuum.contains(AirbyteStreamNameNamespacePair.fromConfiguredAirbyteSteam(c))) - .toList(); LOGGER.info("Streams to be synced via ctid : {}", finalListOfStreamsToBeSyncedViaCtid.size()); - final Map fileNodes = PostgresQueryUtils.fileNodeForStreams(database, - finalListOfStreamsToBeSyncedViaCtid, - getQuoteString()); - final CtidStateManager ctidStateManager = new CtidPerStreamStateManager(streamsCategorised.ctidStreams().statesFromCtidSync(), fileNodes); - final Map tableBlockSizes = - PostgresQueryUtils.getTableBlockSizeForStream( - database, - finalListOfStreamsToBeSyncedViaCtid, - getQuoteString()); - - final PostgresCtidHandler ctidHandler = new PostgresCtidHandler(sourceConfig, database, new CtidPostgresSourceOperations(Optional.empty()), - getQuoteString(), - fileNodes, tableBlockSizes, ctidStateManager, - namespacePair -> Jsons.jsonNode(xminStatus)); - ctidIterator.addAll(ctidHandler.getIncrementalIterators( - new ConfiguredAirbyteCatalog().withStreams(finalListOfStreamsToBeSyncedViaCtid), tableNameToTable, emittedAt)); } else { LOGGER.info("No Streams will be synced via ctid."); } - if (!streamsCategorised.xminStreams().streamsForXminSync().isEmpty()) { - LOGGER.info("Streams to be synced via xmin : {}", streamsCategorised.xminStreams().streamsForXminSync().size()); - final XminStateManager xminStateManager = new XminStateManager(streamsCategorised.xminStreams().statesFromXminSync()); - final PostgresXminHandler xminHandler = new PostgresXminHandler(database, sourceOperations, getQuoteString(), xminStatus, xminStateManager); - - xminIterator.addAll(xminHandler.getIncrementalIterators( - new ConfiguredAirbyteCatalog().withStreams(streamsCategorised.xminStreams().streamsForXminSync()), tableNameToTable, emittedAt)); + if (!streamsCategorised.remainingStreams().streamsForXminSync().isEmpty()) { + LOGGER.info("Streams to be synced via xmin : {}", streamsCategorised.remainingStreams().streamsForXminSync().size()); } else { LOGGER.info("No Streams will be synced via xmin."); } + final XminStateManager xminStateManager = new XminStateManager(streamsCategorised.remainingStreams().statesFromXminSync()); + final PostgresXminHandler xminHandler = new PostgresXminHandler(database, sourceOperations, getQuoteString(), xminStatus, xminStateManager); + + final PostgresCtidHandler ctidHandler = + new PostgresCtidHandler(sourceConfig, database, new CtidPostgresSourceOperations(Optional.empty()), getQuoteString(), + fileNodes, tableBlockSizes, ctidStateManager, + namespacePair -> Jsons.jsonNode(xminStatus)); + + final List> ctidIterators = new ArrayList<>(ctidHandler.getIncrementalIterators( + new ConfiguredAirbyteCatalog().withStreams(finalListOfStreamsToBeSyncedViaCtid), tableNameToTable, emittedAt)); + final List> xminIterators = new ArrayList<>(xminHandler.getIncrementalIterators( + new ConfiguredAirbyteCatalog().withStreams(streamsCategorised.remainingStreams().streamsForXminSync()), tableNameToTable, emittedAt)); + return Stream - .of(ctidIterator, xminIterator) + .of(ctidIterators, xminIterators) + .flatMap(Collection::stream) + .collect(Collectors.toList()); + + } else if (isIncrementalSyncMode(catalog) && ctidFeatureFlags.isCursorSyncEnabled()) { + final PostgresCursorBasedStateManager postgresCursorBasedStateManager = + new PostgresCursorBasedStateManager(stateManager.getRawStateMessages(), catalog); + final StreamsCategorised streamsCategorised = categoriseStreams(postgresCursorBasedStateManager, catalog); + final List streamsUnderVacuum = streamsUnderVacuum(database, + streamsCategorised.ctidStreams().streamsForCtidSync(), + getQuoteString()); + final List finalListOfStreamsToBeSyncedViaCtid = + filterStreamsUnderVacuumForCtidSync(streamsUnderVacuum, streamsCategorised.ctidStreams()); + final Map fileNodes = + PostgresQueryUtils.fileNodeForStreams(database, + finalListOfStreamsToBeSyncedViaCtid, + getQuoteString()); + final CtidStateManager ctidStateManager = new CtidPerStreamStateManager(streamsCategorised.ctidStreams().statesFromCtidSync(), fileNodes); + final Map tableBlockSizes = + PostgresQueryUtils.getTableBlockSizeForStream( + database, + finalListOfStreamsToBeSyncedViaCtid, + getQuoteString()); + if (finalListOfStreamsToBeSyncedViaCtid.isEmpty()) { + LOGGER.info("No Streams will be synced via ctid."); + } else { + LOGGER.info("Streams to be synced via ctid : {}", finalListOfStreamsToBeSyncedViaCtid.size()); + } + + if (!streamsCategorised.remainingStreams().streamsForCursorBasedSync().isEmpty()) { + LOGGER.info("Streams to be synced via cursor : {}", streamsCategorised.remainingStreams().streamsForCursorBasedSync().size()); + } else { + LOGGER.info("No streams to be synced via cursor"); + } + + final Map cursorBasedStatusMap = + getCursorBasedSyncStatusForStreams(database, finalListOfStreamsToBeSyncedViaCtid, postgresCursorBasedStateManager); + + final PostgresCtidHandler cursorBasedCtidHandler = + new PostgresCtidHandler(sourceConfig, + database, + new CtidPostgresSourceOperations(Optional.empty()), + getQuoteString(), + fileNodes, + tableBlockSizes, + ctidStateManager, + namespacePair -> Jsons.jsonNode(cursorBasedStatusMap.get(namespacePair))); + + final List> ctidIterators = new ArrayList<>( + cursorBasedCtidHandler.getIncrementalIterators(new ConfiguredAirbyteCatalog().withStreams(finalListOfStreamsToBeSyncedViaCtid), + tableNameToTable, + emittedAt)); + final List> cursorBasedIterators = new ArrayList<>(super.getIncrementalIterators(database, + new ConfiguredAirbyteCatalog().withStreams( + streamsCategorised.remainingStreams() + .streamsForCursorBasedSync()), + tableNameToTable, + postgresCursorBasedStateManager, emittedAt)); + + return Stream + .of(ctidIterators, cursorBasedIterators) .flatMap(Collection::stream) .collect(Collectors.toList()); - } else { - return super.getIncrementalIterators(database, catalog, tableNameToTable, stateManager, emittedAt); } + + return super.getIncrementalIterators(database, catalog, tableNameToTable, stateManager, emittedAt); } @Override diff --git a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/ctid/CtidFeatureFlags.java b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/ctid/CtidFeatureFlags.java new file mode 100644 index 000000000000..440b43f3d661 --- /dev/null +++ b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/ctid/CtidFeatureFlags.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.postgres.ctid; + +import com.fasterxml.jackson.databind.JsonNode; + +// Feature flags to gate CTID syncs +// One for each type: CDC and standard cursor based +public class CtidFeatureFlags { + + public static final String CDC_VIA_CTID = "cdc_via_ctid"; + public static final String CURSOR_VIA_CTID = "cursor_via_ctid"; + private final JsonNode sourceConfig; + + public CtidFeatureFlags(final JsonNode sourceConfig) { + this.sourceConfig = sourceConfig; + } + + public boolean isCdcSyncEnabled() { + return getFlagValue(CDC_VIA_CTID); + } + + public boolean isCursorSyncEnabled() { + return getFlagValue(CURSOR_VIA_CTID); + } + + private boolean getFlagValue(final String flag) { + return sourceConfig.has(flag) && sourceConfig.get(flag).asBoolean(); + } + +} diff --git a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/ctid/CtidUtils.java b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/ctid/CtidUtils.java new file mode 100644 index 000000000000..4189d384308c --- /dev/null +++ b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/ctid/CtidUtils.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.postgres.ctid; + +import com.google.common.collect.Sets; +import io.airbyte.commons.json.Jsons; +import io.airbyte.protocol.models.v0.AirbyteStateMessage; +import io.airbyte.protocol.models.v0.AirbyteStreamNameNamespacePair; +import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; +import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class CtidUtils { + + public static List identifyNewlyAddedStreams(final ConfiguredAirbyteCatalog fullCatalog, + final Set alreadySeenStreams) { + final Set allStreams = AirbyteStreamNameNamespacePair.fromConfiguredCatalog(fullCatalog); + + final Set newlyAddedStreams = new HashSet<>(Sets.difference(allStreams, alreadySeenStreams)); + + return fullCatalog.getStreams().stream() + .filter(stream -> newlyAddedStreams.contains(AirbyteStreamNameNamespacePair.fromAirbyteStream(stream.getStream()))) + .map(Jsons::clone) + .collect(Collectors.toList()); + } + + public static List getStreamsFromStreamPairs(final ConfiguredAirbyteCatalog catalog, + final Set streamPairs) { + + return catalog.getStreams().stream() + .filter(stream -> streamPairs.contains(AirbyteStreamNameNamespacePair.fromAirbyteStream(stream.getStream()))) + .map(Jsons::clone) + .collect(Collectors.toList()); + } + + public record CtidStreams(List streamsForCtidSync, + List statesFromCtidSync) { + + } + + public record StreamsCategorised (CtidStreams ctidStreams, + T remainingStreams) { + + } + +} diff --git a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/cursor_based/CursorBasedCtidUtils.java b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/cursor_based/CursorBasedCtidUtils.java new file mode 100644 index 000000000000..db26a2a428b8 --- /dev/null +++ b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/cursor_based/CursorBasedCtidUtils.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2023 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.postgres.cursor_based; + +import static io.airbyte.integrations.source.postgres.ctid.CtidUtils.getStreamsFromStreamPairs; +import static io.airbyte.integrations.source.postgres.ctid.CtidUtils.identifyNewlyAddedStreams; + +import com.fasterxml.jackson.databind.JsonNode; +import io.airbyte.integrations.source.postgres.ctid.CtidUtils.CtidStreams; +import io.airbyte.integrations.source.postgres.ctid.CtidUtils.StreamsCategorised; +import io.airbyte.integrations.source.postgres.internal.models.InternalModels.StateType; +import io.airbyte.integrations.source.relationaldb.state.StateManager; +import io.airbyte.protocol.models.v0.AirbyteStateMessage; +import io.airbyte.protocol.models.v0.AirbyteStreamNameNamespacePair; +import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; +import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; +import io.airbyte.protocol.models.v0.StreamDescriptor; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The class mainly categorises the streams based on the state type into two categories : 1. Streams + * that need to be synced via ctid iterator: These are streams that are either newly added or did + * not complete their initial sync. 2. Streams that need to be synced via cursor-based + * iterator: These are streams that have completed their initial sync and are not syncing data + * incrementally. + */ +public class CursorBasedCtidUtils { + + private static final Logger LOGGER = LoggerFactory.getLogger(CursorBasedCtidUtils.class); + + public static StreamsCategorised categoriseStreams(final StateManager stateManager, + final ConfiguredAirbyteCatalog fullCatalog) { + final List rawStateMessages = stateManager.getRawStateMessages(); + final List statesFromCtidSync = new ArrayList<>(); + final Set alreadySeenStreamPairs = new HashSet<>(); + final Set stillInCtidStreamPairs = new HashSet<>(); + + final List statesFromCursorBasedSync = new ArrayList<>(); + final Set cursorBasedSyncStreamPairs = new HashSet<>(); + + if (rawStateMessages != null) { + rawStateMessages.forEach(stateMessage -> { + final JsonNode streamState = stateMessage.getStream().getStreamState(); + final StreamDescriptor streamDescriptor = stateMessage.getStream().getStreamDescriptor(); + if (streamState == null || streamDescriptor == null) { + return; + } + + final AirbyteStreamNameNamespacePair pair = new AirbyteStreamNameNamespacePair(streamDescriptor.getName(), + streamDescriptor.getNamespace()); + + if (streamState.has("state_type")) { + if (streamState.get("state_type").asText().equalsIgnoreCase(StateType.CTID.value())) { + statesFromCtidSync.add(stateMessage); + stillInCtidStreamPairs.add(pair); + } else if (streamState.get("state_type").asText().equalsIgnoreCase(StateType.CURSOR_BASED.value())) { + cursorBasedSyncStreamPairs.add(pair); + statesFromCursorBasedSync.add(stateMessage); + } else { + throw new RuntimeException("Unknown state type: " + streamState.get("state_type").asText()); + } + } else { + LOGGER.info("State type not present, syncing stream {} via cursor", streamDescriptor.getName()); + cursorBasedSyncStreamPairs.add(pair); + statesFromCursorBasedSync.add(stateMessage); + } + alreadySeenStreamPairs.add(new AirbyteStreamNameNamespacePair(streamDescriptor.getName(), streamDescriptor.getNamespace())); + }); + } + + final List newlyAddedStreams = identifyNewlyAddedStreams(fullCatalog, alreadySeenStreamPairs); + final List streamsForCtidSync = getStreamsFromStreamPairs(fullCatalog, stillInCtidStreamPairs); + streamsForCtidSync.addAll(newlyAddedStreams); + + final List streamsForCursorBasedSync = getStreamsFromStreamPairs(fullCatalog, cursorBasedSyncStreamPairs); + + return new StreamsCategorised<>(new CtidStreams(streamsForCtidSync, statesFromCtidSync), + new CursorBasedStreams(streamsForCursorBasedSync, statesFromCursorBasedSync)); + } + + public record CursorBasedStreams(List streamsForCursorBasedSync, + List statesFromCursorBasedSync) {} + +} diff --git a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/cursor_based/PostgresCursorBasedStateManager.java b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/cursor_based/PostgresCursorBasedStateManager.java new file mode 100644 index 000000000000..80de3cdddbc2 --- /dev/null +++ b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/cursor_based/PostgresCursorBasedStateManager.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2023 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.postgres.cursor_based; + +import com.google.common.collect.Lists; +import io.airbyte.commons.json.Jsons; +import io.airbyte.integrations.source.postgres.internal.models.InternalModels.StateType; +import io.airbyte.integrations.source.postgres.internal.models.CursorBasedStatus; +import io.airbyte.integrations.source.relationaldb.CursorInfo; +import io.airbyte.integrations.source.relationaldb.models.DbState; +import io.airbyte.integrations.source.relationaldb.state.StreamStateManager; +import io.airbyte.protocol.models.v0.AirbyteStateMessage; +import io.airbyte.protocol.models.v0.AirbyteStateMessage.AirbyteStateType; +import io.airbyte.protocol.models.v0.AirbyteStreamNameNamespacePair; +import io.airbyte.protocol.models.v0.AirbyteStreamState; +import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; +import io.airbyte.protocol.models.v0.StreamDescriptor; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.stream.Collectors; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This state manager extends the StreamStateManager to enable writing the state_type and version + * keys to the stream state when they're going through the iterator Once we have verified that + * expanding StreamStateManager itself to include this functionality, this class will be removed + */ +public class PostgresCursorBasedStateManager extends StreamStateManager { + + private static final Logger LOGGER = LoggerFactory.getLogger(StreamStateManager.class); + + + public PostgresCursorBasedStateManager(final List airbyteStateMessages, final ConfiguredAirbyteCatalog catalog) { + super(airbyteStateMessages, catalog); + } + + @Override + public AirbyteStateMessage toState(final Optional pair) { + if (pair.isPresent()) { + final Map pairToCursorInfoMap = getPairToCursorInfoMap(); + final Optional cursorInfo = Optional.ofNullable(pairToCursorInfoMap.get(pair.get())); + + if (cursorInfo.isPresent()) { + LOGGER.debug("Generating state message for {}...", pair); + return new AirbyteStateMessage() + .withType(AirbyteStateType.STREAM) + // Temporarily include legacy state for backwards compatibility with the platform + .withData(Jsons.jsonNode(generateDbState(pairToCursorInfoMap))) + .withStream(generateStreamState(pair.get(), cursorInfo.get())); + } else { + LOGGER.warn("Cursor information could not be located in state for stream {}. Returning a new, empty state message...", pair); + return new AirbyteStateMessage().withType(AirbyteStateType.STREAM).withStream(new AirbyteStreamState()); + } + } else { + LOGGER.warn("Stream not provided. Returning a new, empty state message..."); + return new AirbyteStateMessage().withType(AirbyteStateType.STREAM).withStream(new AirbyteStreamState()); + } + } + + /** + * Generates the stream state for the given stream and cursor information. + * + * @param airbyteStreamNameNamespacePair The stream. + * @param cursorInfo The current cursor. + * @return The {@link AirbyteStreamState} representing the current state of the stream. + */ + private AirbyteStreamState generateStreamState(final AirbyteStreamNameNamespacePair airbyteStreamNameNamespacePair, + final CursorInfo cursorInfo) { + return new AirbyteStreamState() + .withStreamDescriptor( + new StreamDescriptor().withName(airbyteStreamNameNamespacePair.getName()).withNamespace(airbyteStreamNameNamespacePair.getNamespace())) + .withStreamState(Jsons.jsonNode(generateDbStreamState(airbyteStreamNameNamespacePair, cursorInfo))); + } + + private CursorBasedStatus generateDbStreamState(final AirbyteStreamNameNamespacePair airbyteStreamNameNamespacePair, + final CursorInfo cursorInfo) { + final CursorBasedStatus state = new CursorBasedStatus(); + state.setStateType(StateType.CURSOR_BASED); + state.setVersion(2L); + state.setStreamName(airbyteStreamNameNamespacePair.getName()); + state.setStreamNamespace(airbyteStreamNameNamespacePair.getNamespace()); + state.setCursorField(cursorInfo.getCursorField() == null ? Collections.emptyList() : Lists.newArrayList(cursorInfo.getCursorField())); + state.setCursor(cursorInfo.getCursor()); + if (cursorInfo.getCursorRecordCount() > 0L) { + state.setCursorRecordCount(cursorInfo.getCursorRecordCount()); + } + return state; + } + + /** + * Generates the legacy global state for backwards compatibility. + * + * @param pairToCursorInfoMap The map of stream name/namespace tuple to the current cursor + * information for that stream + * @return The legacy {@link DbState}. + */ + private DbState generateDbState(final Map pairToCursorInfoMap) { + return new DbState() + .withCdc(false) + .withStreams(pairToCursorInfoMap.entrySet().stream() + .sorted(Entry.comparingByKey()) // sort by stream name then namespace for sanity. + .map(e -> generateDbStreamState(e.getKey(), e.getValue())) + .collect(Collectors.toList())); + } + +} diff --git a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/xmin/PostgresXminHandler.java b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/xmin/PostgresXminHandler.java index 3ec0e3692ffd..cf955dc91cc4 100644 --- a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/xmin/PostgresXminHandler.java +++ b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/xmin/PostgresXminHandler.java @@ -192,7 +192,7 @@ static boolean isSingleWraparound(final XminStatus prevRunXminStatus, final Xmin return currentXminStatus.getNumWraparound() - prevRunXminStatus.getNumWraparound() == 1; } - static boolean shouldPerformFullSync(final XminStatus currentXminStatus, final JsonNode streamState) { + public static boolean shouldPerformFullSync(final XminStatus currentXminStatus, final JsonNode streamState) { // Detects whether source Postgres DB has undergone multiple wraparound events between syncs. return streamState.has("num_wraparound") && (currentXminStatus.getNumWraparound() - streamState.get("num_wraparound").asLong() >= 2); } diff --git a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/xmin/XminCtidUtils.java b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/xmin/XminCtidUtils.java index 4c7fafaa34a4..36da2389f4e7 100644 --- a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/xmin/XminCtidUtils.java +++ b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/xmin/XminCtidUtils.java @@ -4,11 +4,13 @@ package io.airbyte.integrations.source.postgres.xmin; +import static io.airbyte.integrations.source.postgres.ctid.CtidUtils.identifyNewlyAddedStreams; import static io.airbyte.integrations.source.postgres.xmin.PostgresXminHandler.shouldPerformFullSync; import com.fasterxml.jackson.databind.JsonNode; -import com.google.common.collect.Sets; import io.airbyte.commons.json.Jsons; +import io.airbyte.integrations.source.postgres.ctid.CtidUtils.CtidStreams; +import io.airbyte.integrations.source.postgres.ctid.CtidUtils.StreamsCategorised; import io.airbyte.integrations.source.postgres.internal.models.XminStatus; import io.airbyte.integrations.source.relationaldb.state.StateManager; import io.airbyte.protocol.models.v0.AirbyteStateMessage; @@ -16,18 +18,16 @@ import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; import io.airbyte.protocol.models.v0.StreamDescriptor; -import io.airbyte.protocol.models.v0.SyncMode; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.stream.Collectors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * The class mainly categorises the streams based on the state type into two categories : 1. Streams - * that need to be synced via ctid iterator: These are streams that are either newly added or did + * The class mainly categorises the streams based on the state type into two categories: + * 1. Streams that need to be synced via ctid iterator: These are streams that are either newly added or did * not complete their initial sync. 2. Streams that need to be synced via xmin iterator: These are * streams that have completed their initial sync and are not syncing data incrementally. */ @@ -35,9 +35,9 @@ public class XminCtidUtils { private static final Logger LOGGER = LoggerFactory.getLogger(XminCtidUtils.class); - public static StreamsCategorised categoriseStreams(final StateManager stateManager, - final ConfiguredAirbyteCatalog fullCatalog, - final XminStatus currentXminStatus) { + public static StreamsCategorised categoriseStreams(final StateManager stateManager, + final ConfiguredAirbyteCatalog fullCatalog, + final XminStatus currentXminStatus) { final List rawStateMessages = stateManager.getRawStateMessages(); final List statesFromCtidSync = new ArrayList<>(); final List statesFromXminSync = new ArrayList<>(); @@ -90,30 +90,7 @@ public static StreamsCategorised categoriseStreams(final StateManager stateManag .map(Jsons::clone) .toList(); - return new StreamsCategorised(new CtidStreams(streamsForCtidSync, statesFromCtidSync), new XminStreams(streamsForXminSync, statesFromXminSync)); - } - - private static List identifyNewlyAddedStreams(final ConfiguredAirbyteCatalog fullCatalog, - final Set alreadySeenStreams) { - final Set allStreams = AirbyteStreamNameNamespacePair.fromConfiguredCatalog(fullCatalog); - - final Set newlyAddedStreams = new HashSet<>(Sets.difference(allStreams, alreadySeenStreams)); - - return fullCatalog.getStreams().stream() - .filter(c -> c.getSyncMode() == SyncMode.INCREMENTAL) - .filter(stream -> newlyAddedStreams.contains(AirbyteStreamNameNamespacePair.fromAirbyteStream(stream.getStream()))) - .map(Jsons::clone) - .collect(Collectors.toList()); - } - - public record StreamsCategorised(CtidStreams ctidStreams, - XminStreams xminStreams) { - - } - - public record CtidStreams(List streamsForCtidSync, - List statesFromCtidSync) { - + return new StreamsCategorised<>(new CtidStreams(streamsForCtidSync, statesFromCtidSync), new XminStreams(streamsForXminSync, statesFromXminSync)); } public record XminStreams(List streamsForXminSync, diff --git a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/xmin/XminStateManager.java b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/xmin/XminStateManager.java index 14cd2cef0956..58477cd1c4e8 100644 --- a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/xmin/XminStateManager.java +++ b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/xmin/XminStateManager.java @@ -90,11 +90,8 @@ public static AirbyteStateMessage getAirbyteStateMessage(final AirbyteStreamName .withStreamState(Jsons.jsonNode(xminStatus)); // Set state - final AirbyteStateMessage stateMessage = - new AirbyteStateMessage() - .withType(AirbyteStateType.STREAM) - .withStream(airbyteStreamState); - return stateMessage; + return new AirbyteStateMessage() + .withType(AirbyteStateType.STREAM) + .withStream(airbyteStreamState); } - } diff --git a/airbyte-integrations/connectors/source-postgres/src/main/resources/internal_models/internal_models.yaml b/airbyte-integrations/connectors/source-postgres/src/main/resources/internal_models/internal_models.yaml index a79f6ecda22f..9a5d5c630c9d 100644 --- a/airbyte-integrations/connectors/source-postgres/src/main/resources/internal_models/internal_models.yaml +++ b/airbyte-integrations/connectors/source-postgres/src/main/resources/internal_models/internal_models.yaml @@ -10,13 +10,27 @@ properties: "$ref": "#/definitions/XminStatus" ctid_state: "$ref": "#/definitions/CtidStatus" + cursor_based_state: + "$ref": "#/definitions/CursorBasedStatus" definitions: StateType: description: Enum to define the sync mode of state. type: string enum: + - cursorBased - xmin - ctid + CursorBasedStatus: + type: object + extends: + type: object + existingJavaType: "io.airbyte.integrations.source.relationaldb.models.DbStreamState" + properties: + state_type: + "$ref": "#/definitions/StateType" + version: + description: Version of state. + type: integer XminStatus: type: object properties: diff --git a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/CtidEnabledCdcPostgresSourceTest.java b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/CtidEnabledCdcPostgresSourceTest.java index 1006fe762b91..5470a1d93de4 100644 --- a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/CtidEnabledCdcPostgresSourceTest.java +++ b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/CtidEnabledCdcPostgresSourceTest.java @@ -1,5 +1,6 @@ package io.airbyte.integrations.source.postgres; +import static io.airbyte.integrations.source.postgres.ctid.CtidFeatureFlags.CDC_VIA_CTID; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -66,7 +67,7 @@ protected void assertExpectedStateMessages(final List state @Override protected JsonNode getConfig() { JsonNode config = super.getConfig(); - ((ObjectNode) config).put("cdc_via_ctid", true); + ((ObjectNode) config).put(CDC_VIA_CTID, true); return config; } diff --git a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/CtidEnabledPostgresSourceTest.java b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/CtidEnabledPostgresSourceTest.java new file mode 100644 index 000000000000..1ed7890e8a1a --- /dev/null +++ b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/CtidEnabledPostgresSourceTest.java @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2023 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.postgres; + +import static io.airbyte.integrations.source.postgres.ctid.CtidFeatureFlags.CURSOR_VIA_CTID; +import static io.airbyte.integrations.source.postgres.utils.PostgresUnitTestsUtil.createRecord; +import static io.airbyte.integrations.source.postgres.utils.PostgresUnitTestsUtil.extractSpecificFieldFromCombinedMessages; +import static io.airbyte.integrations.source.postgres.utils.PostgresUnitTestsUtil.extractStateMessage; +import static io.airbyte.integrations.source.postgres.utils.PostgresUnitTestsUtil.filterRecords; +import static io.airbyte.integrations.source.postgres.utils.PostgresUnitTestsUtil.map; +import static java.util.stream.Collectors.toList; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import io.airbyte.commons.json.Jsons; +import io.airbyte.commons.util.MoreIterators; +import io.airbyte.integrations.source.postgres.internal.models.CursorBasedStatus; +import io.airbyte.integrations.source.postgres.internal.models.InternalModels.StateType; +import io.airbyte.integrations.source.relationaldb.models.DbStreamState; +import io.airbyte.protocol.models.Field; +import io.airbyte.protocol.models.JsonSchemaType; +import io.airbyte.protocol.models.v0.AirbyteCatalog; +import io.airbyte.protocol.models.v0.AirbyteMessage; +import io.airbyte.protocol.models.v0.AirbyteRecordMessage; +import io.airbyte.protocol.models.v0.AirbyteStateMessage; +import io.airbyte.protocol.models.v0.AirbyteStream; +import io.airbyte.protocol.models.v0.CatalogHelpers; +import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; +import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; +import io.airbyte.protocol.models.v0.DestinationSyncMode; +import io.airbyte.protocol.models.v0.SyncMode; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class CtidEnabledPostgresSourceTest extends PostgresJdbcSourceAcceptanceTest { + + @BeforeEach + public void enableCursorViaCtid() { + ((ObjectNode) config).put(CURSOR_VIA_CTID, true); + } + + @Test + void testReadMultipleTablesIncrementally() throws Exception { + ((ObjectNode) config).put("sync_checkpoint_records", 1); + final String namespace = getDefaultNamespace(); + final String streamOneName = TABLE_NAME + "one"; + // Create a fresh first table + database.execute(connection -> { + connection.createStatement().execute( + createTableQuery(getFullyQualifiedTableName(streamOneName), COLUMN_CLAUSE_WITH_PK, + primaryKeyClause(Collections.singletonList("id")))); + connection.createStatement().execute( + String.format( + "INSERT INTO %s(id, name, updated_at, wakeup_at, last_visited_at, last_comment_at) VALUES (1,'picard', '2004-10-19','10:10:10.123456-05:00','2004-10-19T17:23:54.123456Z','2004-01-01T17:23:54.123456')", + getFullyQualifiedTableName(streamOneName))); + connection.createStatement().execute( + String.format( + "INSERT INTO %s(id, name, updated_at, wakeup_at, last_visited_at, last_comment_at) VALUES (2, 'crusher', '2005-10-19','11:11:11.123456-05:00','2005-10-19T17:23:54.123456Z','2005-01-01T17:23:54.123456')", + getFullyQualifiedTableName(streamOneName))); + connection.createStatement().execute( + String.format( + "INSERT INTO %s(id, name, updated_at, wakeup_at, last_visited_at, last_comment_at) VALUES (3, 'vash', '2006-10-19','12:12:12.123456-05:00','2006-10-19T17:23:54.123456Z','2006-01-01T17:23:54.123456')", + getFullyQualifiedTableName(streamOneName))); + }); + + // Create a fresh second table + final String streamTwoName = TABLE_NAME + "two"; + final String streamTwoFullyQualifiedName = getFullyQualifiedTableName(streamTwoName); + // Insert records into second table + database.execute(ctx -> { + ctx.createStatement().execute( + createTableQuery(streamTwoFullyQualifiedName, COLUMN_CLAUSE_WITH_PK, "")); + ctx.createStatement().execute( + String.format("INSERT INTO %s(id, name, updated_at, wakeup_at, last_visited_at, last_comment_at)" + + "VALUES (40,'Jean Luc','2006-10-19','12:12:12.123456-05:00','2006-10-19T17:23:54.123456Z','2006-01-01T17:23:54.123456')", + streamTwoFullyQualifiedName)); + ctx.createStatement().execute( + String.format("INSERT INTO %s(id, name, updated_at, wakeup_at, last_visited_at, last_comment_at)" + + "VALUES (41, 'Groot', '2006-10-19','12:12:12.123456-05:00','2006-10-19T17:23:54.123456Z','2006-01-01T17:23:54.123456')", + streamTwoFullyQualifiedName)); + ctx.createStatement().execute( + String.format("INSERT INTO %s(id, name, updated_at, wakeup_at, last_visited_at, last_comment_at)" + + "VALUES (42, 'Thanos','2006-10-19','12:12:12.123456-05:00','2006-10-19T17:23:54.123456Z','2006-01-01T17:23:54.123456')", + streamTwoFullyQualifiedName)); + }); + // Create records list that we expect to see in the state message + final List streamTwoExpectedRecords = Arrays.asList( + createRecord(streamTwoName, namespace, map( + COL_ID, 40, + COL_NAME, "Jean Luc", + COL_UPDATED_AT, "2006-10-19", + COL_WAKEUP_AT, "12:12:12.123456-05:00", + COL_LAST_VISITED_AT, "2006-10-19T17:23:54.123456Z", + COL_LAST_COMMENT_AT, "2006-01-01T17:23:54.123456")), + createRecord(streamTwoName, namespace, map( + COL_ID, 41, + COL_NAME, "Groot", + COL_UPDATED_AT, "2006-10-19", + COL_WAKEUP_AT, "12:12:12.123456-05:00", + COL_LAST_VISITED_AT, "2006-10-19T17:23:54.123456Z", + COL_LAST_COMMENT_AT, "2006-01-01T17:23:54.123456")), + createRecord(streamTwoName, namespace, map( + COL_ID, 42, + COL_NAME, "Thanos", + COL_UPDATED_AT, "2006-10-19", + COL_WAKEUP_AT, "12:12:12.123456-05:00", + COL_LAST_VISITED_AT, "2006-10-19T17:23:54.123456Z", + COL_LAST_COMMENT_AT, "2006-01-01T17:23:54.123456"))); + + // Prep and create a configured catalog to perform sync + final AirbyteStream streamOne = getAirbyteStream(streamOneName, namespace); + final AirbyteStream streamTwo = getAirbyteStream(streamTwoName, namespace); + + final ConfiguredAirbyteCatalog configuredCatalog = CatalogHelpers.toDefaultConfiguredCatalog( + new AirbyteCatalog().withStreams(List.of(streamOne, streamTwo))); + configuredCatalog.getStreams().forEach(airbyteStream -> { + airbyteStream.setSyncMode(SyncMode.INCREMENTAL); + airbyteStream.setCursorField(List.of(COL_ID)); + airbyteStream.setDestinationSyncMode(DestinationSyncMode.APPEND); + airbyteStream.withPrimaryKey(List.of(List.of(COL_ID))); + }); + + // Perform initial sync + final List messagesFromFirstSync = MoreIterators + .toList(source.read(config, configuredCatalog, null)); + + final List recordsFromFirstSync = filterRecords(messagesFromFirstSync); + + setEmittedAtToNull(messagesFromFirstSync); + // All records in the 2 configured streams should be present + assertThat(filterRecords(recordsFromFirstSync)).containsExactlyElementsOf( + Stream.concat(getTestMessages(streamOneName).stream().parallel(), + streamTwoExpectedRecords.stream().parallel()).collect(toList())); + + final List actualFirstSyncState = extractStateMessage(messagesFromFirstSync); + // Since we are emitting a state message after each record, we should have 1 state for each record - + // 3 from stream1 and 3 from stream2 + assertEquals(6, actualFirstSyncState.size()); + + // The expected state type should be 2 ctid's and the last one being standard + final List expectedStateTypesFromFirstSync = List.of("ctid", "ctid", "cursorBased"); + final List stateTypeOfStreamOneStatesFromFirstSync = + extractSpecificFieldFromCombinedMessages(messagesFromFirstSync, streamOneName, "state_type"); + final List stateTypeOfStreamTwoStatesFromFirstSync = + extractSpecificFieldFromCombinedMessages(messagesFromFirstSync, streamTwoName, "state_type"); + // It should be the same for stream1 and stream2 + assertEquals(stateTypeOfStreamOneStatesFromFirstSync, expectedStateTypesFromFirstSync); + assertEquals(stateTypeOfStreamTwoStatesFromFirstSync, expectedStateTypesFromFirstSync); + + // Create the expected ctids that we should see + final List expectedCtidsFromFirstSync = List.of("(0,1)", "(0,2)"); + final List ctidFromStreamOneStatesFromFirstSync = + extractSpecificFieldFromCombinedMessages(messagesFromFirstSync, streamOneName, "ctid"); + final List ctidFromStreamTwoStatesFromFirstSync = + extractSpecificFieldFromCombinedMessages(messagesFromFirstSync, streamOneName, "ctid"); + + // Verifying each element and its index to match. + // Only checking the first 2 elements since we have verified that the last state_type is + // "cursorBased" + assertEquals(ctidFromStreamOneStatesFromFirstSync.get(0), expectedCtidsFromFirstSync.get(0)); + assertEquals(ctidFromStreamOneStatesFromFirstSync.get(1), expectedCtidsFromFirstSync.get(1)); + assertEquals(ctidFromStreamTwoStatesFromFirstSync.get(0), expectedCtidsFromFirstSync.get(0)); + assertEquals(ctidFromStreamTwoStatesFromFirstSync.get(1), expectedCtidsFromFirstSync.get(1)); + + // Extract only state messages for each stream + final List streamOneStateMessagesFromFirstSync = extractStateMessage(messagesFromFirstSync, streamOneName); + final List streamTwoStateMessagesFromFirstSync = extractStateMessage(messagesFromFirstSync, streamTwoName); + // Extract the incremental states of each stream's first and second state message + final List streamOneIncrementalStatesFromFirstSync = + List.of(streamOneStateMessagesFromFirstSync.get(0).getStream().getStreamState().get("incremental_state"), + streamOneStateMessagesFromFirstSync.get(1).getStream().getStreamState().get("incremental_state")); + final JsonNode streamOneFinalStreamStateFromFirstSync = streamOneStateMessagesFromFirstSync.get(2).getStream().getStreamState(); + + final List streamTwoIncrementalStatesFromFirstSync = + List.of(streamTwoStateMessagesFromFirstSync.get(0).getStream().getStreamState().get("incremental_state"), + streamTwoStateMessagesFromFirstSync.get(1).getStream().getStreamState().get("incremental_state")); + final JsonNode streamTwoFinalStreamStateFromFirstSync = streamTwoStateMessagesFromFirstSync.get(2).getStream().getStreamState(); + + // The incremental_state of each stream's first and second incremental states is expected + // to be identical to the stream_state of the final state message for each stream + assertEquals(streamOneIncrementalStatesFromFirstSync.get(0), streamOneFinalStreamStateFromFirstSync); + assertEquals(streamOneIncrementalStatesFromFirstSync.get(1), streamOneFinalStreamStateFromFirstSync); + assertEquals(streamTwoIncrementalStatesFromFirstSync.get(0), streamTwoFinalStreamStateFromFirstSync); + assertEquals(streamTwoIncrementalStatesFromFirstSync.get(1), streamTwoFinalStreamStateFromFirstSync); + + // Sync should work with a ctid state AND a cursor-based state from each stream + // Forcing a sync with + // - stream one state still being the first record read via CTID. + // - stream two state being the CTID state before the final emitted state before the cursor switch + final List messagesFromSecondSyncWithMixedStates = MoreIterators + .toList(source.read(config, configuredCatalog, + Jsons.jsonNode(List.of(streamOneStateMessagesFromFirstSync.get(0), + streamTwoStateMessagesFromFirstSync.get(1))))); + + // Extract only state messages for each stream after second sync + final List streamOneStateMessagesFromSecondSync = + extractStateMessage(messagesFromSecondSyncWithMixedStates, streamOneName); + final List stateTypeOfStreamOneStatesFromSecondSync = + extractSpecificFieldFromCombinedMessages(messagesFromSecondSyncWithMixedStates, streamOneName, "state_type"); + + final List streamTwoStateMessagesFromSecondSync = + extractStateMessage(messagesFromSecondSyncWithMixedStates, streamTwoName); + final List stateTypeOfStreamTwoStatesFromSecondSync = + extractSpecificFieldFromCombinedMessages(messagesFromSecondSyncWithMixedStates, streamTwoName, "state_type"); + + // Stream One states after the second sync are expected to have 2 stream states + // - 1 with Ctid state_type and 1 state that is of cursorBased state type + assertEquals(2, streamOneStateMessagesFromSecondSync.size()); + assertEquals(List.of("ctid", "cursorBased"), stateTypeOfStreamOneStatesFromSecondSync); + + // Stream Two states after the second sync are expected to have 1 stream state + // - The state that is of cursorBased state type + assertEquals(1, streamTwoStateMessagesFromSecondSync.size()); + assertEquals(List.of("cursorBased"), stateTypeOfStreamTwoStatesFromSecondSync); + + // Add some data to each table and perform a third read. + // Expect to see all records be synced via cursorBased method and not ctid + + database.execute(ctx -> { + ctx.createStatement().execute( + String.format("INSERT INTO %s(id, name, updated_at, wakeup_at, last_visited_at, last_comment_at)" + + "VALUES (4,'Hooper','2006-10-19','12:12:12.123456-05:00','2006-10-19T17:23:54.123456Z','2006-01-01T17:23:54.123456')", + getFullyQualifiedTableName(streamOneName))); + ctx.createStatement().execute( + String.format("INSERT INTO %s(id, name, updated_at, wakeup_at, last_visited_at, last_comment_at)" + + "VALUES (43, 'Iron Man', '2006-10-19','12:12:12.123456-05:00','2006-10-19T17:23:54.123456Z','2006-01-01T17:23:54.123456')", + streamTwoFullyQualifiedName)); + }); + + final List messagesFromThirdSync = MoreIterators + .toList(source.read(config, configuredCatalog, + Jsons.jsonNode(List.of(streamOneStateMessagesFromSecondSync.get(1), + streamTwoStateMessagesFromSecondSync.get(0))))); + + // Extract only state messages, state type, and cursor for each stream after second sync + final List streamOneStateMessagesFromThirdSync = + extractStateMessage(messagesFromThirdSync, streamOneName); + final List stateTypeOfStreamOneStatesFromThirdSync = + extractSpecificFieldFromCombinedMessages(messagesFromThirdSync, streamOneName, "state_type"); + final List cursorOfStreamOneStatesFromThirdSync = + extractSpecificFieldFromCombinedMessages(messagesFromThirdSync, streamOneName, "cursor"); + + final List streamTwoStateMessagesFromThirdSync = + extractStateMessage(messagesFromThirdSync, streamTwoName); + final List stateTypeOfStreamTwoStatesFromThirdSync = + extractSpecificFieldFromCombinedMessages(messagesFromThirdSync, streamTwoName, "state_type"); + final List cursorOfStreamTwoStatesFromThirdSync = + extractSpecificFieldFromCombinedMessages(messagesFromThirdSync, streamTwoName, "cursor"); + + // Both streams should now be synced via standard cursor and have updated max cursor values + // cursor: 4 for stream one + // cursor: 43 for stream two + assertEquals(1, streamOneStateMessagesFromThirdSync.size()); + assertEquals(List.of("cursorBased"), stateTypeOfStreamOneStatesFromThirdSync); + assertEquals(List.of("4"), cursorOfStreamOneStatesFromThirdSync); + + assertEquals(1, streamTwoStateMessagesFromThirdSync.size()); + assertEquals(List.of("cursorBased"), stateTypeOfStreamTwoStatesFromThirdSync); + assertEquals(List.of("43"), cursorOfStreamTwoStatesFromThirdSync); + } + + @Override + protected DbStreamState buildStreamState(final ConfiguredAirbyteStream configuredAirbyteStream, + final String cursorField, + final String cursorValue) { + return new CursorBasedStatus().withStateType(StateType.CURSOR_BASED).withVersion(2L) + .withStreamName(configuredAirbyteStream.getStream().getName()) + .withStreamNamespace(configuredAirbyteStream.getStream().getNamespace()) + .withCursorField(List.of(cursorField)) + .withCursor(cursorValue) + .withCursorRecordCount(1L); + } + + @Override + protected List getExpectedAirbyteMessagesSecondSync(final String namespace) { + final List expectedMessages = new ArrayList<>(); + expectedMessages.add(new AirbyteMessage().withType(AirbyteMessage.Type.RECORD) + .withRecord(new AirbyteRecordMessage().withStream(streamName).withNamespace(namespace) + .withData(Jsons.jsonNode(ImmutableMap + .of(COL_ID, ID_VALUE_4, + COL_NAME, "riker", + COL_UPDATED_AT, "2006-10-19", + COL_WAKEUP_AT, "12:12:12.123456-05:00", + COL_LAST_VISITED_AT, "2006-10-19T17:23:54.123456Z", + COL_LAST_COMMENT_AT, "2006-01-01T17:23:54.123456"))))); + expectedMessages.add(new AirbyteMessage().withType(AirbyteMessage.Type.RECORD) + .withRecord(new AirbyteRecordMessage().withStream(streamName).withNamespace(namespace) + .withData(Jsons.jsonNode(ImmutableMap + .of(COL_ID, ID_VALUE_5, + COL_NAME, "data", + COL_UPDATED_AT, "2006-10-19", + COL_WAKEUP_AT, "12:12:12.123456-05:00", + COL_LAST_VISITED_AT, "2006-10-19T17:23:54.123456Z", + COL_LAST_COMMENT_AT, "2006-01-01T17:23:54.123456"))))); + final DbStreamState state = new CursorBasedStatus() + .withStateType(StateType.CURSOR_BASED) + .withVersion(2L) + .withStreamName(streamName) + .withStreamNamespace(namespace) + .withCursorField(ImmutableList.of(COL_ID)) + .withCursor("5") + .withCursorRecordCount(1L); + + expectedMessages.addAll(createExpectedTestMessages(List.of(state))); + return expectedMessages; + } + + private AirbyteStream getAirbyteStream(final String tableName, final String namespace) { + return CatalogHelpers.createAirbyteStream( + tableName, + namespace, + Field.of(COL_ID, JsonSchemaType.INTEGER), + Field.of(COL_NAME, JsonSchemaType.STRING), + Field.of(COL_UPDATED_AT, JsonSchemaType.STRING_DATE), + Field.of(COL_WAKEUP_AT, JsonSchemaType.STRING_TIME_WITH_TIMEZONE), + Field.of(COL_LAST_VISITED_AT, JsonSchemaType.STRING_TIMESTAMP_WITH_TIMEZONE), + Field.of(COL_LAST_COMMENT_AT, JsonSchemaType.STRING_TIMESTAMP_WITHOUT_TIMEZONE)) + .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL)) + .withSourceDefinedPrimaryKey(List.of(List.of(COL_ID))); + } + + // + @Override + protected JsonNode getStateData(final AirbyteMessage airbyteMessage, final String streamName) { + final JsonNode streamState = airbyteMessage.getState().getStream().getStreamState(); + if (streamState.get("stream_name").asText().equals(streamName)) { + return streamState; + } + + throw new IllegalArgumentException("Stream not found in state message: " + streamName); + } + +} diff --git a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/PostgresJdbcSourceAcceptanceTest.java b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/PostgresJdbcSourceAcceptanceTest.java index 504c9fcc92ca..04c9046207a2 100644 --- a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/PostgresJdbcSourceAcceptanceTest.java +++ b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/PostgresJdbcSourceAcceptanceTest.java @@ -303,6 +303,10 @@ void testSpec() throws Exception { @Override protected List getTestMessages() { + return getTestMessages(streamName); + } + + protected List getTestMessages(final String streamName) { return Lists.newArrayList( new AirbyteMessage().withType(AirbyteMessage.Type.RECORD) .withRecord(new AirbyteRecordMessage().withStream(streamName).withNamespace(getDefaultNamespace()) diff --git a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/XminPostgresSourceTest.java b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/XminPostgresSourceTest.java index 118656cfe0bb..5e9d1bf27455 100644 --- a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/XminPostgresSourceTest.java +++ b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/XminPostgresSourceTest.java @@ -5,6 +5,8 @@ package io.airbyte.integrations.source.postgres; import static io.airbyte.integrations.source.postgres.utils.PostgresUnitTestsUtil.createRecord; +import static io.airbyte.integrations.source.postgres.utils.PostgresUnitTestsUtil.extractStateMessage; +import static io.airbyte.integrations.source.postgres.utils.PostgresUnitTestsUtil.filterRecords; import static io.airbyte.integrations.source.postgres.utils.PostgresUnitTestsUtil.map; import static io.airbyte.integrations.source.postgres.utils.PostgresUnitTestsUtil.setEmittedAtToNull; import static org.assertj.core.api.Assertions.assertThat; @@ -324,16 +326,6 @@ private static void assertMessageSequence(final List messages) { assertEquals(Type.STATE, messages.get(messages.size() - 1).getType()); } - private static List extractStateMessage(final List messages) { - return messages.stream().filter(r -> r.getType() == Type.STATE).map(AirbyteMessage::getState) - .collect(Collectors.toList()); - } - - private static List filterRecords(final List messages) { - return messages.stream().filter(r -> r.getType() == Type.RECORD) - .collect(Collectors.toList()); - } - private static ConfiguredAirbyteCatalog toConfiguredXminCatalog(final AirbyteCatalog catalog) { return new ConfiguredAirbyteCatalog() .withStreams(catalog.getStreams() diff --git a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/cursor_based/CursorBasedCtidUtilsTest.java b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/cursor_based/CursorBasedCtidUtilsTest.java new file mode 100644 index 000000000000..4979941f8b2e --- /dev/null +++ b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/cursor_based/CursorBasedCtidUtilsTest.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2023 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.source.postgres.cursor_based; + +import static io.airbyte.integrations.source.postgres.cursor_based.CursorBasedCtidUtils.categoriseStreams; +import static io.airbyte.integrations.source.postgres.utils.PostgresUnitTestsUtil.generateStateMessage; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.fasterxml.jackson.databind.JsonNode; +import com.google.common.collect.Lists; +import io.airbyte.commons.json.Jsons; +import io.airbyte.integrations.source.postgres.ctid.CtidUtils.StreamsCategorised; +import io.airbyte.integrations.source.postgres.cursor_based.CursorBasedCtidUtils.CursorBasedStreams; +import io.airbyte.integrations.source.postgres.internal.models.CtidStatus; +import io.airbyte.integrations.source.postgres.internal.models.InternalModels.StateType; +import io.airbyte.integrations.source.postgres.internal.models.CursorBasedStatus; +import io.airbyte.integrations.source.relationaldb.state.StreamStateManager; +import io.airbyte.protocol.models.Field; +import io.airbyte.protocol.models.JsonSchemaType; +import io.airbyte.protocol.models.v0.AirbyteStateMessage; +import io.airbyte.protocol.models.v0.CatalogHelpers; +import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; +import io.airbyte.protocol.models.v0.ConfiguredAirbyteStream; +import io.airbyte.protocol.models.v0.SyncMode; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class CursorBasedCtidUtilsTest { + + @Test + public void emptyStateTest() { + final ConfiguredAirbyteCatalog configuredCatalog = new ConfiguredAirbyteCatalog().withStreams(Arrays.asList(STREAM_1, STREAM_2)); + final StreamStateManager streamStateManager = new StreamStateManager(Collections.emptyList(), configuredCatalog); + final StreamsCategorised streamsCategorised = categoriseStreams(streamStateManager, configuredCatalog); + + assertEquals(2, streamsCategorised.ctidStreams().streamsForCtidSync().size()); + assertEquals(0, streamsCategorised.remainingStreams().streamsForCursorBasedSync().size()); + assertTrue(streamsCategorised.remainingStreams().streamsForCursorBasedSync().isEmpty()); + assertThat(streamsCategorised.ctidStreams().streamsForCtidSync()).containsExactlyInAnyOrder(STREAM_1, STREAM_2); + } + + @Test + public void correctOneCtidOneCursorBasedTest() { + final ConfiguredAirbyteCatalog configuredCatalog = new ConfiguredAirbyteCatalog().withStreams(Arrays.asList(STREAM_1, STREAM_2)); + final JsonNode stream1CtidStatus = Jsons.jsonNode(new CtidStatus() + .withStateType(StateType.CTID) + .withCtid("(0,0)") + .withRelationFilenode(456L)); + + final JsonNode stream2CursorBased = Jsons.jsonNode(new CursorBasedStatus() + .withStateType(StateType.CURSOR_BASED) + .withStreamName(STREAM_2.getStream().getName()) + .withStreamNamespace(STREAM_2.getStream().getNamespace()) + .withCursorField(List.of("COL_ID")) + .withCursor("1") + .withCursorRecordCount(1L)); + + final JsonNode stream2CursorBasedJson = Jsons.jsonNode(stream2CursorBased); + final AirbyteStateMessage stream1CtidState = generateStateMessage(STREAM_1.getStream().getName(), STREAM_1.getStream().getNamespace(), + stream1CtidStatus); + final AirbyteStateMessage stream2StandardState = generateStateMessage(STREAM_2.getStream().getName(), STREAM_2.getStream().getNamespace(), + stream2CursorBasedJson); + final StreamStateManager streamStateManager = new StreamStateManager(List.of(stream1CtidState, stream2StandardState), configuredCatalog); + final StreamsCategorised streamsCategorised = categoriseStreams(streamStateManager, configuredCatalog); + + assertEquals(streamsCategorised.ctidStreams().streamsForCtidSync().size(), 1); + assertEquals(streamsCategorised.remainingStreams().streamsForCursorBasedSync().size(), 1); + assertEquals(streamsCategorised.ctidStreams().streamsForCtidSync().stream().findFirst().get(), STREAM_1); + assertEquals(streamsCategorised.remainingStreams().streamsForCursorBasedSync().stream().findFirst().get(), STREAM_2); + } + + @Test + public void correctEmptyCtidTest() { + final ConfiguredAirbyteCatalog configuredCatalog = new ConfiguredAirbyteCatalog().withStreams(Arrays.asList(STREAM_1, STREAM_2)); + final JsonNode standardStatus = Jsons.jsonNode(new CursorBasedStatus() + .withStateType(StateType.CURSOR_BASED) + .withStreamName(STREAM_2.getStream().getName()) + .withStreamNamespace(STREAM_2.getStream().getNamespace()) + .withCursorField(List.of("COL_ID")) + .withCursor("1") + .withCursorRecordCount(1L)); + + final AirbyteStateMessage stream1CtidState = generateStateMessage(STREAM_1.getStream().getName(), STREAM_1.getStream().getNamespace(), + standardStatus); + final AirbyteStateMessage stream2StandardState = generateStateMessage(STREAM_2.getStream().getName(), STREAM_2.getStream().getNamespace(), + standardStatus); + final StreamStateManager streamStateManager = new StreamStateManager(List.of(stream1CtidState, stream2StandardState), configuredCatalog); + final StreamsCategorised streamsCategorised = categoriseStreams(streamStateManager, configuredCatalog); + + assertEquals(streamsCategorised.ctidStreams().streamsForCtidSync().size(), 0); + assertEquals(streamsCategorised.remainingStreams().streamsForCursorBasedSync().size(), 2); + assertThat(streamsCategorised.remainingStreams().streamsForCursorBasedSync()).containsExactlyInAnyOrder(STREAM_1, STREAM_2); + + } + + private static final ConfiguredAirbyteStream STREAM_1 = CatalogHelpers.toDefaultConfiguredStream(CatalogHelpers.createAirbyteStream( + "STREAM_1", + "SCHEMA", + Field.of("COL_ID", JsonSchemaType.INTEGER), + Field.of("COL_MAKE_ID", JsonSchemaType.INTEGER), + Field.of("COL_MODEL", JsonSchemaType.STRING)) + .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL)) + .withSourceDefinedPrimaryKey(List.of(List.of("COL_ID")))); + + private static final ConfiguredAirbyteStream STREAM_2 = CatalogHelpers.toDefaultConfiguredStream(CatalogHelpers.createAirbyteStream( + "STREAM_2", + "SCHEMA", + Field.of("COL_ID", JsonSchemaType.INTEGER), + Field.of("COL_MAKE_ID", JsonSchemaType.INTEGER), + Field.of("COL_MODEL", JsonSchemaType.STRING)) + .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL)) + .withSourceDefinedPrimaryKey(List.of(List.of("COL_ID")))); + +} diff --git a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/utils/PostgresUnitTestsUtil.java b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/utils/PostgresUnitTestsUtil.java index 88d77cc1bd31..189705298cbd 100644 --- a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/utils/PostgresUnitTestsUtil.java +++ b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/utils/PostgresUnitTestsUtil.java @@ -4,12 +4,19 @@ package io.airbyte.integrations.source.postgres.utils; +import com.fasterxml.jackson.databind.JsonNode; import io.airbyte.commons.json.Jsons; import io.airbyte.protocol.models.v0.AirbyteMessage; import io.airbyte.protocol.models.v0.AirbyteMessage.Type; import io.airbyte.protocol.models.v0.AirbyteRecordMessage; +import io.airbyte.protocol.models.v0.AirbyteStateMessage; +import io.airbyte.protocol.models.v0.AirbyteStateMessage.AirbyteStateType; +import io.airbyte.protocol.models.v0.AirbyteStreamState; +import io.airbyte.protocol.models.v0.StreamDescriptor; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.stream.Collectors; public class PostgresUnitTestsUtil { @@ -47,4 +54,38 @@ public static Map map(final Object... entries) { }; } + public static AirbyteStateMessage generateStateMessage(final String streamName, final String namespace, final JsonNode stateData) { + return new AirbyteStateMessage() + .withType(AirbyteStateType.STREAM) + .withStream(new AirbyteStreamState() + .withStreamDescriptor(new StreamDescriptor() + .withName(streamName) + .withNamespace(namespace)) + .withStreamState(stateData)); + } + + public static List extractStateMessage(final List messages) { + return messages.stream().filter(r -> r.getType() == Type.STATE).map(AirbyteMessage::getState) + .collect(Collectors.toList()); + } + + public static List extractStateMessage(final List messages, final String streamName) { + return messages.stream().filter(r -> r.getType() == Type.STATE && + r.getState().getStream().getStreamDescriptor().getName().equals(streamName)).map(AirbyteMessage::getState) + .collect(Collectors.toList()); + } + + public static List filterRecords(final List messages) { + return messages.stream().filter(r -> r.getType() == Type.RECORD) + .collect(Collectors.toList()); + } + + public static List extractSpecificFieldFromCombinedMessages(final List messages, + final String streamName, + final String field) { + return extractStateMessage(messages).stream() + .filter(s -> s.getStream().getStreamDescriptor().getName().equals(streamName)) + .map(s -> s.getStream().getStreamState().get(field) != null ? s.getStream().getStreamState().get(field).asText() : "").toList(); + } + } diff --git a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/xmin/XminCtidUtilsTest.java b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/xmin/XminCtidUtilsTest.java index 2cefbb4e047b..f4f7297371dd 100644 --- a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/xmin/XminCtidUtilsTest.java +++ b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/xmin/XminCtidUtilsTest.java @@ -11,10 +11,11 @@ import com.fasterxml.jackson.databind.JsonNode; import com.google.common.collect.Lists; import io.airbyte.commons.json.Jsons; +import io.airbyte.integrations.source.postgres.ctid.CtidUtils.StreamsCategorised; import io.airbyte.integrations.source.postgres.internal.models.CtidStatus; import io.airbyte.integrations.source.postgres.internal.models.InternalModels.StateType; import io.airbyte.integrations.source.postgres.internal.models.XminStatus; -import io.airbyte.integrations.source.postgres.xmin.XminCtidUtils.StreamsCategorised; +import io.airbyte.integrations.source.postgres.xmin.XminCtidUtils.XminStreams; import io.airbyte.integrations.source.relationaldb.state.StreamStateManager; import io.airbyte.protocol.models.Field; import io.airbyte.protocol.models.JsonSchemaType; @@ -59,10 +60,10 @@ public void emptyStateTest() { final XminStatus xminStatus = new XminStatus().withStateType(StateType.XMIN).withVersion(2L).withXminXidValue(9L).withXminRawValue(9L) .withNumWraparound(1L); final StreamStateManager streamStateManager = new StreamStateManager(Collections.emptyList(), configuredCatalog); - final StreamsCategorised streamsCategorised = XminCtidUtils.categoriseStreams(streamStateManager, configuredCatalog, xminStatus); + final StreamsCategorised streamsCategorised = XminCtidUtils.categoriseStreams(streamStateManager, configuredCatalog, xminStatus); - assertTrue(streamsCategorised.xminStreams().streamsForXminSync().isEmpty()); - assertTrue(streamsCategorised.xminStreams().statesFromXminSync().isEmpty()); + assertTrue(streamsCategorised.remainingStreams().streamsForXminSync().isEmpty()); + assertTrue(streamsCategorised.remainingStreams().statesFromXminSync().isEmpty()); assertEquals(2, streamsCategorised.ctidStreams().streamsForCtidSync().size()); assertThat(streamsCategorised.ctidStreams().streamsForCtidSync()).containsExactlyInAnyOrder(MODELS_STREAM, MODELS_STREAM_2); @@ -85,12 +86,12 @@ public void correctCategorisationTest() { new StreamDescriptor().withName(MODELS_STREAM_2.getStream().getName()).withNamespace(MODELS_STREAM_2.getStream().getNamespace())); final StreamStateManager streamStateManager = new StreamStateManager(Arrays.asList(xminState, ctidState), configuredCatalog); - final StreamsCategorised streamsCategorised = XminCtidUtils.categoriseStreams(streamStateManager, configuredCatalog, xminStatus); + final StreamsCategorised streamsCategorised = XminCtidUtils.categoriseStreams(streamStateManager, configuredCatalog, xminStatus); - assertEquals(1, streamsCategorised.xminStreams().streamsForXminSync().size()); - assertEquals(MODELS_STREAM, streamsCategorised.xminStreams().streamsForXminSync().get(0)); - assertEquals(1, streamsCategorised.xminStreams().statesFromXminSync().size()); - assertEquals(xminState, streamsCategorised.xminStreams().statesFromXminSync().get(0)); + assertEquals(1, streamsCategorised.remainingStreams().streamsForXminSync().size()); + assertEquals(MODELS_STREAM, streamsCategorised.remainingStreams().streamsForXminSync().get(0)); + assertEquals(1, streamsCategorised.remainingStreams().statesFromXminSync().size()); + assertEquals(xminState, streamsCategorised.remainingStreams().statesFromXminSync().get(0)); assertEquals(1, streamsCategorised.ctidStreams().streamsForCtidSync().size()); assertEquals(MODELS_STREAM_2, streamsCategorised.ctidStreams().streamsForCtidSync().get(0)); From 3fb737c257f73ceb5b9c2e5bdf16edd0c7388db0 Mon Sep 17 00:00:00 2001 From: Artem Inzhyyants <36314070+artem1205@users.noreply.github.com> Date: Wed, 12 Jul 2023 10:29:37 +0200 Subject: [PATCH 32/63] =?UTF-8?q?=F0=9F=90=9B=20Source=20Zendesk=20Support?= =?UTF-8?q?:=20use=20cursor=20pagination=20only=20(#28096)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Source Zendesk Support: use cursor pagination only * Source Zendesk Support: fix logger * Source Zendesk Support: bump version + docs update * Source Zendesk Support: Fix unit tests * Source Zendesk Support: Fix request params * Source Zendesk Support: Fix unit tests * Source Zendesk Support: update expected_records --- .../source-zendesk-support/Dockerfile | 2 +- .../integration_tests/expected_records.jsonl | 4 +- .../source-zendesk-support/metadata.yaml | 2 +- .../source_zendesk_support/source.py | 2 +- .../source_zendesk_support/streams.py | 187 ++++++++++-------- .../unit_tests/unit_test.py | 73 ++----- docs/integrations/sources/zendesk-support.md | 4 + 7 files changed, 133 insertions(+), 141 deletions(-) diff --git a/airbyte-integrations/connectors/source-zendesk-support/Dockerfile b/airbyte-integrations/connectors/source-zendesk-support/Dockerfile index 90efd6998f02..430b028ea67d 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/Dockerfile +++ b/airbyte-integrations/connectors/source-zendesk-support/Dockerfile @@ -25,5 +25,5 @@ COPY source_zendesk_support ./source_zendesk_support ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=0.10.0 +LABEL io.airbyte.version=0.10.1 LABEL io.airbyte.name=airbyte/source-zendesk-support diff --git a/airbyte-integrations/connectors/source-zendesk-support/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-zendesk-support/integration_tests/expected_records.jsonl index 87919d44a960..f24978473c2a 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-zendesk-support/integration_tests/expected_records.jsonl @@ -6,8 +6,8 @@ {"stream":"groups","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/groups/5060105343503.json","id":5060105343503,"is_public":true,"name":"Group 100","description":"","default":false,"deleted":false,"created_at":"2022-06-29T16:22:26Z","updated_at":"2022-06-29T16:22:26Z"},"emitted_at":1687861660537} {"stream":"macros","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/macros/360011363556.json","id":360011363556,"title":"Customer not responding","active":true,"updated_at":"2020-12-11T18:34:06Z","created_at":"2020-12-11T18:34:06Z","default":false,"position":9999,"description":null,"actions":[{"field":"status","value":"pending"},{"field":"comment_value","value":"Hello {{ticket.requester.name}}. Our agent {{current_user.name}} has tried to contact you about this request but we haven't heard back from you yet. Please let us know if we can be of further assistance. Thanks. "}],"restriction":null,"raw_title":"Customer not responding"},"emitted_at":1687861662012} {"stream":"macros","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/macros/360011363536.json","id":360011363536,"title":"Downgrade and inform","active":true,"updated_at":"2020-12-11T18:34:06Z","created_at":"2020-12-11T18:34:06Z","default":false,"position":9999,"description":null,"actions":[{"field":"priority","value":"low"},{"field":"comment_value","value":"We're currently experiencing unusually high traffic. We'll get back to you as soon as possible."}],"restriction":null,"raw_title":"Downgrade and inform"},"emitted_at":1687861662013} -{"stream":"organizations","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/organizations/360033549136.json","id":360033549136,"name":"Airbyte","shared_tickets":true,"shared_comments":true,"external_id":null,"created_at":"2020-12-11T18:34:05Z","updated_at":"2023-04-13T14:51:21Z","domain_names":["cloud.airbyte.com"],"details":"test","notes":"test","group_id":6770788212111,"tags":["test"],"organization_fields":{}},"emitted_at":1687861664327} -{"stream":"organizations","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/organizations/360045373216.json","id":360045373216,"name":"ressssssss","shared_tickets":false,"shared_comments":false,"external_id":null,"created_at":"2021-07-15T18:29:14Z","updated_at":"2021-07-15T18:29:14Z","domain_names":[],"details":"","notes":"","group_id":null,"tags":[],"organization_fields":{}},"emitted_at":1687861664327} +{"stream":"organizations","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/organizations/360033549136.json","id":360033549136,"name":"Airbyte","shared_tickets":true,"shared_comments":true,"external_id":null,"created_at":"2020-12-11T18:34:05Z","updated_at":"2023-04-13T14:51:21Z","domain_names":["cloud.airbyte.com"],"details":"test","notes":"test","group_id":6770788212111,"tags":["test"],"organization_fields":{"test_check_box_field_1":false,"test_drop_down_field_1":null,"test_number_field_1":null}},"emitted_at":1689066709950} +{"stream":"organizations","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/organizations/360045373216.json","id":360045373216,"name":"ressssssss","shared_tickets":false,"shared_comments":false,"external_id":null,"created_at":"2021-07-15T18:29:14Z","updated_at":"2021-07-15T18:29:14Z","domain_names":[],"details":"","notes":"","group_id":null,"tags":[],"organization_fields":{"test_check_box_field_1":false,"test_drop_down_field_1":null,"test_number_field_1":null}},"emitted_at":1689066709951} {"stream":"satisfaction_ratings","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/satisfaction_ratings/4992997209743.json","id":4992997209743,"assignee_id":null,"group_id":null,"requester_id":4992781783439,"ticket_id":121,"score":"offered","created_at":"2022-06-17T16:01:42Z","updated_at":"2022-06-17T16:01:42Z","comment":null},"emitted_at":1687861665961} {"stream":"satisfaction_ratings","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/satisfaction_ratings/4993646311567.json","id":4993646311567,"assignee_id":null,"group_id":null,"requester_id":4993467856015,"ticket_id":122,"score":"offered","created_at":"2022-06-17T21:01:41Z","updated_at":"2022-06-17T21:01:41Z","comment":null},"emitted_at":1687861665962} {"stream":"satisfaction_ratings","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/satisfaction_ratings/5138125924367.json","id":5138125924367,"assignee_id":null,"group_id":null,"requester_id":5137812260495,"ticket_id":123,"score":"offered","created_at":"2022-07-13T16:02:03Z","updated_at":"2022-07-13T16:02:03Z","comment":null},"emitted_at":1687861665962} diff --git a/airbyte-integrations/connectors/source-zendesk-support/metadata.yaml b/airbyte-integrations/connectors/source-zendesk-support/metadata.yaml index 0759f7c60675..9bf8142bbb40 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/metadata.yaml +++ b/airbyte-integrations/connectors/source-zendesk-support/metadata.yaml @@ -7,7 +7,7 @@ data: connectorType: source maxSecondsBetweenMessages: 10800 definitionId: 79c1aa37-dae3-42ae-b333-d1c105477715 - dockerImageTag: 0.10.0 + dockerImageTag: 0.10.1 dockerRepository: airbyte/source-zendesk-support githubIssueLabel: source-zendesk-support icon: zendesk-support.svg diff --git a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/source.py b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/source.py index 58d067b148ad..da0ac3fc3701 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/source.py +++ b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/source.py @@ -63,7 +63,7 @@ class SourceZendeskSupport(AbstractSource): """ @classmethod - def get_authenticator(cls, config: Mapping[str, Any]) -> BasicApiTokenAuthenticator: + def get_authenticator(cls, config: Mapping[str, Any]) -> [TokenAuthenticator, BasicApiTokenAuthenticator]: # old authentication flow support auth_old = config.get("auth_method") diff --git a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/streams.py b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/streams.py index dcab6bcb25b4..6f8a0f8e722d 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/streams.py +++ b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/streams.py @@ -15,7 +15,7 @@ from math import ceil from pickle import PickleError, dumps from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Union -from urllib.parse import parse_qsl, urljoin, urlparse +from urllib.parse import urljoin import pendulum import pytz @@ -103,7 +103,7 @@ def send_future(self, request: requests.PreparedRequest, **kwargs) -> Future: func = sleep_before_executing(sleep_time)(func) if isinstance(self.executor, ProcessPoolExecutor): - self.logger.warning("ProcessPoolExecutor is used to perform IO related tasks for unknown reason!") + logger.warning("ProcessPoolExecutor is used to perform IO related tasks for unknown reason!") # verify function can be pickled try: dumps(func) @@ -172,16 +172,6 @@ def str2unixtime(str_dt: str) -> Optional[int]: dt = datetime.strptime(str_dt, DATETIME_FORMAT) return calendar.timegm(dt.utctimetuple()) - @staticmethod - def _parse_next_page_number(response: requests.Response) -> Optional[int]: - """Parses a response and tries to find next page number""" - try: - next_page = response.json().get("next_page") - except requests.exceptions.JSONDecodeError: - next_page = None - - return dict(parse_qsl(urlparse(next_page).query)).get("page") if next_page else None - def parse_response(self, response: requests.Response, stream_state: Mapping[str, Any], **kwargs) -> Iterable[Mapping]: """try to select relevant data only""" @@ -313,7 +303,10 @@ def _send_request(self, request: requests.PreparedRequest, request_kwargs: Mappi return self._send(request, request_kwargs) def request_params( - self, stream_state: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None, **kwargs + self, + stream_state: Mapping[str, Any], + stream_slice: Mapping[str, Any] = None, + next_page_token: Mapping[str, Any] = None, ) -> MutableMapping[str, Any]: params = {} stream_state = stream_state or {} @@ -410,20 +403,20 @@ def path(self, **kwargs): def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: if self._ignore_pagination: return None - next_page = self._parse_next_page_number(response) - if not next_page: - self._finished = True - return None - return next_page - def request_params(self, next_page_token: Mapping[str, Any] = None, **kwargs) -> MutableMapping[str, Any]: - params = super().request_params(next_page_token=next_page_token, **kwargs) - params.update( - { - "page": next_page_token or 1, - "per_page": self.page_size, - } - ) + meta = response.json().get("meta", {}) + return {"page[after]": meta.get("after_cursor")} if meta.get("has_more") else None + + def request_params( + self, + stream_state: Mapping[str, Any], + stream_slice: Mapping[str, Any] = None, + next_page_token: Mapping[str, Any] = None, + ) -> MutableMapping[str, Any]: + params = super().request_params(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token) + params.update({"page[size]": self.page_size}) + if next_page_token: + params.update(next_page_token) return params @@ -442,14 +435,6 @@ def get_updated_state(self, current_stream_state: MutableMapping[str, Any], late new_value = str((latest_record or {}).get(self.cursor_field, "")) return {self.cursor_field: max(new_value, old_value)} - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - if self._ignore_pagination: - return None - start_time = dict(parse_qsl(urlparse(response.json().get(self.next_page_field), "").query)).get("start_time") - if start_time != self.prev_start_time: - self.prev_start_time = start_time - return {self.cursor_field: int(start_time)} - def check_stream_state(self, stream_state: Mapping[str, Any] = None): """ Returns the state value, if exists. Otherwise, returns user defined `Start Date`. @@ -458,7 +443,10 @@ def check_stream_state(self, stream_state: Mapping[str, Any] = None): return calendar.timegm(pendulum.parse(state).utctimetuple()) def request_params( - self, stream_state: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None, **kwargs + self, + stream_state: Mapping[str, Any], + stream_slice: Mapping[str, Any] = None, + next_page_token: Mapping[str, Any] = None, ) -> MutableMapping[str, Any]: next_page_token = next_page_token or {} parsed_state = self.check_stream_state(stream_state) @@ -503,9 +491,12 @@ def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, return None if response.json().get(END_OF_STREAM_KEY, False) else next_page_token def request_params( - self, stream_state: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None, **kwargs + self, + stream_state: Mapping[str, Any], + stream_slice: Mapping[str, Any] = None, + next_page_token: Mapping[str, Any] = None, ) -> MutableMapping[str, Any]: - params = super().request_params(stream_state, next_page_token, **kwargs) + params = super().request_params(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token) # check "start_time" is not in the future params["start_time"] = self.check_start_time_param(params["start_time"]) if self.sideload_param: @@ -551,12 +542,11 @@ def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapp class OrganizationMemberships(SourceZendeskSupportCursorPaginationStream): """OrganizationMemberships stream: https://developer.zendesk.com/api-reference/ticketing/organizations/organization_memberships/""" - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - meta = response.json().get("meta", {}) - return meta.get("after_cursor") if meta.get("has_more", False) else None - def request_params( - self, stream_state: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None, **kwargs + self, + stream_state: Mapping[str, Any], + stream_slice: Mapping[str, Any] = None, + next_page_token: Mapping[str, Any] = None, ) -> MutableMapping[str, Any]: params = { "start_time": self.check_stream_state(stream_state), @@ -564,7 +554,7 @@ def request_params( } if next_page_token: params.pop("start_time", None) - params["page[after]"] = next_page_token + params.update(next_page_token) return params @@ -637,20 +627,19 @@ class Groups(SourceZendeskSupportStream): class GroupMemberships(SourceZendeskSupportCursorPaginationStream): """GroupMemberships stream: https://developer.zendesk.com/api-reference/ticketing/groups/group_memberships/""" - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - if self._ignore_pagination: - return None - next_page = self._parse_next_page_number(response) - return next_page if next_page else None - def request_params( - self, stream_state: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None, **kwargs + self, + stream_state: Mapping[str, Any], + stream_slice: Mapping[str, Any] = None, + next_page_token: Mapping[str, Any] = None, ) -> MutableMapping[str, Any]: - params = {"page": 1, "per_page": self.page_size, "sort_by": "asc"} + params = super().request_params(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token) + params.update({"sort_by": "asc"}) start_time = self.str2unixtime((stream_state or {}).get(self.cursor_field)) params["start_time"] = start_time if start_time else self.str2unixtime(self._start_date) if next_page_token: - params["page"] = next_page_token + params.pop("start_time", None) + params.update(next_page_token) return params @@ -659,16 +648,14 @@ class SatisfactionRatings(SourceZendeskSupportCursorPaginationStream): SatisfactionRatings stream: https://developer.zendesk.com/api-reference/ticketing/ticket-management/satisfaction_ratings/ """ - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - if self._ignore_pagination: - return None - next_page = self._parse_next_page_number(response) - return next_page if next_page else None - def request_params( - self, stream_state: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None, **kwargs + self, + stream_state: Mapping[str, Any], + stream_slice: Mapping[str, Any] = None, + next_page_token: Mapping[str, Any] = None, ) -> MutableMapping[str, Any]: - params = {"page": 1, "per_page": self.page_size, "sort_by": "asc"} + params = super().request_params(stream_state=stream_state, stream_slice=stream_slice, next_page_token=next_page_token) + params.update({"sort_by": "asc"}) start_time = self.str2unixtime((stream_state or {}).get(self.cursor_field)) params["start_time"] = start_time if start_time else self.str2unixtime(self._start_date) if next_page_token: @@ -687,15 +674,11 @@ class TicketForms(SourceZendeskSupportCursorPaginationStream): class TicketMetrics(SourceZendeskSupportCursorPaginationStream): """TicketMetric stream: https://developer.zendesk.com/api-reference/ticketing/tickets/ticket_metrics/""" - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - """ - https://developer.zendesk.com/documentation/api-basics/pagination/paginating-through-lists-using-cursor-pagination/#when-to-stop-paginating - """ - meta = response.json().get("meta", {}) - return meta.get("after_cursor") if meta.get("has_more", False) else None - def request_params( - self, stream_state: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None, **kwargs + self, + stream_state: Mapping[str, Any], + stream_slice: Mapping[str, Any] = None, + next_page_token: Mapping[str, Any] = None, ) -> MutableMapping[str, Any]: """ To make the Cursor Pagination to return `after_cursor` we should follow these instructions: @@ -709,7 +692,7 @@ def request_params( # when cursor pagination is used, we can pass only `after` and `page size` params, # other params should be omitted. params.pop("start_time", None) - params["page[after]"] = next_page_token + params.update(next_page_token) return params @@ -721,12 +704,11 @@ class TicketSkips(SourceZendeskSupportCursorPaginationStream): def path(self, **kwargs): return "skips.json" - def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: - meta = response.json().get("meta", {}) - return meta.get("after_cursor") if meta.get("has_more", False) else None - def request_params( - self, stream_state: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None, **kwargs + self, + stream_state: Mapping[str, Any], + stream_slice: Mapping[str, Any] = None, + next_page_token: Mapping[str, Any] = None, ) -> MutableMapping[str, Any]: params = { "start_time": self.check_stream_state(stream_state), @@ -734,7 +716,7 @@ def request_params( } if next_page_token: params.pop("start_time", None) - params["page[after]"] = next_page_token + params.update(next_page_token) return params @@ -767,17 +749,23 @@ class TicketAudits(SourceZendeskSupportCursorPaginationStream): transformer = TypeTransformer(TransformConfig.DefaultSchemaNormalization) # This endpoint uses a variant of cursor pagination with some differences from cursor pagination used in other endpoints. - def request_params(self, next_page_token: Mapping[str, Any] = None, **kwargs) -> MutableMapping[str, Any]: + def request_params( + self, + stream_state: Mapping[str, Any], + stream_slice: Mapping[str, Any] = None, + next_page_token: Mapping[str, Any] = None, + ) -> MutableMapping[str, Any]: params = {"sort_by": self.cursor_field, "sort_order": "desc", "limit": self.page_size} - if next_page_token: - params["cursor"] = next_page_token + params.pop("start_time", None) + params.update(next_page_token) return params def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: if self._ignore_pagination: return None - return response.json().get("before_cursor") + response_json = response.json() + return {"cursor": response.json().get("before_cursor")} if response_json.get("before_cursor") else None class Tags(SourceZendeskSupportFullRefreshStream): @@ -793,6 +781,14 @@ class SlaPolicies(SourceZendeskSupportFullRefreshStream): def path(self, *args, **kwargs) -> str: return "slas/policies.json" + def request_params( + self, + stream_state: Mapping[str, Any], + stream_slice: Mapping[str, Any] = None, + next_page_token: Mapping[str, Any] = None, + ) -> MutableMapping[str, Any]: + return {} + class Brands(SourceZendeskSupportFullRefreshStream): """Brands stream: https://developer.zendesk.com/api-reference/ticketing/account-configuration/brands/#list-brands""" @@ -801,6 +797,14 @@ class Brands(SourceZendeskSupportFullRefreshStream): class CustomRoles(SourceZendeskSupportFullRefreshStream): """CustomRoles stream: https://developer.zendesk.com/api-reference/ticketing/account-configuration/custom_roles/#list-custom-roles""" + def request_params( + self, + stream_state: Mapping[str, Any], + stream_slice: Mapping[str, Any] = None, + next_page_token: Mapping[str, Any] = None, + ) -> MutableMapping[str, Any]: + return {} + class Schedules(SourceZendeskSupportFullRefreshStream): """Schedules stream: https://developer.zendesk.com/api-reference/ticketing/ticket-management/schedules/#list-schedules""" @@ -817,6 +821,14 @@ class AccountAttributes(SourceZendeskSupportFullRefreshStream): def path(self, *args, **kwargs) -> str: return "routing/attributes" + def request_params( + self, + stream_state: Mapping[str, Any], + stream_slice: Mapping[str, Any] = None, + next_page_token: Mapping[str, Any] = None, + ) -> MutableMapping[str, Any]: + return {} + class AttributeDefinitions(SourceZendeskSupportFullRefreshStream): """Attribute definitions stream: https://developer.zendesk.com/api-reference/ticketing/ticket-management/skill_based_routing/#list-routing-attribute-definitions""" @@ -834,6 +846,14 @@ def parse_response(self, response: requests.Response, stream_state: Mapping[str, def path(self, *args, **kwargs) -> str: return "routing/attributes/definitions" + def request_params( + self, + stream_state: Mapping[str, Any], + stream_slice: Mapping[str, Any] = None, + next_page_token: Mapping[str, Any] = None, + ) -> MutableMapping[str, Any]: + return {} + class UserSettingsStream(SourceZendeskSupportFullRefreshStream): """Stream for checking of a request token and permissions""" @@ -856,6 +876,14 @@ def get_settings(self) -> Mapping[str, Any]: return resp raise SourceZendeskException("not found settings") + def request_params( + self, + stream_state: Mapping[str, Any], + stream_slice: Mapping[str, Any] = None, + next_page_token: Mapping[str, Any] = None, + ) -> MutableMapping[str, Any]: + return {} + class PostComments(SourceZendeskSupportFullRefreshStream, HttpSubStream): response_list_name = "comments" @@ -876,7 +904,6 @@ def path( class AbstractVotes(SourceZendeskSupportFullRefreshStream, ABC): - response_list_name = "votes" def get_json_schema(self) -> Mapping[str, Any]: diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/unit_test.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/unit_test.py index b2cac08cee49..ef0d6a2f9d08 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/unit_test.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/unit_test.py @@ -193,33 +193,6 @@ def test_check_start_time_param(): assert output == expected -def test_parse_next_page_number(requests_mock): - expected = dict(parse_qsl(urlparse(TICKET_EVENTS_STREAM_RESPONSE.get("next_page")).query)).get("page") - requests_mock.get(STREAM_URL, json=TICKET_EVENTS_STREAM_RESPONSE) - test_response = requests.get(STREAM_URL) - output = BaseSourceZendeskSupportStream._parse_next_page_number(test_response) - assert output == expected - - -def test_parse_next_page_number_from_empty_json(requests_mock): - requests_mock.get(STREAM_URL, text="", status_code=403) - test_response = requests.get(STREAM_URL) - output = BaseSourceZendeskSupportStream._parse_next_page_number(test_response) - assert output is None - - -def test_next_page_token(requests_mock): - # mocking the logic of next_page_token - if TICKET_EVENTS_STREAM_RESPONSE.get(END_OF_STREAM_KEY) is False: - expected = {"created_at": 1122334455} - else: - expected = None - requests_mock.get(STREAM_URL, json=TICKET_EVENTS_STREAM_RESPONSE) - test_response = requests.get(STREAM_URL) - output = TicketComments(**STREAM_ARGS).next_page_token(test_response) - assert expected == output - - @pytest.mark.parametrize( "stream_state, expected", [ @@ -237,17 +210,6 @@ def test_check_stream_state(stream_state, expected): assert result == expected -def test_request_params(requests_mock): - expected = {"start_time": calendar.timegm(pendulum.parse(STREAM_ARGS.get("start_date")).utctimetuple()), "include": "comment_events"} - stream_state = None - requests_mock.get(STREAM_URL, json=TICKET_EVENTS_STREAM_RESPONSE) - test_response = requests.get(STREAM_URL) - next_page_token = TicketComments(**STREAM_ARGS).next_page_token(test_response) - output = TicketComments(**STREAM_ARGS).request_params(stream_state, None) - assert next_page_token is not None - assert expected == output - - def test_parse_response_from_empty_json(requests_mock): requests_mock.get(STREAM_URL, text="", status_code=403) test_response = requests.get(STREAM_URL) @@ -530,7 +492,7 @@ def test_next_page_token(self, stream_cls, expected, mocker): ) def test_request_params(self, stream_cls, expected): stream = stream_cls(**STREAM_ARGS) - result = stream.request_params() + result = stream.request_params(stream_state={}) assert expected == result @@ -595,16 +557,16 @@ def test_next_page_token(self, requests_mock, stream_cls): assert output is None @pytest.mark.parametrize( - "stream_cls", + "stream_cls, expected_params", [ - (Tags), - (SlaPolicies), - (Brands), - (CustomRoles), - (Schedules), - (UserSettingsStream), - (AccountAttributes), - (AttributeDefinitions), + (Tags, {"page[size]": 100}), + (SlaPolicies, {}), + (Brands, {"page[size]": 100}), + (CustomRoles, {}), + (Schedules, {"page[size]": 100}), + (UserSettingsStream, {}), + (AccountAttributes, {}), + (AttributeDefinitions, {}), ], ids=[ "Tags", @@ -617,11 +579,10 @@ def test_next_page_token(self, requests_mock, stream_cls): "AttributeDefinitions", ], ) - def test_request_params(self, stream_cls): - expected = {"page": 1, "per_page": 100} + def test_request_params(self, stream_cls, expected_params): stream = stream_cls(**STREAM_ARGS) result = stream.request_params(next_page_token=None, stream_state=None) - assert expected == result + assert expected_params == result class TestSourceZendeskSupportCursorPaginationStream: @@ -665,7 +626,7 @@ def test_get_updated_state(self, stream_cls, current_state, last_record, expecte "next": "https://subdomain.zendesk.com/api/v2/ticket_metrics.json?page%5Bafter%5D=%3D&page%5Bsize%5D=2", }, }, - "", + {"page[after]": ""}, ), (SatisfactionRatings, {}, None), ( @@ -677,7 +638,7 @@ def test_get_updated_state(self, stream_cls, current_state, last_record, expecte "next": "https://subdomain.zendesk.com/api/v2/ticket_metrics.json?page%5Bafter%5D=%3D&page%5Bsize%5D=2", }, }, - "", + {"page[after]": ""}, ), ( TicketSkips, @@ -688,7 +649,7 @@ def test_get_updated_state(self, stream_cls, current_state, last_record, expecte "next": "https://subdomain.zendesk.com/api/v2/ticket_metrics.json?page%5Bafter%5D=%3D&page%5Bsize%5D=2", }, }, - "", + {"page[after]": ""}, ), ], @@ -738,11 +699,11 @@ def test_check_stream_state(self, stream_cls, expected): @pytest.mark.parametrize( "stream_cls, expected", [ - (GroupMemberships, {"page": 1, "per_page": 100, "sort_by": "asc", "start_time": 1622505600}), + (GroupMemberships, {"sort_by": "asc", "start_time": 1622505600}), (TicketForms, {"start_time": 1622505600}), (TicketMetricEvents, {"start_time": 1622505600}), (TicketAudits, {"sort_by": "created_at", "sort_order": "desc", "limit": 1000}), - (SatisfactionRatings, {"page": 1, "per_page": 100, "sort_by": "asc", "start_time": 1622505600}), + (SatisfactionRatings, {"sort_by": "asc", "start_time": 1622505600}), (TicketMetrics, {"page[size]": 100, "start_time": 1622505600}), (OrganizationMemberships, {"page[size]": 100, "start_time": 1622505600}), (TicketSkips, {"page[size]": 100, "start_time": 1622505600}), diff --git a/docs/integrations/sources/zendesk-support.md b/docs/integrations/sources/zendesk-support.md index 742eb4c676c6..148cf151f903 100644 --- a/docs/integrations/sources/zendesk-support.md +++ b/docs/integrations/sources/zendesk-support.md @@ -65,6 +65,9 @@ The Zendesk Support source connector supports the following streams: - [Ticket Metric Events](https://developer.zendesk.com/api-reference/ticketing/tickets/ticket_metric_events/) \(Incremental\) - [Ticket Skips](https://developer.zendesk.com/api-reference/ticketing/tickets/ticket_skips/) \(Incremental\) - [Users](https://developer.zendesk.com/api-reference/ticketing/ticket-management/incremental_exports/#incremental-user-export) \(Incremental\) +- [Post Comments](https://developer.zendesk.com/api-reference/help_center/help-center-api/post_comments/) +- [Post Votes](https://developer.zendesk.com/api-reference/help_center/help-center-api/votes/#list-votes) +- [Post Comment Votes](https://developer.zendesk.com/api-reference/help_center/help-center-api/votes/#list-votes) ## Performance considerations @@ -76,6 +79,7 @@ The Zendesk connector ideally should not run into Zendesk API limitations under | Version | Date | Pull Request | Subject | |:---------|:-----------|:---------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `0.10.1` | 2023-07-10 | [28096](https://github.com/airbytehq/airbyte/pull/28096) | Replace `offset` pagination with `cursor` pagination | | `0.10.0` | 2023-07-06 | [27991](https://github.com/airbytehq/airbyte/pull/27991) | add streams: `PostVotes`, `PostCommentVotes` | | `0.9.0` | 2023-07-05 | [27961](https://github.com/airbytehq/airbyte/pull/27961) | Add stream: `Post Comments` | | `0.8.1` | 2023-06-27 | [27765](https://github.com/airbytehq/airbyte/pull/27765) | Bugfix: Nonetype error while syncing more then 100000 organizations | From 17a54030a717673988e8dc27cd952e5424cb82b7 Mon Sep 17 00:00:00 2001 From: Arsen Losenko <20901439+arsenlosenko@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:52:33 +0300 Subject: [PATCH 33/63] Source Trello: update expected records (#28194) --- .../source-trello/integration_tests/expected_records.jsonl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airbyte-integrations/connectors/source-trello/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-trello/integration_tests/expected_records.jsonl index e1ca0cf8c55e..b3ba1afdf48d 100644 --- a/airbyte-integrations/connectors/source-trello/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-trello/integration_tests/expected_records.jsonl @@ -13,4 +13,4 @@ {"stream": "lists", "data": {"id": "611aa0ef37acd675af67dc9e", "name": "Done", "closed": false, "idBoard": "611aa0ef37acd675af67dc9b", "pos": 49152, "subscribed": false, "softLimit": null, "status": null}, "emitted_at": 1683406411203} {"stream": "users", "data": {"id": "610be3762899a26d04256dae", "fullName": "integration test", "username": "integrationtest19"}, "emitted_at": 1683406412874} {"stream": "users", "data": {"id": "610be3762899a26d04256dae", "fullName": "integration test", "username": "integrationtest19"}, "emitted_at": 1683406413051} -{"stream":"organizations","data":{"id":"610be50a0537086c571a5684","creationMethod":null,"name":"airbyteworkspace","credits":[],"displayName":"Airbyte Workspace","desc":"","descData":{"emoji":{}},"domainName":"airbyte.io","idBoards":["611aa0ef37acd675af67dc9b","611aa586ef5f2c8e1deec8b6"],"idEnterprise":null,"idMemberCreator":"610be3762899a26d04256dae","invited":false,"invitations":[],"limits":{"orgs":{"totalMembersPerOrg":{"status":"ok","disableAt":4000,"warnAt":3200},"freeBoardsPerOrg":{"status":"ok","disableAt":10,"warnAt":3}}},"memberships":[{"idMember":"610be3762899a26d04256dae","memberType":"admin","unconfirmed":false,"deactivated":false,"id":"610be50a0537086c571a5685"}],"membersCount":1,"prefs":{"permissionLevel":"private","orgInviteRestrict":[],"boardInviteRestrict":"any","externalMembersDisabled":false,"associatedDomain":null,"googleAppsVersion":1,"boardVisibilityRestrict":{"private":"org","org":"org","enterprise":"org","public":"org"},"boardDeleteRestrict":{"private":"org","org":"org","enterprise":"org","public":"org"},"attachmentRestrictions":null,"newLicenseInviteRestrict":null,"newLicenseInviteRestrictUrl":null},"powerUps":[],"products":[],"billableMemberCount":1,"billableCollaboratorCount":0,"url":"https://trello.com/w/airbyteworkspace","website":null,"logoHash":null,"logoUrl":null,"premiumFeatures":["additionalBoardBackgrounds","additionalStickers","customBoardBackgrounds","customEmoji","customStickers","plugins"],"promotions":[],"enterpriseJoinRequest":{},"standardVariation":null,"availableLicenseCount":null,"maximumLicenseCount":null,"ixUpdate":"6","teamType":null},"emitted_at":1687178472338} +{"stream": "organizations", "data": {"id": "610be50a0537086c571a5684", "creationMethod": null, "name": "airbyteworkspace", "credits": [], "displayName": "Airbyte Workspace", "desc": "", "descData": {"emoji": {}}, "domainName": "airbyte.io", "idBoards": ["611aa0ef37acd675af67dc9b", "611aa586ef5f2c8e1deec8b6"], "idEnterprise": null, "idMemberCreator": "610be3762899a26d04256dae", "invited": false, "invitations": [], "limits": {"orgs": {"totalMembersPerOrg": {"status": "ok", "disableAt": 4000, "warnAt": 3200}, "freeBoardsPerOrg": {"status": "ok", "disableAt": 10, "warnAt": 3}}}, "membersCount": 1, "prefs": {"permissionLevel": "private", "orgInviteRestrict": [], "boardInviteRestrict": "any", "externalMembersDisabled": false, "associatedDomain": null, "googleAppsVersion": 1, "boardVisibilityRestrict": {"private": "org", "org": "org", "enterprise": "org", "public": "org"}, "boardDeleteRestrict": {"private": "org", "org": "org", "enterprise": "org", "public": "org"}, "attachmentRestrictions": null, "newLicenseInviteRestrict": null, "newLicenseInviteRestrictUrl": null}, "powerUps": [], "products": [], "billableMemberCount": 1, "billableCollaboratorCount": 0, "url": "https://trello.com/w/airbyteworkspace", "website": null, "logoHash": null, "logoUrl": null, "premiumFeatures": ["additionalBoardBackgrounds", "additionalStickers", "customBoardBackgrounds", "customEmoji", "customStickers", "plugins"], "promotions": [], "enterpriseJoinRequest": {}, "standardVariation": null, "availableLicenseCount": null, "maximumLicenseCount": null, "ixUpdate": "6", "teamType": null, "dateLastActivity": "2023-03-16T20:10:54.595Z", "memberships": [{"idMember": "610be3762899a26d04256dae", "memberType": "admin", "unconfirmed": false, "deactivated": false, "id": "610be50a0537086c571a5685"}]}, "emitted_at": 1689153140722} From 83faee7e4fa0c72e879a160eba5beaed9405c94c Mon Sep 17 00:00:00 2001 From: Arsen Losenko <20901439+arsenlosenko@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:52:44 +0300 Subject: [PATCH 34/63] Source Intercom: update expected records (#28196) --- .../integration_tests/expected_records.jsonl | 67 +++++++------------ 1 file changed, 25 insertions(+), 42 deletions(-) diff --git a/airbyte-integrations/connectors/source-intercom/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-intercom/integration_tests/expected_records.jsonl index 530c78ab1537..6823ccd4dbb4 100644 --- a/airbyte-integrations/connectors/source-intercom/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-intercom/integration_tests/expected_records.jsonl @@ -11,17 +11,17 @@ {"stream": "admins", "data": {"type": "admin", "email": "user8.sample.airbyte@outlook.com", "id": "6407155", "name": "User8 Sample", "away_mode_enabled": false, "away_mode_reassign": false, "has_inbox_seat": true, "team_ids": [6407167, 6407174], "team_priority_level": {"primary_team_ids": [6407167, 6407174]}}, "emitted_at": 1680518975305} {"stream": "admins", "data": {"type": "admin", "email": "user9.sample.airbyte@outlook.com", "id": "6407156", "name": "User9 Sample", "away_mode_enabled": false, "away_mode_reassign": false, "has_inbox_seat": true, "team_ids": [6407168, 6407170, 6407173], "team_priority_level": {"primary_team_ids": [6407168, 6407170, 6407173]}}, "emitted_at": 1680518975306} {"stream": "admins", "data": {"type": "admin", "email": "user10.sample.airbyte@outlook.com", "id": "6407160", "name": "User10 Sample", "away_mode_enabled": false, "away_mode_reassign": false, "has_inbox_seat": true, "team_ids": [6407168, 6407175], "team_priority_level": {"primary_team_ids": [6407168, 6407175]}}, "emitted_at": 1680518975308} -{"stream": "companies", "data": {"type": "company", "company_id": "63ecc5731d460cdc137c906d-qualification-company", "id": "63ecc5731d460cdc137c906c", "app_id": "wjw5eps7", "name": "Test Company 8", "created_at": 1676461427, "updated_at": 1679484652, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 49, "website": "www.company8.com", "industry": "Manufacturing", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1688632233314} -{"stream": "companies", "data": {"type": "company", "company_id": "63ecc52f00fc87e58e8fb1f2-qualification-company", "id": "63ecc52f00fc87e58e8fb1f1", "app_id": "wjw5eps7", "name": "Test Company 7", "created_at": 1676461359, "updated_at": 1679484653, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 23, "website": "www.company7.com", "industry": "Production", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1688632233317} -{"stream": "companies", "data": {"type": "company", "company_id": "63ecc46a811f1737ded479ef-qualification-company", "id": "63ecc46a811f1737ded479ee", "app_id": "wjw5eps7", "name": "Test Company 4", "created_at": 1676461162, "updated_at": 1679484653, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 150, "website": "www.company4.com", "industry": "Software", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1688632233319} -{"stream": "companies", "data": {"type": "company", "company_id": "63ecc5d32059cdacf4ac6171-qualification-company", "id": "63ecc5d32059cdacf4ac6170", "app_id": "wjw5eps7", "name": "Test Company 9", "created_at": 1676461523, "updated_at": 1679484653, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 75, "website": "www.company9.com", "industry": "Sales", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1688632233321} -{"stream": "companies", "data": {"type": "company", "company_id": "63ecc61266325d8ebd24ed11-qualification-company", "id": "63ecc61266325d8ebd24ed10", "app_id": "wjw5eps7", "name": "Test Company 10", "created_at": 1676461586, "updated_at": 1679484652, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 38, "website": "www.company10.com", "industry": "IT", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1688632233323} -{"stream": "companies", "data": {"type": "company", "company_id": "63ecbfccb064f24a4941d219-qualification-company", "id": "63ecbfccb064f24a4941d218", "app_id": "wjw5eps7", "name": "Test Company", "created_at": 1676459980, "updated_at": 1679484653, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 123, "website": "http://test.com", "industry": "IT", "tags": {"type": "tag.list", "tags": [{"type": "tag", "id": "7799571", "name": "Tag1"}, {"type": "tag", "id": "7799570", "name": "Tag2"}, {"type": "tag", "id": "7799640", "name": "Tag10"}]}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1688632233326} -{"stream": "companies", "data": {"type": "company", "company_id": "63ecbfef66325dc8a0ac006f-qualification-company", "id": "63ecbfef66325dc8a0ac006e", "app_id": "wjw5eps7", "name": "Test Company 2", "created_at": 1676460015, "updated_at": 1679484653, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 123, "website": "http://test.com", "industry": "IT 123", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1688632233327} -{"stream": "companies", "data": {"type": "company", "company_id": "63ecc41866325d2e90b0d3c6-qualification-company", "id": "63ecc41866325d2e90b0d3c5", "app_id": "wjw5eps7", "name": "Test Company 3", "created_at": 1676461080, "updated_at": 1679484653, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 50, "website": "www.company3.com", "industry": "IT", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1688632233329} -{"stream": "companies", "data": {"type": "company", "company_id": "63ecc3d60e3c81baaad9f9ef-qualification-company", "id": "63ecc3d60e3c81baaad9f9ee", "app_id": "wjw5eps7", "name": "Company 1", "created_at": 1676461015, "updated_at": 1679484653, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 25, "website": "www.company1.com", "industry": "Sales", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1688632233331} -{"stream": "companies", "data": {"type": "company", "company_id": "63ecc4e99a2c64721f435a23-qualification-company", "id": "63ecc4e99a2c64721f435a22", "app_id": "wjw5eps7", "name": "Test Company 6", "created_at": 1676461289, "updated_at": 1679484652, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 55, "website": "www.company6.com", "industry": "Sales", "tags": {"type": "tag.list", "tags": [{"type": "tag", "id": "7799570", "name": "Tag2"}, {"type": "tag", "id": "7799640", "name": "Tag10"}]}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1688632233333} -{"stream": "companies", "data": {"type": "company", "company_id": "63ecc7afb3789118eb91306b-qualification-company", "id": "63ecc7afb3789118eb91306a", "app_id": "wjw5eps7", "name": "Test Company 11", "created_at": 1676461999, "updated_at": 1679484652, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 9, "website": "www.company11.com", "industry": "Sales", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1688632233335} +{"stream": "companies", "data": {"type": "company", "company_id": "63ecc5731d460cdc137c906d-qualification-company", "id": "63ecc5731d460cdc137c906c", "app_id": "wjw5eps7", "name": "Test Company 8", "created_at": 1676461427, "updated_at": 1679484652, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 49, "website": "www.company8.com", "industry": "Manufacturing", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1689152867526} +{"stream": "companies", "data": {"type": "company", "company_id": "63ecc52f00fc87e58e8fb1f2-qualification-company", "id": "63ecc52f00fc87e58e8fb1f1", "app_id": "wjw5eps7", "name": "Test Company 7", "created_at": 1676461359, "updated_at": 1679484653, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 23, "website": "www.company7.com", "industry": "Production", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1689152867529} +{"stream": "companies", "data": {"type": "company", "company_id": "63ecc46a811f1737ded479ef-qualification-company", "id": "63ecc46a811f1737ded479ee", "app_id": "wjw5eps7", "name": "Test Company 4", "created_at": 1676461162, "updated_at": 1679484653, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 150, "website": "www.company4.com", "industry": "Software", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1689152867531} +{"stream": "companies", "data": {"type": "company", "company_id": "63ecc5d32059cdacf4ac6171-qualification-company", "id": "63ecc5d32059cdacf4ac6170", "app_id": "wjw5eps7", "name": "Test Company 9", "created_at": 1676461523, "updated_at": 1679484653, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 75, "website": "www.company9.com", "industry": "Sales", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1689152867536} +{"stream": "companies", "data": {"type": "company", "company_id": "63ecc61266325d8ebd24ed11-qualification-company", "id": "63ecc61266325d8ebd24ed10", "app_id": "wjw5eps7", "name": "Test Company 10", "created_at": 1676461586, "updated_at": 1679484652, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 38, "website": "www.company10.com", "industry": "IT", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1689152867538} +{"stream": "companies", "data": {"type": "company", "company_id": "63ecbfccb064f24a4941d219-qualification-company", "id": "63ecbfccb064f24a4941d218", "app_id": "wjw5eps7", "name": "Test Company", "created_at": 1676459980, "updated_at": 1679484653, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 123, "website": "http://test.com", "industry": "IT", "tags": {"type": "tag.list", "tags": [{"type": "tag", "id": "7799571", "name": "Tag1"}, {"type": "tag", "id": "7799570", "name": "Tag2"}, {"type": "tag", "id": "7799640", "name": "Tag10"}]}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1689152867533} +{"stream": "companies", "data": {"type": "company", "company_id": "63ecbfef66325dc8a0ac006f-qualification-company", "id": "63ecbfef66325dc8a0ac006e", "app_id": "wjw5eps7", "name": "Test Company 2", "created_at": 1676460015, "updated_at": 1679484653, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 123, "website": "http://test.com", "industry": "IT 123", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1689152867540} +{"stream": "companies", "data": {"type": "company", "company_id": "63ecc41866325d2e90b0d3c6-qualification-company", "id": "63ecc41866325d2e90b0d3c5", "app_id": "wjw5eps7", "name": "Test Company 3", "created_at": 1676461080, "updated_at": 1679484653, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 50, "website": "www.company3.com", "industry": "IT", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1689152867542} +{"stream": "companies", "data": {"type": "company", "company_id": "63ecc3d60e3c81baaad9f9ef-qualification-company", "id": "63ecc3d60e3c81baaad9f9ee", "app_id": "wjw5eps7", "name": "Company 1", "created_at": 1676461015, "updated_at": 1689068298, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 25, "website": "www.company1.com", "industry": "Sales", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1689152867548} +{"stream": "companies", "data": {"type": "company", "company_id": "63ecc4e99a2c64721f435a23-qualification-company", "id": "63ecc4e99a2c64721f435a22", "app_id": "wjw5eps7", "name": "Test Company 6", "created_at": 1676461289, "updated_at": 1679484652, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 55, "website": "www.company6.com", "industry": "Sales", "tags": {"type": "tag.list", "tags": [{"type": "tag", "id": "7799570", "name": "Tag2"}, {"type": "tag", "id": "7799640", "name": "Tag10"}]}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1689152867544} +{"stream": "companies", "data": {"type": "company", "company_id": "63ecc7afb3789118eb91306b-qualification-company", "id": "63ecc7afb3789118eb91306a", "app_id": "wjw5eps7", "name": "Test Company 11", "created_at": 1676461999, "updated_at": 1679484652, "monthly_spend": 0, "session_count": 0, "user_count": 1, "size": 9, "website": "www.company11.com", "industry": "Sales", "tags": {"type": "tag.list", "tags": []}, "segments": {"type": "segment.list", "segments": []}, "plan": {}, "custom_attributes": {"creation_source": "api"}}, "emitted_at": 1689152867546} {"stream": "company_attributes", "data": {"type": "data_attribute", "name": "name", "full_name": "name", "label": "Company name", "description": "The name of a company", "data_type": "string", "api_writable": true, "ui_writable": true, "custom": false, "archived": false, "model": "company"}, "emitted_at": 1680518977060} {"stream": "company_attributes", "data": {"type": "data_attribute", "name": "company_id", "full_name": "company_id", "label": "Company ID", "description": "A number identifying a company", "data_type": "string", "api_writable": false, "ui_writable": false, "custom": false, "archived": false, "model": "company"}, "emitted_at": 1680518977062} {"stream": "company_attributes", "data": {"type": "data_attribute", "name": "last_request_at", "full_name": "last_request_at", "label": "Company last seen", "description": "The last day anyone from a company visited your site or app", "data_type": "date", "api_writable": false, "ui_writable": false, "custom": false, "archived": false, "model": "company"}, "emitted_at": 1680518977064} @@ -50,17 +50,17 @@ {"stream": "company_segments", "data": {"type": "segment", "id": "63ea1a43d9c86cceefd8796e", "name": "Revenue", "created_at": 1676286531, "updated_at": 1676462321, "person_type": "user"}, "emitted_at": 1680518982259} {"stream": "company_segments", "data": {"type": "segment", "id": "63ecc7f36d40e8184b5d47a6", "name": "Sales", "created_at": 1676462067, "updated_at": 1676462069, "person_type": "user"}, "emitted_at": 1680518982262} {"stream": "company_segments", "data": {"type": "segment", "id": "6241a4b8c8b709894fa54df1", "name": "Test_1", "created_at": 1648469176, "updated_at": 1676462341, "person_type": "user"}, "emitted_at": 1680518982266} -{"stream": "conversations", "data": {"type": "conversation", "id": "1", "created_at": 1607553243, "updated_at": 1626346673, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "701718739", "delivered_as": "customer_initiated", "subject": "", "body": "

hey there

", "author": {"type": "lead", "id": "5fd150d50697b6d0bbc4a2c2", "name": null, "email": ""}, "attachments": [], "url": "http://localhost:63342/airbyte-python/airbyte-integrations/bases/base-java/build/tmp/expandedArchives/org.jacoco.agent-0.8.5.jar_6a2df60c47de373ea127d14406367999/about.html?_ijt=uosck1k6vmp2dnl4oqib2g3u9d", "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "5fd150d50697b6d0bbc4a2c2"}]}, "first_contact_reply": {"created_at": 1607553243, "type": "conversation", "url": "http://localhost:63342/airbyte-python/airbyte-integrations/bases/base-java/build/tmp/expandedArchives/org.jacoco.agent-0.8.5.jar_6a2df60c47de373ea127d14406367999/about.html?_ijt=uosck1k6vmp2dnl4oqib2g3u9d"}, "admin_assignee_id": null, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": 4317957, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": 4317954, "first_contact_reply_at": 1607553243, "first_assignment_at": null, "first_admin_reply_at": 1625654131, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": 1607553246, "last_admin_reply_at": 1625656000, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 7}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": null, "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1688632239913} -{"stream": "conversations", "data": {"type": "conversation", "id": "59", "created_at": 1676460979, "updated_at": 1676460980, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51952658", "delivered_as": "automated", "subject": "", "body": "

Test 1

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea418c0931f79d99a197ff"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test 1", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1688632239918} -{"stream": "conversations", "data": {"type": "conversation", "id": "60", "created_at": 1676461133, "updated_at": 1676461134, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51952871", "delivered_as": "automated", "subject": "", "body": "

Test 3

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea41a0eddb9b625fb712c9"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test3", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1688632239922} -{"stream": "conversations", "data": {"type": "conversation", "id": "61", "created_at": 1676461196, "updated_at": 1676461197, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51952963", "delivered_as": "automated", "subject": "", "body": "

Test 4

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea41a1b0e17c53248c7956"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test 4", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1688632239925} -{"stream": "conversations", "data": {"type": "conversation", "id": "63", "created_at": 1676461327, "updated_at": 1676461328, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51953153", "delivered_as": "automated", "subject": "", "body": "

Test 6

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea41a2b2d44e63848146e7"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test 6", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1688632239929} -{"stream": "conversations", "data": {"type": "conversation", "id": "64", "created_at": 1676461395, "updated_at": 1676461396, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51953262", "delivered_as": "automated", "subject": "", "body": "

Test 7

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea41a2c340f850172f2905"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test 7", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1688632239932} -{"stream": "conversations", "data": {"type": "conversation", "id": "65", "created_at": 1676461499, "updated_at": 1676461499, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51953436", "delivered_as": "automated", "subject": "", "body": "

Test Lead 1

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "5fd150d50697b6d0bbc4a2c2"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test Lead 1", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1688632239936} -{"stream": "conversations", "data": {"type": "conversation", "id": "66", "created_at": 1676461563, "updated_at": 1676461564, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51953541", "delivered_as": "automated", "subject": "", "body": "

Test 9

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea41a3b0e17c505e52044d"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test 9", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1688632239939} -{"stream": "conversations", "data": {"type": "conversation", "id": "67", "created_at": 1676461636, "updated_at": 1676461637, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51953649", "delivered_as": "automated", "subject": "", "body": "

Test 10

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea41a7b0e17c5039fbb824"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test 10", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1688632239942} -{"stream": "conversations", "data": {"type": "conversation", "id": "68", "created_at": 1676461800, "updated_at": 1676461800, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51953852", "delivered_as": "automated", "subject": "", "body": "

Test Lead 5001

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ecc6c2811f17873ed2d007"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test Lead 5001", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1688632239945} -{"stream": "conversations", "data": {"type": "conversation", "id": "69", "created_at": 1676462031, "updated_at": 1676462031, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51954139", "delivered_as": "automated", "subject": "", "body": "

Test 11

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea41a80931f79b6998e89f"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test 11", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1688632239948} +{"stream": "conversations", "data": {"type": "conversation", "id": "1", "created_at": 1607553243, "updated_at": 1626346673, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "701718739", "delivered_as": "customer_initiated", "subject": "", "body": "

hey there

", "author": {"type": "lead", "id": "5fd150d50697b6d0bbc4a2c2", "name": null, "email": ""}, "attachments": [], "url": "http://localhost:63342/airbyte-python/airbyte-integrations/bases/base-java/build/tmp/expandedArchives/org.jacoco.agent-0.8.5.jar_6a2df60c47de373ea127d14406367999/about.html?_ijt=uosck1k6vmp2dnl4oqib2g3u9d", "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "5fd150d50697b6d0bbc4a2c2"}]}, "first_contact_reply": {"created_at": 1607553243, "type": "conversation", "url": "http://localhost:63342/airbyte-python/airbyte-integrations/bases/base-java/build/tmp/expandedArchives/org.jacoco.agent-0.8.5.jar_6a2df60c47de373ea127d14406367999/about.html?_ijt=uosck1k6vmp2dnl4oqib2g3u9d"}, "admin_assignee_id": null, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": 4317957, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": 4317954, "first_contact_reply_at": 1607553243, "first_assignment_at": null, "first_admin_reply_at": 1625654131, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": 1607553246, "last_admin_reply_at": 1625656000, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 7}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": null, "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1689153694977} +{"stream": "conversations", "data": {"type": "conversation", "id": "59", "created_at": 1676460979, "updated_at": 1689068230, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51952658", "delivered_as": "automated", "subject": "", "body": "

Test 1

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea418c0931f79d99a197ff"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": false, "state": "closed", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 3}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test 1", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1689153695018} +{"stream": "conversations", "data": {"type": "conversation", "id": "60", "created_at": 1676461133, "updated_at": 1676461134, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51952871", "delivered_as": "automated", "subject": "", "body": "

Test 3

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea41a0eddb9b625fb712c9"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test3", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1689153694982} +{"stream": "conversations", "data": {"type": "conversation", "id": "61", "created_at": 1676461196, "updated_at": 1676461197, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51952963", "delivered_as": "automated", "subject": "", "body": "

Test 4

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea41a1b0e17c53248c7956"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test 4", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1689153694985} +{"stream": "conversations", "data": {"type": "conversation", "id": "63", "created_at": 1676461327, "updated_at": 1676461328, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51953153", "delivered_as": "automated", "subject": "", "body": "

Test 6

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea41a2b2d44e63848146e7"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test 6", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1689153694989} +{"stream": "conversations", "data": {"type": "conversation", "id": "64", "created_at": 1676461395, "updated_at": 1676461396, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51953262", "delivered_as": "automated", "subject": "", "body": "

Test 7

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea41a2c340f850172f2905"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test 7", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1689153694994} +{"stream": "conversations", "data": {"type": "conversation", "id": "65", "created_at": 1676461499, "updated_at": 1676461499, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51953436", "delivered_as": "automated", "subject": "", "body": "

Test Lead 1

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "5fd150d50697b6d0bbc4a2c2"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test Lead 1", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1689153694998} +{"stream": "conversations", "data": {"type": "conversation", "id": "66", "created_at": 1676461563, "updated_at": 1676461564, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51953541", "delivered_as": "automated", "subject": "", "body": "

Test 9

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea41a3b0e17c505e52044d"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test 9", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1689153695003} +{"stream": "conversations", "data": {"type": "conversation", "id": "67", "created_at": 1676461636, "updated_at": 1676461637, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51953649", "delivered_as": "automated", "subject": "", "body": "

Test 10

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea41a7b0e17c5039fbb824"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test 10", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1689153695007} +{"stream": "conversations", "data": {"type": "conversation", "id": "68", "created_at": 1676461800, "updated_at": 1676461800, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51953852", "delivered_as": "automated", "subject": "", "body": "

Test Lead 5001

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ecc6c2811f17873ed2d007"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test Lead 5001", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1689153695011} +{"stream": "conversations", "data": {"type": "conversation", "id": "69", "created_at": 1676462031, "updated_at": 1676462031, "waiting_since": null, "snoozed_until": null, "source": {"type": "conversation", "id": "51954139", "delivered_as": "automated", "subject": "", "body": "

Test 11

", "author": {"type": "admin", "id": "4423433", "name": "Airbyte Team", "email": "integration-test@airbyte.io"}, "attachments": [], "url": null, "redacted": false}, "contacts": {"type": "contact.list", "contacts": [{"type": "contact", "id": "63ea41a80931f79b6998e89f"}]}, "first_contact_reply": null, "admin_assignee_id": 4423433, "team_assignee_id": null, "open": true, "state": "open", "read": false, "tags": {"type": "tag.list", "tags": []}, "priority": "not_priority", "sla_applied": null, "statistics": {"type": "conversation_statistics", "time_to_assignment": null, "time_to_admin_reply": null, "time_to_first_close": null, "time_to_last_close": null, "median_time_to_reply": null, "first_contact_reply_at": null, "first_assignment_at": null, "first_admin_reply_at": null, "first_close_at": null, "last_assignment_at": null, "last_assignment_admin_reply_at": null, "last_contact_reply_at": null, "last_admin_reply_at": null, "last_close_at": null, "last_closed_by_id": null, "count_reopens": 0, "count_assignments": 0, "count_conversation_parts": 2}, "conversation_rating": null, "teammates": {"type": "admin.list", "admins": [{"type": "admin", "id": "4423433"}]}, "title": "Test 11", "custom_attributes": {}, "topics": {"type": "topic.list", "topics": [], "total_count": 0}}, "emitted_at": 1689153695015} {"stream": "conversation_parts", "data": {"type": "conversation_part", "id": "7288120839", "part_type": "comment", "body": "

is this showing up

", "created_at": 1607553246, "updated_at": 1607553246, "notified_at": 1607553246, "assigned_to": null, "author": {"id": "5fd150d50697b6d0bbc4a2c2", "type": "user", "name": null, "email": ""}, "attachments": [], "external_id": null, "redacted": false, "conversation_id": "1"}, "emitted_at": 1688632241806} {"stream": "conversation_parts", "data": {"type": "conversation_part", "id": "7288121348", "part_type": "comment", "body": "

Airbyte [DEV] will reply as soon as they can.

", "created_at": 1607553249, "updated_at": 1607553249, "notified_at": 1607553249, "assigned_to": null, "author": {"id": "4423434", "type": "bot", "name": "Operator", "email": "operator+wjw5eps7@intercom.io"}, "attachments": [], "external_id": null, "redacted": false, "conversation_id": "1"}, "emitted_at": 1688632241811} {"stream": "conversation_parts", "data": {"type": "conversation_part", "id": "7288121392", "part_type": "comment", "body": "

Give the team a way to reach you:

", "created_at": 1607553250, "updated_at": 1607553250, "notified_at": 1607553250, "assigned_to": null, "author": {"id": "4423434", "type": "bot", "name": "Operator", "email": "operator+wjw5eps7@intercom.io"}, "attachments": [], "external_id": null, "redacted": false, "conversation_id": "1"}, "emitted_at": 1688632241815} @@ -87,26 +87,9 @@ {"stream": "contact_attributes", "data": {"type": "data_attribute", "name": "android_sdk_version", "full_name": "android_sdk_version", "label": "Android SDK version", "description": "The version of the Android SDK a person is using", "data_type": "string", "api_writable": false, "ui_writable": false, "custom": false, "archived": false, "model": "contact"}, "emitted_at": 1680518989386} {"stream": "contact_attributes", "data": {"type": "data_attribute", "name": "ios_app_name", "full_name": "ios_app_name", "label": "iOS App name", "description": "The name of iOS app a person is using", "data_type": "string", "api_writable": false, "ui_writable": false, "custom": false, "archived": false, "model": "contact"}, "emitted_at": 1680518989387} {"stream": "contact_attributes", "data": {"type": "data_attribute", "name": "ios_sdk_version", "full_name": "ios_sdk_version", "label": "iOS SDK version", "description": "The version of the iOS SDK a person is using", "data_type": "string", "api_writable": false, "ui_writable": false, "custom": false, "archived": false, "model": "contact"}, "emitted_at": 1680518989389} -{"stream": "contacts", "data": {"type": "contact", "id": "63ea41aaeddb9b627ce9b882", "workspace_id": "wjw5eps7", "external_id": "20033080", "role": "user", "email": "user20.sample@gmail.com", "phone": null, "name": "User33080", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296619, "updated_at": 1676296619, "signed_up_at": 2328134400, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": null, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41aaeddb9b627ce9b882/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41aaeddb9b627ce9b882/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [], "url": "/contacts/63ea41aaeddb9b627ce9b882/companies", "total_count": 0, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41aaeddb9b627ce9b882/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246727} -{"stream": "contacts", "data": {"type": "contact", "id": "63ea41b1b0e17c51fa4eb704", "workspace_id": "wjw5eps7", "external_id": "20037835", "role": "user", "email": "user20.sample@gmail.com", "phone": null, "name": "User37835", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296625, "updated_at": 1676296625, "signed_up_at": 2738966400, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": null, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41b1b0e17c51fa4eb704/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41b1b0e17c51fa4eb704/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [], "url": "/contacts/63ea41b1b0e17c51fa4eb704/companies", "total_count": 0, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41b1b0e17c51fa4eb704/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246730} -{"stream": "contacts", "data": {"type": "contact", "id": "63ea41b1c340f84dffe8cddc", "workspace_id": "wjw5eps7", "external_id": "20033579", "role": "user", "email": "user20.sample@gmail.com", "phone": null, "name": "User33579", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296625, "updated_at": 1676296625, "signed_up_at": 2371248000, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": null, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41b1c340f84dffe8cddc/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41b1c340f84dffe8cddc/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [], "url": "/contacts/63ea41b1c340f84dffe8cddc/companies", "total_count": 0, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41b1c340f84dffe8cddc/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246733} -{"stream": "contacts", "data": {"type": "contact", "id": "63ea41b1eddb9b607f593949", "workspace_id": "wjw5eps7", "external_id": "20035970", "role": "user", "email": "user20.sample@gmail.com", "phone": null, "name": "User35970", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296625, "updated_at": 1676296625, "signed_up_at": 2577830400, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": null, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41b1eddb9b607f593949/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41b1eddb9b607f593949/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [], "url": "/contacts/63ea41b1eddb9b607f593949/companies", "total_count": 0, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41b1eddb9b607f593949/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246736} -{"stream": "contacts", "data": {"type": "contact", "id": "63ea41b1eddb9b625fb7130a", "workspace_id": "wjw5eps7", "external_id": "20042431", "role": "user", "email": "user20.sample@gmail.com", "phone": null, "name": "User42431", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296625, "updated_at": 1676296625, "signed_up_at": 3136060800, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": null, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41b1eddb9b625fb7130a/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41b1eddb9b625fb7130a/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [], "url": "/contacts/63ea41b1eddb9b625fb7130a/companies", "total_count": 0, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41b1eddb9b625fb7130a/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246739} -{"stream": "contacts", "data": {"type": "contact", "id": "63ea41e6ab35564e6f32f4a6", "workspace_id": "wjw5eps7", "external_id": "20049782", "role": "user", "email": "user20.sample@gmail.com", "phone": null, "name": "User49782", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296678, "updated_at": 1676296678, "signed_up_at": 3771187200, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": null, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41e6ab35564e6f32f4a6/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41e6ab35564e6f32f4a6/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [], "url": "/contacts/63ea41e6ab35564e6f32f4a6/companies", "total_count": 0, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41e6ab35564e6f32f4a6/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246741} -{"stream": "contacts", "data": {"type": "contact", "id": "63ecbef231c68598171f7cc2", "workspace_id": "wjw5eps7", "external_id": "123456789", "role": "user", "email": "test@test.com", "phone": null, "name": "Test User", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676459763, "updated_at": 1676459763, "signed_up_at": null, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": null, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [], "url": "/contacts/63ecbef231c68598171f7cc2/tags", "total_count": 0, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ecbef231c68598171f7cc2/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [], "url": "/contacts/63ecbef231c68598171f7cc2/companies", "total_count": 0, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ecbef231c68598171f7cc2/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246744} -{"stream": "contacts", "data": {"type": "contact", "id": "63ea419cb0e17c50f294c724", "workspace_id": "wjw5eps7", "external_id": "20033712", "role": "user", "email": "user20.sample@gmail.com", "phone": null, "name": "User33712", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296604, "updated_at": 1676460037, "signed_up_at": 2382739200, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": null, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea419cb0e17c50f294c724/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea419cb0e17c50f294c724/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [{"id": "63ecbfef66325dc8a0ac006e", "type": "company", "url": "/companies/63ecbfef66325dc8a0ac006e"}], "url": "/contacts/63ea419cb0e17c50f294c724/companies", "total_count": 1, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea419cb0e17c50f294c724/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246746} -{"stream": "contacts", "data": {"type": "contact", "id": "63ea41a0eddb9b625fb712c9", "workspace_id": "wjw5eps7", "external_id": "20030866", "role": "user", "email": "user20.sample@gmail.com", "phone": "+188844477723", "name": "User30866", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296608, "updated_at": 1676461134, "signed_up_at": 2136844800, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": 1676461134, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41a0eddb9b625fb712c9/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41a0eddb9b625fb712c9/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [{"id": "63ecc41866325d2e90b0d3c5", "type": "company", "url": "/companies/63ecc41866325d2e90b0d3c5"}], "url": "/contacts/63ea41a0eddb9b625fb712c9/companies", "total_count": 1, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41a0eddb9b625fb712c9/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246749} -{"stream": "contacts", "data": {"type": "contact", "id": "63ea41a1b0e17c53248c7956", "workspace_id": "wjw5eps7", "external_id": "20031178", "role": "user", "email": "user20.sample@gmail.com", "phone": "+13888333888", "name": "User31178", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296609, "updated_at": 1676461197, "signed_up_at": 2163801600, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": 1676461197, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41a1b0e17c53248c7956/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41a1b0e17c53248c7956/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [{"id": "63ecc46a811f1737ded479ee", "type": "company", "url": "/companies/63ecc46a811f1737ded479ee"}], "url": "/contacts/63ea41a1b0e17c53248c7956/companies", "total_count": 1, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41a1b0e17c53248c7956/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246751} -{"stream": "contacts", "data": {"type": "contact", "id": "63ea41a2b2d44e63848146e7", "workspace_id": "wjw5eps7", "external_id": "20028832", "role": "user", "email": "user20.sample@gmail.com", "phone": "+13335556789", "name": "User28832", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296610, "updated_at": 1676461327, "signed_up_at": 1961107200, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": 1676461327, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41a2b2d44e63848146e7/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41a2b2d44e63848146e7/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [{"id": "63ecc4e99a2c64721f435a22", "type": "company", "url": "/companies/63ecc4e99a2c64721f435a22"}], "url": "/contacts/63ea41a2b2d44e63848146e7/companies", "total_count": 1, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41a2b2d44e63848146e7/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246754} -{"stream": "contacts", "data": {"type": "contact", "id": "63ea41a2c340f850172f2905", "workspace_id": "wjw5eps7", "external_id": "20032071", "role": "user", "email": "user20.sample@gmail.com", "phone": "+13888333888", "name": "User32071", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296610, "updated_at": 1676461395, "signed_up_at": 2240956800, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": 1676461395, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41a2c340f850172f2905/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41a2c340f850172f2905/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [{"id": "63ecc52f00fc87e58e8fb1f1", "type": "company", "url": "/companies/63ecc52f00fc87e58e8fb1f1"}], "url": "/contacts/63ea41a2c340f850172f2905/companies", "total_count": 1, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41a2c340f850172f2905/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246756} -{"stream": "contacts", "data": {"type": "contact", "id": "63ea41a30931f79c14406608", "workspace_id": "wjw5eps7", "external_id": "20032315", "role": "user", "email": "user20.sample@gmail.com", "phone": "+13844463883", "name": "User32315", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296611, "updated_at": 1676461454, "signed_up_at": 2262038400, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": null, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41a30931f79c14406608/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41a30931f79c14406608/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [{"id": "63ecc5731d460cdc137c906c", "type": "company", "url": "/companies/63ecc5731d460cdc137c906c"}], "url": "/contacts/63ea41a30931f79c14406608/companies", "total_count": 1, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41a30931f79c14406608/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246759} -{"stream": "contacts", "data": {"type": "contact", "id": "5fd150d50697b6d0bbc4a2c2", "workspace_id": "wjw5eps7", "external_id": "56f1e303-24f7-4f0a-ae18-0bafd587c894", "role": "lead", "email": null, "phone": null, "name": null, "avatar": "https://static.intercomassets.com/app/pseudonym_avatars_2019/yellow-guitar.png", "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1607553237, "updated_at": 1676461499, "signed_up_at": null, "last_seen_at": 1607553243, "last_replied_at": 1607553246, "last_contacted_at": 1676461499, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": "chrome", "browser_version": "87.0.4280.88", "browser_language": "en", "os": "OS X 10.15.6", "location": {"type": "location", "country": "United States", "region": "California", "city": "Daly City", "country_code": "USA", "continent_code": "NA"}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [], "url": "/contacts/5fd150d50697b6d0bbc4a2c2/tags", "total_count": 0, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/5fd150d50697b6d0bbc4a2c2/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [], "url": "/contacts/5fd150d50697b6d0bbc4a2c2/companies", "total_count": 0, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/5fd150d50697b6d0bbc4a2c2/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246761} -{"stream": "contacts", "data": {"type": "contact", "id": "63ea41a3b0e17c505e52044d", "workspace_id": "wjw5eps7", "external_id": "20032233", "role": "user", "email": "user20.sample@gmail.com", "phone": "+13823333883", "name": "User32233", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296611, "updated_at": 1676461564, "signed_up_at": 2254953600, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": 1676461564, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41a3b0e17c505e52044d/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41a3b0e17c505e52044d/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [{"id": "63ecc5d32059cdacf4ac6170", "type": "company", "url": "/companies/63ecc5d32059cdacf4ac6170"}], "url": "/contacts/63ea41a3b0e17c505e52044d/companies", "total_count": 1, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41a3b0e17c505e52044d/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246772} -{"stream": "contacts", "data": {"type": "contact", "id": "63ea41a7b0e17c5039fbb824", "workspace_id": "wjw5eps7", "external_id": "20036235", "role": "user", "email": "user20.sample@gmail.com", "phone": "+13888463888", "name": "User36235", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296615, "updated_at": 1676461637, "signed_up_at": 2600726400, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": 1676461637, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41a7b0e17c5039fbb824/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41a7b0e17c5039fbb824/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [{"id": "63ecc61266325d8ebd24ed10", "type": "company", "url": "/companies/63ecc61266325d8ebd24ed10"}], "url": "/contacts/63ea41a7b0e17c5039fbb824/companies", "total_count": 1, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41a7b0e17c5039fbb824/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246775} -{"stream": "contacts", "data": {"type": "contact", "id": "63ecc6c2811f17873ed2d007", "workspace_id": "wjw5eps7", "external_id": "347ff2b4-93a0-4d78-b0e2-487c3855a3fd", "role": "lead", "email": "user5001.sample.airbyte@gmail.com", "phone": "+13335556789", "name": "User5001", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676461762, "updated_at": 1676461800, "signed_up_at": null, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": 1676461800, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [], "url": "/contacts/63ecc6c2811f17873ed2d007/tags", "total_count": 0, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ecc6c2811f17873ed2d007/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [{"id": "63ecbfccb064f24a4941d218", "type": "company", "url": "/companies/63ecbfccb064f24a4941d218"}], "url": "/contacts/63ecc6c2811f17873ed2d007/companies", "total_count": 1, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ecc6c2811f17873ed2d007/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246777} -{"stream": "contacts", "data": {"type": "contact", "id": "63ea41a80931f79b6998e89f", "workspace_id": "wjw5eps7", "external_id": "20033328", "role": "user", "email": "user20.sample@gmail.com", "phone": "+13888463888", "name": "User33328", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296616, "updated_at": 1676462031, "signed_up_at": 2349561600, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": 1676462031, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41a80931f79b6998e89f/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41a80931f79b6998e89f/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [{"id": "63ecc7afb3789118eb91306a", "type": "company", "url": "/companies/63ecc7afb3789118eb91306a"}], "url": "/contacts/63ea41a80931f79b6998e89f/companies", "total_count": 1, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41a80931f79b6998e89f/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246779} -{"stream": "contacts", "data": {"type": "contact", "id": "64a3f5ec2d9792fb1a1f4cb3", "workspace_id": "wjw5eps7", "external_id": null, "role": "user", "email": "integration-test+1@aribyte.io", "phone": null, "name": "yurii", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1688466924, "updated_at": 1688466924, "signed_up_at": null, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": null, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [], "url": "/contacts/64a3f5ec2d9792fb1a1f4cb3/tags", "total_count": 0, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/64a3f5ec2d9792fb1a1f4cb3/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [], "url": "/contacts/64a3f5ec2d9792fb1a1f4cb3/companies", "total_count": 0, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/64a3f5ec2d9792fb1a1f4cb3/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246782} -{"stream": "contacts", "data": {"type": "contact", "id": "63ea418c0931f79d99a197ff", "workspace_id": "wjw5eps7", "external_id": "20026950", "role": "user", "email": "user20.sample@gmail.com", "phone": "+133344455567", "name": "User26950", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296589, "updated_at": 1688467344, "signed_up_at": 1798502400, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": 1676460980, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {"Company": null}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}, {"id": "7800216", "type": "tag", "url": "/tags/7800216"}, {"id": "7799571", "type": "tag", "url": "/tags/7799571"}], "url": "/contacts/63ea418c0931f79d99a197ff/tags", "total_count": 3, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea418c0931f79d99a197ff/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [{"id": "63ecc3d60e3c81baaad9f9ee", "type": "company", "url": "/companies/63ecc3d60e3c81baaad9f9ee"}], "url": "/contacts/63ea418c0931f79d99a197ff/companies", "total_count": 1, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea418c0931f79d99a197ff/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1688632246784} +{"stream": "contacts", "data": {"type": "contact", "id": "63ea41aaeddb9b627ce9b882", "workspace_id": "wjw5eps7", "external_id": "20033080", "role": "user", "email": "user20.sample@gmail.com", "phone": null, "name": "User33080", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296619, "updated_at": 1676296619, "signed_up_at": 2328134400, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": null, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41aaeddb9b627ce9b882/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41aaeddb9b627ce9b882/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [], "url": "/contacts/63ea41aaeddb9b627ce9b882/companies", "total_count": 0, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41aaeddb9b627ce9b882/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1689154147400} +{"stream": "contacts", "data": {"type": "contact", "id": "63ea41b1b0e17c51fa4eb704", "workspace_id": "wjw5eps7", "external_id": "20037835", "role": "user", "email": "user20.sample@gmail.com", "phone": null, "name": "User37835", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296625, "updated_at": 1676296625, "signed_up_at": 2738966400, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": null, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41b1b0e17c51fa4eb704/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41b1b0e17c51fa4eb704/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [], "url": "/contacts/63ea41b1b0e17c51fa4eb704/companies", "total_count": 0, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41b1b0e17c51fa4eb704/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1689154147403} +{"stream": "contacts", "data": {"type": "contact", "id": "63ea41b1c340f84dffe8cddc", "workspace_id": "wjw5eps7", "external_id": "20033579", "role": "user", "email": "user20.sample@gmail.com", "phone": null, "name": "User33579", "avatar": null, "owner_id": null, "social_profiles": {"type": "list", "data": []}, "has_hard_bounced": false, "marked_email_as_spam": false, "unsubscribed_from_emails": false, "created_at": 1676296625, "updated_at": 1676296625, "signed_up_at": 2371248000, "last_seen_at": null, "last_replied_at": null, "last_contacted_at": null, "last_email_opened_at": null, "last_email_clicked_at": null, "language_override": null, "browser": null, "browser_version": null, "browser_language": null, "os": null, "location": {"type": "location", "country": null, "region": null, "city": null, "country_code": null, "continent_code": null}, "android_app_name": null, "android_app_version": null, "android_device": null, "android_os_version": null, "android_sdk_version": null, "android_last_seen_at": null, "ios_app_name": null, "ios_app_version": null, "ios_device": null, "ios_os_version": null, "ios_sdk_version": null, "ios_last_seen_at": null, "custom_attributes": {}, "tags": {"type": "list", "data": [{"id": "7800292", "type": "tag", "url": "/tags/7800292"}], "url": "/contacts/63ea41b1c340f84dffe8cddc/tags", "total_count": 1, "has_more": false}, "notes": {"type": "list", "data": [], "url": "/contacts/63ea41b1c340f84dffe8cddc/notes", "total_count": 0, "has_more": false}, "companies": {"type": "list", "data": [], "url": "/contacts/63ea41b1c340f84dffe8cddc/companies", "total_count": 0, "has_more": false}, "opted_out_subscription_types": {"type": "list", "data": [], "url": "/contacts/63ea41b1c340f84dffe8cddc/subscriptions", "total_count": 0, "has_more": false}, "utm_campaign": null, "utm_content": null, "utm_medium": null, "utm_source": null, "utm_term": null, "referrer": null, "sms_consent": false, "unsubscribed_from_sms": false}, "emitted_at": 1689154147406} {"stream": "segments", "data": {"type": "segment", "id": "5f8d1c6caee76458e332f238", "name": "Active", "created_at": 1603083372, "updated_at": 1603083372, "person_type": "user"}, "emitted_at": 1680518991074} {"stream": "segments", "data": {"type": "segment", "id": "63ea19b36ea882cf2f785a45", "name": "Country", "created_at": 1676286387, "updated_at": 1676286387, "person_type": "user"}, "emitted_at": 1680518991078} {"stream": "segments", "data": {"type": "segment", "id": "5f8d1c6caee76458e332f237", "name": "New", "created_at": 1603083372, "updated_at": 1603083372, "person_type": "user"}, "emitted_at": 1680518991082} From 7a9b01f185e0b50c4c64fb70fcdbdb30b9d66228 Mon Sep 17 00:00:00 2001 From: Arsen Losenko <20901439+arsenlosenko@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:52:54 +0300 Subject: [PATCH 35/63] Source Zendesk Support: update expected records (#28197) --- .../integration_tests/expected_records.jsonl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/airbyte-integrations/connectors/source-zendesk-support/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-zendesk-support/integration_tests/expected_records.jsonl index f24978473c2a..ab1a30b6fd43 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-zendesk-support/integration_tests/expected_records.jsonl @@ -6,8 +6,8 @@ {"stream":"groups","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/groups/5060105343503.json","id":5060105343503,"is_public":true,"name":"Group 100","description":"","default":false,"deleted":false,"created_at":"2022-06-29T16:22:26Z","updated_at":"2022-06-29T16:22:26Z"},"emitted_at":1687861660537} {"stream":"macros","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/macros/360011363556.json","id":360011363556,"title":"Customer not responding","active":true,"updated_at":"2020-12-11T18:34:06Z","created_at":"2020-12-11T18:34:06Z","default":false,"position":9999,"description":null,"actions":[{"field":"status","value":"pending"},{"field":"comment_value","value":"Hello {{ticket.requester.name}}. Our agent {{current_user.name}} has tried to contact you about this request but we haven't heard back from you yet. Please let us know if we can be of further assistance. Thanks. "}],"restriction":null,"raw_title":"Customer not responding"},"emitted_at":1687861662012} {"stream":"macros","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/macros/360011363536.json","id":360011363536,"title":"Downgrade and inform","active":true,"updated_at":"2020-12-11T18:34:06Z","created_at":"2020-12-11T18:34:06Z","default":false,"position":9999,"description":null,"actions":[{"field":"priority","value":"low"},{"field":"comment_value","value":"We're currently experiencing unusually high traffic. We'll get back to you as soon as possible."}],"restriction":null,"raw_title":"Downgrade and inform"},"emitted_at":1687861662013} -{"stream":"organizations","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/organizations/360033549136.json","id":360033549136,"name":"Airbyte","shared_tickets":true,"shared_comments":true,"external_id":null,"created_at":"2020-12-11T18:34:05Z","updated_at":"2023-04-13T14:51:21Z","domain_names":["cloud.airbyte.com"],"details":"test","notes":"test","group_id":6770788212111,"tags":["test"],"organization_fields":{"test_check_box_field_1":false,"test_drop_down_field_1":null,"test_number_field_1":null}},"emitted_at":1689066709950} -{"stream":"organizations","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/organizations/360045373216.json","id":360045373216,"name":"ressssssss","shared_tickets":false,"shared_comments":false,"external_id":null,"created_at":"2021-07-15T18:29:14Z","updated_at":"2021-07-15T18:29:14Z","domain_names":[],"details":"","notes":"","group_id":null,"tags":[],"organization_fields":{"test_check_box_field_1":false,"test_drop_down_field_1":null,"test_number_field_1":null}},"emitted_at":1689066709951} +{"stream": "organizations", "data": {"url": "https://d3v-airbyte.zendesk.com/api/v2/organizations/360033549136.json", "id": 360033549136, "name": "Airbyte", "shared_tickets": true, "shared_comments": true, "external_id": null, "created_at": "2020-12-11T18:34:05Z", "updated_at": "2023-04-13T14:51:21Z", "domain_names": ["cloud.airbyte.com"], "details": "test", "notes": "test", "group_id": 6770788212111, "tags": ["test"], "organization_fields": {"test_check_box_field_1": false, "test_drop_down_field_1": null, "test_number_field_1": null}}, "emitted_at": 1689155026459} +{"stream": "organizations", "data": {"url": "https://d3v-airbyte.zendesk.com/api/v2/organizations/360045373216.json", "id": 360045373216, "name": "ressssssss", "shared_tickets": false, "shared_comments": false, "external_id": null, "created_at": "2021-07-15T18:29:14Z", "updated_at": "2021-07-15T18:29:14Z", "domain_names": [], "details": "", "notes": "", "group_id": null, "tags": [], "organization_fields": {"test_check_box_field_1": false, "test_drop_down_field_1": null, "test_number_field_1": null}}, "emitted_at": 1689155026459} {"stream":"satisfaction_ratings","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/satisfaction_ratings/4992997209743.json","id":4992997209743,"assignee_id":null,"group_id":null,"requester_id":4992781783439,"ticket_id":121,"score":"offered","created_at":"2022-06-17T16:01:42Z","updated_at":"2022-06-17T16:01:42Z","comment":null},"emitted_at":1687861665961} {"stream":"satisfaction_ratings","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/satisfaction_ratings/4993646311567.json","id":4993646311567,"assignee_id":null,"group_id":null,"requester_id":4993467856015,"ticket_id":122,"score":"offered","created_at":"2022-06-17T21:01:41Z","updated_at":"2022-06-17T21:01:41Z","comment":null},"emitted_at":1687861665962} {"stream":"satisfaction_ratings","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/satisfaction_ratings/5138125924367.json","id":5138125924367,"assignee_id":null,"group_id":null,"requester_id":5137812260495,"ticket_id":123,"score":"offered","created_at":"2022-07-13T16:02:03Z","updated_at":"2022-07-13T16:02:03Z","comment":null},"emitted_at":1687861665962} From 537b8c44a74c8e44dda71723cfb0ffc4e838e0e8 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Wed, 12 Jul 2023 16:39:33 +0200 Subject: [PATCH 36/63] Connector builder: Extend compatibility guide (#28145) * extend comp guide * fix --- .../connector-builder-compatibility.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/connector-development/connector-builder-ui/connector-builder-compatibility.md b/docs/connector-development/connector-builder-ui/connector-builder-compatibility.md index c9fdaf5de3f8..2910f67ec445 100644 --- a/docs/connector-development/connector-builder-ui/connector-builder-compatibility.md +++ b/docs/connector-development/connector-builder-ui/connector-builder-compatibility.md @@ -1,6 +1,7 @@ # Compatibility Guide Answer the following questions to determine whether the Connector Builder is the right tool to build the connector you need: - [ ] [Is it an HTTP API returning a collection of records synchronously?](#is-the-integration-an-http-api-returning-a-collection-of-records-synchronously) +- [ ] [Are data endpoints fixed?](#are-data-endpoints-fixed) - [ ] [Is the API using one of the following authentication mechanism?](#what-type-of-authentication-is-required) - [Basic HTTP](#basic-http) - [API key injected in request header or query parameter](#api-key) @@ -79,6 +80,14 @@ Examples: If the integration is not an HTTP API returning the records synchronously, use the Python CDK. +## Are data endpoints fixed? + +The connector builder requires the data endpoints to be fixed. This means the data endpoints representing separate streams are not dynamically generated based on the data or user configuration, but specified as part of the API documentation. + +For example, the [Congress API](https://api.congress.gov/#/) specifies the data endpoints as part of the documentation, while the [Salesforce API](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_discoveryresource.htm) features a dynamic and configurable list of resources that can't be known in advance. + +If an integration has a dynamic list of data endpoints representing separate streams, use the Python CDK. + ## What type of authentication is required? Look up the authentication mechanism in the API documentation, and identify which type it is. From cb1081e6803b0215467ea50632fb2100d9a2cdf4 Mon Sep 17 00:00:00 2001 From: Christo Grabowski <108154848+ChristoGrab@users.noreply.github.com> Date: Wed, 12 Jul 2023 11:31:04 -0400 Subject: [PATCH 37/63] =?UTF-8?q?=F0=9F=93=9D=20Docs:=20update=20HubSpot?= =?UTF-8?q?=20source=20page=20(#28022)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: hubspot source page cleanup * rework setup steps * add branching paths for cloud vs oss authentication * merge engagement-screen-notes sections * move step skipping note for Cloud users to top of setup * update in-app setup steps to match docs * remove stream scopes list from inapp guide * added stream list back to inapp guide * remove sentence implying start date is optional * small touch-ups and fixes * fix typo * modify engagements note and add env-specific sections * add recommended tags to authentication methods --- docs/integrations/sources/hubspot.inapp.md | 45 ++++++--- docs/integrations/sources/hubspot.md | 105 ++++++++++++++------- 2 files changed, 106 insertions(+), 44 deletions(-) diff --git a/docs/integrations/sources/hubspot.inapp.md b/docs/integrations/sources/hubspot.inapp.md index e5efa6e57035..fdafd906607e 100644 --- a/docs/integrations/sources/hubspot.inapp.md +++ b/docs/integrations/sources/hubspot.inapp.md @@ -1,17 +1,16 @@ -## Prerequisite +## Prerequisites -* Access to your HubSpot account +- HubSpot Account +- **For Airbyte Open Source**: Private App with Access Token -## Setup guide +### Authentication method +You can use OAuth or a Private App to authenticate your HubSpot account. For Airbyte Cloud users, we highly recommend you use OAuth rather than Private App authentication, as it significantly simplifies the setup process. -1. You can use OAuth or a Private App to authenticate your HubSpot account. We recommend using OAuth for Airbyte Cloud. - * To authenticate using OAuth for Airbyte Cloud, ensure your user has the appropriate scopes for HubSpot and then click **Authenticate your HubSpot account** to sign in with HubSpot and authorize your account. - * To authenticate using a Private App, navigate to **Settings** and click **Private Apps** under Account Setup. Create a new private app and add the appropriate scopes to your private app. -2. (Optional) For **Start date**, enter the date in `YYYY-MM-DDTHH:mm:ssZ` format. The data added on and after this date will be replicated. If this field is blank, Airbyte will replicate all data. -3. Click Set up source. +For more information on which authentication method to choose and the required setup steps, see our full +[Hubspot documentation](https://docs.airbyte.com/integrations/sources/hubspot/). -## Scopes Required (for Private App) -Add the following scopes to your private app to ensure Airbyte can sync all available data. To see a breakdown of the specific scopes each stream uses, see our full [Hubspot documentation](https://docs.airbyte.com/integrations/sources/hubspot/). +### Scopes Required (for Private App and Open Source OAuth) +Unless you are authenticating via OAuth on **Airbyte Cloud**, you must manually configure scopes to ensure Airbyte can sync all available data. To see a breakdown of the specific scopes each stream uses, see our full [Hubspot documentation](https://docs.airbyte.com/integrations/sources/hubspot/). * `content` * `forms` @@ -29,8 +28,30 @@ Add the following scopes to your private app to ensure Airbyte can sync all avai * `crm.objects.owners.read` * `crm.objects.custom.read` +## Setup guide + +1. Log in to your [Airbyte Cloud](https://cloud.airbyte.com/workspaces) or Airbyte Open Source account. +2. From the Airbyte UI, click **Sources**, then click on **+ New Source** and select **HubSpot** from the list of available sources. +3. Enter a **Source name** of your choosing. +4. From the **Authentication** dropdown, select your chosen authentication method: + + +#### For Airbyte Cloud users: +- To authenticate using OAuth, select **OAuth** and click **Authenticate your HubSpot account** to sign in with HubSpot and authorize your account. +- To authenticate using a Private App, select **Private App** and enter the Access Token for your HubSpot account. + + + +#### For Airbyte Open Source users: +- To authenticate using OAuth, select **OAuth** and enter your Client ID, Client Secret, and Refresh Token. +- To authenticate using a Private App, select **Private App** and enter the Access Token for your HubSpot account. + + +5. For **Start date**, use the provided datepicker or enter the date programmatically in the following format: +`yyyy-mm-ddThh:mm:ssZ`. The data added on and after this date will be replicated. If this field is blank, Airbyte will replicate all data. +6. Click **Set up source** and wait for the tests to complete. + ## Supported Objects Airbyte supports syncing standard and custom CRM objects. Custom CRM objects will appear as streams available for sync, alongside the standard objects. - -For detailed information on supported sync modes, supported streams, performance considerations, refer to the full documentation for [Hubspot](https://docs.airbyte.com/integrations/sources/hubspot/). \ No newline at end of file +For detailed information on supported sync modes, supported streams, performance considerations, refer to the full documentation for [Hubspot](https://docs.airbyte.com/integrations/sources/hubspot/). diff --git a/docs/integrations/sources/hubspot.md b/docs/integrations/sources/hubspot.md index 12132436f809..a57858e93bcd 100644 --- a/docs/integrations/sources/hubspot.md +++ b/docs/integrations/sources/hubspot.md @@ -1,14 +1,43 @@ # HubSpot -This page guides you through setting up the HubSpot source connector. +This page contains the setup guide and reference information for the [HubSpot](https://www.hubspot.com/) source connector. -## Prerequisite +## Prerequisites -You can use OAuth or a Private App to authenticate your HubSpot account. +- HubSpot Account +- **For Airbyte Open Source**: Private App with Access Token -In Airbyte Cloud, we highly recommend you use OAuth and not Private App authentication as it significantly simplifies the setup process. +## Setup guide -If you are using either OAuth in Airbyte OSS or Private App authentication, you need to configure the appropriate [scopes](https://legacydocs.hubspot.com/docs/methods/oauth2/initiate-oauth-integration#scopes) for the following streams: +**For Airbyte Cloud** users, we highly recommend you use OAuth rather than Private App authentication, as it significantly simplifies the setup process. + +**For Airbyte Open Source** users we recommend Private App authentication. + +More information on HubSpot authentication methods can be found +[here](https://developers.hubspot.com/docs/api/intro-to-auth). + +### Step 1: Set up the authentication method + +#### Private App setup (Recommended for Airbyte Open Source) + +If you are authenticating via a Private App, you will need to use your Access Token to set up the connector. Please refer to the +[official HubSpot documentation](https://developers.hubspot.com/docs/api/private-apps) for a detailed guide. + + +#### OAuth setup for Airbyte Open Source (Not recommended) + +If you are using Oauth to authenticate on Airbyte Open Source, please refer to [Hubspot's detailed walkthrough](https://developers.hubspot.com/docs/api/working-with-oauth). To set up the connector, you will need to acquire your: + +- Client ID +- Client Secret +- Refresh Token + + + +### Step 2: Configure the scopes for your streams + +Next, you need to configure the appropriate scopes for the following streams. Please refer to +[Hubspot's page on scopes](https://legacydocs.hubspot.com/docs/methods/oauth2/initiate-oauth-integration#scopes) for instructions. | Stream | Required Scope | | :-------------------------- | :----------------------------------------------------------------------------------------------------------- | @@ -36,17 +65,29 @@ If you are using either OAuth in Airbyte OSS or Private App authentication, you | `tickets` | `tickets` | | `workflows` | `automation` | -## Set up the HubSpot source connector +### Step 3: Set up the HubSpot source connector in Airbyte -1. Log into your [Airbyte Cloud](https://cloud.airbyte.com/workspaces) or Airbyte Open Source account. -2. Click **Sources** and then click **+ New source**. -3. On the Set up the source page, select **HubSpot** from the Source type dropdown. -4. Enter a name for your source. -5. For **Start date**, enter the date in YYYY-MM-DDTHH:mm:ssZ format. The data added on and after this date will be replicated. If this field is blank, Airbyte will replicate all data. -6. You can use OAuth or an Private Apps to authenticate your HubSpot account. We recommend using OAuth for Airbyte Cloud and an Private Apps for Airbyte Open Source. - - To authenticate using OAuth for Airbyte Cloud, ensure you have [set the appropriate scopes for HubSpot](#prerequisite) and then click **Authenticate your HubSpot account** to sign in with HubSpot and authorize your account. - - To authenticate using a Private App, select **Private App** from the Authentication dropdown and enter the Access Token for your HubSpot account which you can obtain by following the instructions provided by Hubspot [here](https://developers.hubspot.com/docs/api/private-apps). -7. Click **Set up source**. +1. Log in to your [Airbyte Cloud](https://cloud.airbyte.com/workspaces) or Airbyte Open Source account. +2. From the Airbyte UI, click **Sources**, then click on **+ New Source** and select **HubSpot** from the list of available sources. +3. Enter a **Source name** of your choosing. +4. From the **Authentication** dropdown, select your chosen authentication method: + + +#### For Airbyte Cloud users: +- **Recommended:** To authenticate using OAuth, select **OAuth** and click **Authenticate your HubSpot account** to sign in with HubSpot and authorize your account. +- **Not Recommended:**To authenticate using a Private App, select **Private App** and enter the Access Token for your HubSpot account. + + + +#### For Airbyte Open Source users: +- **Recommended:** To authenticate using a Private App, select **Private App** and enter the Access Token for your HubSpot account. +- **Not Recommended:**To authenticate using OAuth, select **OAuth** and enter your Client ID, Client Secret, and Refresh Token. + + + +5. For **Start date**, use the provided datepicker or enter the date programmatically in the following format: +`yyyy-mm-ddThh:mm:ssZ`. The data added on and after this date will be replicated. +6. Click **Set up source** and wait for the tests to complete. ## Supported sync modes @@ -55,14 +96,14 @@ The HubSpot source connector supports the following [sync modes](https://docs.ai - Full Refresh - Incremental -## Supported Streams - :::note There are two types of incremental sync: 1. Incremental (standard server-side, where API returns only the data updated or generated since the last sync) 2. Client-Side Incremental (API returns all available data and connector filters out only new records) - ::: +::: + +## Supported streams The HubSpot source connector supports the following streams: @@ -100,30 +141,37 @@ The HubSpot source connector supports the following streams: Custom CRM Objects will appear as streams available for sync, alongside the standard objects listed above. -If you setup your connections before April 15th, 2023 (on Cloud) or before 0.8.0 (OSS) then you'll need to do some additional work to sync custom CRM objects. +If you set up your connections before April 15th, 2023 (on Cloud) or before 0.8.0 (OSS) then you'll need to do some additional work to sync custom CRM objects. First you need to give the connector some additional permissions: - **If you are using OAuth on Cloud** go to the Hubspot source settings page in the Airbyte UI and reauthenticate via Oauth to allow Airbyte the permissions to access custom objects. -- **If you are using OAuth on OSS or Private App auth (on OSS or Cloud)**: you'll need to go into the Hubspot UI where you created your private app or oauth application and add the `crm.objects.custom.read` scope to your app's scopes. See Hubspot's instructions here. +- **If you are using OAuth on OSS or Private App auth (on OSS or Cloud)**: you'll need to go into the Hubspot UI where you created your Private App or OAuth application and add the `crm.objects.custom.read` scope to your app's scopes. See HubSpot's instructions [here](https://developers.hubspot.com/docs/api/working-with-oauth#scopes). -Then, go to the replication settings of your connection and click “refresh source schema” to pull in those new streams for syncing. +Then, go to the replication settings of your connection and click **refresh source schema** to pull in those new streams for syncing. -### A note on the `engagements` stream - -Objects in the `engagements` stream can have one of the following types: `note`, `email`, `task`, `meeting`, `call`. Depending on the type of engagement, different properties is set for that object in the `engagements_metadata` table in the destination: +### Notes on the `engagements` stream +1. Objects in the `engagements` stream can have one of the following types: `note`, `email`, `task`, `meeting`, `call`. Depending on the type of engagement, different properties are set for that object in the `engagements_metadata` table in the destination: - A `call` engagement has a corresponding `engagements_metadata` object with non-null values in the `toNumber`, `fromNumber`, `status`, `externalId`, `durationMilliseconds`, `externalAccountId`, `recordingUrl`, `body`, and `disposition` columns. - An `email` engagement has a corresponding `engagements_metadata` object with non-null values in the `subject`, `html`, and `text` columns. In addition, there will be records in four related tables, `engagements_metadata_from`, `engagements_metadata_to`, `engagements_metadata_cc`, `engagements_metadata_bcc`. - A `meeting` engagement has a corresponding `engagements_metadata` object with non-null values in the `body`, `startTime`, `endTime`, and `title` columns. - A `note` engagement has a corresponding `engagements_metadata` object with non-null values in the `body` column. - A `task` engagement has a corresponding `engagements_metadata` object with non-null values in the `body`, `status`, and `forObjectType` columns. +2. The `engagements` stream uses two different APIs based on the length of time since the last sync and the number of records which Airbyte hasn't yet synced. +- **EngagementsRecent** if the following two criteria are met: + - The last sync was performed within the last 30 days + - Fewer than 10,000 records are being synced +- **EngagementsAll** if either of these criteria are not met. + +Because of this, the `engagements` stream can be slow to sync if it hasn't synced within the last 30 days and/or is generating large volumes of new data. We therefore recommend scheduling frequent syncs. + ## Performance considerations The connector is restricted by normal HubSpot [rate limitations](https://legacydocs.hubspot.com/apps/api_guidelines). -Some streams, such as `workflows` need to be enabled before they can be read using a connector authenticated using an `API Key`. If reading a stream that is not enabled, a log message returned to the output and the sync operation only sync the other streams available. +Some streams, such as `workflows`, need to be enabled before they can be read using a connector authenticated using an `API Key`. If reading a stream that is not enabled, a log message returned to the output and the sync operation only sync the other streams available. Example of the output message when trying to read `workflows` stream with missing permissions for the `API Key`: @@ -139,13 +187,6 @@ Example of the output message when trying to read `workflows` stream with missin HubSpot's API will [rate limit](https://developers.hubspot.com/docs/api/usage-details) the amount of records you can sync daily, so make sure that you are on the appropriate plan if you are planning on syncing more than 250,000 records per day. -### A note on the `engagements` stream -Engagements stream uses two types of API: -- EngagementsRecent if start_date/last_sync_date is less than 30 days and API is able to return all records (<10k) -- EngagementsAll which extracts all records, but supports filter on connector side - -It means that in order to perform fast incremental sync, it should be scheduled no rarer than once at 30 days and should not sync more than 10k new records. Otherwise, sync of all records is performed with filtering on connector side. - ## Tutorials Now that you have set up the Hubspot source connector, check out the following Hubspot tutorial: From a0f74e825bc1a63b8291464eff13e536c390ad55 Mon Sep 17 00:00:00 2001 From: Christo Grabowski <108154848+ChristoGrab@users.noreply.github.com> Date: Wed, 12 Jul 2023 11:31:24 -0400 Subject: [PATCH 38/63] =?UTF-8?q?=F0=9F=93=9D=20Docs:=20Files=20Source=20s?= =?UTF-8?q?etup=20steps=20update=20(#28090)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add connector setup steps * add links to Azure Blob storage guides * add instructions for azure blob * expand SSH/SCP/SFTP configuration field section * complete update of setup steps * change limited tag for local filesystem to OSS * minor fixes to file source page --- docs/integrations/sources/file.md | 145 +++++++++++++++++------------- 1 file changed, 85 insertions(+), 60 deletions(-) diff --git a/docs/integrations/sources/file.md b/docs/integrations/sources/file.md index c6edac9c0310..99ee0add09bd 100644 --- a/docs/integrations/sources/file.md +++ b/docs/integrations/sources/file.md @@ -4,72 +4,97 @@ This page contains the setup guide and reference information for the Files sourc ## Prerequisites -- URL to access the file -- Format -- Reader options -- Storage Providers +- A file hosted on AWS S3, GCS, HTTPS, or an SFTP server ## Setup guide -**For Airbyte Cloud:** - -Setup through Airbyte Cloud will be exactly the same as the open-source setup, except for the fact that local files are disabled. +**For Airbyte Cloud users:** Please note that locally stored files cannot be used as a source in Airbyte Cloud. +### Step 1: Set up the connector in Airbyte + +1. From the Airbyte UI, click the **Sources** tab, then click **+ New source** and select **Files (CSV, JSON, Excel, Feather, Parquet)** from the list of available sources. +2. Enter a **Source name** of your choosing. +3. For **Dataset Name**, enter the _name_ of the final table to replicate this file into (should include letters, numbers, dashes and underscores only). +4. For **File Format**, select the _format_ of the file to replicate from the dropdown menu (Warning: some formats may be experimental. Please refer to [the table of supported formats](#file-formats)). + +### Step 2: Select the provider and set provider-specific configurations: + +1. For **Storage Provider**, use the dropdown menu to select the _Storage Provider_ or _Location_ of the file(s) which should be replicated, then configure the provider-specific fields as needed: + +#### HTTPS: Public Web [Default] +- `User-Agent` (Optional) + +Set this to active if you want to add the [User-Agent header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) to requests (inactive by default). + +#### GCS: Google Cloud Storage +- `Service Account JSON` (Required for **private** buckets) + +To access **private** buckets stored on Google Cloud, this connector requires a service account JSON credentials file with the appropriate permissions. A detailed breakdown of this topic can be found at the [Google Cloud service accounts page](https://cloud.google.com/iam/docs/service-accounts). Please generate the "credentials.json" file and copy its content to this field, ensuring it is in JSON format. **If you are accessing publicly available data**, this field is not required. + +#### S3: Amazon Web Services +- `AWS Access Key ID` (Required for **private** buckets) +- `AWS Secret Access Key` (Required for **private** buckets) + +To access **private** buckets stored on AWS S3, this connector requires valid credentials with the necessary permissions. To access these keys, refer to the +[AWS IAM documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html). +More information on setting permissions in AWS can be found +[here](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html). **If you are accessing publicly available data**, these fields are not required. + +#### AzBlob: Azure Blob Storage +- `Storage Account` (Required) + +This is the globally unique name of the storage account that the desired blob sits within. See the [Azure documentation](https://docs.microsoft.com/en-us/azure/storage/common/storage-account-overview) for more details. + +**If you are accessing private storage**, you must also provide _one_ of the following security credentials with the necessary permissions: + +- `SAS Token`: [Find more information here](https://learn.microsoft.com/en-us/azure/storage/common/storage-sas-overview). +- `Shared Key`: [Find more information here](https://learn.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key). + +#### SSH: Secure Shell / SCP: Secure Copy Protocol / SFTP: Secure File Transfer Protocol +- `Host` (Required) + +Enter the _hostname_ or _IP address_ of the remote server where the file trasfer will take place. +- `User` (Required) + +Enter the _username_ associated with your account on the remote server. +- `Password` (Optional) + +**If required by the remote server**, enter the _password_ associated with your user account. Otherwise, leave this field blank. +- `Port` (Optional) + +Specify the _port number_ to use for the connection. The default port is usually 22. However, if your remote server uses a non-standard port, you can enter the appropriate port number here. + +#### Local Filesystem (Airbyte Open Source only) +- `Storage` + +:::caution +Currently, the local storage URL for reading must start with the local mount "/local/". +::: -**For Airbyte Open Source:** +Please note that if you are replicating data from a locally stored file on Windows OS, you will need to open the `.env` file in your local Airbyte root folder and change the values for: +- `LOCAL_ROOT` +- `LOCAL_DOCKER_MOUNT` +- `HACK_LOCAL_ROOT_PARENT` -1. Once the File Source is selected, you should define both the storage provider along its URL and format of the file. -2. Depending on the provider choice and privacy of the data, you will have to configure more options. +Please set these to an existing absolute path on your machine. Colons in the path need to be replaced with a double forward slash, `//`. `LOCAL_ROOT` & `LOCAL_DOCKER_MOUNT` should be set to the same value, and `HACK_LOCAL_ROOT_PARENT` should be set to their parent directory. -### Fields description - -- For `Dataset Name` use the _name_ of the final table to replicate this file into (should include letters, numbers dash and underscores only). -- For `File Format` use the _format_ of the file which should be replicated (Warning: some formats may be experimental, please refer to the docs). -- For `Reader Options` use a _string in JSON_ format. It depends on the chosen file format to provide additional options and tune its behavior. For example, `{}` for empty options, `{"sep": " "}` for set up separator to one space ' '. -- For `URL` use the _URL_ path to access the file which should be replicated. -- For `Storage Provider` use the _storage Provider_ or _Location_ of the file(s) which should be replicated. - - [Default] _Public Web_ - - `User-Agent` set to active if you want to add User-Agent to requests - - _GCS: Google Cloud Storage_ - - `Service Account JSON` In order to access private Buckets stored on Google Cloud, this connector would need a service account json credentials with the proper permissions as described here. Please generate the credentials.json file and copy/paste its content to this field (expecting JSON formats). If accessing publicly available data, this field is not necessary. - - _S3: Amazon Web Services_ - - `AWS Access Key ID` In order to access private Buckets stored on AWS S3, this connector would need credentials with the proper permissions. If accessing publicly available data, this field is not necessary. - - `AWS Secret Access Key`In order to access private Buckets stored on AWS S3, this connector would need credentials with the proper permissions. If accessing publicly available data, this field is not necessary. - - _AzBlob: Azure Blob Storage_ - - `Storage Account` The globally unique name of the storage account that the desired blob sits within. See here for more details. - - `SAS Token` To access Azure Blob Storage, this connector would need credentials with the proper permissions. One option is a SAS (Shared Access Signature) token. If accessing publicly available data, this field is not necessary. - - `Shared Key` To access Azure Blob Storage, this connector would need credentials with the proper permissions. One option is a storage account shared key (aka account key or access key). If accessing publicly available data, this field is not necessary. - - _SSH: Secure Shell_ - - `User` use _username_. - - `Password` use _password_. - - `Host` use a _host_. - - `Port` use a _port_ for your host. - - _SCP: Secure copy protocol_ - - `User` use _username_. - - `Password` use _password_. - - `Host` use a _host_. - - `Port` use a _port_ for your host. - - _SFTP: Secure File Transfer Protocol_ - - `User` use _username_. - - `Password` use _password_. - - `Host` use a _host_. - - `Port` use a _port_ for your host. - - _Local Filesystem (limited)_ - - `Storage` WARNING: Note that the local storage URL available for reading must start with the local mount "/local/" at the moment until we implement more advanced docker mounting options. - -#### Provider Specific Information - -- In case of Google Drive, it is necesary to use the Download URL, the format for that is `https://drive.google.com/uc?export=download&id=[DRIVE_FILE_ID]` where `[DRIVE_FILE_ID]` is the string found in the Share URL here `https://drive.google.com/file/d/[DRIVE_FILE_ID]/view?usp=sharing` -- In case of GCS, it is necessary to provide the content of the service account keyfile to access private buckets. See settings of [BigQuery Destination](../destinations/bigquery.md) -- In case of AWS S3, the pair of `aws_access_key_id` and `aws_secret_access_key` is necessary to access private S3 buckets. -- In case of AzBlob, we account for the base URL, you should only need to include the path to your file(eg. `container/file.csv`). It is also necessary to provide the `storage_account` in which the blob you want to access resides. Either `sas_token` [(info)](https://docs.microsoft.com/en-us/azure/storage/blobs/sas-service-create?tabs=dotnet) or `shared_key` [(info)](https://docs.microsoft.com/en-us/azure/storage/common/storage-account-keys-manage?tabs=azure-portal) is necessary to access private blobs. -- In case of a locally stored file on a Windows OS, it's necessary to change the values for `LOCAL_ROOT`, `LOCAL_DOCKER_MOUNT` and `HACK_LOCAL_ROOT_PARENT` in the `.env` file to an existing absolute path on your machine (colons in the path need to be replaced with a double forward slash, //). `LOCAL_ROOT` & `LOCAL_DOCKER_MOUNT` should be the same value, and `HACK_LOCAL_ROOT_PARENT` should be the parent directory of the other two. +### Step 3: Complete the connector setup +1. For **URL**, enter the _URL path_ of the file to be replicated. + +:::note +When connecting to a file located in **Google Drive**, please note that you need to utilize the Download URL format: `https://drive.google.com/uc?export=download&id=[DRIVE_FILE_ID]`. `[DRIVE_FILE_ID]` should be replaced with the unique string found in the Share URL specific to Google Drive. You can find the Share URL by visiting `https://drive.google.com/file/d/[DRIVE_FILE_ID]/view?usp=sharing`. + +When connecting to a file using **Azure Blob Storage**, please note that we account for the base URL. Therefore, you should only need to include the path to your specific file (eg `container/file.csv`). +::: + +2. For **Reader Options** (Optional), you may choose to enter a _string_ in JSON format. Depending on the file format of your source, this will provide additional options and tune the Reader's behavior. Please refer to the [next section](#reader-options) for a breakdown of the possible inputs. This field may be left blank if you do not wish to configure custom Reader options. +3. Click **Set up source** and wait for the tests to complete. ### Reader Options @@ -94,9 +119,9 @@ For example, you can use the `{"orient" : "records"}` to change how orientation If you need to read Excel Binary Workbook, please specify `excel_binary` format in `File Format` select. - :::warning - This connector does not support syncing unstructured data files such as raw text, audio, or videos. - ::: +:::caution +This connector does not support syncing unstructured data files such as raw text, audio, or videos. +::: ## Supported sync modes @@ -108,9 +133,9 @@ If you need to read Excel Binary Workbook, please specify `excel_binary` format | Replicate Folders (multiple Files) | No | | Replicate Glob Patterns (multiple Files) | No | - :::info - This source produces a single table for the target file as it replicates only one file at a time for the moment. Note that you should provide the `dataset_name` which dictates how the table will be identified in the destination (since `URL` can be made of complex characters). - ::: +:::note +This source produces a single table for the target file as it replicates only one file at a time for the moment. Note that you should provide the `dataset_name` which dictates how the table will be identified in the destination (since `URL` can be made of complex characters). +::: ## File / Stream Compression @@ -139,7 +164,7 @@ If you need to read Excel Binary Workbook, please specify `excel_binary` format | Format | Supported? | | --------------------- | ---------- | | CSV | Yes | -| JSON | Yes | +| JSON/JSONL | Yes | | HTML | No | | XML | No | | Excel | Yes | From a6d9fb01f1fd0eb4c037792fd9ee0c06b43cd07a Mon Sep 17 00:00:00 2001 From: Arsen Losenko <20901439+arsenlosenko@users.noreply.github.com> Date: Wed, 12 Jul 2023 19:26:05 +0300 Subject: [PATCH 39/63] Source Stripe: update expected records (#28201) --- .../source-stripe/integration_tests/expected_records.jsonl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/airbyte-integrations/connectors/source-stripe/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-stripe/integration_tests/expected_records.jsonl index 9f4a10cc3584..e88b03f86de1 100644 --- a/airbyte-integrations/connectors/source-stripe/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-stripe/integration_tests/expected_records.jsonl @@ -15,7 +15,7 @@ {"stream": "customer_balance_transactions", "data": {"id": "cbtxn_1MWIPLEcXtiJtvvhLnQYjVCj", "object": "customer_balance_transaction", "amount": 50000.0, "created": 1675166031, "credit_note": null, "currency": "usd", "customer": "cus_NGoTFiJFVbSsvZ", "description": "Test credit balance", "ending_balance": 50000.0, "invoice": null, "livemode": false, "metadata": {}, "type": "adjustment"}, "emitted_at": 1683202557981} {"stream": "customers", "data": {"id": "cus_LIiHR6omh14Xdg", "object": "customer", "address": {"city": "san francisco", "country": "US", "line1": "san francisco", "line2": "", "postal_code": "", "state": "CA"}, "balance": 0, "created": 1646998902, "currency": "usd", "default_currency": "usd", "default_source": "card_1MSHU1EcXtiJtvvhytSN6V54", "delinquent": false, "description": "test", "discount": null, "email": "test@airbyte_integration_test.com", "invoice_prefix": "09A6A98F", "invoice_settings": {"custom_fields": null, "default_payment_method": null, "footer": null, "rendering_options": null}, "livemode": false, "metadata": {}, "name": "Test", "next_invoice_sequence": 1, "phone": null, "preferred_locales": [], "shipping": {"address": {"city": "", "country": "US", "line1": "", "line2": "", "postal_code": "", "state": ""}, "name": "", "phone": ""}, "tax_exempt": "none", "test_clock": null}, "emitted_at": 1686177824476} {"stream": "disputes", "data": {"id": "dp_1MSI78EcXtiJtvvhxC77m2kh", "object": "dispute", "amount": 700, "balance_transaction": "txn_1MSI78EcXtiJtvvhAGjxP1UM", "balance_transactions": [{"id": "txn_1MSI78EcXtiJtvvhAGjxP1UM", "object": "balance_transaction", "amount": -700, "available_on": 1674518400, "created": 1674211590, "currency": "usd", "description": "Chargeback withdrawal for ch_3MSI77EcXtiJtvvh1GzoukUC", "exchange_rate": null, "fee": 1500, "fee_details": [{"amount": 1500, "application": null, "currency": "usd", "description": "Dispute fee", "type": "stripe_fee"}], "net": -2200, "reporting_category": "dispute", "source": "dp_1MSI78EcXtiJtvvhxC77m2kh", "status": "available", "type": "adjustment"}], "charge": "ch_3MSI77EcXtiJtvvh1GzoukUC", "created": 1674211590, "currency": "usd", "evidence": {"access_activity_log": null, "billing_address": "12345", "cancellation_policy": null, "cancellation_policy_disclosure": null, "cancellation_rebuttal": null, "customer_communication": null, "customer_email_address": null, "customer_name": null, "customer_purchase_ip": null, "customer_signature": null, "duplicate_charge_documentation": null, "duplicate_charge_explanation": null, "duplicate_charge_id": null, "product_description": null, "receipt": null, "refund_policy": null, "refund_policy_disclosure": null, "refund_refusal_explanation": null, "service_date": null, "service_documentation": null, "shipping_address": null, "shipping_carrier": null, "shipping_date": null, "shipping_documentation": null, "shipping_tracking_number": null, "uncategorized_file": null, "uncategorized_text": null}, "evidence_details": {"due_by": 1675036799.0, "has_evidence": false, "past_due": false, "submission_count": 0}, "is_charge_refundable": false, "livemode": false, "metadata": {}, "payment_intent": "pi_3MSI77EcXtiJtvvh1glmQd8s", "reason": "fraudulent", "status": "lost"}, "emitted_at": 1683202559823} -{"stream": "events", "data": {"id": "evt_1NGSfsEcXtiJtvvh9seXQITM", "object": "event", "api_version": "2020-08-27", "created": 1686168584, "data": {"object": {"id": "in_1NGReoEcXtiJtvvhZKvbLxUn", "object": "invoice", "account_country": "US", "account_name": "Airbyte, Inc.", "account_tax_ids": null, "amount_due": 600, "amount_paid": 600, "amount_remaining": 0, "amount_shipping": 0, "application": null, "application_fee_amount": null, "attempt_count": 1, "attempted": true, "auto_advance": false, "automatic_tax": {"enabled": true, "status": "complete"}, "billing_reason": "subscription_create", "charge": "ch_3NGSfpEcXtiJtvvh05excHEd", "collection_method": "charge_automatically", "created": 1686164674, "currency": "usd", "custom_fields": null, "customer": "cus_NGoTFiJFVbSsvZ", "customer_address": {"city": "", "country": "US", "line1": "Street 2, 34567", "line2": "", "postal_code": "94114", "state": "CA"}, "customer_email": "user1.sample@zohomail.eu", "customer_name": "Test Customer 2", "customer_phone": null, "customer_shipping": {"address": {"city": "", "country": "US", "line1": "Street 2, 34567", "line2": "", "postal_code": "94114", "state": "CA"}, "name": "Test Customer 2", "phone": ""}, "customer_tax_exempt": "none", "customer_tax_ids": [], "default_payment_method": null, "default_source": null, "default_tax_rates": [], "description": "Thanks for your business!", "discount": null, "discounts": [], "due_date": null, "ending_balance": 0, "footer": "Test Invoice", "from_invoice": null, "hosted_invoice_url": "https://invoice.stripe.com/i/acct_1JwnoiEcXtiJtvvh/test_YWNjdF8xSndub2lFY1h0aUp0dnZoLF9PMldpMmt5WHUxY2Vzak8xeW9HUDU0blZSclN6eFN0LDc2NzA5Mzg00200dRoOWYml?s=ap", "invoice_pdf": "https://pay.stripe.com/invoice/acct_1JwnoiEcXtiJtvvh/test_YWNjdF8xSndub2lFY1h0aUp0dnZoLF9PMldpMmt5WHUxY2Vzak8xeW9HUDU0blZSclN6eFN0LDc2NzA5Mzg00200dRoOWYml/pdf?s=ap", "last_finalization_error": null, "latest_revision": null, "lines": {"object": "list", "data": [{"id": "il_1NGReoEcXtiJtvvh3lGHUhDd", "object": "line_item", "amount": 600, "amount_excluding_tax": 600, "currency": "usd", "description": "1 \u00d7 tu (at $6.00 / month)", "discount_amounts": [], "discountable": true, "discounts": [], "livemode": false, "metadata": {}, "period": {"end": 1688756673, "start": 1686164673}, "plan": {"id": "price_1MSHZoEcXtiJtvvh6O8TYD8T", "object": "plan", "active": true, "aggregate_usage": null, "amount": 600, "amount_decimal": "600", "billing_scheme": "per_unit", "created": 1674209524, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": {}, "nickname": null, "product": "prod_NCgx1XP2IFQyKF", "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed"}, "price": {"id": "price_1MSHZoEcXtiJtvvh6O8TYD8T", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1674209524, "currency": "usd", "custom_unit_amount": null, "livemode": false, "lookup_key": null, "metadata": {}, "nickname": null, "product": "prod_NCgx1XP2IFQyKF", "recurring": {"aggregate_usage": null, "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed"}, "tax_behavior": "exclusive", "tiers_mode": null, "transform_quantity": null, "type": "recurring", "unit_amount": 600, "unit_amount_decimal": "600"}, "proration": false, "proration_details": {"credited_items": null}, "quantity": 1, "subscription": "sub_1NGReoEcXtiJtvvhq6goDeqt", "subscription_item": "si_O2WiEt5xsnTylQ", "tax_amounts": [{"amount": 0, "inclusive": false, "tax_rate": "txr_1NGRWTEcXtiJtvvhEnQVN0cr", "taxability_reason": "not_collecting", "taxable_amount": 0}], "tax_rates": [], "type": "subscription", "unit_amount_excluding_tax": "600"}], "has_more": false, "total_count": 1, "url": "/v1/invoices/in_1NGReoEcXtiJtvvhZKvbLxUn/lines"}, "livemode": false, "metadata": {}, "next_payment_attempt": null, "number": "C09C1837-0005", "on_behalf_of": null, "paid": true, "paid_out_of_band": false, "payment_intent": "pi_3NGSfpEcXtiJtvvh0gaX9CGZ", "payment_settings": {"default_mandate": null, "payment_method_options": null, "payment_method_types": null}, "period_end": 1686164673, "period_start": 1686164673, "post_payment_credit_notes_amount": 0, "pre_payment_credit_notes_amount": 0, "quote": null, "receipt_number": null, "rendering_options": null, "shipping_cost": null, "shipping_details": null, "starting_balance": 0, "statement_descriptor": null, "status": "paid", "status_transitions": {"finalized_at": 1686168580, "marked_uncollectible_at": null, "paid_at": 1686168580, "voided_at": null}, "subscription": "sub_1NGReoEcXtiJtvvhq6goDeqt", "subtotal": 600, "subtotal_excluding_tax": 600, "tax": 0, "test_clock": null, "total": 600, "total_discount_amounts": [], "total_excluding_tax": 600, "total_tax_amounts": [{"amount": 0, "inclusive": false, "tax_rate": "txr_1NGRWTEcXtiJtvvhEnQVN0cr", "taxability_reason": "not_collecting", "taxable_amount": 0}], "transfer_data": null, "webhooks_delivered_at": 1686164674}}, "livemode": false, "pending_webhooks": 0, "request": {"id": null, "idempotency_key": null}, "type": "invoice.finalized"}, "emitted_at": 1686178308889} +{"stream": "events", "data": {"id": "evt_1NSrYfEcXtiJtvvhoo4M4yDP", "object": "event", "api_version": "2020-08-27", "created": 1689124173, "data": {"object": {"object": "balance", "available": [{"amount": 513474, "currency": "usd", "source_types": {"card": 513474}}], "connect_reserved": [{"amount": 0, "currency": "usd"}], "issuing": {"available": [{"amount": 150000, "currency": "usd"}]}, "livemode": false, "pending": [{"amount": 0, "currency": "usd", "source_types": {"card": 0}}]}}, "livemode": false, "pending_webhooks": 0, "request": {"id": null, "idempotency_key": null}, "type": "balance.available"}, "emitted_at": 1689154783946} {"stream": "invoice_items", "data": {"id": "ii_1K9GKLEcXtiJtvvhmr2AYOAx", "object": "invoiceitem", "amount": 8400, "currency": "usd", "customer": "cus_Kou8knsO3qQOwU", "date": 1640123817, "description": "a box of parsnips", "discountable": true, "discounts": [], "invoice": "in_1K9GK0EcXtiJtvvhSo2LvGqT", "livemode": false, "metadata": {}, "period": {"end": 1640123817.0, "start": 1640123817}, "plan": null, "price": {"id": "price_1K9GKLEcXtiJtvvhXbrg33lq", "object": "price", "active": false, "billing_scheme": "per_unit", "created": 1640123817, "currency": "usd", "custom_unit_amount": null, "livemode": false, "lookup_key": null, "metadata": {}, "nickname": null, "product": "prod_Kou8cQxtIpF1p7", "recurring": null, "tax_behavior": "unspecified", "tiers_mode": null, "transform_quantity": null, "type": "one_time", "unit_amount": 8400, "unit_amount_decimal": "8400"}, "proration": false, "quantity": 1, "subscription": null, "tax_rates": [], "test_clock": null, "unit_amount": 8400, "unit_amount_decimal": "8400"}, "emitted_at": 1683202562589} {"stream": "invoice_items", "data": {"id": "ii_1MX384EcXtiJtvvhguyn3iYb", "object": "invoiceitem", "amount": 6000, "currency": "usd", "customer": "cus_NGoTFiJFVbSsvZ", "date": 1675345628, "description": "Test Product 1", "discountable": true, "discounts": ["di_1MX384EcXtiJtvvhkOrY57Ep"], "invoice": "in_1MX37hEcXtiJtvvhRSl1KbQm", "livemode": false, "metadata": {}, "period": {"end": 1675345628.0, "start": 1675345628}, "plan": null, "price": {"id": "price_1MX364EcXtiJtvvhE3WgTl4O", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1675345504, "currency": "usd", "custom_unit_amount": null, "livemode": false, "lookup_key": null, "metadata": {}, "nickname": null, "product": "prod_NHcKselSHfKdfc", "recurring": null, "tax_behavior": "exclusive", "tiers_mode": null, "transform_quantity": null, "type": "one_time", "unit_amount": 2000, "unit_amount_decimal": "2000"}, "proration": false, "quantity": 3, "subscription": null, "tax_rates": [], "test_clock": null, "unit_amount": 2000, "unit_amount_decimal": "2000"}, "emitted_at": 1683202562845} {"stream": "invoice_items", "data": {"id": "ii_1MX2yfEcXtiJtvvhfhyOG7SP", "object": "invoiceitem", "amount": 25200, "currency": "usd", "customer": "cus_NGoTFiJFVbSsvZ", "date": 1675345045, "description": "edgao-test-product", "discountable": true, "discounts": ["di_1MX2ysEcXtiJtvvh8ORqRVKm"], "invoice": "in_1MX2yFEcXtiJtvvhMXhUCgKx", "livemode": false, "metadata": {}, "period": {"end": 1675345045.0, "start": 1675345045}, "plan": null, "price": {"id": "price_1K9GbqEcXtiJtvvhJ3lZe4i5", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1640124902, "currency": "usd", "custom_unit_amount": null, "livemode": false, "lookup_key": null, "metadata": {}, "nickname": null, "product": "prod_KouQ5ez86yREmB", "recurring": null, "tax_behavior": "inclusive", "tiers_mode": null, "transform_quantity": null, "type": "one_time", "unit_amount": 12600, "unit_amount_decimal": "12600"}, "proration": false, "quantity": 2, "subscription": null, "tax_rates": [], "test_clock": null, "unit_amount": 12600, "unit_amount_decimal": "12600"}, "emitted_at": 1683202562846} @@ -35,7 +35,7 @@ {"stream": "promotion_codes", "data": {"id": "promo_1MVtmkEcXtiJtvvht0RA3MKg", "object": "promotion_code", "active": true, "code": "FRIENDS20", "coupon": {"id": "iJ6qlwM5", "object": "coupon", "amount_off": null, "created": 1674208993, "currency": null, "duration": "forever", "duration_in_months": null, "livemode": false, "max_redemptions": null, "metadata": {}, "name": "\u0415\u0443\u0456\u0435", "percent_off": 10.0, "redeem_by": null, "times_redeemed": 3, "valid": true}, "created": 1675071382, "customer": null, "expires_at": null, "livemode": false, "max_redemptions": null, "metadata": {}, "restrictions": {"first_time_transaction": true, "minimum_amount": 10000, "minimum_amount_currency": "usd"}, "times_redeemed": 0}, "emitted_at": 1683202575239} {"stream": "refunds", "data": {"id": "re_3MVuZyEcXtiJtvvh0A6rSbeJ", "object": "refund", "amount": 200000, "balance_transaction": "txn_3MVuZyEcXtiJtvvh0v0QyAMx", "charge": "ch_3MVuZyEcXtiJtvvh0tiVC7DI", "created": 1675074488, "currency": "usd", "metadata": {}, "payment_intent": "pi_3MVuZyEcXtiJtvvh07Ehi4cx", "reason": "fraudulent", "receipt_number": "3278-5368", "source_transfer_reversal": null, "status": "succeeded", "transfer_reversal": null}, "emitted_at": 1683202576655} {"stream": "subscription_items", "data": {"id": "si_O2WiEt5xsnTylQ", "object": "subscription_item", "billing_thresholds": null, "created": 1686164674, "metadata": {}, "plan": {"id": "price_1MSHZoEcXtiJtvvh6O8TYD8T", "object": "plan", "active": true, "aggregate_usage": null, "amount": 600, "amount_decimal": "600", "billing_scheme": "per_unit", "created": 1674209524, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": {}, "nickname": null, "product": "prod_NCgx1XP2IFQyKF", "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed"}, "price": {"id": "price_1MSHZoEcXtiJtvvh6O8TYD8T", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1674209524, "currency": "usd", "custom_unit_amount": null, "livemode": false, "lookup_key": null, "metadata": {}, "nickname": null, "product": "prod_NCgx1XP2IFQyKF", "recurring": {"aggregate_usage": null, "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed"}, "tax_behavior": "exclusive", "tiers_mode": null, "transform_quantity": null, "type": "recurring", "unit_amount": 600, "unit_amount_decimal": "600"}, "quantity": 1, "subscription": "sub_1NGReoEcXtiJtvvhq6goDeqt", "tax_rates": []}, "emitted_at": 1686178607748} -{"stream": "subscriptions", "data": {"id": "sub_1NGReoEcXtiJtvvhq6goDeqt", "object": "subscription", "application": null, "application_fee_percent": null, "automatic_tax": {"enabled": true}, "billing_cycle_anchor": 1686164673.0, "billing_thresholds": null, "cancel_at": null, "cancel_at_period_end": false, "canceled_at": null, "cancellation_details": {"comment": null, "feedback": null, "reason": null}, "collection_method": "charge_automatically", "created": 1686164673, "currency": "usd", "current_period_end": 1688756673.0, "current_period_start": 1686164673, "customer": "cus_NGoTFiJFVbSsvZ", "days_until_due": null, "default_payment_method": null, "default_source": null, "default_tax_rates": [], "description": null, "discount": null, "ended_at": null, "items": {"object": "list", "data": [{"id": "si_O2WiEt5xsnTylQ", "object": "subscription_item", "billing_thresholds": null, "created": 1686164674, "metadata": {}, "plan": {"id": "price_1MSHZoEcXtiJtvvh6O8TYD8T", "object": "plan", "active": true, "aggregate_usage": null, "amount": 600, "amount_decimal": "600", "billing_scheme": "per_unit", "created": 1674209524, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": {}, "nickname": null, "product": "prod_NCgx1XP2IFQyKF", "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed"}, "price": {"id": "price_1MSHZoEcXtiJtvvh6O8TYD8T", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1674209524, "currency": "usd", "custom_unit_amount": null, "livemode": false, "lookup_key": null, "metadata": {}, "nickname": null, "product": "prod_NCgx1XP2IFQyKF", "recurring": {"aggregate_usage": null, "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed"}, "tax_behavior": "exclusive", "tiers_mode": null, "transform_quantity": null, "type": "recurring", "unit_amount": 600, "unit_amount_decimal": "600"}, "quantity": 1, "subscription": "sub_1NGReoEcXtiJtvvhq6goDeqt", "tax_rates": []}], "has_more": false, "total_count": 1.0, "url": "/v1/subscription_items?subscription=sub_1NGReoEcXtiJtvvhq6goDeqt"}, "latest_invoice": "in_1NGReoEcXtiJtvvhZKvbLxUn", "livemode": false, "metadata": {}, "next_pending_invoice_item_invoice": null, "on_behalf_of": null, "pause_collection": null, "payment_settings": {"payment_method_options": null, "payment_method_types": null, "save_default_payment_method": null}, "pending_invoice_item_interval": null, "pending_setup_intent": null, "pending_update": null, "plan": {"id": "price_1MSHZoEcXtiJtvvh6O8TYD8T", "object": "plan", "active": true, "aggregate_usage": null, "amount": 600, "amount_decimal": "600", "billing_scheme": "per_unit", "created": 1674209524, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": {}, "nickname": null, "product": "prod_NCgx1XP2IFQyKF", "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed"}, "quantity": 1, "schedule": "sub_sched_1NGRenEcXtiJtvvhmM4eGaJN", "start_date": 1686164673, "status": "active", "test_clock": null, "transfer_data": null, "trial_end": null, "trial_settings": {"end_behavior": {"missing_payment_method": "create_invoice"}}, "trial_start": null}, "emitted_at": 1686178604597} +{"stream": "subscriptions", "data": {"id": "sub_1NGReoEcXtiJtvvhq6goDeqt", "object": "subscription", "application": null, "application_fee_percent": null, "automatic_tax": {"enabled": true}, "billing_cycle_anchor": 1686164673.0, "billing_thresholds": null, "cancel_at": null, "cancel_at_period_end": false, "canceled_at": null, "cancellation_details": {"comment": null, "feedback": null, "reason": null}, "collection_method": "charge_automatically", "created": 1686164673, "currency": "usd", "current_period_end": 1691435073.0, "current_period_start": 1688756673, "customer": "cus_NGoTFiJFVbSsvZ", "days_until_due": null, "default_payment_method": null, "default_source": null, "default_tax_rates": [], "description": null, "discount": null, "ended_at": null, "items": {"object": "list", "data": [{"id": "si_O2WiEt5xsnTylQ", "object": "subscription_item", "billing_thresholds": null, "created": 1686164674, "metadata": {}, "plan": {"id": "price_1MSHZoEcXtiJtvvh6O8TYD8T", "object": "plan", "active": true, "aggregate_usage": null, "amount": 600, "amount_decimal": "600", "billing_scheme": "per_unit", "created": 1674209524, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": {}, "nickname": null, "product": "prod_NCgx1XP2IFQyKF", "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed"}, "price": {"id": "price_1MSHZoEcXtiJtvvh6O8TYD8T", "object": "price", "active": true, "billing_scheme": "per_unit", "created": 1674209524, "currency": "usd", "custom_unit_amount": null, "livemode": false, "lookup_key": null, "metadata": {}, "nickname": null, "product": "prod_NCgx1XP2IFQyKF", "recurring": {"aggregate_usage": null, "interval": "month", "interval_count": 1, "trial_period_days": null, "usage_type": "licensed"}, "tax_behavior": "exclusive", "tiers_mode": null, "transform_quantity": null, "type": "recurring", "unit_amount": 600, "unit_amount_decimal": "600"}, "quantity": 1, "subscription": "sub_1NGReoEcXtiJtvvhq6goDeqt", "tax_rates": []}], "has_more": false, "total_count": 1.0, "url": "/v1/subscription_items?subscription=sub_1NGReoEcXtiJtvvhq6goDeqt"}, "latest_invoice": "in_1NRJxMEcXtiJtvvhbs8xdP68", "livemode": false, "metadata": {}, "next_pending_invoice_item_invoice": null, "on_behalf_of": null, "pause_collection": null, "payment_settings": {"payment_method_options": null, "payment_method_types": null, "save_default_payment_method": null}, "pending_invoice_item_interval": null, "pending_setup_intent": null, "pending_update": null, "plan": {"id": "price_1MSHZoEcXtiJtvvh6O8TYD8T", "object": "plan", "active": true, "aggregate_usage": null, "amount": 600, "amount_decimal": "600", "billing_scheme": "per_unit", "created": 1674209524, "currency": "usd", "interval": "month", "interval_count": 1, "livemode": false, "metadata": {}, "nickname": null, "product": "prod_NCgx1XP2IFQyKF", "tiers_mode": null, "transform_usage": null, "trial_period_days": null, "usage_type": "licensed"}, "quantity": 1, "schedule": "sub_sched_1NGRenEcXtiJtvvhmM4eGaJN", "start_date": 1686164673, "status": "active", "test_clock": null, "transfer_data": null, "trial_end": null, "trial_settings": {"end_behavior": {"missing_payment_method": "create_invoice"}}, "trial_start": null}, "emitted_at": 1689156254766} {"stream": "subscription_schedule", "data": {"id": "sub_sched_1NGRenEcXtiJtvvhmM4eGaJN", "object": "subscription_schedule", "application": null, "canceled_at": null, "completed_at": null, "created": 1686164673, "current_phase": {"end_date": 1717787073, "start_date": 1686164673}, "customer": "cus_NGoTFiJFVbSsvZ", "default_settings": {"application_fee_percent": null, "automatic_tax": {"enabled": false}, "billing_cycle_anchor": "automatic", "billing_thresholds": null, "collection_method": "charge_automatically", "default_payment_method": null, "default_source": null, "description": null, "invoice_settings": null, "on_behalf_of": null, "transfer_data": null}, "end_behavior": "cancel", "livemode": false, "metadata": {}, "phases": [{"add_invoice_items": [], "application_fee_percent": null, "automatic_tax": {"enabled": true}, "billing_cycle_anchor": null, "billing_thresholds": null, "collection_method": null, "coupon": null, "currency": "usd", "default_payment_method": null, "default_tax_rates": [], "description": null, "end_date": 1717787073, "invoice_settings": "{'days_until_due': None}", "items": [{"billing_thresholds": null, "metadata": {}, "plan": "price_1MSHZoEcXtiJtvvh6O8TYD8T", "price": "price_1MSHZoEcXtiJtvvh6O8TYD8T", "quantity": 1, "tax_rates": []}], "metadata": {}, "on_behalf_of": null, "proration_behavior": "create_prorations", "start_date": 1686164673, "transfer_data": null, "trial_end": null}, {"add_invoice_items": [], "application_fee_percent": null, "automatic_tax": {"enabled": true}, "billing_cycle_anchor": null, "billing_thresholds": null, "collection_method": null, "coupon": null, "currency": "usd", "default_payment_method": null, "default_tax_rates": [], "description": null, "end_date": 1749323073, "invoice_settings": "{'days_until_due': None}", "items": [{"billing_thresholds": null, "metadata": {}, "plan": "price_1MSHZoEcXtiJtvvh6O8TYD8T", "price": "price_1MSHZoEcXtiJtvvh6O8TYD8T", "quantity": 1, "tax_rates": []}], "metadata": {}, "on_behalf_of": null, "proration_behavior": "create_prorations", "start_date": 1717787073, "transfer_data": null, "trial_end": null}], "released_at": null, "released_subscription": null, "renewal_interval": null, "status": "active", "subscription": "sub_1NGReoEcXtiJtvvhq6goDeqt", "test_clock": null}, "emitted_at": 1686178609921} {"stream": "setup_intents", "data": {"id": "seti_1KnfIjEcXtiJtvvhPw5znVKY", "object": "setup_intent", "application": null, "automatic_payment_methods": null, "cancellation_reason": null, "client_secret": "seti_1KnfIjEcXtiJtvvhPw5znVKY_secret_LUebPsqMz6AF4ivxIg4LMaAT0OdZF5L", "created": 1649752937, "customer": null, "description": null, "flow_directions": null, "last_setup_error": null, "latest_attempt": "setatt_1KnfIjEcXtiJtvvhqDfSlpM4", "livemode": false, "mandate": null, "metadata": {}, "next_action": null, "on_behalf_of": null, "payment_method": "pm_1KnfIj2eZvKYlo2CAlv2Vhqc", "payment_method_options": {"acss_debit": {"currency": "cad", "mandate_options": {"interval_description": "First day of every month", "payment_schedule": "interval", "transaction_type": "personal"}, "verification_method": "automatic"}}, "payment_method_types": ["acss_debit"], "single_use_mandate": null, "status": "succeeded", "usage": "off_session"}, "emitted_at": 1683202583460} {"stream": "setup_intents", "data": {"id": "seti_1KnfIcEcXtiJtvvh61qlCaDf", "object": "setup_intent", "application": null, "automatic_payment_methods": null, "cancellation_reason": null, "client_secret": "seti_1KnfIcEcXtiJtvvh61qlCaDf_secret_LUebcbyw8V1e8Pxk3aAjzDXMOXdFMCe", "created": 1649752930, "customer": null, "description": null, "flow_directions": null, "last_setup_error": null, "latest_attempt": "setatt_1KnfIdEcXtiJtvvhpDrYVlRP", "livemode": false, "mandate": null, "metadata": {}, "next_action": null, "on_behalf_of": null, "payment_method": "pm_1KnfIc2eZvKYlo2Civ7snSPy", "payment_method_options": {"acss_debit": {"currency": "cad", "mandate_options": {"interval_description": "First day of every month", "payment_schedule": "interval", "transaction_type": "personal"}, "verification_method": "automatic"}}, "payment_method_types": ["acss_debit"], "single_use_mandate": null, "status": "succeeded", "usage": "off_session"}, "emitted_at": 1683202583461} From ead6bcfbea4cc7e75d92a2a432349899dcc9f413 Mon Sep 17 00:00:00 2001 From: Arsen Losenko <20901439+arsenlosenko@users.noreply.github.com> Date: Wed, 12 Jul 2023 19:27:47 +0300 Subject: [PATCH 40/63] =?UTF-8?q?=F0=9F=90=9B=20Source=20Twilio:=20update?= =?UTF-8?q?=20expected=20records=20(#28216)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Source Twilio: update expected records * Add channel_metadata property to stream conversation_messages --- airbyte-integrations/connectors/source-twilio/Dockerfile | 2 +- .../source-twilio/integration_tests/expected_records.jsonl | 2 +- airbyte-integrations/connectors/source-twilio/metadata.yaml | 2 +- .../source_twilio/schemas/conversation_messages.json | 3 +++ docs/integrations/sources/twilio.md | 1 + 5 files changed, 7 insertions(+), 3 deletions(-) diff --git a/airbyte-integrations/connectors/source-twilio/Dockerfile b/airbyte-integrations/connectors/source-twilio/Dockerfile index c68528ba082f..da9ca91b6d97 100644 --- a/airbyte-integrations/connectors/source-twilio/Dockerfile +++ b/airbyte-integrations/connectors/source-twilio/Dockerfile @@ -12,5 +12,5 @@ COPY main.py ./ ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=0.8.0 +LABEL io.airbyte.version=0.8.1 LABEL io.airbyte.name=airbyte/source-twilio diff --git a/airbyte-integrations/connectors/source-twilio/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-twilio/integration_tests/expected_records.jsonl index cadc1b1fe052..18f35c457489 100644 --- a/airbyte-integrations/connectors/source-twilio/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-twilio/integration_tests/expected_records.jsonl @@ -20,7 +20,7 @@ {"stream": "conferences", "data": {"status": "completed", "reason_conference_ended": "last-participant-left", "date_updated": "2023-03-15T11:46:39Z", "region": "us1", "friendly_name": "EH85d42ab639efdcbdbe8da21f798d00af", "uri": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Conferences/CF00e87d952b927f55f6abb3f9d9a1b91c.json", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "call_sid_ending_conference": "CA7b08148666a4d91a2cbfa335b92ddf5c", "sid": "CF00e87d952b927f55f6abb3f9d9a1b91c", "date_created": "2023-03-15T11:46:08Z", "api_version": "2010-04-01", "subresource_uris": {"participants": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Conferences/CF00e87d952b927f55f6abb3f9d9a1b91c/Participants.json", "recordings": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Conferences/CF00e87d952b927f55f6abb3f9d9a1b91c/Recordings.json"}}, "emitted_at": 1682602861809} {"stream": "conferences", "data": {"status": "completed", "reason_conference_ended": "last-participant-left", "date_updated": "2023-04-03T20:04:23Z", "region": "us1", "friendly_name": "Conference2", "uri": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Conferences/CFc9ece7e3f80f85e05a61c69faee62a2a.json", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "call_sid_ending_conference": "CAd6d69b48d5dd857fc0c8640234e3f6fc", "sid": "CFc9ece7e3f80f85e05a61c69faee62a2a", "date_created": "2023-04-03T20:03:52Z", "api_version": "2010-04-01", "subresource_uris": {"participants": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Conferences/CFc9ece7e3f80f85e05a61c69faee62a2a/Participants.json", "recordings": "/2010-04-01/Accounts/ACdade166c12e160e9ed0a6088226718fb/Conferences/CFc9ece7e3f80f85e05a61c69faee62a2a/Recordings.json"}}, "emitted_at": 1682602861810} {"stream": "conversations", "data": {"unique_name": null, "date_updated": "2023-03-21T13:39:44Z", "friendly_name": "Friendly Conversation", "timers": {}, "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "url": "https://conversations.twilio.com/v1/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e", "state": "active", "date_created": "2023-03-21T13:39:44Z", "messaging_service_sid": "MGfdf707ca9a7e03496ad79dc64e5e543e", "sid": "CH0ed7b4c3498e455a96fa09fcccee720e", "attributes": "{}", "bindings": null, "chat_service_sid": "IS5fcc074f7ead44c99a0a24a374a7e19f", "links": {"participants": "https://conversations.twilio.com/v1/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e/Participants", "messages": "https://conversations.twilio.com/v1/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e/Messages", "webhooks": "https://conversations.twilio.com/v1/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e/Webhooks"}}, "emitted_at": 1682602862574} -{"stream": "conversation_messages", "data": {"body": "Ahoy there", "index": 0, "author": "smee", "date_updated": "2023-04-01T12:37:19Z", "media": null, "participant_sid": null, "conversation_sid": "CH0ed7b4c3498e455a96fa09fcccee720e", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "delivery": null, "url": "https://conversations.twilio.com/v1/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e/Messages/IMd28bbec7d60f4c9b84595170871c6f28", "date_created": "2023-04-01T12:37:19Z", "content_sid": null, "sid": "IMd28bbec7d60f4c9b84595170871c6f28", "attributes": "{}", "links": {"delivery_receipts": "https://conversations.twilio.com/v1/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e/Messages/IMd28bbec7d60f4c9b84595170871c6f28/Receipts"}}, "emitted_at": 1682602863760} +{"stream": "conversation_messages", "data": {"body": "Ahoy there", "index": 0, "author": "smee", "date_updated": "2023-04-01T12:37:19Z", "media": null, "participant_sid": null, "conversation_sid": "CH0ed7b4c3498e455a96fa09fcccee720e", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "delivery": null, "url": "https://conversations.twilio.com/v1/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e/Messages/IMd28bbec7d60f4c9b84595170871c6f28", "date_created": "2023-04-01T12:37:19Z", "content_sid": null, "sid": "IMd28bbec7d60f4c9b84595170871c6f28", "attributes": "{}", "links": {"delivery_receipts": "https://conversations.twilio.com/v1/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e/Messages/IMd28bbec7d60f4c9b84595170871c6f28/Receipts", "channel_metadata": "https://conversations.twilio.com/v1/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e/Messages/IMd28bbec7d60f4c9b84595170871c6f28/ChannelMetadata"}}, "emitted_at": 1689154923233} {"stream": "conversation_participants", "data": {"last_read_message_index": null, "date_updated": "2023-04-13T11:52:17Z", "last_read_timestamp": null, "conversation_sid": "CH0ed7b4c3498e455a96fa09fcccee720e", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "url": "https://conversations.twilio.com/v1/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e/Participants/MB0a984a4238f14b828cf277becf880bd4", "date_created": "2023-04-13T11:52:17Z", "role_sid": "RLca3ff6cb9bc9404caf14e43b63fed446", "sid": "MB0a984a4238f14b828cf277becf880bd4", "attributes": "{}", "identity": "Integration Test 2", "messaging_binding": null}, "emitted_at": 1682602864970} {"stream": "conversation_participants", "data": {"last_read_message_index": null, "date_updated": "2023-04-13T11:52:02Z", "last_read_timestamp": null, "conversation_sid": "CH0ed7b4c3498e455a96fa09fcccee720e", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "url": "https://conversations.twilio.com/v1/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e/Participants/MB41bb002a3a5e412fa7f2459dcfb4925f", "date_created": "2023-04-13T11:52:02Z", "role_sid": "RLca3ff6cb9bc9404caf14e43b63fed446", "sid": "MB41bb002a3a5e412fa7f2459dcfb4925f", "attributes": "{}", "identity": "Integration Test", "messaging_binding": null}, "emitted_at": 1682602864972} {"stream":"flows","data":{"status":"published","date_updated":"2022-09-23T14:31:33Z","friendly_name":"conference_test","account_sid":"ACdade166c12e160e9ed0a6088226718fb","url":"https://studio.twilio.com/v1/Flows/FW7ad717a690629a6da33bd3c8b9cf7d97","version":15,"sid":"FW7ad717a690629a6da33bd3c8b9cf7d97","date_created":"2022-09-23T14:28:11Z","links":{"engagements":"https://studio.twilio.com/v1/Flows/FW7ad717a690629a6da33bd3c8b9cf7d97/Engagements","executions":"https://studio.twilio.com/v1/Flows/FW7ad717a690629a6da33bd3c8b9cf7d97/Executions"}},"emitted_at":1687780616829} diff --git a/airbyte-integrations/connectors/source-twilio/metadata.yaml b/airbyte-integrations/connectors/source-twilio/metadata.yaml index 36d6c2b42730..1c4f1646d71f 100644 --- a/airbyte-integrations/connectors/source-twilio/metadata.yaml +++ b/airbyte-integrations/connectors/source-twilio/metadata.yaml @@ -8,7 +8,7 @@ data: connectorSubtype: api connectorType: source definitionId: b9dc6155-672e-42ea-b10d-9f1f1fb95ab1 - dockerImageTag: 0.8.0 + dockerImageTag: 0.8.1 dockerRepository: airbyte/source-twilio githubIssueLabel: source-twilio icon: twilio.svg diff --git a/airbyte-integrations/connectors/source-twilio/source_twilio/schemas/conversation_messages.json b/airbyte-integrations/connectors/source-twilio/source_twilio/schemas/conversation_messages.json index 3631be2fb9ff..478a3d47b38f 100644 --- a/airbyte-integrations/connectors/source-twilio/source_twilio/schemas/conversation_messages.json +++ b/airbyte-integrations/connectors/source-twilio/source_twilio/schemas/conversation_messages.json @@ -89,6 +89,9 @@ "properties": { "delivery_receipts": { "type": ["null", "string"] + }, + "channel_metadata": { + "type": ["null", "string"] } } } diff --git a/docs/integrations/sources/twilio.md b/docs/integrations/sources/twilio.md index 2a309c62e5df..e2b3d9a578c6 100644 --- a/docs/integrations/sources/twilio.md +++ b/docs/integrations/sources/twilio.md @@ -92,6 +92,7 @@ For more information, see [the Twilio docs for rate limitations](https://support | Version | Date | Pull Request | Subject | |:--------|:-----------|:----------------------------------------------------------|:--------------------------------------------------------------------------------------------------------| +| 0.8.1 | 2023-07-12 | [28216](https://github.com/airbytehq/airbyte/pull/28216) | Add property `channel_metadata` to `ConversationMessages` schema | | 0.8.0 | 2023-06-11 | [*****](https://github.com/airbytehq/airbyte/pull/*****) | Add new stream `VerifyServices` | | 0.7.0 | 2023-05-03 | [25781](https://github.com/airbytehq/airbyte/pull/25781) | Add new stream `Trunks` | | 0.6.0 | 2023-05-03 | [25783](https://github.com/airbytehq/airbyte/pull/25783) | Add new stream `Roles` with parent `Services` | From 6792753b8688523c9aef42948d37bef82b144fc0 Mon Sep 17 00:00:00 2001 From: btkcodedev Date: Wed, 12 Jul 2023 22:18:20 +0530 Subject: [PATCH 41/63] =?UTF-8?q?=E2=9C=A8=20New=20Source:=20Gainsight-px?= =?UTF-8?q?=20[Low=20Code=20CDK]=20(#26998)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial commit * Update source_definitions.yaml * Update source_specs.yaml * change manifest * fix manifest * fix schema * fix conflict * fix conflict * fix schema, refactor manifest, add new streams * add streams to docs * add stream users * add new stream survey_response * update docs * EOF, formatting * Add new stream, Update docs * Add new streams * Refactor Schemas * Change gainsight to gainsight-px * Add spec * Change spec * rewrite spec * Fix Schemas, metadata * Add pagination, fix schemas * Add icon * Update gainsight-px.md * Update supportUrl to documentationUrl Co-authored-by: Mal Hancock * Rename to icon.svg * fix metedata.yaml --------- Co-authored-by: Mal Hancock --- .../source-gainsight-px/.dockerignore | 6 + .../connectors/source-gainsight-px/Dockerfile | 38 ++++ .../connectors/source-gainsight-px/README.md | 82 ++++++++ .../source-gainsight-px/__init__.py | 3 + .../acceptance-test-config.yml | 51 +++++ .../acceptance-test-docker.sh | 3 + .../source-gainsight-px/build.gradle | 9 + .../connectors/source-gainsight-px/icon.svg | 1 + .../integration_tests/__init__.py | 3 + .../integration_tests/abnormal_state.json | 5 + .../integration_tests/acceptance.py | 16 ++ .../integration_tests/configured_catalog.json | 76 ++++++++ .../integration_tests/invalid_config.json | 3 + .../integration_tests/sample_config.json | 3 + .../connectors/source-gainsight-px/main.py | 13 ++ .../source-gainsight-px/metadata.yaml | 22 +++ .../source-gainsight-px/requirements.txt | 2 + .../connectors/source-gainsight-px/setup.py | 29 +++ .../source_gainsight_px/__init__.py | 8 + .../source_gainsight_px/manifest.yaml | 150 +++++++++++++++ .../source_gainsight_px/schemas/accounts.json | 71 +++++++ .../schemas/admin_attributes.json | 41 ++++ .../source_gainsight_px/schemas/articles.json | 62 +++++++ .../source_gainsight_px/schemas/feature.json | 43 +++++ .../source_gainsight_px/schemas/kcbot.json | 65 +++++++ .../source_gainsight_px/schemas/segments.json | 14 ++ .../schemas/user_attributes.json | 41 ++++ .../source_gainsight_px/schemas/users.json | 175 ++++++++++++++++++ .../source_gainsight_px/source.py | 18 ++ .../source_gainsight_px/spec.yaml | 14 ++ docs/integrations/sources/gainsight-px.md | 74 ++++++++ 31 files changed, 1141 insertions(+) create mode 100644 airbyte-integrations/connectors/source-gainsight-px/.dockerignore create mode 100644 airbyte-integrations/connectors/source-gainsight-px/Dockerfile create mode 100644 airbyte-integrations/connectors/source-gainsight-px/README.md create mode 100644 airbyte-integrations/connectors/source-gainsight-px/__init__.py create mode 100644 airbyte-integrations/connectors/source-gainsight-px/acceptance-test-config.yml create mode 100755 airbyte-integrations/connectors/source-gainsight-px/acceptance-test-docker.sh create mode 100644 airbyte-integrations/connectors/source-gainsight-px/build.gradle create mode 100644 airbyte-integrations/connectors/source-gainsight-px/icon.svg create mode 100644 airbyte-integrations/connectors/source-gainsight-px/integration_tests/__init__.py create mode 100644 airbyte-integrations/connectors/source-gainsight-px/integration_tests/abnormal_state.json create mode 100644 airbyte-integrations/connectors/source-gainsight-px/integration_tests/acceptance.py create mode 100644 airbyte-integrations/connectors/source-gainsight-px/integration_tests/configured_catalog.json create mode 100644 airbyte-integrations/connectors/source-gainsight-px/integration_tests/invalid_config.json create mode 100644 airbyte-integrations/connectors/source-gainsight-px/integration_tests/sample_config.json create mode 100644 airbyte-integrations/connectors/source-gainsight-px/main.py create mode 100644 airbyte-integrations/connectors/source-gainsight-px/metadata.yaml create mode 100644 airbyte-integrations/connectors/source-gainsight-px/requirements.txt create mode 100644 airbyte-integrations/connectors/source-gainsight-px/setup.py create mode 100644 airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/__init__.py create mode 100644 airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/manifest.yaml create mode 100644 airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/accounts.json create mode 100644 airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/admin_attributes.json create mode 100644 airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/articles.json create mode 100644 airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/feature.json create mode 100644 airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/kcbot.json create mode 100644 airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/segments.json create mode 100644 airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/user_attributes.json create mode 100644 airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/users.json create mode 100644 airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/source.py create mode 100644 airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/spec.yaml create mode 100644 docs/integrations/sources/gainsight-px.md diff --git a/airbyte-integrations/connectors/source-gainsight-px/.dockerignore b/airbyte-integrations/connectors/source-gainsight-px/.dockerignore new file mode 100644 index 000000000000..8f1f9150d35a --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/.dockerignore @@ -0,0 +1,6 @@ +* +!Dockerfile +!main.py +!source_gainsight_px +!setup.py +!secrets diff --git a/airbyte-integrations/connectors/source-gainsight-px/Dockerfile b/airbyte-integrations/connectors/source-gainsight-px/Dockerfile new file mode 100644 index 000000000000..b00e69c3e089 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/Dockerfile @@ -0,0 +1,38 @@ +FROM python:3.9.11-alpine3.15 as base + +# build and load all requirements +FROM base as builder +WORKDIR /airbyte/integration_code + +# upgrade pip to the latest version +RUN apk --no-cache upgrade \ + && pip install --upgrade pip \ + && apk --no-cache add tzdata build-base + + +COPY setup.py ./ +# install necessary packages to a temporary folder +RUN pip install --prefix=/install . + +# build a clean environment +FROM base +WORKDIR /airbyte/integration_code + +# copy all loaded and built libraries to a pure basic image +COPY --from=builder /install /usr/local +# add default timezone settings +COPY --from=builder /usr/share/zoneinfo/Etc/UTC /etc/localtime +RUN echo "Etc/UTC" > /etc/timezone + +# bash is installed for more convenient debugging. +RUN apk --no-cache add bash + +# copy payload code only +COPY main.py ./ +COPY source_gainsight_px ./source_gainsight_px + +ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" +ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] + +LABEL io.airbyte.version=0.1.0 +LABEL io.airbyte.name=airbyte/source-gainsight-px diff --git a/airbyte-integrations/connectors/source-gainsight-px/README.md b/airbyte-integrations/connectors/source-gainsight-px/README.md new file mode 100644 index 000000000000..7373411b868a --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/README.md @@ -0,0 +1,82 @@ +# Gainsight Px Source + +This is the repository for the Gainsight Px configuration based source connector. +For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.com/integrations/sources/gainsight-px). + +## Local development + +#### Building via Gradle +You can also build the connector in Gradle. This is typically used in CI and not needed for your development workflow. + +To build using Gradle, from the Airbyte repository root, run: +``` +./gradlew :airbyte-integrations:connectors:source-gainsight-px:build +``` + +#### Create credentials +**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/gainsight-px) +to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_gainsight_px/spec.yaml` file. +Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. +See `integration_tests/sample_config.json` for a sample config file. + +**If you are an Airbyte core member**, copy the credentials in Lastpass under the secret name `source gainsight-px test creds` +and place them into `secrets/config.json`. + +### Locally running the connector docker image + +#### Build +First, make sure you build the latest Docker image: +``` +docker build . -t airbyte/source-gainsight-px:dev +``` + +You can also build the connector image via Gradle: +``` +./gradlew :airbyte-integrations:connectors:source-gainsight-px:airbyteDocker +``` +When building via Gradle, the docker image name and tag, respectively, are the values of the `io.airbyte.name` and `io.airbyte.version` `LABEL`s in +the Dockerfile. + +#### Run +Then run any of the connector commands as follows: +``` +docker run --rm airbyte/source-gainsight-px:dev spec +docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-gainsight-px:dev check --config /secrets/config.json +docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-gainsight-px:dev discover --config /secrets/config.json +docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-gainsight-px:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json +``` +## Testing + +#### Acceptance Tests +Customize `acceptance-test-config.yml` file to configure tests. See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) for more information. +If your connector requires to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py. + +To run your integration tests with Docker, run: +``` +./acceptance-test-docker.sh +``` + +### Using gradle to run tests +All commands should be run from airbyte project root. +To run unit tests: +``` +./gradlew :airbyte-integrations:connectors:source-gainsight-px:unitTest +``` +To run acceptance and custom integration tests: +``` +./gradlew :airbyte-integrations:connectors:source-gainsight-px:integrationTest +``` + +## Dependency Management +All of your dependencies should go in `setup.py`, NOT `requirements.txt`. The requirements file is only used to connect internal Airbyte dependencies in the monorepo for local development. +We split dependencies between two groups, dependencies that are: +* required for your connector to work need to go to `MAIN_REQUIREMENTS` list. +* required for the testing need to go to `TEST_REQUIREMENTS` list + +### Publishing a new version of the connector +You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what? +1. Make sure your changes are passing unit and integration tests. +1. Bump the connector version in `Dockerfile` -- just increment the value of the `LABEL io.airbyte.version` appropriately (we use [SemVer](https://semver.org/)). +1. Create a Pull Request. +1. Pat yourself on the back for being an awesome contributor. +1. Someone from Airbyte will take a look at your PR and iterate with you to merge it into master. diff --git a/airbyte-integrations/connectors/source-gainsight-px/__init__.py b/airbyte-integrations/connectors/source-gainsight-px/__init__.py new file mode 100644 index 000000000000..c941b3045795 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/__init__.py @@ -0,0 +1,3 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# diff --git a/airbyte-integrations/connectors/source-gainsight-px/acceptance-test-config.yml b/airbyte-integrations/connectors/source-gainsight-px/acceptance-test-config.yml new file mode 100644 index 000000000000..bd7e46aae2c5 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/acceptance-test-config.yml @@ -0,0 +1,51 @@ +# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-gainsight-px:dev +acceptance_tests: + spec: + tests: + - spec_path: "source_gainsight_px/spec.yaml" + connection: + tests: + - config_path: "secrets/config.json" + status: "succeed" + - config_path: "integration_tests/invalid_config.json" + status: "failed" + discovery: + tests: + - config_path: "secrets/config.json" + basic_read: + tests: + - config_path: "secrets/config.json" + configured_catalog_path: "integration_tests/configured_catalog.json" + empty_streams: + - name: accounts + bypass_reason: "Sandbox account cannot seed the stream" + - name: articles + bypass_reason: "Sandbox account cannot seed the stream" + - name: feature + bypass_reason: "Sandbox account cannot seed the stream" + - name: segments + bypass_reason: "Sandbox account cannot seed the stream" + - name: kcbot + bypass_reason: "Sandbox account cannot seed the stream" + - name: users + bypass_reason: "Sandbox account cannot seed the stream" +# TODO uncomment this block to specify that the tests should assert the connector outputs the records provided in the input file a file +# expect_records: +# path: "integration_tests/expected_records.jsonl" +# extra_fields: no +# exact_order: no +# extra_records: yes + incremental: + bypass_reason: "This connector does not implement incremental sync" +# TODO uncomment this block this block if your connector implements incremental sync: +# tests: +# - config_path: "secrets/config.json" +# configured_catalog_path: "integration_tests/configured_catalog.json" +# future_state: +# future_state_path: "integration_tests/abnormal_state.json" + full_refresh: + tests: + - config_path: "secrets/config.json" + configured_catalog_path: "integration_tests/configured_catalog.json" diff --git a/airbyte-integrations/connectors/source-gainsight-px/acceptance-test-docker.sh b/airbyte-integrations/connectors/source-gainsight-px/acceptance-test-docker.sh new file mode 100755 index 000000000000..b6d65deeccb4 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/acceptance-test-docker.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +source "$(git rev-parse --show-toplevel)/airbyte-integrations/bases/connector-acceptance-test/acceptance-test-docker.sh" diff --git a/airbyte-integrations/connectors/source-gainsight-px/build.gradle b/airbyte-integrations/connectors/source-gainsight-px/build.gradle new file mode 100644 index 000000000000..735ea0dbde01 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/build.gradle @@ -0,0 +1,9 @@ +plugins { + id 'airbyte-python' + id 'airbyte-docker' + id 'airbyte-connector-acceptance-test' +} + +airbytePython { + moduleDirectory 'source_gainsight_px' +} diff --git a/airbyte-integrations/connectors/source-gainsight-px/icon.svg b/airbyte-integrations/connectors/source-gainsight-px/icon.svg new file mode 100644 index 000000000000..e46c1d3780f2 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/icon.svg @@ -0,0 +1 @@ +Asset 2 \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-gainsight-px/integration_tests/__init__.py b/airbyte-integrations/connectors/source-gainsight-px/integration_tests/__init__.py new file mode 100644 index 000000000000..c941b3045795 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/integration_tests/__init__.py @@ -0,0 +1,3 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# diff --git a/airbyte-integrations/connectors/source-gainsight-px/integration_tests/abnormal_state.json b/airbyte-integrations/connectors/source-gainsight-px/integration_tests/abnormal_state.json new file mode 100644 index 000000000000..52b0f2c2118f --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/integration_tests/abnormal_state.json @@ -0,0 +1,5 @@ +{ + "todo-stream-name": { + "todo-field-name": "todo-abnormal-value" + } +} diff --git a/airbyte-integrations/connectors/source-gainsight-px/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-gainsight-px/integration_tests/acceptance.py new file mode 100644 index 000000000000..9e6409236281 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/integration_tests/acceptance.py @@ -0,0 +1,16 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +import pytest + +pytest_plugins = ("connector_acceptance_test.plugin",) + + +@pytest.fixture(scope="session", autouse=True) +def connector_setup(): + """This fixture is a placeholder for external resources that acceptance test might require.""" + # TODO: setup test dependencies if needed. otherwise remove the TODO comments + yield + # TODO: clean up test dependencies diff --git a/airbyte-integrations/connectors/source-gainsight-px/integration_tests/configured_catalog.json b/airbyte-integrations/connectors/source-gainsight-px/integration_tests/configured_catalog.json new file mode 100644 index 000000000000..e97f8ad9def0 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/integration_tests/configured_catalog.json @@ -0,0 +1,76 @@ +{ + "streams": [ + { + "stream": { + "name": "accounts", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "articles", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "admin_attributes", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "feature", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "segments", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "kcbot", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "user_attributes", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "users", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + } + ] +} diff --git a/airbyte-integrations/connectors/source-gainsight-px/integration_tests/invalid_config.json b/airbyte-integrations/connectors/source-gainsight-px/integration_tests/invalid_config.json new file mode 100644 index 000000000000..6016942564e8 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/integration_tests/invalid_config.json @@ -0,0 +1,3 @@ +{ + "api_key": "wrong-api-key" +} diff --git a/airbyte-integrations/connectors/source-gainsight-px/integration_tests/sample_config.json b/airbyte-integrations/connectors/source-gainsight-px/integration_tests/sample_config.json new file mode 100644 index 000000000000..3fc2c76d0430 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/integration_tests/sample_config.json @@ -0,0 +1,3 @@ +{ + "api_key": "25yyyxxx-abcd-qwer-asdf-cvbnvbnmpoiu" +} diff --git a/airbyte-integrations/connectors/source-gainsight-px/main.py b/airbyte-integrations/connectors/source-gainsight-px/main.py new file mode 100644 index 000000000000..5ae4980cd0e0 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/main.py @@ -0,0 +1,13 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +import sys + +from airbyte_cdk.entrypoint import launch +from source_gainsight_px import SourceGainsightPx + +if __name__ == "__main__": + source = SourceGainsightPx() + launch(source, sys.argv[1:]) diff --git a/airbyte-integrations/connectors/source-gainsight-px/metadata.yaml b/airbyte-integrations/connectors/source-gainsight-px/metadata.yaml new file mode 100644 index 000000000000..81022b5d0cb6 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/metadata.yaml @@ -0,0 +1,22 @@ +data: + allowedHosts: + hosts: + - api.aptrinsic.com/v1 + registries: + oss: + enabled: true + connectorSubtype: api + connectorType: source + definitionId: 0da3b186-8879-4e94-8738-55b48762f1e8 + dockerImageTag: 0.1.0 + dockerRepository: airbyte/source-gainsight-px + githubIssueLabel: source-gainsight-px + icon: gainsight-px.svg + license: MIT + name: Gainsight Px + releaseStage: alpha + documentationUrl: https://docs.airbyte.com/integrations/sources/gainsight-px + tags: + - language:low-code + - language:python +metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/source-gainsight-px/requirements.txt b/airbyte-integrations/connectors/source-gainsight-px/requirements.txt new file mode 100644 index 000000000000..cc57334ef619 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/requirements.txt @@ -0,0 +1,2 @@ +-e ../../bases/connector-acceptance-test +-e . diff --git a/airbyte-integrations/connectors/source-gainsight-px/setup.py b/airbyte-integrations/connectors/source-gainsight-px/setup.py new file mode 100644 index 000000000000..00d5c11ff3f6 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/setup.py @@ -0,0 +1,29 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +from setuptools import find_packages, setup + +MAIN_REQUIREMENTS = [ + "airbyte-cdk~=0.1", +] + +TEST_REQUIREMENTS = [ + "pytest~=6.2", + "pytest-mock~=3.6.1", + "connector-acceptance-test", +] + +setup( + name="source_gainsight_px", + description="Source implementation for Gainsight Px.", + author="Airbyte", + author_email="contact@airbyte.io", + packages=find_packages(), + install_requires=MAIN_REQUIREMENTS, + package_data={"": ["*.json", "*.yaml", "schemas/*.json", "schemas/shared/*.json"]}, + extras_require={ + "tests": TEST_REQUIREMENTS, + }, +) diff --git a/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/__init__.py b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/__init__.py new file mode 100644 index 000000000000..c0d02e94d047 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/__init__.py @@ -0,0 +1,8 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +from .source import SourceGainsightPx + +__all__ = ["SourceGainsightPx"] diff --git a/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/manifest.yaml b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/manifest.yaml new file mode 100644 index 000000000000..98ec31f0e92c --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/manifest.yaml @@ -0,0 +1,150 @@ +version: "0.29.0" + +definitions: + selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: [] + + custom_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: ["{{ parameters.extractorPath }}"] + + requester: + type: HttpRequester + url_base: "https://api.aptrinsic.com/v1/" + http_method: "GET" + authenticator: + type: ApiKeyAuthenticator + header: "X-APTRINSIC-API-KEY" + api_token: "{{ config['api_key'] }}" + + retriever: + type: SimpleRetriever + paginator: + type: "DefaultPaginator" + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ last_records[-1]['scrollId'] }}" + page_size: 5 + page_token_option: + type: "RequestPath" + field_name: "scrollId" + inject_into: "request_parameter" + requester: + $ref: "#/definitions/requester" + record_selector: + $ref: "#/definitions/selector" + + custom_retriever: + type: SimpleRetriever + paginator: + type: NoPagination + requester: + $ref: "#/definitions/requester" + record_selector: + $ref: "#/definitions/custom_selector" + + base_stream: + type: DeclarativeStream + retriever: + $ref: "#/definitions/retriever" + + accounts_stream: + $parameters: + path: "accounts" + extractorPath: "accounts" + type: DeclarativeStream + retriever: + $ref: "#/definitions/custom_retriever" + name: "accounts" + primary_key: "id" + + admin_attributes_stream: + $parameters: + path: "admin/model/account/attributes" + $ref: "#/definitions/base_stream" + name: "admin_attributes" + primary_key: "id" + + articles_stream: + $parameters: + path: "articles" + extractorPath: "articleExternalViewList" + type: DeclarativeStream + retriever: + $ref: "#/definitions/custom_retriever" + name: "articles" + primary_key: "id" + + feature_stream: + $parameters: + path: "feature" + extractorPath: "features" + type: DeclarativeStream + retriever: + $ref: "#/definitions/custom_retriever" + name: "feature" + primary_key: "id" + + segments_stream: + $parameters: + path: "segment" + extractorPath: "segments" + type: DeclarativeStream + retriever: + $ref: "#/definitions/custom_retriever" + name: "segments" + + kcbot_stream: + $parameters: + path: "kcbot" + extractorPath: "kcList" + type: DeclarativeStream + retriever: + $ref: "#/definitions/custom_retriever" + name: "kcbot" + primary_key: "id" + + user_attributes_stream: + $parameters: + path: "admin/model/user/attributes" + $ref: "#/definitions/base_stream" + name: "user_attributes" + primary_key: "id" + + users_stream: + $parameters: + path: "users" + extractorPath: "users" + type: DeclarativeStream + retriever: + $ref: "#/definitions/custom_retriever" + name: "users" + primary_key: "id" + +streams: + - "#/definitions/accounts_stream" + - "#/definitions/admin_attributes_stream" + - "#/definitions/articles_stream" + - "#/definitions/feature_stream" + - "#/definitions/segments_stream" + - "#/definitions/kcbot_stream" + - "#/definitions/user_attributes_stream" + - "#/definitions/users_stream" + +check: + type: CheckStream + stream_names: + - "accounts" + - "admin_attributes" + - "articles" + - "feature" + - "segments" + - "kcbot" + - "user_attributes" + - "users" + diff --git a/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/accounts.json b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/accounts.json new file mode 100644 index 000000000000..a1a30710c6f8 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/accounts.json @@ -0,0 +1,71 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Accounts Schema", + "additionalProperties": true, + "type": ["null", "object"], + "properties": { + "id": { + "type": ["null", "string"] + }, + "name": { + "type": ["null", "string"] + }, + "trackedSubscriptionId": { + "type": ["null", "string"] + }, + "sfdcId": { + "type": ["null", "string"] + }, + "lastSeenDate": { + "type": ["null", "string"] + }, + "dunsNumber": { + "type": ["null", "string"] + }, + "industry": { + "type": ["null", "string"] + }, + "numberOfEmployees": { + "type": ["null", "string"] + }, + "sicCode": { + "type": ["null", "string"] + }, + "website": { + "type": ["null", "string"] + }, + "naicsCode": { + "type": ["null", "string"] + }, + "plan": { + "type": ["null", "string"] + }, + "location": { + "type": ["null", "string"] + }, + "numberOfUsers": { + "type": ["null", "string"] + }, + "propertyKeys": { + "type": ["null", "array"], + "items": { + "location": { + "type": ["null", "string"] + } + } + }, + "createDate": { + "type": ["null", "string"] + }, + "lastModifiedDate": { + "type": ["null", "string"] + }, + "customAttributes": { + "type": ["null", "object"], + "additionalProperties": true + }, + "parentGroupId": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/admin_attributes.json b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/admin_attributes.json new file mode 100644 index 000000000000..ac6e73995f9d --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/admin_attributes.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "User Attributes Schema", + "additionalProperties": true, + "type": ["null", "object"], + "properties": { + "id": { + "type": ["null", "string"] + }, + "name": { + "type": ["null", "string"] + }, + "apiName": { + "type": ["null", "string"] + }, + "internalName": { + "type": ["null", "string"] + }, + "description": { + "type": ["null", "string"] + }, + "type": { + "type": ["null", "string"] + }, + "state": { + "type": ["null", "string"] + }, + "origin": { + "type": ["null", "string"] + }, + "createdDate": { + "type": ["null", "number"] + }, + "modifiedDate": { + "type": ["null", "number"] + }, + "defaultValue": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/articles.json b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/articles.json new file mode 100644 index 000000000000..1143e451f009 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/articles.json @@ -0,0 +1,62 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Articles Schema", + "additionalProperties": true, + "type": ["null", "object"], + "properties": { + "id": { + "type": ["null", "string"] + }, + "modifiedBy": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "string"] + }, + "name": { + "type": ["null", "string"] + } + } + }, + "articleKCs": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "kcId": { + "type": ["null", "string"] + }, + "kcName": { + "type": ["null", "string"] + } + } + } + }, + "articleName": { + "type": ["null", "string"] + }, + "author": { + "type": ["null", "string"] + }, + "createdDate": { + "type": ["null", "number"] + }, + "modifiedDate": { + "type": ["null", "number"] + }, + "productId": { + "type": ["null", "string"] + }, + "productName": { + "type": ["null", "string"] + }, + "releaseDate": { + "type": ["null", "string"] + }, + "viewType": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/feature.json b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/feature.json new file mode 100644 index 000000000000..064d1979189a --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/feature.json @@ -0,0 +1,43 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Feature Schema", + "additionalProperties": true, + "type": ["null", "object"], + "properties": { + "id": { + "type": ["null", "string"] + }, + "name": { + "type": ["null", "string"] + }, + "type": { + "type": ["null", "string"], + "enum": ["FEATURE", "MODULE"] + }, + "parentFeatureId": { + "type": ["null", "string"] + }, + "propertyKey": { + "type": ["null", "string"] + }, + "status": { + "type": ["null", "string"], + "enum": ["ACTIVATED", "DELETED"] + }, + "featureLabels": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "string"] + }, + "name": { + "type": ["null", "string"] + }, + "color": { + "type": ["null", "string"] + } + } + } + } +} diff --git a/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/kcbot.json b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/kcbot.json new file mode 100644 index 000000000000..13e357d4d841 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/kcbot.json @@ -0,0 +1,65 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "KCBot Schema", + "additionalProperties": true, + "type": ["null", "object"], + "properties": { + "createdBy": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "string"] + }, + "name": { + "type": ["null", "string"] + } + } + }, + "createdDate": { + "type": ["null", "number"] + }, + "description": { + "type": ["null", "string"] + }, + "environments": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "id": { + "type": ["null", "string"] + }, + "modifiedBy": { + "additionalProperties": true, + "type": ["null", "object"], + "properties": { + "id": { + "type": ["null", "string"] + }, + "name": { + "type": ["null", "string"] + } + } + }, + "modifiedDate": { + "type": ["null", "number"] + }, + "name": { + "type": ["null", "string"] + }, + "priority": { + "type": ["null", "number"] + }, + "productId": { + "type": ["null", "string"] + }, + "productName": { + "type": ["null", "string"] + }, + "status": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/segments.json b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/segments.json new file mode 100644 index 000000000000..1382369c2a86 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/segments.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Segment Schema", + "additionalProperties": true, + "type": ["null", "object"], + "properties": { + "id": { + "type": ["null", "string"] + }, + "name": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/user_attributes.json b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/user_attributes.json new file mode 100644 index 000000000000..ac6e73995f9d --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/user_attributes.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "User Attributes Schema", + "additionalProperties": true, + "type": ["null", "object"], + "properties": { + "id": { + "type": ["null", "string"] + }, + "name": { + "type": ["null", "string"] + }, + "apiName": { + "type": ["null", "string"] + }, + "internalName": { + "type": ["null", "string"] + }, + "description": { + "type": ["null", "string"] + }, + "type": { + "type": ["null", "string"] + }, + "state": { + "type": ["null", "string"] + }, + "origin": { + "type": ["null", "string"] + }, + "createdDate": { + "type": ["null", "number"] + }, + "modifiedDate": { + "type": ["null", "number"] + }, + "defaultValue": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/users.json b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/users.json new file mode 100644 index 000000000000..e2337f049ba4 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/schemas/users.json @@ -0,0 +1,175 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Users Schema", + "additionalProperties": true, + "type": ["null", "object"], + "properties": { + "aptrinsicId": { + "type": ["null", "string"] + }, + "identifyId": { + "type": ["null", "string"] + }, + "type": { + "type": ["null", "string"], + "enum": ["LEAD", "USER", "VISITOR", "EMPTY_USER_TYPE"] + }, + "gender": { + "type": ["null", "string"], + "enum": ["MALE", "FEMALE", "OTHER", "EMPTY_GENDER"] + }, + "email": { + "type": ["null", "string"] + }, + "firstName": { + "type": ["null", "string"] + }, + "lastName": { + "type": ["null", "string"] + }, + "lastSeenDate": { + "type": ["null", "integer"], + "format": "int64" + }, + "signUpDate": { + "type": ["null", "integer"], + "format": "int64" + }, + "firstVisitDate": { + "type": ["null", "integer"], + "format": "int64" + }, + "title": { + "type": ["null", "string"] + }, + "phone": { + "type": ["null", "string"] + }, + "score": { + "type": ["null", "integer"], + "format": "int64" + }, + "role": { + "type": ["null", "string"] + }, + "subscriptionId": { + "type": ["null", "string"] + }, + "accountId": { + "type": ["null", "string"] + }, + "numberOfVisits": { + "type": ["null", "integer"], + "format": "int32" + }, + "location": { + "type": ["null", "string"] + }, + "propertyKeys": { + "type": ["null", "array"], + "description": "Aptrinsic Tag Key, at least one is required", + "items": { + "type": ["null", "string"] + }, + "examples": [["AP-XXXXXXXXXX-2"]] + }, + "createDate": { + "type": ["null", "integer"], + "format": "int64" + }, + "lastModifiedDate": { + "type": ["null", "integer"], + "format": "int64" + }, + "globalUnsubscribe": { + "type": ["null", "boolean"] + }, + "sfdcContactId": { + "type": ["null", "string"] + }, + "lastVisitedUserAgentData": { + "type": ["null", "array"], + "items": { + "propertyKey": { + "type": ["null", "string"] + }, + "userAgent": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "rawUserAgent": { + "type": ["null", "string"] + }, + "device": { + "type": ["null", "string"] + }, + "platformType": { + "type": ["null", "string"] + }, + "platformVersion": { + "type": ["null", "string"] + }, + "browserType": { + "type": ["null", "string"] + }, + "browserVersion": { + "type": ["null", "string"] + } + } + } + } + }, + "id": { + "type": ["null", "string"], + "description": "Synonym for identifyId, output only, not filterable" + }, + "lastInferredLocation": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "countryName": { + "type": ["null", "string"] + }, + "countryCode": { + "type": ["null", "string"] + }, + "stateName": { + "type": ["null", "string"] + }, + "stateCode": { + "type": ["null", "string"] + }, + "city": { + "type": ["null", "string"] + }, + "street": { + "type": ["null", "string"] + }, + "postalCode": { + "type": ["null", "string"] + }, + "continent": { + "type": ["null", "string"] + }, + "regionName": { + "type": ["null", "string"] + }, + "timeZone": { + "type": ["null", "string"] + }, + "coordinates": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "latitude": { + "type": ["null", "number"] + }, + "longitude": { + "type": ["null", "number"] + } + } + } + } + } + } +} diff --git a/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/source.py b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/source.py new file mode 100644 index 000000000000..0ea94fe90b48 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/source.py @@ -0,0 +1,18 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource + +""" +This file provides the necessary constructs to interpret a provided declarative YAML configuration file into +source connector. + +WARNING: Do not modify this file. +""" + + +# Declarative Source +class SourceGainsightPx(YamlDeclarativeSource): + def __init__(self): + super().__init__(**{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/spec.yaml b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/spec.yaml new file mode 100644 index 000000000000..a78bb4fef492 --- /dev/null +++ b/airbyte-integrations/connectors/source-gainsight-px/source_gainsight_px/spec.yaml @@ -0,0 +1,14 @@ +documentation_url: https://docs.airbyte.com/integrations/sources/gainsight-px +connectionSpecification: + $schema: http://json-schema.org/draft-07/schema# + title: Gainsight Px Spec + type: object + additionalProperties: true + required: + - api_key + properties: + api_key: + title: API Key + type: string + description: The Aptrinsic API Key which is recieved from the dashboard settings (ref - https://app.aptrinsic.com/settings/api-keys) + airbyte_secret: true diff --git a/docs/integrations/sources/gainsight-px.md b/docs/integrations/sources/gainsight-px.md new file mode 100644 index 000000000000..5ad6d9d4c27b --- /dev/null +++ b/docs/integrations/sources/gainsight-px.md @@ -0,0 +1,74 @@ +# Gainsight-API + +This page contains the setup guide and reference information for the [Gainsight-PX-API](https://gainsightpx.docs.apiary.io/) source connector from [Gainsight-PX](https://support.gainsight.com/PX/API_for_Developers) + +## Prerequisites + +Api key is mandate for this connector to work, It could be generated from the dashboard settings (ref - https://app.aptrinsic.com/settings/api-keys). + +## Setup guide + +### Step 1: Set up Gainsight-API connection + +- Generate an API key (Example: 12345) +- Params (If specific info is needed) +- Available params + - api_key: The aptrinsic api_key + +## Step 2: Set up the Gainsight-APIs connector in Airbyte + +### For Airbyte Cloud: + +1. [Log into your Airbyte Cloud](https://cloud.airbyte.io/workspaces) account. +2. In the left navigation bar, click **Sources**. In the top-right corner, click **+new source**. +3. On the Set up the source page, enter the name for the Gainsight-API connector and select **Gainsight-API** from the Source type dropdown. +4. Enter your `api_key`. +5. Enter the params configuration if needed. Supported params are: query, orientation, size, color, locale, collection_id \ +video_id, photo_id +6. Click **Set up source**. + +### For Airbyte OSS: + +1. Navigate to the Airbyte Open Source dashboard. +2. Set the name for your source. +3. Enter your `api_key`. +4. Enter the params configuration if needed. Supported params are: query, orientation, size, color, locale, collection_id \ +video_id, photo_id +5. Click **Set up source**. + +## Supported sync modes + +The Gainsight-API source connector supports the following [sync modes](https://docs.airbyte.com/cloud/core-concepts#connection-sync-modes): + +| Feature | Supported? | +| :---------------------------- | :--------- | +| Full Refresh Sync | Yes | +| Incremental Sync | No | +| Replicate Incremental Deletes | No | +| SSL connection | Yes | +| Namespaces | No | + +## Supported Streams + +- accounts +- admin_attributes +- articles +- feature +- kcbot +- segments +- user_attributes +- users + +## API method example + +GET https://api.aptrinsic.com/v1/accounts + +## Performance considerations + +Gainsight-PX-API's [API reference](https://gainsightpx.docs.apiary.io/) has v1 at present. The connector as default uses v1. + +## Changelog + +| Version | Date | Pull Request | Subject | +| :------ | :--------- | :----------------------------------------------------- | :------------- | +| 0.1.0 | 2023-05-10 | [Init](https://github.com/airbytehq/airbyte/pull/26998)| Initial PR | From 6f89af01d782231c0d9b45030979e2b117386d0c Mon Sep 17 00:00:00 2001 From: "Roman Yermilov [GL]" <86300758+roman-yermilov-gl@users.noreply.github.com> Date: Wed, 12 Jul 2023 21:05:25 +0400 Subject: [PATCH 42/63] Source Google Ads: disable logging (#28230) * Source Google Ads: disable logging * Source Google Ads: bump version, update changelog --- airbyte-integrations/connectors/source-google-ads/Dockerfile | 2 +- .../connectors/source-google-ads/metadata.yaml | 2 +- .../connectors/source-google-ads/source_google_ads/streams.py | 4 +++- docs/integrations/sources/google-ads.md | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/airbyte-integrations/connectors/source-google-ads/Dockerfile b/airbyte-integrations/connectors/source-google-ads/Dockerfile index 968e56fb06e8..7924661a6271 100644 --- a/airbyte-integrations/connectors/source-google-ads/Dockerfile +++ b/airbyte-integrations/connectors/source-google-ads/Dockerfile @@ -13,5 +13,5 @@ COPY main.py ./ ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=0.6.0 +LABEL io.airbyte.version=0.6.1 LABEL io.airbyte.name=airbyte/source-google-ads diff --git a/airbyte-integrations/connectors/source-google-ads/metadata.yaml b/airbyte-integrations/connectors/source-google-ads/metadata.yaml index ac969b74d91b..ba2a4e207391 100644 --- a/airbyte-integrations/connectors/source-google-ads/metadata.yaml +++ b/airbyte-integrations/connectors/source-google-ads/metadata.yaml @@ -6,7 +6,7 @@ data: connectorSubtype: api connectorType: source definitionId: 253487c0-2246-43ba-a21f-5116b20a2c50 - dockerImageTag: 0.6.0 + dockerImageTag: 0.6.1 dockerRepository: airbyte/source-google-ads githubIssueLabel: source-google-ads icon: google-adwords.svg diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py b/airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py index 71fb44526f53..6a08b30ad57c 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py @@ -203,7 +203,9 @@ def read_records( date_in_latest_record = pendulum.parse(record[self.cursor_field]) cursor_value = (max(date_in_current_stream, date_in_latest_record)).to_date_string() self.state = {customer_id: {self.cursor_field: cursor_value}} - self.incremental_sieve_logger.info(f"Updated state for customer {customer_id}. Full state is {self.state}.") + # When large amount of data this log produces so much records so the enire log is not usable + # See: https://github.com/airbytehq/oncall/issues/2460 + # self.incremental_sieve_logger.info(f"Updated state for customer {customer_id}. Full state is {self.state}.") yield record continue self.state = {customer_id: {self.cursor_field: record[self.cursor_field]}} diff --git a/docs/integrations/sources/google-ads.md b/docs/integrations/sources/google-ads.md index c44fbfab08e9..667f331109bc 100644 --- a/docs/integrations/sources/google-ads.md +++ b/docs/integrations/sources/google-ads.md @@ -162,6 +162,7 @@ Due to a limitation in the Google Ads API which does not allow getting performan | Version | Date | Pull Request | Subject | |:---------|:-----------|:---------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------| +| `0.6.1` | 2023-07-12 | [28230](https://github.com/airbytehq/airbyte/pull/28230) | Reduce amount of logs produced by the connector while working with big amount of data | | `0.6.0` | 2023-07-10 | [28078](https://github.com/airbytehq/airbyte/pull/28078) | Add new stream `Campaign Budget` | | `0.5.0` | 2023-07-07 | [28042](https://github.com/airbytehq/airbyte/pull/28042) | Add metrics & segment to `Campaigns` stream | | `0.4.3` | 2023-07-05 | [27959](https://github.com/airbytehq/airbyte/pull/27959) | Add `audience` and `user_interest` streams | From b52e88a977ebebff8bc8b9c7fd542fe6b5f2e5a2 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Wed, 12 Jul 2023 20:06:59 +0200 Subject: [PATCH 43/63] =?UTF-8?q?=F0=9F=8E=89=20New=20Destination=20Vector?= =?UTF-8?q?=20Database=20(powered=20by=20LangChain)=20(#26184)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * basic version * polish * iterate * keep working * fix spec * wip * improve destination * basic unit tests * move embedding dimensionality into embedder * improve several things * adjust documentation * remove unnecessary call * add some debug information * fix local destination * various small fixes * bring tests into order * document and add batching to pinecone * checklist * improve performance a bit and add test * fix formatting * fix metadata * install C++ 11 on python base * no more alpine for ci-connector-ops * remove hard-to-run test * more documentation * better documentation * add icon * some small adjustments * review comments * format * review comments --------- Co-authored-by: alafanechere Co-authored-by: Augustin --- .../destination-langchain/.dockerignore | 5 + .../destination-langchain/Dockerfile | 40 +++ .../destination-langchain/README.md | 123 ++++++++++ .../destination-langchain/bootstrap.md | 26 ++ .../destination-langchain/build.gradle | 8 + .../destination_langchain/__init__.py | 8 + .../destination_langchain/batcher.py | 26 ++ .../destination_langchain/config.py | 123 ++++++++++ .../destination_langchain/destination.py | 88 +++++++ .../document_processor.py | 112 +++++++++ .../destination_langchain/embedder.py | 78 ++++++ .../destination_langchain/indexer.py | 142 +++++++++++ .../destination_langchain/measure_time.py | 29 +++ .../destination_langchain/utils.py | 9 + .../examples/configured_catalog.json | 20 ++ .../examples/messages.jsonl | 2 + .../connectors/destination-langchain/icon.svg | 4 + .../base_integration_test.py | 42 ++++ .../local_integration_test.py | 46 ++++ .../pinecone_integration_test.py | 76 ++++++ .../connectors/destination-langchain/main.py | 11 + .../destination-langchain/metadata.yaml | 20 ++ .../destination-langchain/requirements.txt | 1 + .../connectors/destination-langchain/setup.py | 34 +++ .../destination-langchain/test_local.py | 25 ++ .../destination-langchain/test_pinecone.py | 43 ++++ .../unit_tests/batcher_test.py | 94 +++++++ .../unit_tests/destination_test.py | 103 ++++++++ .../unit_tests/docarray_indexer_test.py | 95 +++++++ .../unit_tests/document_processor_test.py | 232 ++++++++++++++++++ .../unit_tests/pinecone_indexer_test.py | 101 ++++++++ docs/integrations/destinations/langchain.md | 101 ++++++++ .../pipelines/actions/environments.py | 16 +- 33 files changed, 1875 insertions(+), 8 deletions(-) create mode 100644 airbyte-integrations/connectors/destination-langchain/.dockerignore create mode 100644 airbyte-integrations/connectors/destination-langchain/Dockerfile create mode 100644 airbyte-integrations/connectors/destination-langchain/README.md create mode 100644 airbyte-integrations/connectors/destination-langchain/bootstrap.md create mode 100644 airbyte-integrations/connectors/destination-langchain/build.gradle create mode 100644 airbyte-integrations/connectors/destination-langchain/destination_langchain/__init__.py create mode 100644 airbyte-integrations/connectors/destination-langchain/destination_langchain/batcher.py create mode 100644 airbyte-integrations/connectors/destination-langchain/destination_langchain/config.py create mode 100644 airbyte-integrations/connectors/destination-langchain/destination_langchain/destination.py create mode 100644 airbyte-integrations/connectors/destination-langchain/destination_langchain/document_processor.py create mode 100644 airbyte-integrations/connectors/destination-langchain/destination_langchain/embedder.py create mode 100644 airbyte-integrations/connectors/destination-langchain/destination_langchain/indexer.py create mode 100644 airbyte-integrations/connectors/destination-langchain/destination_langchain/measure_time.py create mode 100644 airbyte-integrations/connectors/destination-langchain/destination_langchain/utils.py create mode 100644 airbyte-integrations/connectors/destination-langchain/examples/configured_catalog.json create mode 100644 airbyte-integrations/connectors/destination-langchain/examples/messages.jsonl create mode 100644 airbyte-integrations/connectors/destination-langchain/icon.svg create mode 100644 airbyte-integrations/connectors/destination-langchain/integration_tests/base_integration_test.py create mode 100644 airbyte-integrations/connectors/destination-langchain/integration_tests/local_integration_test.py create mode 100644 airbyte-integrations/connectors/destination-langchain/integration_tests/pinecone_integration_test.py create mode 100644 airbyte-integrations/connectors/destination-langchain/main.py create mode 100644 airbyte-integrations/connectors/destination-langchain/metadata.yaml create mode 100644 airbyte-integrations/connectors/destination-langchain/requirements.txt create mode 100644 airbyte-integrations/connectors/destination-langchain/setup.py create mode 100644 airbyte-integrations/connectors/destination-langchain/test_local.py create mode 100644 airbyte-integrations/connectors/destination-langchain/test_pinecone.py create mode 100644 airbyte-integrations/connectors/destination-langchain/unit_tests/batcher_test.py create mode 100644 airbyte-integrations/connectors/destination-langchain/unit_tests/destination_test.py create mode 100644 airbyte-integrations/connectors/destination-langchain/unit_tests/docarray_indexer_test.py create mode 100644 airbyte-integrations/connectors/destination-langchain/unit_tests/document_processor_test.py create mode 100644 airbyte-integrations/connectors/destination-langchain/unit_tests/pinecone_indexer_test.py create mode 100644 docs/integrations/destinations/langchain.md diff --git a/airbyte-integrations/connectors/destination-langchain/.dockerignore b/airbyte-integrations/connectors/destination-langchain/.dockerignore new file mode 100644 index 000000000000..188ab8cdf977 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/.dockerignore @@ -0,0 +1,5 @@ +* +!Dockerfile +!main.py +!destination_langchain +!setup.py diff --git a/airbyte-integrations/connectors/destination-langchain/Dockerfile b/airbyte-integrations/connectors/destination-langchain/Dockerfile new file mode 100644 index 000000000000..3bacafbe532f --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/Dockerfile @@ -0,0 +1,40 @@ +FROM nickgryg/alpine-pandas:3.9.12 as base + +# build and load all requirements +FROM base as builder +WORKDIR /airbyte/integration_code + +# upgrade pip to the latest version +RUN apk --no-cache upgrade \ + && pip install --upgrade pip \ + && apk --no-cache add tzdata build-base swig libffi-dev libstdc++ + +COPY setup.py ./ + +RUN pip install --upgrade pip + +# install necessary packages to a temporary folder +RUN pip install --prefix=/install . + +# build a clean environment +FROM base +WORKDIR /airbyte/integration_code + +# copy all loaded and built libraries to a pure basic image +COPY --from=builder /install /usr/local +# add default timezone settings +COPY --from=builder /usr/share/zoneinfo/Etc/UTC /etc/localtime +RUN echo "Etc/UTC" > /etc/timezone + +# bash is installed for more convenient debugging. +RUN apk --no-cache add bash + +# copy payload code only +COPY main.py ./ +COPY destination_langchain ./destination_langchain + +ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" +ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] + +LABEL io.airbyte.version=0.0.1 +LABEL io.airbyte.name=airbyte/destination-langchain diff --git a/airbyte-integrations/connectors/destination-langchain/README.md b/airbyte-integrations/connectors/destination-langchain/README.md new file mode 100644 index 000000000000..fd1de42965e9 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/README.md @@ -0,0 +1,123 @@ +# Langchain Destination + +This is the repository for the Langchain destination connector, written in Python. +For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.com/integrations/destinations/langchain). + +## Local development + +### Prerequisites +**To iterate on this connector, make sure to complete this prerequisites section.** + +#### Minimum Python version required `= 3.9.0` + +#### Build & Activate Virtual Environment and install dependencies +From this connector directory, create a virtual environment: +``` +python -m venv .venv +``` + +This will generate a virtualenv for this module in `.venv/`. Make sure this venv is active in your +development environment of choice. To activate it from the terminal, run: +``` +source .venv/bin/activate +pip install -r requirements.txt +``` +If you are in an IDE, follow your IDE's instructions to activate the virtualenv. + +Note that while we are installing dependencies from `requirements.txt`, you should only edit `setup.py` for your dependencies. `requirements.txt` is +used for editable installs (`pip install -e`) to pull in Python dependencies from the monorepo and will call `setup.py`. +If this is mumbo jumbo to you, don't worry about it, just put your deps in `setup.py` but install using `pip install -r requirements.txt` and everything +should work as you expect. + +#### Building via Gradle +From the Airbyte repository root, run: +``` +./gradlew :airbyte-integrations:connectors:destination-langchain:build +``` + +#### Create credentials +**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/destinations/langchain) +to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `destination_langchain/spec.json` file. +Note that the `secrets` directory is gitignored by default, so there is no danger of accidentally checking in sensitive information. +See `integration_tests/sample_config.json` for a sample config file. + +**If you are an Airbyte core member**, copy the credentials in Lastpass under the secret name `destination langchain test creds` +and place them into `secrets/config.json`. + +### Locally running the connector +``` +python main.py spec +python main.py check --config secrets/config.json +python main.py discover --config secrets/config.json +python main.py read --config secrets/config.json --catalog integration_tests/configured_catalog.json +``` + +### Locally running the connector docker image + +#### Build +First, make sure you build the latest Docker image: +``` +docker build . -t airbyte/destination-langchain:dev +``` + +You can also build the connector image via Gradle: +``` +./gradlew :airbyte-integrations:connectors:destination-langchain:airbyteDocker +``` +When building via Gradle, the docker image name and tag, respectively, are the values of the `io.airbyte.name` and `io.airbyte.version` `LABEL`s in +the Dockerfile. + +#### Run +Then run any of the connector commands as follows: +``` +docker run --rm airbyte/destination-langchain:dev spec +docker run --rm -v $(pwd)/secrets:/secrets airbyte/destination-langchain:dev check --config /secrets/config.json +# messages.jsonl is a file containing line-separated JSON representing AirbyteMessages +cat messages.jsonl | docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/destination-langchain:dev write --config /secrets/config.json --catalog /integration_tests/configured_catalog.json +``` +## Testing + Make sure to familiarize yourself with [pytest test discovery](https://docs.pytest.org/en/latest/goodpractices.html#test-discovery) to know how your test files and methods should be named. +First install test dependencies into your virtual environment: +``` +pip install .[tests] +``` +### Unit Tests +To run unit tests locally, from the connector directory run: +``` +python -m pytest unit_tests +``` + +### Integration Tests +There are two types of integration tests: Acceptance Tests (Airbyte's test suite for all destination connectors) and custom integration tests (which are specific to this connector). +#### Custom Integration tests +Place custom tests inside `integration_tests/` folder, then, from the connector root, run +``` +python -m pytest integration_tests +``` +#### Acceptance Tests +Coming soon: + +### Using gradle to run tests +All commands should be run from airbyte project root. +To run unit tests: +``` +./gradlew :airbyte-integrations:connectors:destination-langchain:unitTest +``` +To run acceptance and custom integration tests: +``` +./gradlew :airbyte-integrations:connectors:destination-langchain:integrationTest +``` + +## Dependency Management +All of your dependencies should go in `setup.py`, NOT `requirements.txt`. The requirements file is only used to connect internal Airbyte dependencies in the monorepo for local development. +We split dependencies between two groups, dependencies that are: +* required for your connector to work need to go to `MAIN_REQUIREMENTS` list. +* required for the testing need to go to `TEST_REQUIREMENTS` list + +### Publishing a new version of the connector +You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what? +1. Make sure your changes are passing unit and integration tests. +1. Bump the connector version in `Dockerfile` -- just increment the value of the `LABEL io.airbyte.version` appropriately (we use [SemVer](https://semver.org/)). +1. Create a Pull Request. +1. Pat yourself on the back for being an awesome contributor. +1. Someone from Airbyte will take a look at your PR and iterate with you to merge it into master. diff --git a/airbyte-integrations/connectors/destination-langchain/bootstrap.md b/airbyte-integrations/connectors/destination-langchain/bootstrap.md new file mode 100644 index 000000000000..e4dbdd01256c --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/bootstrap.md @@ -0,0 +1,26 @@ +# Langchain Destination Connector Bootstrap + +This destination does three things: +* Split records into chunks and separates metadata from text data +* Embeds text data into an embedding vector +* Stores the metadata and embedding vector in a vector database + +The record processing is using the text split components from https://python.langchain.com/docs/modules/data_connection/document_transformers/. + +There are two possible providers for generating embeddings, [OpenAI](https://python.langchain.com/docs/modules/data_connection/text_embedding/integrations/openai) and [Fake embeddings](https://python.langchain.com/docs/modules/data_connection/text_embedding/integrations/fake) for testing purposes. + +Embedded documents are stored in a vector database. Currently, [Pinecone](https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/pinecone) and the locally stored [DocArrayHnswSearch](https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/docarray_hnsw) are supported. + +For all three components, it's easily possible to add new integrations based on the existing abstractions of the langchain library. In some cases (like the pinecone integration), it's necessary to use the underlying APIs directly to implement more features or improve performance. + +## Pinecone integration + +The pinecone integration is adding stream and primary key to the vector metadata which allows for deduped incremental and full refreshes. It's using the [official pinecone python client](https://github.com/pinecone-io/pinecone-python-client). + +You can use the `test_pinecone.py` file to check whether the pipeline works as expected. + +## DocArrayHnswSearch integration + +The DocArrayHnswSearch integration is storing the vector metadata in a local file in the local root (`/local` in the container, `/tmp/airbyte_local` on the host). It's not possible to dedupe records, so only full refresh syncs are supported. DocArrayHnswSearch uses hnswlib under the hood, but the integration is fully relying on the langchain abstraction. + +You can use the `test_local.py` file to check whether the pipeline works as expected. \ No newline at end of file diff --git a/airbyte-integrations/connectors/destination-langchain/build.gradle b/airbyte-integrations/connectors/destination-langchain/build.gradle new file mode 100644 index 000000000000..9ac8fa2191ac --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/build.gradle @@ -0,0 +1,8 @@ +plugins { + id 'airbyte-python' + id 'airbyte-docker' +} + +airbytePython { + moduleDirectory 'destination_langchain' +} diff --git a/airbyte-integrations/connectors/destination-langchain/destination_langchain/__init__.py b/airbyte-integrations/connectors/destination-langchain/destination_langchain/__init__.py new file mode 100644 index 000000000000..3e63cd2eb391 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/destination_langchain/__init__.py @@ -0,0 +1,8 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +from .destination import DestinationLangchain + +__all__ = ["DestinationLangchain"] diff --git a/airbyte-integrations/connectors/destination-langchain/destination_langchain/batcher.py b/airbyte-integrations/connectors/destination-langchain/destination_langchain/batcher.py new file mode 100644 index 000000000000..ab3ad18c83d8 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/destination_langchain/batcher.py @@ -0,0 +1,26 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +from typing import Any, Callable, List + + +class Batcher: + def __init__(self, batch_size: int, flush_handler: Callable[[List[Any]], None]): + self.batch_size = batch_size + self.buffer = [] + self.flush_handler = flush_handler + + def add(self, item: Any): + self.buffer.append(item) + self._flush_if_necessary() + + def flush(self): + if len(self.buffer) == 0: + return + self.flush_handler(list(self.buffer)) + self.buffer.clear() + + def _flush_if_necessary(self): + if len(self.buffer) >= self.batch_size: + self.flush() diff --git a/airbyte-integrations/connectors/destination-langchain/destination_langchain/config.py b/airbyte-integrations/connectors/destination-langchain/destination_langchain/config.py new file mode 100644 index 000000000000..1236122f4b0a --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/destination_langchain/config.py @@ -0,0 +1,123 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import json +import re +from typing import List, Literal, Optional, Union + +from jsonschema import RefResolver +from pydantic import BaseModel, Field + + +class ProcessingConfigModel(BaseModel): + chunk_size: int = Field( + ..., + title="Chunk size", + maximum=8191, + description="Size of chunks in tokens to store in vector store (make sure it is not too big for the context if your LLM)", + ) + chunk_overlap: int = Field( + title="Chunk overlap", + description="Size of overlap between chunks in tokens to store in vector store to better capture relevant context", + default=0, + ) + text_fields: Optional[List[str]] = Field( + ..., + title="Text fields to embed", + description="List of fields in the record that should be used to calculate the embedding. All other fields are passed along as meta fields. The field list is applied to all streams in the same way and non-existing fields are ignored. If none are defined, all fields are considered text fields. When specifying text fields, you can access nested fields in the record by using dot notation, e.g. `user.name` will access the `name` field in the `user` object. It's also possible to use wildcards to access all fields in an object, e.g. `users.*.name` will access all `names` fields in all entries of the `users` array.", + always_show=True, + examples=["text", "user.name", "users.*.name"], + ) + + class Config: + schema_extra = {"group": "processing"} + + +class OpenAIEmbeddingConfigModel(BaseModel): + mode: Literal["openai"] = Field("openai", const=True) + openai_key: str = Field(..., title="OpenAI API key", airbyte_secret=True) + + class Config: + title = "OpenAI" + schema_extra = { + "description": "Use the OpenAI API to embed text. This option is using the text-embedding-ada-002 model with 1536 embedding dimensions." + } + + +class FakeEmbeddingConfigModel(BaseModel): + mode: Literal["fake"] = Field("fake", const=True) + + class Config: + title = "Fake" + schema_extra = { + "description": "Use a fake embedding made out of random vectors with 1536 embedding dimensions. This is useful for testing the data pipeline without incurring any costs." + } + + +class PineconeIndexingModel(BaseModel): + mode: Literal["pinecone"] = Field("pinecone", const=True) + pinecone_key: str = Field(..., title="Pinecone API key", airbyte_secret=True) + pinecone_environment: str = Field(..., title="Pinecone environment", description="Pinecone environment to use") + index: str = Field(..., title="Index", description="Pinecone index to use") + + class Config: + title = "Pinecone" + schema_extra = { + "description": "Pinecone is a popular vector store that can be used to store and retrieve embeddings. It is a managed service and can also be queried from outside of langchain." + } + + +class DocArrayHnswSearchIndexingModel(BaseModel): + mode: Literal["DocArrayHnswSearch"] = Field("DocArrayHnswSearch", const=True) + destination_path: str = Field( + ..., + title="Destination Path", + description="Path to the directory where hnswlib and meta data files will be written. The files will be placed inside that local mount. All files in the specified destination directory will be deleted on each run.", + examples=["/local/my_hnswlib_index"], + ) + + class Config: + title = "DocArrayHnswSearch" + schema_extra = { + "description": "DocArrayHnswSearch is a lightweight Document Index implementation provided by Docarray that runs fully locally and is best suited for small- to medium-sized datasets. It stores vectors on disk in hnswlib, and stores all other data in SQLite." + } + + +class ConfigModel(BaseModel): + processing: ProcessingConfigModel + embedding: Union[OpenAIEmbeddingConfigModel, FakeEmbeddingConfigModel] = Field( + ..., title="Embedding", description="Embedding configuration", discriminator="mode", group="embedding", type="object" + ) + indexing: Union[PineconeIndexingModel, DocArrayHnswSearchIndexingModel] = Field( + ..., title="Indexing", description="Indexing configuration", discriminator="mode", group="indexing", type="object" + ) + + class Config: + title = "Langchain Destination Config" + schema_extra = { + "groups": [ + {"id": "processing", "title": "Processing"}, + {"id": "embedding", "title": "Embedding"}, + {"id": "indexing", "title": "Indexing"}, + ] + } + + @staticmethod + def resolve_refs(schema: dict) -> dict: + # config schemas can't contain references, so inline them + json_schema_ref_resolver = RefResolver.from_schema(schema) + str_schema = json.dumps(schema) + for ref_block in re.findall(r'{"\$ref": "#\/definitions\/.+?(?="})"}', str_schema): + ref = json.loads(ref_block)["$ref"] + str_schema = str_schema.replace(ref_block, json.dumps(json_schema_ref_resolver.resolve(ref)[1])) + pyschema: dict = json.loads(str_schema) + del pyschema["definitions"] + return pyschema + + @classmethod + def schema(cls): + """we're overriding the schema classmethod to enable some post-processing""" + schema = super().schema() + schema = cls.resolve_refs(schema) + return schema diff --git a/airbyte-integrations/connectors/destination-langchain/destination_langchain/destination.py b/airbyte-integrations/connectors/destination-langchain/destination_langchain/destination.py new file mode 100644 index 000000000000..5dd43b8a3d4b --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/destination_langchain/destination.py @@ -0,0 +1,88 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +from typing import Any, Iterable, List, Mapping + +from airbyte_cdk import AirbyteLogger +from airbyte_cdk.destinations import Destination +from airbyte_cdk.models import ( + AirbyteConnectionStatus, + AirbyteMessage, + AirbyteRecordMessage, + ConfiguredAirbyteCatalog, + ConnectorSpecification, + Status, + Type, +) +from airbyte_cdk.models.airbyte_protocol import DestinationSyncMode +from destination_langchain.batcher import Batcher +from destination_langchain.config import ConfigModel +from destination_langchain.document_processor import DocumentProcessor +from destination_langchain.embedder import Embedder, FakeEmbedder, OpenAIEmbedder +from destination_langchain.indexer import DocArrayHnswSearchIndexer, Indexer, PineconeIndexer +from langchain.document_loaders.base import Document + +BATCH_SIZE = 128 + +indexer_map = {"pinecone": PineconeIndexer, "DocArrayHnswSearch": DocArrayHnswSearchIndexer} + +embedder_map = {"openai": OpenAIEmbedder, "fake": FakeEmbedder} + + +class DestinationLangchain(Destination): + indexer: Indexer + processor: DocumentProcessor + embedder: Embedder + + def _init_indexer(self, config: ConfigModel): + self.embedder = embedder_map[config.embedding.mode](config.embedding) + self.indexer = indexer_map[config.indexing.mode](config.indexing, self.embedder) + + def _process_batch(self, batch: List[AirbyteRecordMessage]): + documents: List[Document] = [] + ids_to_delete = [] + for record in batch: + record_documents, record_id_to_delete = self.processor.process(record) + documents.extend(record_documents) + if record_id_to_delete is not None: + ids_to_delete.append(record_id_to_delete) + self.indexer.index(documents, ids_to_delete) + + def write( + self, config: Mapping[str, Any], configured_catalog: ConfiguredAirbyteCatalog, input_messages: Iterable[AirbyteMessage] + ) -> Iterable[AirbyteMessage]: + config_model = ConfigModel.parse_obj(config) + self._init_indexer(config_model) + self.processor = DocumentProcessor(config_model.processing, configured_catalog, max_metadata_size=self.indexer.max_metadata_size) + batcher = Batcher(BATCH_SIZE, lambda batch: self._process_batch(batch)) + self.indexer.pre_sync(configured_catalog) + for message in input_messages: + if message.type == Type.STATE: + # Emitting a state message indicates that all records which came before it have been written to the destination. So we flush + # the queue to ensure writes happen, then output the state message to indicate it's safe to checkpoint state + batcher.flush() + yield message + elif message.type == Type.RECORD: + batcher.add(message.record) + batcher.flush() + yield from self.indexer.post_sync() + + def check(self, logger: AirbyteLogger, config: Mapping[str, Any]) -> AirbyteConnectionStatus: + self._init_indexer(ConfigModel.parse_obj(config)) + embedder_error = self.embedder.check() + indexer_error = self.indexer.check() + errors = [error for error in [embedder_error, indexer_error] if error is not None] + if len(errors) > 0: + return AirbyteConnectionStatus(status=Status.FAILED, message="\n".join(errors)) + else: + return AirbyteConnectionStatus(status=Status.SUCCEEDED) + + def spec(self, *args: Any, **kwargs: Any) -> ConnectorSpecification: + return ConnectorSpecification( + documentationUrl="https://docs.airbyte.com/integrations/destinations/langchain", + supportsIncremental=True, + supported_destination_sync_modes=[DestinationSyncMode.overwrite, DestinationSyncMode.append, DestinationSyncMode.append_dedup], + connectionSpecification=ConfigModel.schema(), # type: ignore[attr-defined] + ) diff --git a/airbyte-integrations/connectors/destination-langchain/destination_langchain/document_processor.py b/airbyte-integrations/connectors/destination-langchain/destination_langchain/document_processor.py new file mode 100644 index 000000000000..c054cafd8930 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/destination_langchain/document_processor.py @@ -0,0 +1,112 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import logging +from typing import List, Mapping, Optional, Tuple, Union + +import dpath.util +from airbyte_cdk.models import AirbyteRecordMessage, ConfiguredAirbyteCatalog, ConfiguredAirbyteStream +from airbyte_cdk.models.airbyte_protocol import AirbyteStream, DestinationSyncMode +from destination_langchain.config import ProcessingConfigModel +from dpath.exceptions import PathNotFound +from langchain.document_loaders.base import Document +from langchain.text_splitter import RecursiveCharacterTextSplitter +from langchain.utils import stringify_dict + +METADATA_STREAM_FIELD = "_airbyte_stream" +METADATA_RECORD_ID_FIELD = "_record_id" + + +class DocumentProcessor: + streams: Mapping[str, ConfiguredAirbyteStream] + + def __init__(self, config: ProcessingConfigModel, catalog: ConfiguredAirbyteCatalog, max_metadata_size: Optional[int] = None): + self.streams = {self._stream_identifier(stream.stream): stream for stream in catalog.streams} + self.max_metadata_size = max_metadata_size + + self.splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder( + chunk_size=config.chunk_size, chunk_overlap=config.chunk_overlap + ) + self.text_fields = config.text_fields + self.logger = logging.getLogger("airbyte.document_processor") + + def _stream_identifier(self, stream: Union[AirbyteStream, AirbyteRecordMessage]) -> str: + if isinstance(stream, AirbyteStream): + return stream.name if stream.namespace is None else f"{stream.namespace}_{stream.name}" + else: + return stream.stream if stream.namespace is None else f"{stream.namespace}_{stream.stream}" + + def process(self, record: AirbyteRecordMessage) -> Tuple[List[Document], Optional[str]]: + """ + Generate documents from records. + :param records: List of AirbyteRecordMessages + :return: Tuple of (List of document chunks, record id to delete if a stream is in dedup mode to avoid stale documents in the vector store) + """ + doc = self._generate_document(record) + if doc is None: + self.logger.warning(f"Record {str(record.data)[:250]}... does not contain any text fields. Skipping.") + return [], None + chunks = self._split_document(doc) + id_to_delete = doc.metadata[METADATA_RECORD_ID_FIELD] if METADATA_RECORD_ID_FIELD in doc.metadata else None + return chunks, id_to_delete + + def _generate_document(self, record: AirbyteRecordMessage) -> Optional[Document]: + relevant_fields = self._extract_relevant_fields(record) + if len(relevant_fields) == 0: + return None + metadata = self._extract_metadata(record) + text = stringify_dict(relevant_fields) + return Document(page_content=text, metadata=metadata) + + def _extract_relevant_fields(self, record: AirbyteRecordMessage) -> dict: + relevant_fields = {} + if self.text_fields: + for field in self.text_fields: + values = dpath.util.values(record.data, field, separator=".") + if values and len(values) > 0: + relevant_fields[field] = values + else: + relevant_fields = record.data + return relevant_fields + + def _extract_metadata(self, record: AirbyteRecordMessage) -> dict: + metadata = record.data + if self.text_fields: + for field in self.text_fields: + try: + dpath.util.delete(metadata, field, separator=".") + except PathNotFound: + pass # if the field doesn't exist, do nothing + metadata = self._truncate_metadata(metadata) + stream_identifier = self._stream_identifier(record) + current_stream = self.streams[stream_identifier] + metadata[METADATA_STREAM_FIELD] = stream_identifier + # if the sync mode is deduping, use the primary key to upsert existing records instead of appending new ones + if current_stream.primary_key and current_stream.destination_sync_mode == DestinationSyncMode.append_dedup: + # TODO support nested and composite primary keys + metadata[METADATA_RECORD_ID_FIELD] = record.data[current_stream.primary_key[0][0]] + return metadata + + def _truncate_metadata(self, metadata: dict) -> dict: + """ + Normalize metadata to ensure it is within the size limit and doesn't contain complex objects. + """ + result = {} + current_size = 0 + + for key, value in metadata.items(): + if isinstance(value, (str, int, float, bool)): + # Calculate the size of the key and value + item_size = len(str(key)) + len(str(value)) + + # Check if adding the item exceeds the size limit + if self.max_metadata_size is None or current_size + item_size <= self.max_metadata_size: + result[key] = value + current_size += item_size + + return result + + def _split_document(self, doc: Document) -> List[Document]: + chunks = self.splitter.split_documents([doc]) + return chunks diff --git a/airbyte-integrations/connectors/destination-langchain/destination_langchain/embedder.py b/airbyte-integrations/connectors/destination-langchain/destination_langchain/embedder.py new file mode 100644 index 000000000000..55e0674e88a3 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/destination_langchain/embedder.py @@ -0,0 +1,78 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +from abc import ABC, abstractmethod +from typing import Optional + +from destination_langchain.config import FakeEmbeddingConfigModel, OpenAIEmbeddingConfigModel +from destination_langchain.utils import format_exception +from langchain.embeddings.base import Embeddings +from langchain.embeddings.fake import FakeEmbeddings +from langchain.embeddings.openai import OpenAIEmbeddings + + +class Embedder(ABC): + def __init__(self): + pass + + @abstractmethod + def check(self) -> Optional[str]: + pass + + @property + @abstractmethod + def langchain_embeddings(self) -> Embeddings: + pass + + @property + @abstractmethod + def embedding_dimensions(self) -> int: + pass + + +OPEN_AI_VECTOR_SIZE = 1536 + + +class OpenAIEmbedder(Embedder): + def __init__(self, config: OpenAIEmbeddingConfigModel): + super().__init__() + self.embeddings = OpenAIEmbeddings(openai_api_key=config.openai_key, chunk_size=8191) + + def check(self) -> Optional[str]: + try: + self.embeddings.embed_query("test") + except Exception as e: + return format_exception(e) + return None + + @property + def langchain_embeddings(self) -> Embeddings: + return self.embeddings + + @property + def embedding_dimensions(self) -> int: + # vector size produced by text-embedding-ada-002 model + return OPEN_AI_VECTOR_SIZE + + +class FakeEmbedder(Embedder): + def __init__(self, config: FakeEmbeddingConfigModel): + super().__init__() + self.embeddings = FakeEmbeddings(size=OPEN_AI_VECTOR_SIZE) + + def check(self) -> Optional[str]: + try: + self.embeddings.embed_query("test") + except Exception as e: + return format_exception(e) + return None + + @property + def langchain_embeddings(self) -> Embeddings: + return self.embeddings + + @property + def embedding_dimensions(self) -> int: + # use same vector size as for OpenAI embeddings to keep it realistic + return OPEN_AI_VECTOR_SIZE diff --git a/airbyte-integrations/connectors/destination-langchain/destination_langchain/indexer.py b/airbyte-integrations/connectors/destination-langchain/destination_langchain/indexer.py new file mode 100644 index 000000000000..35f2f68b2cf9 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/destination_langchain/indexer.py @@ -0,0 +1,142 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import itertools +import os +import uuid +from abc import ABC, abstractmethod +from typing import Any, List, Optional + +import pinecone +from airbyte_cdk.models import ConfiguredAirbyteCatalog +from airbyte_cdk.models.airbyte_protocol import AirbyteLogMessage, AirbyteMessage, DestinationSyncMode, Level, Type +from destination_langchain.config import DocArrayHnswSearchIndexingModel, PineconeIndexingModel +from destination_langchain.document_processor import METADATA_RECORD_ID_FIELD, METADATA_STREAM_FIELD +from destination_langchain.embedder import Embedder +from destination_langchain.measure_time import measure_time +from destination_langchain.utils import format_exception +from langchain.document_loaders.base import Document +from langchain.vectorstores.docarray import DocArrayHnswSearch + + +class Indexer(ABC): + def __init__(self, config: Any, embedder: Embedder): + self.config = config + self.embedder = embedder + pass + + def pre_sync(self, catalog: ConfiguredAirbyteCatalog): + pass + + def post_sync(self) -> List[AirbyteMessage]: + pass + + @abstractmethod + def index(self, document_chunks: List[Document], delete_ids: List[str]): + pass + + @abstractmethod + def check(self) -> Optional[str]: + pass + + @property + def max_metadata_size(self) -> Optional[int]: + return None + + +def chunks(iterable, batch_size): + """A helper function to break an iterable into chunks of size batch_size.""" + it = iter(iterable) + chunk = tuple(itertools.islice(it, batch_size)) + while chunk: + yield chunk + chunk = tuple(itertools.islice(it, batch_size)) + + +# large enough to speed up processing, small enough to not hit pinecone request limits +PINECONE_BATCH_SIZE = 40 + + +class PineconeIndexer(Indexer): + config: PineconeIndexingModel + + def __init__(self, config: PineconeIndexingModel, embedder: Embedder): + super().__init__(config, embedder) + pinecone.init(api_key=config.pinecone_key, environment=config.pinecone_environment, threaded=True) + self.pinecone_index = pinecone.Index(config.index, pool_threads=10) + self.embed_fn = measure_time(self.embedder.langchain_embeddings.embed_documents) + + def pre_sync(self, catalog: ConfiguredAirbyteCatalog): + for stream in catalog.streams: + if stream.destination_sync_mode == DestinationSyncMode.overwrite: + self.pinecone_index.delete(filter={METADATA_STREAM_FIELD: stream.stream.name}) + + def post_sync(self): + return [AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=Level.WARN, message=self.embed_fn._get_stats()))] + + def index(self, document_chunks, delete_ids): + if len(delete_ids) > 0: + self.pinecone_index.delete(filter={METADATA_RECORD_ID_FIELD: {"$in": delete_ids}}) + embedding_vectors = self.embed_fn([chunk.page_content for chunk in document_chunks]) + pinecone_docs = [] + for i in range(len(document_chunks)): + chunk = document_chunks[i] + metadata = chunk.metadata + metadata["text"] = chunk.page_content + pinecone_docs.append((str(uuid.uuid4()), embedding_vectors[i], metadata)) + async_results = [ + self.pinecone_index.upsert(vectors=ids_vectors_chunk, async_req=True, show_progress=False) + for ids_vectors_chunk in chunks(pinecone_docs, batch_size=PINECONE_BATCH_SIZE) + ] + # Wait for and retrieve responses (this raises in case of error) + [async_result.get() for async_result in async_results] + + def check(self) -> Optional[str]: + try: + pinecone.describe_index(self.config.index) + except Exception as e: + return format_exception(e) + return None + + @property + def max_metadata_size(self) -> int: + # leave some space for the text field + return 40_960 - 10_000 + + +class DocArrayHnswSearchIndexer(Indexer): + config: DocArrayHnswSearchIndexingModel + + def __init__(self, config: DocArrayHnswSearchIndexingModel, embedder: Embedder): + super().__init__(config, embedder) + + def _init_vectorstore(self): + self.vectorstore = DocArrayHnswSearch.from_params( + embedding=self.embedder.langchain_embeddings, work_dir=self.config.destination_path, n_dim=self.embedder.embedding_dimensions + ) + + def pre_sync(self, catalog: ConfiguredAirbyteCatalog): + for stream in catalog.streams: + if stream.destination_sync_mode != DestinationSyncMode.overwrite: + raise Exception( + f"DocArrayHnswSearchIndexer only supports overwrite mode, got {stream.destination_sync_mode} for stream {stream.stream.name}" + ) + for file in os.listdir(self.config.destination_path): + os.remove(os.path.join(self.config.destination_path, file)) + self._init_vectorstore() + + def post_sync(self): + return [AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=Level.WARN, message=self.index._get_stats()))] + + @measure_time + def index(self, document_chunks, delete_ids: List[str]): + # does not support deleting documents, always full refresh sync + self.vectorstore.add_documents(document_chunks) + + def check(self) -> Optional[str]: + try: + self._init_vectorstore() + except Exception as e: + return format_exception(e) + return None diff --git a/airbyte-integrations/connectors/destination-langchain/destination_langchain/measure_time.py b/airbyte-integrations/connectors/destination-langchain/destination_langchain/measure_time.py new file mode 100644 index 000000000000..da074de5801e --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/destination_langchain/measure_time.py @@ -0,0 +1,29 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import time + + +def measure_time(func): + def wrapper(*args, **kwargs): + wrapper.count += 1 + start_time = time.time() + result = func(*args, **kwargs) + end_time = time.time() + execution_time = end_time - start_time + + wrapper.total_time += execution_time + wrapper.average_time = wrapper.total_time / wrapper.count + + return result + + wrapper.count = 0 + wrapper.total_time = 0 + wrapper.average_time = 0 + wrapper._get_stats = lambda: get_stats(wrapper) + + def get_stats(wrapper): + return f"Function '{func.__name__}' called {wrapper.count} time(s).\nAverage execution time: {wrapper.average_time:.6f} seconds.\nTotal execution time: {wrapper.total_time:.6f} seconds." + + return wrapper diff --git a/airbyte-integrations/connectors/destination-langchain/destination_langchain/utils.py b/airbyte-integrations/connectors/destination-langchain/destination_langchain/utils.py new file mode 100644 index 000000000000..05644e2e7709 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/destination_langchain/utils.py @@ -0,0 +1,9 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import traceback + + +def format_exception(exception: Exception) -> None: + return str(exception) + "\n" + "".join(traceback.TracebackException.from_exception(exception).format()) diff --git a/airbyte-integrations/connectors/destination-langchain/examples/configured_catalog.json b/airbyte-integrations/connectors/destination-langchain/examples/configured_catalog.json new file mode 100644 index 000000000000..9ec161468685 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/examples/configured_catalog.json @@ -0,0 +1,20 @@ +{ + "streams": [ + { + "stream": { + "name": "example_stream", + "json_schema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": {} + }, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": false, + "default_cursor_field": ["column_name"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + } + ] + } + \ No newline at end of file diff --git a/airbyte-integrations/connectors/destination-langchain/examples/messages.jsonl b/airbyte-integrations/connectors/destination-langchain/examples/messages.jsonl new file mode 100644 index 000000000000..80e15fb36948 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/examples/messages.jsonl @@ -0,0 +1,2 @@ +{"type": "RECORD", "record": {"stream": "example_stream", "data": { "title": "value1", "field2": "value2" }, "emitted_at": 1625383200000}} +{"type": "RECORD", "record": {"stream": "example_stream", "data": { "title": "value2", "field2": "value2" }, "emitted_at": 1625383200000}} \ No newline at end of file diff --git a/airbyte-integrations/connectors/destination-langchain/icon.svg b/airbyte-integrations/connectors/destination-langchain/icon.svg new file mode 100644 index 000000000000..6796e747d783 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/icon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/airbyte-integrations/connectors/destination-langchain/integration_tests/base_integration_test.py b/airbyte-integrations/connectors/destination-langchain/integration_tests/base_integration_test.py new file mode 100644 index 000000000000..bcbcf6e49836 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/integration_tests/base_integration_test.py @@ -0,0 +1,42 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import unittest +from typing import Any, Dict + +from airbyte_cdk.models import ( + AirbyteMessage, + AirbyteRecordMessage, + AirbyteStateMessage, + AirbyteStream, + ConfiguredAirbyteCatalog, + ConfiguredAirbyteStream, + DestinationSyncMode, + SyncMode, + Type, +) + + +class BaseIntegrationTest(unittest.TestCase): + def _get_configured_catalog(self, destination_mode: DestinationSyncMode) -> ConfiguredAirbyteCatalog: + stream_schema = {"type": "object", "properties": {"str_col": {"type": "str"}, "int_col": {"type": "integer"}}} + + overwrite_stream = ConfiguredAirbyteStream( + stream=AirbyteStream( + name="mystream", json_schema=stream_schema, supported_sync_modes=[SyncMode.incremental, SyncMode.full_refresh] + ), + primary_key=[["int_col"]], + sync_mode=SyncMode.incremental, + destination_sync_mode=destination_mode, + ) + + return ConfiguredAirbyteCatalog(streams=[overwrite_stream]) + + def _state(self, data: Dict[str, Any]) -> AirbyteMessage: + return AirbyteMessage(type=Type.STATE, state=AirbyteStateMessage(data=data)) + + def _record(self, stream: str, str_value: str, int_value: int) -> AirbyteMessage: + return AirbyteMessage( + type=Type.RECORD, record=AirbyteRecordMessage(stream=stream, data={"str_col": str_value, "int_col": int_value}, emitted_at=0) + ) diff --git a/airbyte-integrations/connectors/destination-langchain/integration_tests/local_integration_test.py b/airbyte-integrations/connectors/destination-langchain/integration_tests/local_integration_test.py new file mode 100644 index 000000000000..0530c712e0fa --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/integration_tests/local_integration_test.py @@ -0,0 +1,46 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import logging +import os +import tempfile + +from airbyte_cdk.models import DestinationSyncMode, Status +from destination_langchain.destination import DestinationLangchain +from destination_langchain.embedder import OPEN_AI_VECTOR_SIZE +from integration_tests.base_integration_test import BaseIntegrationTest +from langchain.embeddings import FakeEmbeddings +from langchain.vectorstores import DocArrayHnswSearch + + +class LocalIntegrationTest(BaseIntegrationTest): + def setUp(self): + self.temp_dir = tempfile.mkdtemp() + self.config = { + "processing": {"text_fields": ["str_col"], "chunk_size": 1000}, + "embedding": {"mode": "fake"}, + "indexing": {"mode": "DocArrayHnswSearch", "destination_path": self.temp_dir}, + } + + def tearDown(self): + for file in os.listdir(self.temp_dir): + os.remove(os.path.join(self.temp_dir, file)) + os.removedirs(self.temp_dir) + + def test_check_valid_config(self): + outcome = DestinationLangchain().check(logging.getLogger("airbyte"), self.config) + assert outcome.status == Status.SUCCEEDED + + def test_write(self): + catalog = self._get_configured_catalog(DestinationSyncMode.overwrite) + first_state_message = self._state({"state": "1"}) + first_record_chunk = [self._record("mystream", f"Dogs are nice, number {i}", i) for i in range(5)] + + destination = DestinationLangchain() + list(destination.write(self.config, catalog, [*first_record_chunk, first_state_message])) + + vector_store = DocArrayHnswSearch.from_params(embedding=FakeEmbeddings(size=OPEN_AI_VECTOR_SIZE), work_dir=self.temp_dir, n_dim=OPEN_AI_VECTOR_SIZE) + + result = vector_store.similarity_search("does not match anyway", 10) + assert len(result) == 5 diff --git a/airbyte-integrations/connectors/destination-langchain/integration_tests/pinecone_integration_test.py b/airbyte-integrations/connectors/destination-langchain/integration_tests/pinecone_integration_test.py new file mode 100644 index 000000000000..b6c555ea3c3c --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/integration_tests/pinecone_integration_test.py @@ -0,0 +1,76 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import json +import logging + +import pinecone +from airbyte_cdk.models import DestinationSyncMode, Status +from destination_langchain.destination import DestinationLangchain +from destination_langchain.embedder import OPEN_AI_VECTOR_SIZE +from integration_tests.base_integration_test import BaseIntegrationTest +from langchain.embeddings import OpenAIEmbeddings +from langchain.vectorstores import Pinecone + + +class PineconeIntegrationTest(BaseIntegrationTest): + def _init_pinecone(self): + pinecone.init(api_key=self.config["indexing"]["pinecone_key"], environment=self.config["indexing"]["pinecone_environment"]) + + def setUp(self): + with open("secrets/config.json", "r") as f: + self.config = json.loads(f.read()) + self._init_pinecone() + + def tearDown(self): + # make sure pinecone is initialized correctly before cleaning up + self._init_pinecone() + pinecone.Index("testdata").delete(delete_all=True) + + def test_check_valid_config(self): + outcome = DestinationLangchain().check(logging.getLogger("airbyte"), self.config) + assert outcome.status == Status.SUCCEEDED + + def test_check_invalid_config(self): + outcome = DestinationLangchain().check( + logging.getLogger("airbyte"), + { + "processing": {"text_fields": ["str_col"], "chunk_size": 1000}, + "embedding": {"mode": "openai", "openai_key": "mykey"}, + "indexing": { + "mode": "pinecone", + "pinecone_key": "mykey", + "index": "testdata", + "pinecone_environment": "asia-southeast1-gcp-free", + }, + }, + ) + assert outcome.status == Status.FAILED + + def test_write(self): + catalog = self._get_configured_catalog(DestinationSyncMode.overwrite) + first_state_message = self._state({"state": "1"}) + first_record_chunk = [self._record("mystream", f"Dogs are number {i}", i) for i in range(5)] + + # initial sync + destination = DestinationLangchain() + list(destination.write(self.config, catalog, [*first_record_chunk, first_state_message])) + assert pinecone.Index("testdata").describe_index_stats().total_vector_count == 5 + + # incrementalally update a doc + incremental_catalog = self._get_configured_catalog(DestinationSyncMode.append_dedup) + list(destination.write(self.config, incremental_catalog, [self._record("mystream", "Cats are nice", 2), first_state_message])) + result = pinecone.Index("testdata").query( + vector=[0] * OPEN_AI_VECTOR_SIZE, top_k=10, filter={"_record_id": 2}, include_metadata=True + ) + assert len(result.matches) == 1 + assert result.matches[0].metadata["text"] == "str_col: Cats are nice" + + # test langchain integration + embeddings = OpenAIEmbeddings(openai_api_key=self.config["embedding"]["openai_key"]) + pinecone.init(api_key=self.config["indexing"]["pinecone_key"], environment=self.config["indexing"]["pinecone_environment"]) + index = pinecone.Index("testdata") + vector_store = Pinecone(index, embeddings.embed_query, "text") + result = vector_store.similarity_search("feline animals", 1) + assert result[0].metadata["_record_id"] == 2 diff --git a/airbyte-integrations/connectors/destination-langchain/main.py b/airbyte-integrations/connectors/destination-langchain/main.py new file mode 100644 index 000000000000..717d9a760388 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/main.py @@ -0,0 +1,11 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +import sys + +from destination_langchain import DestinationLangchain + +if __name__ == "__main__": + DestinationLangchain().run(sys.argv[1:]) diff --git a/airbyte-integrations/connectors/destination-langchain/metadata.yaml b/airbyte-integrations/connectors/destination-langchain/metadata.yaml new file mode 100644 index 000000000000..be1010642e03 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/metadata.yaml @@ -0,0 +1,20 @@ +data: + registries: + oss: + enabled: false + connectorSubtype: database + connectorType: destination + definitionId: cf98d52c-ba5a-4dfd-8ada-c1baebfa6e73 + dockerImageTag: 0.0.1 + dockerRepository: airbyte/destination-langchain + githubIssueLabel: destination-langchain + icon: langchain.svg + license: MIT + name: Vector Database (powered by LangChain) + releaseDate: 2023-07-15 + releaseStage: alpha + supportUrl: https://docs.airbyte.com/integrations/destinations/langchain + documentationUrl: https://docs.airbyte.com/integrations/destinations/langchain + tags: + - language:python +metadataSpecVersion: "1.0" diff --git a/airbyte-integrations/connectors/destination-langchain/requirements.txt b/airbyte-integrations/connectors/destination-langchain/requirements.txt new file mode 100644 index 000000000000..d6e1198b1ab1 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/requirements.txt @@ -0,0 +1 @@ +-e . diff --git a/airbyte-integrations/connectors/destination-langchain/setup.py b/airbyte-integrations/connectors/destination-langchain/setup.py new file mode 100644 index 000000000000..fe060aa7e1d6 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/setup.py @@ -0,0 +1,34 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +from setuptools import find_packages, setup + +MAIN_REQUIREMENTS = [ + "airbyte-cdk", + "langchain", + "openai", + "requests", + "tiktoken", + "docarray[hnswlib]>=0.32.0", + "pinecone-client", + "typing-inspect==0.8.0", + "typing_extensions==4.5.0", + "pydantic==1.10.8", +] + +TEST_REQUIREMENTS = ["pytest~=6.2"] + +setup( + name="destination_langchain", + description="Destination implementation for Langchain.", + author="Airbyte", + author_email="contact@airbyte.io", + packages=find_packages(), + install_requires=MAIN_REQUIREMENTS, + package_data={"": ["*.json"]}, + extras_require={ + "tests": TEST_REQUIREMENTS, + }, +) diff --git a/airbyte-integrations/connectors/destination-langchain/test_local.py b/airbyte-integrations/connectors/destination-langchain/test_local.py new file mode 100644 index 000000000000..b38364e110b6 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/test_local.py @@ -0,0 +1,25 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +from langchain.chains import RetrievalQA +from langchain.embeddings import OpenAIEmbeddings +from langchain.llms import OpenAI +from langchain.vectorstores import DocArrayHnswSearch + +# Run with OPENAI_API_KEY set in the environment + +embeddings = OpenAIEmbeddings() +vector_store = DocArrayHnswSearch.from_params(embeddings, "/tmp/airbyte_local/special_path", 1536) + +# print(vector_store.similarity_search("python", 1)) + +qa = RetrievalQA.from_chain_type(llm=OpenAI(temperature=0), chain_type="stuff", retriever=vector_store.as_retriever()) + +print("Chat Langchain Demo") +print("Ask a question to begin:") +while True: + query = input("") + answer = qa.run(query) + print(answer) + print("\nWhat else can I help you with:") diff --git a/airbyte-integrations/connectors/destination-langchain/test_pinecone.py b/airbyte-integrations/connectors/destination-langchain/test_pinecone.py new file mode 100644 index 000000000000..41e87a8cf243 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/test_pinecone.py @@ -0,0 +1,43 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import os + +import pinecone +from langchain.chains import RetrievalQA +from langchain.embeddings import OpenAIEmbeddings +from langchain.llms import OpenAI +from langchain.vectorstores import Pinecone + +# Run with OPENAI_API_KEY, PINECONE_KEY and PINECONE_ENV set in the environment + +embeddings = OpenAIEmbeddings() +pinecone.init(api_key=os.environ["PINECONE_KEY"], environment=os.environ["PINECONE_ENV"]) +index = pinecone.Index("testdata") +vector_store = Pinecone(index, embeddings.embed_query, "text") + + +# Playing with a Github issue search use case + +# prompt_template = """You are a question-answering bot operating on Github issues. Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer. In the end, state the issue number you based your answer on. + +# {context} + +# Question: {question} +# Helpful Answer:""" +# prompt = PromptTemplate( +# template=prompt_template, input_variables=["context", "question"] +# ) +# document_prompt = PromptTemplate(input_variables=["page_content", "number"], template="{page_content}, issue number: {number}") +# qa = RetrievalQA.from_chain_type(llm=OpenAI(temperature=0), chain_type="stuff", retriever=vector_store.as_retriever(), chain_type_kwargs={"prompt": prompt, "document_prompt": document_prompt}) + +qa = RetrievalQA.from_chain_type(llm=OpenAI(temperature=0), chain_type="stuff", retriever=vector_store.as_retriever()) + +print("Chat Langchain Demo") +print("Ask a question to begin:") +while True: + query = input("") + answer = qa.run(query) + print(answer) + print("\nWhat else can I help you with:") diff --git a/airbyte-integrations/connectors/destination-langchain/unit_tests/batcher_test.py b/airbyte-integrations/connectors/destination-langchain/unit_tests/batcher_test.py new file mode 100644 index 000000000000..50538ea324b7 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/unit_tests/batcher_test.py @@ -0,0 +1,94 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import unittest +from unittest.mock import MagicMock + +from destination_langchain.batcher import Batcher + + +class BatcherTestCase(unittest.TestCase): + def test_add_single_item(self): + # Arrange + batch_size = 3 + flush_handler_mock = MagicMock() + batcher = Batcher(batch_size, flush_handler_mock) + + # Act + batcher.add(1) + + # Assert + self.assertFalse(flush_handler_mock.called) + + def test_add_flushes_batch(self): + # Arrange + batch_size = 3 + flush_handler_mock = MagicMock() + batcher = Batcher(batch_size, flush_handler_mock) + + # Act + batcher.add(1) + batcher.add(2) + batcher.add(3) + + # Assert + flush_handler_mock.assert_called_once_with([1, 2, 3]) + + def test_flush_empty_buffer(self): + # Arrange + batch_size = 3 + flush_handler_mock = MagicMock() + batcher = Batcher(batch_size, flush_handler_mock) + + # Act + batcher.flush() + + # Assert + self.assertFalse(flush_handler_mock.called) + + def test_flush_non_empty_buffer(self): + # Arrange + batch_size = 3 + flush_handler_mock = MagicMock() + batcher = Batcher(batch_size, flush_handler_mock) + batcher.add(1) + batcher.add(2) + + # Act + batcher.flush() + + # Assert + flush_handler_mock.assert_called_once_with([1, 2]) + self.assertEqual(len(batcher.buffer), 0) + + def test_flush_if_necessary_flushes_batch(self): + # Arrange + batch_size = 3 + flush_handler_mock = MagicMock() + batcher = Batcher(batch_size, flush_handler_mock) + batcher.add(1) + batcher.add(2) + batcher.add(3) + + # Act + batcher.add(4) + batcher.add(5) + + # Assert + flush_handler_mock.assert_called_once_with([1, 2, 3]) + self.assertEqual(len(batcher.buffer), 2) + + def test_flush_if_necessary_does_not_flush_incomplete_batch(self): + # Arrange + batch_size = 3 + flush_handler_mock = MagicMock() + batcher = Batcher(batch_size, flush_handler_mock) + batcher.add(1) + + # Act + batcher.add(2) + + # Assert + self.assertFalse(flush_handler_mock.called) + self.assertEqual(len(batcher.buffer), 2) diff --git a/airbyte-integrations/connectors/destination-langchain/unit_tests/destination_test.py b/airbyte-integrations/connectors/destination-langchain/unit_tests/destination_test.py new file mode 100644 index 000000000000..2b27d4d25ed6 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/unit_tests/destination_test.py @@ -0,0 +1,103 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +from unittest.mock import MagicMock, patch + +from airbyte_cdk.models.airbyte_protocol import ( + AirbyteLogMessage, + AirbyteMessage, + AirbyteRecordMessage, + AirbyteStateMessage, + ConfiguredAirbyteCatalog, + Level, + Type, +) +from destination_langchain.config import ConfigModel +from destination_langchain.destination import BATCH_SIZE, DestinationLangchain, embedder_map, indexer_map + + +def _generate_record_message(index: int): + return AirbyteMessage(type=Type.RECORD, record=AirbyteRecordMessage(stream="example_stream", emitted_at=1234, data={"column_name": f"value {index}", "id": index})) + + +@patch.dict(embedder_map, {"openai": MagicMock()}) +@patch.dict(indexer_map, {"pinecone": MagicMock()}) +def test_write(): + """ + Basic test for the write method, batcher and document processor. + """ + config = { + "processing": {"text_fields": ["column_name"], "chunk_size": 1000}, + "embedding": {"mode": "openai", "openai_key": "mykey"}, + "indexing": { + "mode": "pinecone", + "pinecone_key": "mykey", + "index": "myindex", + "pinecone_environment": "myenv", + }, + } + config_model = ConfigModel.parse_obj(config) + + configured_catalog: ConfiguredAirbyteCatalog = ConfiguredAirbyteCatalog.parse_obj( + { + "streams": [ + { + "stream": { + "name": "example_stream", + "json_schema": {"$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": {}}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": False, + "default_cursor_field": ["column_name"], + }, + "primary_key": [["id"]], + "sync_mode": "incremental", + "destination_sync_mode": "append_dedup", + } + ] + } + ) + # messages are flushed after 32 records or after a state message, so this will trigger two batches to be processed + input_messages = [_generate_record_message(i) for i in range(BATCH_SIZE + 5)] + state_message = AirbyteMessage(type=Type.STATE, state=AirbyteStateMessage()) + input_messages.append(state_message) + # messages are also flushed once the input messages are exhausted, so this will trigger another batch + input_messages.extend([_generate_record_message(i) for i in range(5)]) + + mock_embedder = MagicMock() + embedder_map["openai"].return_value = mock_embedder + + mock_indexer = MagicMock() + indexer_map["pinecone"].return_value = mock_indexer + mock_indexer.max_metadata_size = 1000 + post_sync_log_message = AirbyteMessage(type=Type.LOG, log=AirbyteLogMessage(level=Level.INFO, message="post sync")) + mock_indexer.post_sync.return_value = [post_sync_log_message] + + # Create the DestinationLangchain instance + destination = DestinationLangchain() + + output_messages = destination.write(config, configured_catalog, input_messages) + output_message = next(output_messages) + # assert state message is + assert output_message == state_message + + embedder_map["openai"].assert_called_with(config_model.embedding) + indexer_map["pinecone"].assert_called_with(config_model.indexing, mock_embedder) + mock_indexer.pre_sync.assert_called_with(configured_catalog) + + # 1 batches due to max batch size reached and 1 batch due to state message + assert mock_indexer.index.call_count == 2 + + output_message = next(output_messages) + assert output_message == post_sync_log_message + + try: + next(output_messages) + assert False, "Expected end of message stream" + except StopIteration: + pass + + # 1 batch due to end of message stream + assert mock_indexer.index.call_count == 3 + + mock_indexer.post_sync.assert_called() diff --git a/airbyte-integrations/connectors/destination-langchain/unit_tests/docarray_indexer_test.py b/airbyte-integrations/connectors/destination-langchain/unit_tests/docarray_indexer_test.py new file mode 100644 index 000000000000..d4486811d2dc --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/unit_tests/docarray_indexer_test.py @@ -0,0 +1,95 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import unittest +from unittest.mock import MagicMock, patch + +from airbyte_cdk.models import ConfiguredAirbyteCatalog +from destination_langchain.config import DocArrayHnswSearchIndexingModel +from destination_langchain.indexer import DocArrayHnswSearchIndexer +from langchain.document_loaders.base import Document + + +class DocArrayIndexerTest(unittest.TestCase): + def setUp(self): + self.config = DocArrayHnswSearchIndexingModel(mode="DocArrayHnswSearch", destination_path="/tmp/made_up") + self.embedder = MagicMock() + self.embedder.embedding_dimensions = 3 + self.indexer = DocArrayHnswSearchIndexer(self.config, self.embedder) + self.indexer.vectorstore = MagicMock() + + def test_docarray_index(self): + docs = [ + Document(page_content="test", metadata={"_airbyte_stream": "abc"}), + Document(page_content="test2", metadata={"_airbyte_stream": "abc"}), + ] + + self.indexer.index( + docs, + ["delete_id1", "delete_id2"], + ) + # deleted documents are ignored + self.indexer.vectorstore.add_documents.assert_called_with(docs) + + def test_docarray_pre_sync_fail(self): + try: + self.indexer.pre_sync(ConfiguredAirbyteCatalog.parse_obj( + { + "streams": [ + { + "stream": { + "name": "example_stream", + "json_schema": {"$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": {}}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": False, + "default_cursor_field": ["column_name"], + }, + "primary_key": [["id"]], + "sync_mode": "incremental", + "destination_sync_mode": "append_dedup", + }, + ] + } + )) + assert False, "Expected exception" + except Exception as e: + assert str(e) == "DocArrayHnswSearchIndexer only supports overwrite mode, got DestinationSyncMode.append_dedup for stream example_stream" + + @patch('os.listdir') + @patch('os.remove') + def test_docarray_pre_sync_succeed(self, remove_mock, listdir_mock): + listdir_mock.return_value = ["file1", "file2"] + self.indexer._init_vectorstore = MagicMock() + self.indexer.pre_sync(ConfiguredAirbyteCatalog.parse_obj( + { + "streams": [ + { + "stream": { + "name": "example_stream", + "json_schema": {"$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": {}}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": False, + "default_cursor_field": ["column_name"], + }, + "primary_key": [["id"]], + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite", + }, + { + "stream": { + "name": "example_stream2", + "json_schema": {"$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": {}}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": False, + "default_cursor_field": ["column_name"], + }, + "primary_key": [["id"]], + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite", + }, + ] + } + )) + assert remove_mock.call_count == 2 + assert self.indexer._init_vectorstore.call_count == 1 diff --git a/airbyte-integrations/connectors/destination-langchain/unit_tests/document_processor_test.py b/airbyte-integrations/connectors/destination-langchain/unit_tests/document_processor_test.py new file mode 100644 index 000000000000..63031635d1cf --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/unit_tests/document_processor_test.py @@ -0,0 +1,232 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +from unittest.mock import MagicMock + +from airbyte_cdk.models import AirbyteStream, ConfiguredAirbyteCatalog, ConfiguredAirbyteStream +from airbyte_cdk.models.airbyte_protocol import AirbyteRecordMessage, DestinationSyncMode, SyncMode +from destination_langchain.config import ProcessingConfigModel +from destination_langchain.document_processor import DocumentProcessor + + +def initialize_processor(): + config = ProcessingConfigModel(chunk_size=48, chunk_overlap=0, text_fields=None) + catalog = ConfiguredAirbyteCatalog( + streams=[ + ConfiguredAirbyteStream( + stream=AirbyteStream(name="stream1", json_schema={}, namespace="namespace1", supported_sync_modes=[SyncMode.full_refresh]), + sync_mode=SyncMode.full_refresh, + destination_sync_mode=DestinationSyncMode.overwrite, + primary_key=[["id"]], + ), + ConfiguredAirbyteStream( + stream=AirbyteStream(name="stream2", json_schema={}, supported_sync_modes=[SyncMode.full_refresh]), + sync_mode=SyncMode.full_refresh, + destination_sync_mode=DestinationSyncMode.overwrite, + ), + ] + ) + return DocumentProcessor(config=config, catalog=catalog) + + +def test_process_single_chunk_without_metadata(): + processor = initialize_processor() + + record = AirbyteRecordMessage( + stream="stream1", + namespace="namespace1", + data={ + "id": 1, + "text": "This is the text", + }, + emitted_at=1234, + ) + + chunks, id_to_delete = processor.process(record) + + assert len(chunks) == 1 + # natural id is only set for dedup mode + assert "_record_id" not in chunks[0].metadata + assert chunks[0].metadata["_airbyte_stream"] == "namespace1_stream1" + assert chunks[0].page_content == "id: 1\ntext: This is the text" + assert id_to_delete is None + + +def test_process_single_chunk_without_namespace(): + config = ProcessingConfigModel(chunk_size=48, chunk_overlap=0, text_fields=None) + catalog = ConfiguredAirbyteCatalog( + streams=[ + ConfiguredAirbyteStream( + stream=AirbyteStream(name="stream1", json_schema={}, supported_sync_modes=[SyncMode.full_refresh]), + sync_mode=SyncMode.full_refresh, + destination_sync_mode=DestinationSyncMode.overwrite, + ), + ] + ) + processor = DocumentProcessor(config=config, catalog=catalog) + + record = AirbyteRecordMessage( + stream="stream1", + data={ + "id": 1, + "text": "This is the text", + }, + emitted_at=1234, + ) + + chunks, _ = processor.process(record) + assert chunks[0].metadata["_airbyte_stream"] == "stream1" + + +def test_complex_text_fields(): + processor = initialize_processor() + + record = AirbyteRecordMessage( + stream="stream1", + namespace="namespace1", + data={ + "id": 1, + "nested": { + "texts": [ + {"text": "This is the text"}, + {"text": "And another"}, + ] + }, + "non_text": "a", + "non_text_2": 1, + "text": "This is the regular text", + "other_nested": { + "non_text": { + "a": "xyz", + "b": "abc" + } + } + }, + emitted_at=1234, + ) + + processor.text_fields = ["nested.texts.*.text", "text", "other_nested.non_text", "non.*.existing"] + + chunks, _ = processor.process(record) + + assert len(chunks) == 1 + assert chunks[0].page_content == """nested.texts.*.text: This is the text +And another +text: This is the regular text +other_nested.non_text: \na: xyz +b: abc""" + assert chunks[0].metadata == { + "id": 1, + "non_text": "a", + "non_text_2": 1, + "_airbyte_stream": "namespace1_stream1" + } + + +def test_non_text_fields(): + processor = initialize_processor() + + record = AirbyteRecordMessage( + stream="stream1", + namespace="namespace1", + data={ + "id": 1, + "text": "This is the regular text", + }, + emitted_at=1234, + ) + + processor.text_fields = ["another_field"] + processor.logger = MagicMock() + + chunks, id_to_delete = processor.process(record) + + assert len(chunks) == 0 + assert id_to_delete is None + assert processor.logger.warning.called + + +def test_metadata_normalization(): + processor = initialize_processor() + + record = AirbyteRecordMessage( + stream="stream1", + namespace="namespace1", + data={ + "id": 1, + "a_complex_field": {"a_nested_field": "a_nested_value"}, + "too_big": "a" * 1000, + "small": "a", + "text": "This is the text", + }, + emitted_at=1234, + ) + + processor.text_fields = ["text"] + processor.max_metadata_size = 100 + + chunks, id_to_delete = processor.process(record) + + assert len(chunks) == 1 + assert chunks[0].page_content == "text: This is the text" + assert id_to_delete is None + + for chunk in chunks: + assert len(chunk.metadata) == 3 + assert "a_complex_field" not in chunk.metadata + assert "too_big" not in chunk.metadata + assert "small" in chunk.metadata + + +def test_process_multiple_chunks_with_relevant_fields(): + processor = initialize_processor() + + record = AirbyteRecordMessage( + stream="stream1", + namespace="namespace1", + data={ + "id": 1, + "name": "John Doe", + "text": "This is the text and it is long enough to be split into multiple chunks. This is the text and it is long enough to be split into multiple chunks. This is the text and it is long enough to be split into multiple chunks", + "age": 25, + }, + emitted_at=1234, + ) + + processor.text_fields = ["text"] + + chunks, id_to_delete = processor.process(record) + + assert len(chunks) == 2 + + for chunk in chunks: + assert chunk.metadata["age"] == 25 + assert id_to_delete is None + + +def test_process_multiple_chunks_with_dedupe_mode(): + processor = initialize_processor() + + record = AirbyteRecordMessage( + stream="stream1", + namespace="namespace1", + data={ + "id": 99, + "text": "This is the text and it is long enough to be split into multiple chunks. This is the text and it is long enough to be split into multiple chunks. This is the text and it is long enough to be split into multiple chunks", + "age": 25, + }, + emitted_at=1234, + ) + + processor.text_fields = ["text"] + + processor.streams["namespace1_stream1"].destination_sync_mode = DestinationSyncMode.append_dedup + processor.streams["namespace1_stream1"].primary_key = [["id"]] # Primary key defined + + chunks, id_to_delete = processor.process(record) + + assert len(chunks) > 1 + assert chunks[0].metadata["_record_id"] == 99 + assert id_to_delete == 99 diff --git a/airbyte-integrations/connectors/destination-langchain/unit_tests/pinecone_indexer_test.py b/airbyte-integrations/connectors/destination-langchain/unit_tests/pinecone_indexer_test.py new file mode 100644 index 000000000000..5a6b37edce59 --- /dev/null +++ b/airbyte-integrations/connectors/destination-langchain/unit_tests/pinecone_indexer_test.py @@ -0,0 +1,101 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +from unittest.mock import ANY, MagicMock + +from airbyte_cdk.models import ConfiguredAirbyteCatalog +from destination_langchain.config import PineconeIndexingModel +from destination_langchain.indexer import PineconeIndexer +from langchain.document_loaders.base import Document + + +def create_pinecone_indexer(): + config = PineconeIndexingModel(mode="pinecone", pinecone_environment="myenv", pinecone_key="mykey", index="myindex") + embedder = MagicMock() + indexer = PineconeIndexer(config, embedder) + + indexer.pinecone_index.delete = MagicMock() + indexer.embed_fn = MagicMock(return_value=[[1, 2, 3], [4, 5, 6]]) + indexer.pinecone_index.upsert = MagicMock() + return indexer + + +def test_pinecone_index_upsert_and_delete(): + indexer = create_pinecone_indexer() + indexer.index( + [ + Document(page_content="test", metadata={"_airbyte_stream": "abc"}), + Document(page_content="test2", metadata={"_airbyte_stream": "abc"}), + ], + ["delete_id1", "delete_id2"], + ) + indexer.pinecone_index.delete.assert_called_with(filter={"_record_id": {"$in": ["delete_id1", "delete_id2"]}}) + indexer.pinecone_index.upsert.assert_called_with( + vectors=( + (ANY, [1, 2, 3], {"_airbyte_stream": "abc", "text": "test"}), + (ANY, [4, 5, 6], {"_airbyte_stream": "abc", "text": "test2"}), + ), + async_req=True, + show_progress=False + ) + + +def test_pinecone_index_empty_batch(): + indexer = create_pinecone_indexer() + indexer.index( + [ + ], + [], + ) + indexer.pinecone_index.delete.assert_not_called() + indexer.pinecone_index.upsert.assert_not_called() + + +def test_pinecone_index_upsert_batching(): + indexer = create_pinecone_indexer() + indexer.embed_fn = MagicMock(return_value=[[i, i, i] for i in range(50)]) + indexer.index( + [Document(page_content=f"test {i}", metadata={"_airbyte_stream": "abc"}) for i in range(50)], + [], + ) + assert indexer.pinecone_index.upsert.call_count == 2 + for i in range(40): + assert indexer.pinecone_index.upsert.call_args_list[0].kwargs["vectors"][i] == (ANY, [i, i, i], {"_airbyte_stream": "abc", "text": f"test {i}"}) + for i in range(40, 50): + assert indexer.pinecone_index.upsert.call_args_list[1].kwargs["vectors"][i-40] == (ANY, [i, i, i], {"_airbyte_stream": "abc", "text": f"test {i}"}) + + +def test_pinecone_pre_sync(): + indexer = create_pinecone_indexer() + indexer.pre_sync(ConfiguredAirbyteCatalog.parse_obj( + { + "streams": [ + { + "stream": { + "name": "example_stream", + "json_schema": {"$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": {}}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": False, + "default_cursor_field": ["column_name"], + }, + "primary_key": [["id"]], + "sync_mode": "incremental", + "destination_sync_mode": "append_dedup", + }, + { + "stream": { + "name": "example_stream2", + "json_schema": {"$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": {}}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": False, + "default_cursor_field": ["column_name"], + }, + "primary_key": [["id"]], + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite", + } + ] + } + )) + indexer.pinecone_index.delete.assert_called_with(filter={"_airbyte_stream": "example_stream2"}) diff --git a/docs/integrations/destinations/langchain.md b/docs/integrations/destinations/langchain.md new file mode 100644 index 000000000000..961dfc34d561 --- /dev/null +++ b/docs/integrations/destinations/langchain.md @@ -0,0 +1,101 @@ +# Langchain + + +## Overview + +This destination prepares data to be used by [Langchain](https://langchain.com/) to retrieve relevant context for question answering use cases. + +There are three parts to this: +* Processing - split up individual records in chunks so they will fit the context window and decide which fields to use as context and which are supplementary metadata. +* Embedding - convert the text into a vector representation using a pre-trained model (currently only OpenAI `text-embedding-ada-002` is supported) +* Indexing - store the vectors in a vector database for similarity search + +### Processing + +Each record will be split into text fields and meta fields as configured in the "Processing" section. All text fields are concatenated into a single string and then split into chunks of configured length. The meta fields are stored as-is along with the embedded text chunks. Please note that meta data fields can only be used for filtering and not for retrieval and have to be of type string, number, boolean (all other values are ignored). Depending on the chosen vector store, additional limitations might apply. + +When specifying text fields, you can access nested fields in the record by using dot notation, e.g. `user.name` will access the `name` field in the `user` object. It's also possible to use wildcards to access all fields in an object, e.g. `users.*.name` will access all `names` fields in all entries of the `users` array. + +The chunk length is measured in tokens produced by the `tiktoken` library. The maximum is 8191 tokens, which is the maximum length supported by the `text-embedding-ada-002` model. + +The stream name gets added as a metadata field `_airbyte_stream` to each document. If available, the primary key of the record is used to identify the document to avoid duplications when updated versions of records are indexed. It is added as the `_natural_id` metadata field. + +### Embedding + +THe OpenAI embedding API is used to calculate embeddings - see [OpenAI API](https://beta.openai.com/docs/api-reference/text-embedding) for details. To do so, an OpenAI API key is required. + +This integration will be constrained by the [speed of the OpenAI embedding API](https://platform.openai.com/docs/guides/rate-limits/overview). + +For testing purposes, it's also possible to use the [Fake embeddings](https://python.langchain.com/docs/modules/data_connection/text_embedding/integrations/fake) integration. It will generate random embeddings and is suitable to test a data pipeline without incurring embedding costs. + +### Indexing + +#### DocArrayHnswSearch vector store + +For local testing, the [DocArrayHnswSearch](https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/docarray_hnsw) is recommended - it stores the vectors in a local file with a sqlite database for metadata. It is not suitable for production use, but it is the easiest to set up for testing and development purposes. + +The `destination_path` has to start with `/local`. Any directory nesting within local will be mapped onto the local mount. + +By default, the `LOCAL_ROOT` env variable in the `.env` file is set `/tmp/airbyte_local`. + +The local mount is mounted by Docker onto `LOCAL_ROOT`. This means the `/local` is substituted by `/tmp/airbyte_local` by default. + +DocArrayHnswSearch does not support incremental sync, so the destination will always do a full refresh sync. + +To initialize a langchain QA chain based on the indexed data, use the following code (set the openai API key as `OPENAI_API_KEY` env variable): + +```python +from langchain import OpenAI +from langchain.chains import RetrievalQA +from langchain.llms import OpenAI +from langchain.vectorstores import DocArrayHnswSearch +from langchain.embeddings import OpenAIEmbeddings + +embeddings = OpenAIEmbeddings() +vector_store = DocArrayHnswSearch.from_params(embeddings, "/tmp/airbyte_local/", 1536) + +qa = RetrievalQA.from_chain_type(llm=OpenAI(temperature=0), chain_type="stuff", retriever=vector_store.as_retriever()) +``` + +:::danger + +This destination will delete all existing files in the configured directory on each. Make sure to not use a directory that contains other files. + +::: + +:::caution + +DocArrayHnswSearch is meant to be used on a local workstation and won't work on Kubernetes. + +Please make sure that Docker Desktop has access to `/tmp` (and `/private` on a MacOS, as /tmp has a symlink that points to /private. It will not work otherwise). You allow it with "File sharing" in `Settings -> Resources -> File sharing -> add the one or two above folder` and hit the "Apply & restart" button. + +::: + +#### Pinecone vector store + +For production use, use the pinecone vector store. Use the Pinecone web UI or API to create a project and an index before running the destination. All streams will be indexed into the same index, the `_airbyte_stream` metadata field is used to distinguish between streams. Overall, the size of the metadata fields is limited to 30KB per document. Both OpenAI and Fake embeddings are produced with 1536 vector dimensions, make sure to configure the index accordingly. + +To initialize a langchain QA chain based on the indexed data, use the following code (set the open API key and pinecone key and environment as `OPENAI_API_KEY`, `PINECONE_KEY` and `PINECONE_ENV` env variables): + +```python +from langchain import OpenAI +from langchain.chains import RetrievalQA +from langchain.llms import OpenAI +from langchain.vectorstores import Pinecone +from langchain.embeddings import OpenAIEmbeddings +import pinecone +import os + +embeddings = OpenAIEmbeddings() +pinecone.init(api_key=os.environ["PINECONE_KEY"], environment=os.environ["PINECONE_ENV"]) +index = pinecone.Index("") +vector_store = Pinecone(index, embeddings.embed_query, "text") + +qa = RetrievalQA.from_chain_type(llm=OpenAI(temperature=0), chain_type="stuff", retriever=vector_store.as_retriever()) +``` + +## CHANGELOG + +| Version | Date | Pull Request | Subject | +|:--------| :--------- |:--------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------| +| 0.0.1 | 2023-07-26 | [#26184](https://github.com/airbytehq/airbyte/pull/26184) | Initial release | \ No newline at end of file diff --git a/tools/ci_connector_ops/ci_connector_ops/pipelines/actions/environments.py b/tools/ci_connector_ops/ci_connector_ops/pipelines/actions/environments.py index 28a1d035832d..e138339415ea 100644 --- a/tools/ci_connector_ops/ci_connector_ops/pipelines/actions/environments.py +++ b/tools/ci_connector_ops/ci_connector_ops/pipelines/actions/environments.py @@ -31,7 +31,7 @@ from ci_connector_ops.pipelines.contexts import ConnectorContext, PipelineContext -def with_python_base(context: PipelineContext, python_image_name: str = "python:3.9-slim") -> Container: +def with_python_base(context: PipelineContext) -> Container: """Build a Python container with a cache volume for pip cache. Args: @@ -44,13 +44,14 @@ def with_python_base(context: PipelineContext, python_image_name: str = "python: Returns: Container: The python base environment container. """ - if not python_image_name.startswith("python:3"): - raise ValueError("You have to use a python image to build the python base environment") + pip_cache: CacheVolume = context.dagger_client.cache_volume("pip_cache") base_container = ( context.dagger_client.container() - .from_(python_image_name) + .from_("python:3.9-slim") + .with_exec(["apt-get", "update"]) + .with_exec(["apt-get", "install", "-y", "build-essential", "cmake", "g++", "libffi-dev", "libstdc++6", "git"]) .with_mounted_cache("/root/.cache/pip", pip_cache) .with_exec(["pip", "install", "pip==23.1.2"]) ) @@ -367,10 +368,9 @@ async def with_ci_connector_ops(context: PipelineContext) -> Container: Returns: Container: A python environment container with ci_connector_ops installed. """ - python_base_environment: Container = with_python_base(context, "python:3-alpine") - python_with_git = with_alpine_packages(python_base_environment, ["gcc", "libffi-dev", "musl-dev", "git"]) + python_base_environment: Container = with_python_base(context) - return await with_installed_python_package(context, python_with_git, CI_CONNECTOR_OPS_SOURCE_PATH) + return await with_installed_python_package(context, python_base_environment, CI_CONNECTOR_OPS_SOURCE_PATH) def with_global_dockerd_service(dagger_client: Client) -> Container: @@ -567,7 +567,7 @@ def with_poetry(context: PipelineContext) -> Container: Returns: Container: A python environment with poetry installed. """ - python_base_environment: Container = with_python_base(context, "python:3.9") + python_base_environment: Container = with_python_base(context) python_with_git = with_debian_packages(python_base_environment, ["git"]) python_with_poetry = with_pip_packages(python_with_git, ["poetry"]) From 56a7f07a9283e8deb2d987c8526cc8dff7bb654e Mon Sep 17 00:00:00 2001 From: Christo Grabowski <108154848+ChristoGrab@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:27:58 -0400 Subject: [PATCH 44/63] =?UTF-8?q?=F0=9F=93=9D=20Docs:=20Source=20S3=20docu?= =?UTF-8?q?mentation=20update=20(#28229)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add detailed setup steps for s3 bucket * complete s3 setup steps * compress versioned setup steps * update S3 Provider Settings section * update CSV and Parquet sections * update file format settings section * final edits/fixes * maintain typecase of True/False * Update docs/integrations/sources/s3.md Co-authored-by: Sherif A. Nada * Update docs/integrations/sources/s3.md Co-authored-by: Sherif A. Nada * Update docs/integrations/sources/s3.md Co-authored-by: Sherif A. Nada * Update docs/integrations/sources/s3.md Co-authored-by: Sherif A. Nada * add example to escape character field description --------- Co-authored-by: Sherif A. Nada --- docs/integrations/sources/s3.md | 189 +++++++++++++++++++++----------- 1 file changed, 127 insertions(+), 62 deletions(-) diff --git a/docs/integrations/sources/s3.md b/docs/integrations/sources/s3.md index ee7e89e28b69..0f5468c56c4b 100644 --- a/docs/integrations/sources/s3.md +++ b/docs/integrations/sources/s3.md @@ -3,46 +3,66 @@ This page contains the setup guide and reference information for the Amazon S3 source connector. :::info -Cloud storage may incur egress costs. Egress refers to data that is transferred out of the cloud storage system, such as when you download files or access them from a different location. For more information, see the [Amazon S3 pricing guide](https://aws.amazon.com/s3/pricing/). +Please note that using cloud storage may incur egress costs. Egress refers to data that is transferred out of the cloud storage system, such as when you download files or access them from a different location. For detailed information on egress costs, please consult the [Amazon S3 pricing guide](https://aws.amazon.com/s3/pricing/). ::: ## Prerequisites -Define file pattern, see the [Path Patterns section](s3.md#path-patterns) +- Access to the S3 bucket containing the files to replicate. ## Setup guide ### Step 1: Set up Amazon S3 -- If syncing from a private bucket, the credentials you use for the connection must have have both `read` and `list` access on the S3 bucket. `list` is required to discover files based on the provided pattern\(s\). +**If you are syncing from a private bucket**, you will need to provide your `AWS Access Key ID` and `AWS Secret Access Key` to authenticate the connection, and ensure that the IAM user associated with the credentials has `read` and `list` permissions for the bucket. If you are unfamiliar with configuring AWS permissions, you can follow these steps to obtain the necessary permissions and credentials: -### Step 2: Set up the Amazon S3 connector in Airbyte +1. Log in to your Amazon AWS account and open the [IAM console](https://console.aws.amazon.com/iam/home#home). +2. In the IAM dashboard, select **Policies**, then click **Create Policy**. +3. Select the **JSON** tab, then paste the following JSON into the Policy editor (be sure to substitute in your bucket name): - +``` +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:GetObject", + "s3:ListBucket" + ], + "Resource": [ + "arn:aws:s3:::{your-bucket-name}/*", + "arn:aws:s3:::{your-bucket-name}" + ] + } + ] +} +``` -**For Airbyte Cloud:** +4. Give your policy a descriptive name, then click **Create policy**. +5. In the IAM dashboard, click **Users**. Select an existing IAM user or create a new one by clicking **Add users**. +6. If you are using an _existing_ IAM user, click the **Add permissions** dropdown menu and select **Add permissions**. If you are creating a _new_ user, you will be taken to the Permissions screen after selecting a name. +7. Select **Attach policies directly**, then find and check the box for your new policy. Click **Next**, then **Add permissions**. +8. After successfully creating your user, select the **Security credentials** tab and click **Create access key**. You will be prompted to select a use case and add optional tags to your access key. Click **Create access key** to generate the keys. -1. [Log into your Airbyte Cloud](https://cloud.airbyte.com/workspaces) account. -2. In the left navigation bar, click ****. In the top-right corner, click **+new source/destination**. -3. On the Set up the source/destination page, enter the name for the `connector name` connector and select **connector name** from the `Source/Destination` type dropdown. -4. Set `dataset` appropriately. This will be the name of the table in the destination. -5. If your bucket contains _only_ files containing data for this table, use `**` as path_pattern. See the [Path Patterns section](s3.md#path-patterns) for more specific pattern matching. -6. Leave schema as `{}` to automatically infer it from the file\(s\). For details on providing a schema, see the [User Schema section](s3.md#user-schema). -7. Fill in the fields within the provider box appropriately. If your bucket is not public, add [credentials](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) with sufficient permissions under `aws_access_key_id` and `aws_secret_access_key`. -8. Choose the format corresponding to the format of your files and fill in fields as required. If unsure about values, try out the defaults and come back if needed. Find details on these settings [here](s3.md#file-format-settings). - +:::caution +Your `Secret Access Key` will only be visible once upon creation. Be sure to copy and store it securely for future use. +::: - +For more information on managing your access keys, please refer to the +[official AWS documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html). -**For Airbyte Open Source:** +### Step 2: Set up the Amazon S3 connector in Airbyte -1. Create a new S3 source with a suitable name. Since each S3 source maps to just a single table, it may be worth including that in the name. -2. Set `dataset` appropriately. This will be the name of the table in the destination. -3. If your bucket contains _only_ files containing data for this table, use `**` as path_pattern. See the [Path Patterns section](s3.md#path-patterns) for more specific pattern matching. -4. Leave schema as `{}` to automatically infer it from the file\(s\). For details on providing a schema, see the [User Schema section](s3.md#user-schema). -5. Fill in the fields within the provider box appropriately. If your bucket is not public, add [credentials](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) with sufficient permissions under `aws_access_key_id` and `aws_secret_access_key`. -6. Choose the format corresponding to the format of your files and fill in fields as required. If unsure about values, try out the defaults and come back if needed. Find details on these settings [here](s3.md#file-format-settings). - +1. [Log in to your Airbyte Cloud](https://cloud.airbyte.com/workspaces) account, or navigate to your Airbyte Open Source dashboard. +2. In the left navigation bar, click **Sources**. In the top-right corner, click **+ New source**. +3. Find and select **S3** from the list of available sources. +4. Enter the **Output Stream Name**. This will be the name of the table in the destination (can contain letters, numbers and underscores). +5. Enter the **Pattern of files to replicate**. This is a regular expression that allows Airbyte to pattern match the specific files to replicate. If you are replicating all the files within your bucket, use `**` as the pattern. For more precise pattern matching options, refer to the [Path Patterns section](#path-patterns) below. +6. Enter the name of the **Bucket** containing your files to replicate. +7. Toggle the **Optional fields** under the **Bucket** field to expand additional configuration options. **If you are syncing from a private bucket**, you must fill the **AWS Access Key ID** and **AWS Secret Access Key** fields with the appropriate credentials to authenticate the connection. All other fields are optional and can be left empty. Refer to the [S3 Provider Settings section](#s3-provider-settings) below for more information on each field. +8. In the **File Format** box, use the dropdown menu to select the format of the files you'd like to replicate. The supported formats are **CSV**, **Parquet**, **Avro** and **JSONL**. Toggling the **Optional fields** button within the **File Format** box will allow you to enter additional configurations based on the selected format. For a detailed breakdown of these settings, refer to the [File Format section](#file-format-settings) below. +6. (Optional) - If you want to enforce a specific schema, you can enter a **Manually enforced data schema**. By default, this value is set to `{}` and will automatically infer the schema from the file\(s\) you are replicating. For details on providing a custom schema, refer to the [User Schema section](#user-schema). ## Supported sync modes @@ -152,66 +172,111 @@ Please note, the S3 Source connector used to infer schemas from all the availabl ## S3 Provider Settings -- `bucket` : name of the bucket your files are in -- `aws_access_key_id` : one half of the [required credentials](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) for accessing a private bucket. -- `aws_secret_access_key` : other half of the [required credentials](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) for accessing a private bucket. -- `path_prefix` : an optional string that limits the files returned by AWS when listing files to only that those starting with this prefix. This is different to path_pattern as it gets pushed down to the API call made to S3 rather than filtered in Airbyte and it does not accept pattern-style symbols \(like wildcards `*`\). We recommend using this if your bucket has many folders and files that are unrelated to this stream and all the relevant files will always sit under this chosen prefix. - - Together with `path_pattern`, there are multiple ways to specify the files to sync. For example, all the following configs are equivalent: - - `path_prefix` = ``, `path_pattern` = `path1/path2/myFolder/**/*`. - - `path_prefix` = `path1/`, `path_pattern` = `path2/myFolder/**/*.csv`. - - `path_prefix` = `path1/path2/` and `path_pattern` = `myFolder/**/*.csv` - - `path_prefix` = `path1/path2/myFolder/`, `path_pattern` = `**/*.csv`. This is the most efficient one because the directories are filtered earlier in the S3 API call. However, the difference in efficiency is usually negligible. - - The rationale of having both `path_prefix` and `path_pattern` is to accommodate as many use cases as possible. If you found them confusing, feel free to ignore `path_prefix` and just set the `path_pattern`. -- `endpoint` : optional parameter that allow using of non Amazon S3 compatible services. Leave it blank for using default Amazon serivce. -- `use_ssl` : Allows using custom servers that configured to use plain http. Ignored in case of using Amazon service. -- `verify_ssl_cert` : Skip ssl validity check in case of using custom servers with self signed certificates. Ignored in case of using Amazon service. +- **AWS Access Key ID**: One half of the [required credentials](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) for accessing a private bucket. +- **AWS Secret Access Key**: The other half of the [required credentials](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) for accessing a private bucket. +- **Path Prefix**: An optional string that limits the files returned by AWS when listing files to only those starting with the specified prefix. This is different than the **Path Pattern**, as the prefix is applied directly to the API call made to S3, rather than being filtered within Airbyte. **This is not a regular expression** and does not accept pattern-style symbols like wildcards (`*`). We recommend using this filter to improve performance if the connector if your bucket has many folders and files that are unrelated to the data you want to replicate, and all the relevant files will always reside under the specified prefix. + - Together with the **Path Pattern**, there are multiple ways to specify the files to sync. For example, all the following configurations are equivalent: + - **Prefix** = ``, **Pattern** = `path1/path2/myFolder/**/*` + - **Prefix** = `path1/`, **Pattern** = `path2/myFolder/**/*.csv` + - **Prefix** = `path1/path2/`, **Pattern** = `myFolder/**/*.csv` + - **Prefix** = `path1/path2/myFolder/`, **Pattern** = `**/*.csv` + + - The ability to individually configure the prefix and pattern has been included to accommodate situations where you do not want to replicate the majority of the files in the bucket. If you are unsure of the best approach, you can safely leave the **Path Prefix** field empty and just [set the Path Pattern](#path-patterns) to meet your requirements. +- **Endpoint**: An optional parameter that enables the use of non-Amazon S3 compatible services. If you are using the default Amazon service, leave this field blank. +- **Start Date**: An optional parameter that marks a starting date and time in UTC for data replication. Any files that have _not_ been modified since this specified date/time will _not_ be replicated. Use the provided datepicker (recommended) or enter the desired date programmatically in the format `YYYY-MM-DDTHH:mm:ssZ`. Leaving this field blank will replicate data from all files that have not been excluded by the **Path Pattern** and **Path Prefix**. - **File Format Settings** +## File Format Settings - The Reader in charge of loading the file format is currently based on [PyArrow](https://arrow.apache.org/docs/python/generated/pyarrow.csv.open_csv.html) \(Apache Arrow\). +The Reader in charge of loading the file format is currently based on [PyArrow](https://arrow.apache.org/docs/python/generated/pyarrow.csv.open_csv.html) \(Apache Arrow\). - Note that all files within one stream must adhere to the same read options for every provided format. +:::note +All files within one stream must adhere to the same read options for every provided format. +::: ### CSV Since CSV files are effectively plain text, providing specific reader options is often required for correct parsing of the files. These settings are applied when a CSV is created or exported so please ensure that this process happens consistently over time. -- `delimiter` : Even though CSV is an acronymn for Comma Separated Values, it is used more generally as a term for flat file data that may or may not be comma separated. The delimiter field lets you specify which character acts as the separator. -- `quote_char` : In some cases, data values may contain instances of reserved characters \(like a comma, if that's the delimiter\). CSVs can allow this behaviour by wrapping a value in defined quote characters so that on read it can parse it correctly. -- `escape_char` : An escape character can be used to prefix a reserved character and allow correct parsing. -- `encoding` : Some data may use a different character set \(typically when different alphabets are involved\). See the [list of allowable encodings here](https://docs.python.org/3/library/codecs.html#standard-encodings). -- `double_quote` : Whether two quotes in a quoted CSV value denote a single quote in the data. -- `newlines_in_values` : Sometimes referred to as `multiline`. In most cases, newline characters signal the end of a row in a CSV, however text data may contain newline characters within it. Setting this to True allows correct parsing in this case. -- `block_size` : This is the number of bytes to process in memory at a time while reading files. The default value here is usually fine but if your table is particularly wide \(lots of columns / data in fields is large\) then raising this might solve failures on detecting schema. Since this defines how much data to read into memory, raising this too high could cause Out Of Memory issues so use with caution. -- `additional_reader_options` : This allows for editing the less commonly required CSV [ConvertOptions](https://arrow.apache.org/docs/python/generated/pyarrow.csv.ConvertOptions.html#pyarrow.csv.ConvertOptions). The value must be a valid JSON string, e.g.: - - ```text - {"timestamp_parsers": ["%m/%d/%Y %H:%M", "%Y/%m/%d %H:%M"], "strings_can_be_null": true, "null_values": ["NA", "NULL"]} +- **Delimiter**: Even though CSV is an acronym for Comma Separated Values, it is used more generally as a term for flat file data that may or may not be comma separated. The delimiter field lets you specify which character acts as the separator. To use [tab-delimiters](https://en.wikipedia.org/wiki/Tab-separated_values), you can set this value to `\t`. By default, this value is set to `,`. +- **Infer Datatypes**: This option determines whether a schema for the source should be inferred from the current data. When set to False and a custom schema is provided, the manually enforced schema takes precedence. If no custom schema is set and this option is set to False, all fields will be read as strings. Set to True by default. +- **Quote Character**: In some cases, data values may contain instances of reserved characters \(like a comma, if that's the delimiter\). CSVs can handle this by wrapping a value in defined quote characters so that on read it can parse it correctly. By default, this is set to `"`. +- **Escape Character**: An escape character can be used to prefix a reserved character and ensure correct parsing. A commonly used character is the backslash (`\`). For example, given the following data: + +``` +Product,Description,Price +Jeans,"Navy Blue, Bootcut, 34\"",49.99 +``` + +The backslash (`\`) is used directly before the second double quote (`"`) to indicate that it is _not_ the closing quote for the field, but rather a literal double quote character that should be included in the value (in this example, denoting the size of the jeans in inches: `34"` ). + +Leaving this field blank (default option) will disallow escaping. + +- **Encoding**: Some data may use a different character set \(typically when different alphabets are involved\). See the [list of allowable encodings here](https://docs.python.org/3/library/codecs.html#standard-encodings). By default, this is set to `utf8`. +- **Double Quote**: This option determines whether two quotes in a quoted CSV value denote a single quote in the data. Set to True by default. +- **Allow newlines in values**: Also known as _multiline_, this option addresses situations where newline characters occur within text data. Typically, newline characters signify the end of a row in a CSV, but when this option is set to True, parsing correctly handles newlines within values. Set to False by default. +- **Additional Reader Options**: This allows for editing the less commonly used CSV [ConvertOptions](https://arrow.apache.org/docs/python/generated/pyarrow.csv.ConvertOptions.html#pyarrow.csv.ConvertOptions). The value must be a valid JSON string, e.g.: + + ``` + { + "timestamp_parsers": [ + "%m/%d/%Y %H:%M", "%Y/%m/%d %H:%M" + ], + "strings_can_be_null": true, + "null_values": [ + "NA", "NULL" + ] + } ``` -- `advanced_options` : This allows for editing the less commonly required CSV [ReadOptions](https://arrow.apache.org/docs/python/generated/pyarrow.csv.ReadOptions.html#pyarrow.csv.ReadOptions). The value must be a valid JSON string. One use case for this is when your CSV has no header, or you want to use custom column names, you can specify `column_names` using this option. +- **Advanced Options**: This allows for editing the less commonly used CSV [ReadOptions](https://arrow.apache.org/docs/python/generated/pyarrow.csv.ReadOptions.html#pyarrow.csv.ReadOptions). The value must be a valid JSON string. One use case for this is when your CSV has no header, or if you want to use custom column names. You can specify `column_names` using this option. For example: - ```test - {"column_names": ["column1", "column2", "column3"]} ``` + { + "column_names": [ + "column1", "column2", "column3" + ] + } + ``` + +- **Block Size**: This is the number of bytes to process in memory at a time while reading files. The default value of `10000` is usually suitable, but if your files are particularly wide (lots of columns, or the values in the columns are particularly large), increasing this might help avoid schema detection failures. + +:::caution +Be cautious when raising this value too high, as it may result in Out Of Memory issues due to increased memory usage. +::: ### Parquet -Apache Parquet file is a column-oriented data storage format of the Apache Hadoop ecosystem. It provides efficient data compression and encoding schemes with enhanced performance to handle complex data in bulk. For now, the solution involves iterating through individual files at the abstract level thus partitioned parquet datasets are unsupported. The following settings are available: +Apache Parquet is a column-oriented data storage format of the Apache Hadoop ecosystem. It provides efficient data compression and encoding schemes with enhanced performance to handle complex data in bulk. At the moment, partitioned parquet datasets are unsupported. The following settings are available: -- `buffer_size` : If positive, perform read buffering when deserializing individual column chunks. Otherwise IO calls are unbuffered. -- `columns` : If not None, only these columns will be read from the file. -- `batch_size` : Maximum number of records per batch. Batches may be smaller if there aren’t enough rows in the file. +- **Selected Columns**: If you only want to sync a subset of the columns from the file(s), enter the desired columns here as a comma-delimited list. Leave this field empty to sync all columns. +- **Record Batch Size**: Sets the maximum number of records per batch. Batches may be smaller if there aren’t enough rows in the file. This option can help avoid out-of-memory errors if your data is particularly wide. Set to `65536` by default. +- **Buffer Size**: If set to a positive number, read buffering is performed during the deserializing of individual column chunks. Otherwise I/O calls are unbuffered. Set to `2` by default. -You can find details on [here](https://arrow.apache.org/docs/python/generated/pyarrow.parquet.ParquetFile.html#pyarrow.parquet.ParquetFile.iter_batches). +For more information on these fields, please refer to the [Apache documentation](https://arrow.apache.org/docs/python/generated/pyarrow.parquet.ParquetFile.html#pyarrow.parquet.ParquetFile.iter_batches). ### Avro -The avro parser uses [fastavro](https://fastavro.readthedocs.io/en/latest/). Currently, no additional options are supported. +The Avro parser uses the [Fastavro library](https://fastavro.readthedocs.io/en/latest/). Currently, no additional options are supported. + +### JSONL -### Jsonl +The JSONL parser uses the PyArrow library, which only supports the line-delimited JSON format. For more detailed info, please refer to the [official docs](https://arrow.apache.org/docs/python/json.html). -The Jsonl parser uses pyarrow hence,only the line-delimited JSON format is supported.For more detailed info, please refer to the [docs](https://arrow.apache.org/docs/python/generated/pyarrow.json.read_json.html) +- **Allow newlines in values**: While JSONL typically has each JSON object on a separate line, there are cases where newline characters may appear within JSON values, such as multiline strings. This option enables the parser to correctly interpret and treat newline characters within values. Please note that setting this option to True may affect performance. Set to False by default. + +- **Unexpected field behavior**: This parameter determines how any JSON fields outside of the explicit schema (if defined) are handled. Possible behaviors include: + + - `ignore`: Unexpected JSON fields are ignored. + - `error`: Error out on unexpected JSON fields. + - `infer`: Unexpected JSON fields are type-inferred and included in the output. + +Set to `infer` by default. + +- **Block Size**: This sets the number of bytes to process in memory at a time while reading files. The default value of `10000` is usually suitable, but if your files are particularly wide (lots of columns or the values in the columns are particularly large), increasing this might help avoid schema detection failures. + +:::caution +Be cautious when raising this value too high, as it may result in Out Of Memory issues due to increased memory usage. +::: ## Changelog From c76235c468699bd8f3da5c2b6ff01bd7df84f484 Mon Sep 17 00:00:00 2001 From: Davin Chia Date: Wed, 12 Jul 2023 11:36:48 -0700 Subject: [PATCH 45/63] Remove Snowflake insert tests that are no longer applicable. (#28245) We no longer support the insert method. Confirmed in https://airbytehq-team.slack.com/archives/C03C4AVJWG4/p1688711004709439. --- ...wflakeInsertDestinationAcceptanceTest.java | 253 ------------------ 1 file changed, 253 deletions(-) delete mode 100644 airbyte-integrations/connectors/destination-snowflake/src/test-integration/java/io/airbyte/integrations/destination/snowflake/SnowflakeInsertDestinationAcceptanceTest.java diff --git a/airbyte-integrations/connectors/destination-snowflake/src/test-integration/java/io/airbyte/integrations/destination/snowflake/SnowflakeInsertDestinationAcceptanceTest.java b/airbyte-integrations/connectors/destination-snowflake/src/test-integration/java/io/airbyte/integrations/destination/snowflake/SnowflakeInsertDestinationAcceptanceTest.java deleted file mode 100644 index d82ac8eed581..000000000000 --- a/airbyte-integrations/connectors/destination-snowflake/src/test-integration/java/io/airbyte/integrations/destination/snowflake/SnowflakeInsertDestinationAcceptanceTest.java +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2023 Airbyte, Inc., all rights reserved. - */ - -package io.airbyte.integrations.destination.snowflake; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.common.base.Preconditions; -import io.airbyte.commons.io.IOs; -import io.airbyte.commons.json.Jsons; -import io.airbyte.commons.resources.MoreResources; -import io.airbyte.commons.string.Strings; -import io.airbyte.configoss.StandardCheckConnectionOutput; -import io.airbyte.configoss.StandardCheckConnectionOutput.Status; -import io.airbyte.db.factory.DataSourceFactory; -import io.airbyte.db.jdbc.JdbcDatabase; -import io.airbyte.integrations.base.JavaBaseConstants; -import io.airbyte.integrations.destination.NamingConventionTransformer; -import io.airbyte.integrations.standardtest.destination.DestinationAcceptanceTest; -import io.airbyte.integrations.standardtest.destination.argproviders.DataArgumentsProvider; -import io.airbyte.integrations.standardtest.destination.comparator.TestDataComparator; -import io.airbyte.protocol.models.v0.AirbyteCatalog; -import io.airbyte.protocol.models.v0.AirbyteConnectionStatus; -import io.airbyte.protocol.models.v0.AirbyteMessage; -import io.airbyte.protocol.models.v0.CatalogHelpers; -import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; -import java.nio.file.Path; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; -import java.util.stream.Collectors; -import javax.sql.DataSource; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ArgumentsSource; - -public class SnowflakeInsertDestinationAcceptanceTest extends DestinationAcceptanceTest { - - private static final NamingConventionTransformer NAME_TRANSFORMER = new SnowflakeSQLNameTransformer(); - protected static final String NO_ACTIVE_WAREHOUSE_ERR_MSG = - "No active warehouse selected in the current session. Select an active warehouse with the 'use warehouse' command."; - - protected static final String NO_USER_PRIVILEGES_ERR_MSG = - "Encountered Error with Snowflake Configuration: Current role does not have permissions on the target schema please verify your privileges"; - - protected static final String IP_NOT_IN_WHITE_LIST_ERR_MSG = "is not allowed to access Snowflake. Contact your account administrator."; - - // this config is based on the static config, and it contains a random - // schema name that is different for each test run - private JsonNode config; - private JdbcDatabase database; - private DataSource dataSource; - - @Override - protected String getImageName() { - return "airbyte/destination-snowflake:dev"; - } - - @Override - protected JsonNode getConfig() { - return config; - } - - @Override - protected TestDataComparator getTestDataComparator() { - return new SnowflakeTestDataComparator(); - } - - @Override - protected boolean supportBasicDataTypeTest() { - return true; - } - - @Override - protected boolean supportArrayDataTypeTest() { - return true; - } - - @Override - protected boolean supportObjectDataTypeTest() { - return true; - } - - public JsonNode getStaticConfig() { - final JsonNode insertConfig = Jsons.deserialize(IOs.readFile(Path.of("secrets/insert_config.json"))); - Preconditions.checkArgument(!SnowflakeDestinationResolver.isS3Copy(insertConfig)); - Preconditions.checkArgument(!SnowflakeDestinationResolver.isGcsCopy(insertConfig)); - return insertConfig; - } - - @Override - protected JsonNode getFailCheckConfig() { - final JsonNode invalidConfig = Jsons.clone(config); - ((ObjectNode) invalidConfig.get("credentials")).put("password", "wrong password"); - return invalidConfig; - } - - @Override - protected List retrieveRecords(final TestDestinationEnv env, - final String streamName, - final String namespace, - final JsonNode streamSchema) - throws Exception { - return retrieveRecordsFromTable(NAME_TRANSFORMER.getRawTableName(streamName), NAME_TRANSFORMER.getNamespace(namespace)) - .stream() - .map(r -> r.get(JavaBaseConstants.COLUMN_NAME_DATA.toUpperCase())) - .collect(Collectors.toList()); - } - - @Override - protected boolean implementsNamespaces() { - return true; - } - - @Override - protected boolean supportNamespaceTest() { - return true; - } - - @Override - protected Optional getNameTransformer() { - return Optional.of(NAME_TRANSFORMER); - } - - @Override - protected List retrieveNormalizedRecords(final TestDestinationEnv testEnv, final String streamName, final String namespace) - throws Exception { - final String tableName = NAME_TRANSFORMER.getIdentifier(streamName); - final String schema = NAME_TRANSFORMER.getNamespace(namespace); - return retrieveRecordsFromTable(tableName, schema); - } - - private List retrieveRecordsFromTable(final String tableName, final String schema) throws SQLException { - final TimeZone timeZone = TimeZone.getTimeZone("UTC"); - TimeZone.setDefault(timeZone); - - return database.bufferedResultSetQuery( - connection -> { - try (final ResultSet tableInfo = connection.createStatement() - .executeQuery(String.format("SHOW TABLES LIKE '%s' IN SCHEMA %s;", tableName, schema))) { - assertTrue(tableInfo.next()); - // check that we're creating permanent tables. DBT defaults to transient tables, which have - // `TRANSIENT` as the value for the `kind` column. - assertEquals("TABLE", tableInfo.getString("kind")); - connection.createStatement().execute("ALTER SESSION SET TIMEZONE = 'UTC';"); - return connection.createStatement() - .executeQuery(String.format("SELECT * FROM %s.%s ORDER BY %s ASC;", schema, tableName, JavaBaseConstants.COLUMN_NAME_EMITTED_AT)); - } - }, - new SnowflakeTestSourceOperations()::rowToJson); - } - - // for each test we create a new schema in the database. run the test in there and then remove it. - @Override - protected void setup(final TestDestinationEnv testEnv) throws Exception { - final String schemaName = Strings.addRandomSuffix("integration_test", "_", 5); - final String createSchemaQuery = String.format("CREATE SCHEMA %s", schemaName); - - this.config = Jsons.clone(getStaticConfig()); - ((ObjectNode) config).put("schema", schemaName); - - dataSource = SnowflakeDatabase.createDataSource(config, OssCloudEnvVarConsts.AIRBYTE_OSS); - database = SnowflakeDatabase.getDatabase(dataSource); - database.execute(createSchemaQuery); - } - - @Override - protected void tearDown(final TestDestinationEnv testEnv) throws Exception { - final String createSchemaQuery = String.format("DROP SCHEMA IF EXISTS %s", config.get("schema").asText()); - database.execute(createSchemaQuery); - DataSourceFactory.close(dataSource); - } - - @Test - public void testCheckWithNoActiveWarehouseConnection() throws Exception { - // Config to user(creds) that has no warehouse assigned - final JsonNode config = Jsons.deserialize(IOs.readFile( - Path.of("secrets/internal_staging_config_no_active_warehouse.json"))); - - final StandardCheckConnectionOutput standardCheckConnectionOutput = runCheck(config); - - assertEquals(Status.FAILED, standardCheckConnectionOutput.getStatus()); - assertThat(standardCheckConnectionOutput.getMessage()).contains(NO_ACTIVE_WAREHOUSE_ERR_MSG); - } - - @Test - public void testCheckWithNoTextSchemaPermissionConnection() throws Exception { - // Config to user (creds) that has no permission to schema - final JsonNode config = Jsons.deserialize(IOs.readFile( - Path.of("secrets/config_no_text_schema_permission.json"))); - - final StandardCheckConnectionOutput standardCheckConnectionOutput = runCheck(config); - - assertEquals(Status.FAILED, standardCheckConnectionOutput.getStatus()); - assertThat(standardCheckConnectionOutput.getMessage()).contains(NO_USER_PRIVILEGES_ERR_MSG); - } - - @Test - public void testCheckIpNotInWhiteListConnection() throws Exception { - // Config to user(creds) that has no warehouse assigned - final JsonNode config = Jsons.deserialize(IOs.readFile( - Path.of("secrets/insert_ip_not_in_whitelist_config.json"))); - - final StandardCheckConnectionOutput standardCheckConnectionOutput = runCheck(config); - - assertEquals(Status.FAILED, standardCheckConnectionOutput.getStatus()); - assertThat(standardCheckConnectionOutput.getMessage()).contains(IP_NOT_IN_WHITE_LIST_ERR_MSG); - } - - @Test - public void testBackwardCompatibilityAfterAddingOauth() { - final JsonNode deprecatedStyleConfig = Jsons.clone(config); - final JsonNode password = deprecatedStyleConfig.get("credentials").get("password"); - - ((ObjectNode) deprecatedStyleConfig).remove("credentials"); - ((ObjectNode) deprecatedStyleConfig).set("password", password); - - assertEquals(Status.SUCCEEDED, runCheckWithCatchedException(deprecatedStyleConfig)); - } - - @Test - void testCheckWithKeyPairAuth() throws Exception { - final JsonNode credentialsJsonString = Jsons.deserialize(IOs.readFile(Path.of("secrets/config_key_pair.json"))); - final AirbyteConnectionStatus check = new SnowflakeDestination(OssCloudEnvVarConsts.AIRBYTE_OSS).check(credentialsJsonString); - assertEquals(AirbyteConnectionStatus.Status.SUCCEEDED, check.getStatus()); - } - - /** - * This test is disabled because it is very slow, and should only be run manually for now. - */ - @Disabled - @ParameterizedTest - @ArgumentsSource(DataArgumentsProvider.class) - public void testSyncWithBillionRecords(final String messagesFilename, final String catalogFilename) throws Exception { - final AirbyteCatalog catalog = Jsons.deserialize(MoreResources.readResource(catalogFilename), AirbyteCatalog.class); - final ConfiguredAirbyteCatalog configuredCatalog = CatalogHelpers.toDefaultConfiguredCatalog(catalog); - final List messages = MoreResources.readResource(messagesFilename).lines() - .map(record -> Jsons.deserialize(record, AirbyteMessage.class)).toList(); - - final List largeNumberRecords = - Collections.nCopies(15000000, messages).stream().flatMap(List::stream).collect(Collectors.toList()); - - final JsonNode config = getConfig(); - runSyncAndVerifyStateOutput(config, largeNumberRecords, configuredCatalog, false); - } - -} From 9f12062a35b208e9d8de60a0cba703f97b743dc0 Mon Sep 17 00:00:00 2001 From: pnavarromuttdata <115086978+pnavarromuttdata@users.noreply.github.com> Date: Wed, 12 Jul 2023 15:50:09 -0300 Subject: [PATCH 46/63] :tada: Source Facebook Marketing - add action report time enum to adinsights class (#26345) * chore: bump version * feat: new action_report_time spec into custom_insights stream * feat: airbyte-config new action_report_time enum spec into custom_insights stream FBMarketing * feat: new action_report_time tests * fix: update allOf instead of array json spec * chore: update docs source connector * update pr id into version history doc * update metadata.yaml * adding action report time into cloud registry and oss registry * fix formatting of python files * fix: update type action_report_time * fix: update title action report time * fix: format python files with flake8 * fix: update version to minor version * fix: remove action report time default value in test_get_custom_insights_stream * fix: keep old config for some unit tests * fix: put missing action breakdowns * fix: remove default value variable and set into class argument directly * chore: bump version * Delete changes from cloud_registry * Removed action_report_time from oss registry --------- Co-authored-by: Juan Marchese Co-authored-by: sajarin Co-authored-by: Serhii Lazebnyi <53845333+lazebnyi@users.noreply.github.com> Co-authored-by: Serhii Lazebnyi --- .../source-facebook-marketing/Dockerfile | 2 +- .../integration_tests/spec.json | 7 +++ .../source-facebook-marketing/metadata.yaml | 2 +- .../source_facebook_marketing/source.py | 1 + .../source_facebook_marketing/spec.py | 11 ++++ .../streams/base_insight_streams.py | 3 ++ .../unit_tests/test_async_job.py | 1 + .../unit_tests/test_base_insight_streams.py | 1 + .../unit_tests/test_streams.py | 52 ++++++++++++++----- .../sources/facebook-marketing.md | 46 ++++++++-------- 10 files changed, 89 insertions(+), 37 deletions(-) diff --git a/airbyte-integrations/connectors/source-facebook-marketing/Dockerfile b/airbyte-integrations/connectors/source-facebook-marketing/Dockerfile index e61cc18335b3..1c2b842a4cd5 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/Dockerfile +++ b/airbyte-integrations/connectors/source-facebook-marketing/Dockerfile @@ -13,5 +13,5 @@ ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=1.0.1 +LABEL io.airbyte.version=1.1.0 LABEL io.airbyte.name=airbyte/source-facebook-marketing diff --git a/airbyte-integrations/connectors/source-facebook-marketing/integration_tests/spec.json b/airbyte-integrations/connectors/source-facebook-marketing/integration_tests/spec.json index 21f4a862c9e9..0324ab907136 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/integration_tests/spec.json +++ b/airbyte-integrations/connectors/source-facebook-marketing/integration_tests/spec.json @@ -285,6 +285,13 @@ ] } }, + "action_report_time": { + "title": "Action Report Time", + "description": "Determines the report time of action stats. For example, if a person saw the ad on Jan 1st but converted on Jan 2nd, when you query the API with action_report_time=impression, you see a conversion on Jan 1st. When you query the API with action_report_time=conversion, you see a conversion on Jan 2nd.", + "default": "mixed", + "enum": ["conversion", "impression", "mixed"], + "type": "string" + }, "time_increment": { "title": "Time Increment", "description": "Time window in days by which to aggregate statistics. The sync will be chunked into N day intervals, where N is the number of days you specified. For example, if you set this value to 7, then all statistics will be reported as 7-day aggregates by starting from the start_date. If the start and end dates are October 1st and October 30th, then the connector will output 5 records: 01 - 06, 07 - 13, 14 - 20, 21 - 27, and 28 - 30 (3 days only).", diff --git a/airbyte-integrations/connectors/source-facebook-marketing/metadata.yaml b/airbyte-integrations/connectors/source-facebook-marketing/metadata.yaml index d2795b64131d..b80b80434483 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/metadata.yaml +++ b/airbyte-integrations/connectors/source-facebook-marketing/metadata.yaml @@ -5,7 +5,7 @@ data: connectorSubtype: api connectorType: source definitionId: e7778cfc-e97c-4458-9ecb-b4f2bba8946c - dockerImageTag: 1.0.1 + dockerImageTag: 1.1.0 dockerRepository: airbyte/source-facebook-marketing githubIssueLabel: source-facebook-marketing icon: facebook.svg diff --git a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/source.py b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/source.py index a4c679fecc9a..a5cbe1aa93cd 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/source.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/source.py @@ -261,6 +261,7 @@ def get_custom_insights_streams(self, api: API, config: ConnectorConfig) -> List breakdowns=list(set(insight.breakdowns)), action_breakdowns=list(set(insight.action_breakdowns)), action_breakdowns_allow_empty=config.action_breakdowns_allow_empty, + action_report_time=insight.action_report_time, time_increment=insight.time_increment, start_date=insight.start_date or config.start_date, end_date=insight.end_date or config.end_date, diff --git a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/spec.py b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/spec.py index b9c0f9a51fc6..901451dfffbc 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/spec.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/spec.py @@ -52,6 +52,17 @@ class Config: default=[], ) + action_report_time: str = Field( + title="Action Report Time", + description=( + "Determines the report time of action stats. For example, if a person saw the ad on Jan 1st " + "but converted on Jan 2nd, when you query the API with action_report_time=impression, you see a conversion on Jan 1st. " + "When you query the API with action_report_time=conversion, you see a conversion on Jan 2nd." + ), + default="mixed", + enum=["conversion", "impression", "mixed"], + ) + time_increment: Optional[PositiveInt] = Field( title="Time Increment", description=( diff --git a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/base_insight_streams.py b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/base_insight_streams.py index 8e93929c9c33..5913b8a78eb4 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/base_insight_streams.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/source_facebook_marketing/streams/base_insight_streams.py @@ -60,6 +60,7 @@ def __init__( breakdowns: List[str] = None, action_breakdowns: List[str] = None, action_breakdowns_allow_empty: bool = False, + action_report_time: str = "mixed", time_increment: Optional[int] = None, insights_lookback_window: int = None, level: str = "ad", @@ -78,6 +79,7 @@ def __init__( if breakdowns is not None: self.breakdowns = breakdowns self.time_increment = time_increment or self.time_increment + self.action_report_time = action_report_time self._new_class_name = name self._insights_lookback_window = insights_lookback_window self.level = level @@ -276,6 +278,7 @@ def request_params(self, **kwargs) -> MutableMapping[str, Any]: return { "level": self.level, "action_breakdowns": self.action_breakdowns, + "action_report_time": self.action_report_time, "breakdowns": self.breakdowns, "fields": self.fields, "time_increment": self.time_increment, diff --git a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_async_job.py b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_async_job.py index 9fa467b9d6e8..69941a42501d 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_async_job.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_async_job.py @@ -40,6 +40,7 @@ def job_fixture(api, account): params = { "level": "ad", "action_breakdowns": [], + "action_report_time": "mixed", "breakdowns": [], "fields": ["field1", "field2"], "time_increment": 1, diff --git a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_base_insight_streams.py b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_base_insight_streams.py index 59952d4e915e..c773ad505dec 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_base_insight_streams.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_base_insight_streams.py @@ -55,6 +55,7 @@ def test_init(self, api): assert stream.action_breakdowns == ["action_type", "action_target_id", "action_destination"] assert stream.name == "ads_insights" assert stream.primary_key == ["date_start", "account_id", "ad_id"] + assert stream.action_report_time == "mixed" def test_init_override(self, api): stream = AdsInsights( diff --git a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_streams.py b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_streams.py index 5fccdaf5f6e9..13638dbfef97 100644 --- a/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_streams.py +++ b/airbyte-integrations/connectors/source-facebook-marketing/unit_tests/test_streams.py @@ -49,10 +49,12 @@ def test_filter_all_statuses(api, mocker): @pytest.mark.parametrize( - "url", ["https://graph.facebook.com", "https://graph.facebook.com?test=123%23%24%25%2A&test2=456", "https://graph.facebook.com?"] + "url", ["https://graph.facebook.com", + "https://graph.facebook.com?test=123%23%24%25%2A&test2=456", "https://graph.facebook.com?"] ) def test_fetch_thumbnail_data_url(url, requests_mock): - requests_mock.get(url, status_code=200, headers={"content-type": "content-type"}, content=b"") + requests_mock.get(url, status_code=200, headers={ + "content-type": "content-type"}, content=b"") assert fetch_thumbnail_data_url(url) == "data:content-type;base64," @@ -61,7 +63,8 @@ def test_parse_call_rate_header(): "x-business-use-case-usage": '{"test":[{"type":"ads_management","call_count":1,"total_cputime":1,' '"total_time":1,"estimated_time_to_regain_access":1}]}' } - assert MyFacebookAdsApi._parse_call_rate_header(headers) == (1, duration(minutes=1)) + assert MyFacebookAdsApi._parse_call_rate_header( + headers) == (1, duration(minutes=1)) @pytest.mark.parametrize( @@ -69,30 +72,53 @@ def test_parse_call_rate_header(): [ [AdsInsights, [], ["action_type", "action_target_id", "action_destination"]], [AdsInsightsActionType, [], ["action_type"]], - [AdsInsightsAgeAndGender, ["age", "gender"], ["action_type", "action_target_id", "action_destination"]], - [AdsInsightsCountry, ["country"], ["action_type", "action_target_id", "action_destination"]], - [AdsInsightsDma, ["dma"], ["action_type", "action_target_id", "action_destination"]], - [AdsInsightsPlatformAndDevice, ["publisher_platform", "platform_position", "impression_device"], ["action_type"]], - [AdsInsightsRegion, ["region"], ["action_type", "action_target_id", "action_destination"]], + [AdsInsightsAgeAndGender, ["age", "gender"], [ + "action_type", "action_target_id", "action_destination"]], + [AdsInsightsCountry, ["country"], ["action_type", + "action_target_id", "action_destination"]], + [AdsInsightsDma, ["dma"], ["action_type", + "action_target_id", "action_destination"]], + [AdsInsightsPlatformAndDevice, ["publisher_platform", + "platform_position", "impression_device"], ["action_type"]], + [AdsInsightsRegion, ["region"], ["action_type", + "action_target_id", "action_destination"]], ], ) def test_ads_insights_breakdowns(class_name, breakdowns, action_breakdowns): - kwargs = {"api": None, "start_date": pendulum.now(), "end_date": pendulum.now(), "insights_lookback_window": 1} + kwargs = {"api": None, "start_date": pendulum.now( + ), "end_date": pendulum.now(), "insights_lookback_window": 1} stream = class_name(**kwargs) assert stream.breakdowns == breakdowns assert stream.action_breakdowns == action_breakdowns def test_custom_ads_insights_breakdowns(): - kwargs = {"api": None, "start_date": pendulum.now(), "end_date": pendulum.now(), "insights_lookback_window": 1} - stream = AdsInsights(breakdowns=["mmm"], action_breakdowns=["action_destination"], **kwargs) + kwargs = {"api": None, "start_date": pendulum.now( + ), "end_date": pendulum.now(), "insights_lookback_window": 1} + stream = AdsInsights(breakdowns=["mmm"], action_breakdowns=[ + "action_destination"], **kwargs) assert stream.breakdowns == ["mmm"] assert stream.action_breakdowns == ["action_destination"] stream = AdsInsights(breakdowns=[], action_breakdowns=[], **kwargs) assert stream.breakdowns == [] - assert stream.action_breakdowns == ["action_type", "action_target_id", "action_destination"] + assert stream.action_breakdowns == [ + "action_type", "action_target_id", "action_destination"] - stream = AdsInsights(breakdowns=[], action_breakdowns=[], action_breakdowns_allow_empty=True, **kwargs) + stream = AdsInsights(breakdowns=[], action_breakdowns=[], + action_breakdowns_allow_empty=True, **kwargs) assert stream.breakdowns == [] assert stream.action_breakdowns == [] + + +def test_custom_ads_insights_action_report_times(): + kwargs = {"api": None, "start_date": pendulum.now(), "end_date": pendulum.now( + ), "insights_lookback_window": 1, "action_breakdowns": ["action_destination"], "breakdowns": []} + stream = AdsInsights(**kwargs) + assert stream.action_report_time == "mixed" + + stream = AdsInsights(action_report_time="conversion", **kwargs) + assert stream.action_report_time == "conversion" + + stream = AdsInsights(action_report_time="impression", **kwargs) + assert stream.action_report_time == "impression" diff --git a/docs/integrations/sources/facebook-marketing.md b/docs/integrations/sources/facebook-marketing.md index 163330a7ff0e..41973ba1d04c 100644 --- a/docs/integrations/sources/facebook-marketing.md +++ b/docs/integrations/sources/facebook-marketing.md @@ -43,27 +43,28 @@ This page guides you through the process of setting up the Facebook Marketing so 8. (Optional) Toggle the **Fetch Thumbnail Images** button to fetch the `thumbnail_url` and store the result in `thumbnail_data_url` for each [Ad Creative](https://developers.facebook.com/docs/marketing-api/creative/). 9. (Optional) In the Custom Insights section. A list which contains ad statistics entries, each entry must have a name and can contain fields, breakdowns or action_breakdowns. Click on "add" to fill this field. - To retrieve specific fields from Facebook Ads Insights combined with other breakdowns, you can choose which fields and breakdowns to sync. - We recommend following the Facebook Marketing [documentation](https://developers.facebook.com/docs/marketing-api/insights/breakdowns) to understand the breakdown limitations. Some fields can not be requested and many others only work when combined with specific fields. For example, the breakdown `app_id` is only supported with the `total_postbacks` field. - - To configure Custom Insights: - - 1. For **Name**, enter a name for the insight. This will be used as the Airbyte stream name - 2. For **Level**, enter the level of the fields you want to pull from the Facebook Marketing API. By default, 'ad'. You can specify also account, campaign or adset. - 3. For **Fields**, enter a list of the fields you want to pull from the Facebook Marketing API. - 4. For **End Date**, enter the date in the `YYYY-MM-DDTHH:mm:ssZ` format. The data added on and before this date will be replicated. If this field is blank, Airbyte will replicate the latest data. - 5. For **Breakdowns**, enter a list of the breakdowns you want to configure. - 6. For **Start Date**, enter the date in the `YYYY-MM-DDTHH:mm:ssZ` format. The data added on and after this date will be replicated. If this field is blank, Airbyte will replicate all data. - 7. For **Action Breakdown**, enter a list of the action breakdowns you want to configure. - 8. For **Custom Insights Lookback Window**, fill in the appropriate value. See [more](#facebook-marketing-attribution-reporting) on this parameter. - 9. Click **Done**. - 10. For **Page Size of Requests**, fill in the page size in case pagination kicks in. Feel free to ignore it, the default value should work in most cases. - 11. For **Insights Lookback Window**, fill in the appropriate value. Facebook freezes insight data 28 days after it was generated, which means that all data from the past 28 days may have changed since we last emitted it, so you can retrieve refreshed insights from the past by setting this parameter. If you set a custom lookback window value in Facebook account, please provide the same value here. See [more](#facebook-marketing-attribution-reporting) on this parameter. - 12. Click **Set up source**. - - :::warning - Additional streams for Facebook Marketing are dynamically created based on the specified Custom Insights. For an existing Facebook Marketing source, when you are updating or removing Custom Insights, you should also ensure that any connections syncing to these streams are either disabled or have had their source schema refreshed. - ::: + To retrieve specific fields from Facebook Ads Insights combined with other breakdowns, you can choose which fields and breakdowns to sync. + We recommend following the Facebook Marketing [documentation](https://developers.facebook.com/docs/marketing-api/insights/breakdowns) to understand the breakdown limitations. Some fields can not be requested and many others only work when combined with specific fields. For example, the breakdown `app_id` is only supported with the `total_postbacks` field. + + To configure Custom Insights: + + 1. For **Name**, enter a name for the insight. This will be used as the Airbyte stream name + 2. For **Level**, enter the level of the fields you want to pull from the Facebook Marketing API. By default, 'ad'. You can specify also account, campaign or adset. + 3. For **Fields**, enter a list of the fields you want to pull from the Facebook Marketing API. + 4. For **End Date**, enter the date in the `YYYY-MM-DDTHH:mm:ssZ` format. The data added on and before this date will be replicated. If this field is blank, Airbyte will replicate the latest data. + 5. For **Breakdowns**, enter a list of the breakdowns you want to configure. + 6. For **Start Date**, enter the date in the `YYYY-MM-DDTHH:mm:ssZ` format. The data added on and after this date will be replicated. If this field is blank, Airbyte will replicate all data. + 7. For **Action Breakdown**, enter a list of the action breakdowns you want to configure. + 8. For **Action Report Time**, enter the action report time you want to configure (mixed, conversion or impression). + 9. For **Custom Insights Lookback Window**, fill in the appropriate value. See [more](#facebook-marketing-attribution-reporting) on this parameter. + 10. Click **Done**. + 12. For **Page Size of Requests**, fill in the page size in case pagination kicks in. Feel free to ignore it, the default value should work in most cases. + 13. For **Insights Lookback Window**, fill in the appropriate value. Facebook freezes insight data 28 days after it was generated, which means that all data from the past 28 days may have changed since we last emitted it, so you can retrieve refreshed insights from the past by setting this parameter. If you set a custom lookback window value in Facebook account, please provide the same value here. See [more](#facebook-marketing-attribution-reporting) on this parameter. + 14. Click **Set up source**. + + :::warning + Additional streams for Facebook Marketing are dynamically created based on the specified Custom Insights. For an existing Facebook Marketing source, when you are updating or removing Custom Insights, you should also ensure that any connections syncing to these streams are either disabled or have had their source schema refreshed. + ::: @@ -166,7 +167,8 @@ Please be informed that the connector uses the `lookback_window` parameter to pe ## Changelog | Version | Date | Pull Request | Subject | -| :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +|:--------|:-----------|:---------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 1.1.0 | 2023-07-11 | [26345](https://github.com/airbytehq/airbyte/pull/26345) | add new `action_report_time` attribute to `AdInsights` class | | 1.0.1 | 2023-07-07 | [27979](https://github.com/airbytehq/airbyte/pull/27979) | Added the ability to restore the reduced request record limit after the successful retry, and handle the `unknown error` (code 99) with the retry strategy | | 1.0.0 | 2023-07-05 | [27563](https://github.com/airbytehq/airbyte/pull/27563) | Migrate to FB SDK version 17 | | 0.5.0 | 2023-06-26 | [27728](https://github.com/airbytehq/airbyte/pull/27728) | License Update: Elv2 | From 40e62fbcb4c578a2af1eab89b915fddbabdf32d8 Mon Sep 17 00:00:00 2001 From: Alexandre Girard Date: Wed, 12 Jul 2023 13:40:30 -0700 Subject: [PATCH 47/63] Implement parquet parser (#28064) * Implement parquet parser * move comment * comments * Automated Commit - Formatting Changes * cleanup * Update * remove superfluous method * update * format --------- Co-authored-by: girarda --- .../file_based/file_types/parquet_parser.py | 115 ++++- airbyte-cdk/python/setup.py | 2 + .../sources/file_based/file_types/__init__.py | 0 .../file_types/test_parquet_parser.py | 124 ++++++ .../file_based/in_memory_files_source.py | 29 +- .../file_based/scenarios/parquet_scenarios.py | 398 ++++++++++++++++++ .../sources/file_based/test_scenarios.py | 66 +-- 7 files changed, 705 insertions(+), 29 deletions(-) create mode 100644 airbyte-cdk/python/unit_tests/sources/file_based/file_types/__init__.py create mode 100644 airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_parquet_parser.py create mode 100644 airbyte-cdk/python/unit_tests/sources/file_based/scenarios/parquet_scenarios.py diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/parquet_parser.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/parquet_parser.py index ec049c65ce3b..03b45000dcef 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/parquet_parser.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/parquet_parser.py @@ -2,21 +2,130 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # -from typing import Any, Dict, Iterable +import json +from typing import Any, Dict, Iterable, Mapping +import pyarrow as pa +import pyarrow.parquet as pq from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser from airbyte_cdk.sources.file_based.remote_file import RemoteFile +from pyarrow import Scalar class ParquetParser(FileTypeParser): async def infer_schema( self, config: FileBasedStreamConfig, file: RemoteFile, stream_reader: AbstractFileBasedStreamReader ) -> Dict[str, Any]: - ... + # Pyarrow can detect the schema of a parquet file by reading only its metadata. + # https://github.com/apache/arrow/blob/main/python/pyarrow/_parquet.pyx#L1168-L1243 + parquet_file = pq.ParquetFile(stream_reader.open_file(file)) + parquet_schema = parquet_file.schema_arrow + schema = {field.name: ParquetParser.parquet_type_to_schema_type(field.type) for field in parquet_schema} + return schema def parse_records( self, config: FileBasedStreamConfig, file: RemoteFile, stream_reader: AbstractFileBasedStreamReader ) -> Iterable[Dict[str, Any]]: - ... + table = pq.read_table(stream_reader.open_file(file)) + for batch in table.to_batches(): + for i in range(batch.num_rows): + row_dict = {column: ParquetParser._to_output_value(batch.column(column)[i]) for column in table.column_names} + yield row_dict + + @staticmethod + def _to_output_value(parquet_value: Scalar) -> Any: + """ + Convert a pyarrow scalar to a value that can be output by the source. + """ + # Convert date and datetime objects to isoformat strings + if pa.types.is_time(parquet_value.type) or pa.types.is_timestamp(parquet_value.type) or pa.types.is_date(parquet_value.type): + return parquet_value.as_py().isoformat() + + # Convert month_day_nano_interval to array + if parquet_value.type == pa.month_day_nano_interval(): + return json.loads(json.dumps(parquet_value.as_py())) + + # Decode binary strings to utf-8 + if ParquetParser._is_binary(parquet_value.type): + return parquet_value.as_py().decode("utf-8") + if pa.types.is_decimal(parquet_value.type): + return str(parquet_value.as_py()) + + # Dictionaries are stored as two columns: indices and values + # The indices column is an array of integers that maps to the values column + if pa.types.is_dictionary(parquet_value.type): + return { + "indices": parquet_value.indices.tolist(), + "values": parquet_value.dictionary.tolist(), + } + + # Convert duration to seconds, then convert to the appropriate unit + if pa.types.is_duration(parquet_value.type): + duration = parquet_value.as_py() + duration_seconds = duration.total_seconds() + if parquet_value.type.unit == "s": + return duration_seconds + elif parquet_value.type.unit == "ms": + return duration_seconds * 1000 + elif parquet_value.type.unit == "us": + return duration_seconds * 1_000_000 + elif parquet_value.type.unit == "ns": + return duration_seconds * 1_000_000_000 + duration.nanoseconds + else: + raise ValueError(f"Unknown duration unit: {parquet_value.type.unit}") + else: + return parquet_value.as_py() + + @staticmethod + def parquet_type_to_schema_type(parquet_type: pa.DataType) -> Mapping[str, str]: + """ + Convert a pyarrow data type to an Airbyte schema type. + Parquet data types are defined at https://arrow.apache.org/docs/python/api/datatypes.html + """ + + if pa.types.is_timestamp(parquet_type): + return {"type": "string", "format": "date-time"} + elif pa.types.is_date(parquet_type): + return {"type": "string", "format": "date"} + elif ParquetParser._is_string(parquet_type): + return {"type": "string"} + elif pa.types.is_boolean(parquet_type): + return {"type": "boolean"} + elif ParquetParser._is_integer(parquet_type): + return {"type": "integer"} + elif pa.types.is_floating(parquet_type): + return {"type": "number"} + elif ParquetParser._is_object(parquet_type): + return {"type": "object"} + elif ParquetParser._is_list(parquet_type): + return {"type": "array"} + else: + raise ValueError(f"Unsupported parquet type: {parquet_type}") + + @staticmethod + def _is_binary(parquet_type: pa.DataType) -> bool: + return bool(pa.types.is_binary(parquet_type) or pa.types.is_large_binary(parquet_type)) + + @staticmethod + def _is_integer(parquet_type: pa.DataType) -> bool: + return bool(pa.types.is_integer(parquet_type) or pa.types.is_duration(parquet_type)) + + @staticmethod + def _is_string(parquet_type: pa.DataType) -> bool: + return bool( + pa.types.is_time(parquet_type) + or pa.types.is_string(parquet_type) + or pa.types.is_large_string(parquet_type) + or pa.types.is_decimal(parquet_type) # Return as a string to ensure no precision is lost + or ParquetParser._is_binary(parquet_type) # Best we can do is return as a string since we do not support binary + ) + + @staticmethod + def _is_object(parquet_type: pa.DataType) -> bool: + return bool(pa.types.is_dictionary(parquet_type) or pa.types.is_struct(parquet_type)) + + @staticmethod + def _is_list(parquet_type: pa.DataType) -> bool: + return bool(pa.types.is_list(parquet_type) or pa.types.is_large_list(parquet_type) or parquet_type == pa.month_day_nano_interval()) diff --git a/airbyte-cdk/python/setup.py b/airbyte-cdk/python/setup.py index 15d763841cf7..afe63bdb5cfd 100644 --- a/airbyte-cdk/python/setup.py +++ b/airbyte-cdk/python/setup.py @@ -63,6 +63,7 @@ "Jinja2~=3.1.2", "cachetools", "wcmatch==8.4", + "pyarrow==12.0.1", ], python_requires=">=3.8", extras_require={ @@ -74,6 +75,7 @@ "pytest-mock", "requests-mock", "pytest-httpserver", + "pandas==2.0.3", ], "sphinx-docs": [ "Sphinx~=4.2", diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/file_types/__init__.py b/airbyte-cdk/python/unit_tests/sources/file_based/file_types/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_parquet_parser.py b/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_parquet_parser.py new file mode 100644 index 000000000000..5926d4d52c8d --- /dev/null +++ b/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_parquet_parser.py @@ -0,0 +1,124 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import datetime +import math +from typing import Any, Mapping + +import pyarrow as pa +import pytest +from airbyte_cdk.sources.file_based.file_types import ParquetParser +from pyarrow import Scalar + + +@pytest.mark.parametrize( + "parquet_type, expected_type", + [ + pytest.param(pa.bool_(), {"type": "boolean"}, id="test_parquet_bool"), + pytest.param(pa.int8(), {"type": "integer"}, id="test_parquet_int8"), + pytest.param(pa.int16(), {"type": "integer"}, id="test_parquet_int16"), + pytest.param(pa.int32(), {"type": "integer"}, id="test_parquet_int32"), + pytest.param(pa.uint8(), {"type": "integer"}, id="test_parquet_uint8"), + pytest.param(pa.uint16(), {"type": "integer"}, id="test_parquet_uint16"), + pytest.param(pa.uint32(), {"type": "integer"}, id="test_parquet_uint32"), + pytest.param(pa.float16(), {"type": "number"}, id="test_parquet_float16"), + pytest.param(pa.float32(), {"type": "number"}, id="test_parquet_float32"), + pytest.param(pa.float64(), {"type": "number"}, id="test_parquet_float64"), + pytest.param(pa.time32("s"), {"type": "string"}, id="test_parquet_time32s"), + pytest.param(pa.time32("ms"), {"type": "string"}, id="test_parquet_time32ms"), + pytest.param(pa.time64("us"), {"type": "string"}, id="test_parquet_time64us"), + pytest.param(pa.time64("ns"), {"type": "string"}, id="test_parquet_time64us"), + pytest.param(pa.timestamp("s"), {"type": "string", "format": "date-time"}, id="test_parquet_timestamps_s"), + pytest.param(pa.timestamp("ms"), {"type": "string", "format": "date-time"}, id="test_parquet_timestamp_ms"), + pytest.param(pa.timestamp("s", "utc"), {"type": "string", "format": "date-time"}, id="test_parquet_timestamps_s_with_tz"), + pytest.param(pa.timestamp("ms", "est"), {"type": "string", "format": "date-time"}, id="test_parquet_timestamps_ms_with_tz"), + pytest.param(pa.date32(), {"type": "string", "format": "date"}, id="test_parquet_date32"), + pytest.param(pa.date64(), {"type": "string", "format": "date"}, id="test_parquet_date64"), + pytest.param(pa.duration("s"), {"type": "integer"}, id="test_duration_s"), + pytest.param(pa.duration("ms"), {"type": "integer"}, id="test_duration_ms"), + pytest.param(pa.duration("us"), {"type": "integer"}, id="test_duration_us"), + pytest.param(pa.duration("ns"), {"type": "integer"}, id="test_duration_ns"), + pytest.param(pa.month_day_nano_interval(), {"type": "array"}, id="test_parquet_month_day_nano_interval"), + pytest.param(pa.binary(), {"type": "string"}, id="test_binary"), + pytest.param(pa.string(), {"type": "string"}, id="test_parquet_string"), + pytest.param(pa.utf8(), {"type": "string"}, id="test_utf8"), + pytest.param(pa.large_binary(), {"type": "string"}, id="test_large_binary"), + pytest.param(pa.large_string(), {"type": "string"}, id="test_large_string"), + pytest.param(pa.large_utf8(), {"type": "string"}, id="test_large_utf8"), + pytest.param(pa.dictionary(pa.int32(), pa.string()), {"type": "object"}, id="test_dictionary"), + pytest.param(pa.struct([pa.field("field", pa.int32())]), {"type": "object"}, id="test_struct"), + pytest.param(pa.list_(pa.int32()), {"type": "array"}, id="test_list"), + pytest.param(pa.large_list(pa.int32()), {"type": "array"}, id="test_large_list"), + pytest.param(pa.decimal128(2), {"type": "string"}, id="test_decimal128"), + pytest.param(pa.decimal256(2), {"type": "string"}, id="test_decimal256"), + ] +) +def test_type_mapping(parquet_type: pa.DataType, expected_type: Mapping[str, str]) -> None: + if expected_type is None: + with pytest.raises(ValueError): + ParquetParser.parquet_type_to_schema_type(parquet_type) + else: + assert ParquetParser.parquet_type_to_schema_type(parquet_type) == expected_type + + +@pytest.mark.parametrize( + "pyarrow_type, parquet_object, expected_value", + [ + pytest.param(pa.bool_(), True, True, id="test_bool"), + pytest.param(pa.int8(), -1, -1, id="test_int8"), + pytest.param(pa.int16(), 2, 2, id="test_int16"), + pytest.param(pa.int32(), 3, 3, id="test_int32"), + pytest.param(pa.uint8(), 4, 4, id="test_parquet_uint8"), + pytest.param(pa.uint16(), 5, 5, id="test_parquet_uint16"), + pytest.param(pa.uint32(), 6, 6, id="test_parquet_uint32"), + pytest.param(pa.float32(), 2.7, 2.7, id="test_parquet_float32"), + pytest.param(pa.float64(), 3.14, 3.14, id="test_parquet_float64"), + pytest.param(pa.time32("s"), datetime.time(1, 2, 3), "01:02:03", id="test_parquet_time32s"), + pytest.param(pa.time32("ms"), datetime.time(3, 4, 5), "03:04:05", id="test_parquet_time32ms"), + pytest.param(pa.time64("us"), datetime.time(6, 7, 8), "06:07:08", id="test_parquet_time64us"), + pytest.param(pa.time64("ns"), datetime.time(9, 10, 11), "09:10:11", id="test_parquet_time64us"), + pytest.param(pa.timestamp("s"), datetime.datetime(2023, 7, 7, 10, 11, 12), "2023-07-07T10:11:12", id="test_parquet_timestamps_s"), + pytest.param(pa.timestamp("ms"), datetime.datetime(2024, 8, 8, 11, 12, 13), "2024-08-08T11:12:13", id="test_parquet_timestamp_ms"), + pytest.param(pa.timestamp("s", "utc"), datetime.datetime(2020, 1, 1, 1, 1, 1, tzinfo=datetime.timezone.utc), + "2020-01-01T01:01:01+00:00", id="test_parquet_timestamps_s_with_tz"), + pytest.param(pa.timestamp("ms", "utc"), datetime.datetime(2021, 2, 3, 4, 5, tzinfo=datetime.timezone.utc), + "2021-02-03T04:05:00+00:00", id="test_parquet_timestamps_ms_with_tz"), + pytest.param(pa.date32(), datetime.date(2023, 7, 7), "2023-07-07", id="test_parquet_date32"), + pytest.param(pa.date64(), datetime.date(2023, 7, 8), "2023-07-08", id="test_parquet_date64"), + pytest.param(pa.duration("s"), 12345, 12345, id="test_duration_s"), + pytest.param(pa.duration("ms"), 12345, 12345, id="test_duration_ms"), + pytest.param(pa.duration("us"), 12345, 12345, id="test_duration_us"), + pytest.param(pa.duration("ns"), 12345, 12345, id="test_duration_ns"), + pytest.param(pa.month_day_nano_interval(), datetime.timedelta(days=3, microseconds=4), [0, 3, 4000], + id="test_parquet_month_day_nano_interval"), + pytest.param(pa.binary(), b"this is a binary string", "this is a binary string", id="test_binary"), + pytest.param(pa.string(), "this is a string", "this is a string", id="test_parquet_string"), + pytest.param(pa.utf8(), "utf8".encode("utf8"), "utf8", id="test_utf8"), + pytest.param(pa.large_binary(), b"large binary string", "large binary string", id="test_large_binary"), + pytest.param(pa.large_string(), "large string", "large string", id="test_large_string"), + pytest.param(pa.large_utf8(), "large utf8", "large utf8", id="test_large_utf8"), + pytest.param(pa.struct([pa.field("field", pa.int32())]), {"field": 1}, {"field": 1}, id="test_struct"), + pytest.param(pa.list_(pa.int32()), [1, 2, 3], [1, 2, 3], id="test_list"), + pytest.param(pa.large_list(pa.int32()), [4, 5, 6], [4, 5, 6], id="test_large_list"), + pytest.param(pa.decimal128(5, 3), 12, "12.000", id="test_decimal128"), + pytest.param(pa.decimal256(8, 2), 13, "13.00", id="test_decimal256"), + ] +) +def test_value_transformation(pyarrow_type: pa.DataType, parquet_object: Scalar, expected_value: Any) -> None: + pyarrow_value = pa.array([parquet_object], type=pyarrow_type)[0] + py_value = ParquetParser._to_output_value(pyarrow_value) + if isinstance(py_value, float): + assert math.isclose(py_value, expected_value, abs_tol=0.01) + else: + assert py_value == expected_value + + +def test_value_dictionary() -> None: + # Setting the dictionary is more involved than other data types so we test it in a separate test + dictionary_values = ["apple", "banana", "cherry"] + indices = [0, 1, 2, 0, 1] + indices_array = pa.array(indices, type=pa.int8()) + dictionary = pa.DictionaryArray.from_arrays(indices_array, dictionary_values) + py_value = ParquetParser._to_output_value(dictionary) + assert py_value == {"indices": [0, 1, 2, 0, 1], "values": ["apple", "banana", "cherry"]} diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/in_memory_files_source.py b/airbyte-cdk/python/unit_tests/sources/file_based/in_memory_files_source.py index a68f73670edc..859d7fe56756 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/in_memory_files_source.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/in_memory_files_source.py @@ -4,10 +4,14 @@ import csv import io +import tempfile from datetime import datetime from io import IOBase from typing import Any, Dict, Iterable, List, Optional +import pandas as pd +import pyarrow as pa +import pyarrow.parquet as pq from airbyte_cdk.models import ConfiguredAirbyteCatalog from airbyte_cdk.sources.file_based.default_file_based_availability_strategy import DefaultFileBasedAvailabilityStrategy from airbyte_cdk.sources.file_based.discovery_policy import AbstractDiscoveryPolicy @@ -54,8 +58,8 @@ class InMemoryFilesStreamReader(AbstractFileBasedStreamReader): file_write_options: Optional[Dict[str, Any]] def get_matching_files( - self, - globs: List[str], + self, + globs: List[str], ) -> Iterable[RemoteFile]: yield from AbstractFileBasedStreamReader.filter_files_by_globs([ RemoteFile(uri=f, last_modified=datetime.strptime(data["last_modified"], "%Y-%m-%dT%H:%M:%S.%fZ"), file_type=self.file_type) @@ -82,3 +86,24 @@ def _make_csv_file_contents(self, file_name: str) -> str: writer = csv.writer(fh) writer.writerows(self.files[file_name]["contents"]) return fh.getvalue() + + +class TemporaryParquetFilesStreamReader(InMemoryFilesStreamReader): + """ + A file reader that writes RemoteFiles to a temporary file and then reads them back. + """ + + def open_file(self, file: RemoteFile) -> IOBase: + return io.BytesIO(self._make_file_contents(file.uri)) + + def _make_file_contents(self, file_name: str) -> bytes: + contents = self.files[file_name]["contents"] + schema = self.files[file_name].get("schema") + + df = pd.DataFrame(contents[1:], columns=contents[0]) + with tempfile.TemporaryFile() as fp: + table = pa.Table.from_pandas(df, schema) + pq.write_table(table, fp) + + fp.seek(0) + return fp.read() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/parquet_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/parquet_scenarios.py new file mode 100644 index 000000000000..e4781bc6f7fb --- /dev/null +++ b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/parquet_scenarios.py @@ -0,0 +1,398 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import datetime + +import pyarrow as pa +from unit_tests.sources.file_based.in_memory_files_source import TemporaryParquetFilesStreamReader +from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenarioBuilder + +_single_parquet_file = { + "a.parquet": { + "contents": [ + ("col1", "col2"), + ("val11", "val12"), + ("val21", "val22"), + ], + "last_modified": "2023-06-05T03:54:07.000Z", + } +} + +_multiple_parquet_file = { + "a.parquet": { + "contents": [ + ("col1", "col2"), + ("val11a", "val12a"), + ("val21a", "val22a"), + ], + "last_modified": "2023-06-05T03:54:07.000Z", + }, + "b.parquet": { + "contents": [ + ("col1", "col2", "col3"), + ("val11b", "val12b", "val13b"), + ("val21b", "val22b", "val23b"), + ], + "last_modified": "2023-06-05T03:54:07.000Z", + }, +} + +_parquet_file_with_various_types = { + "a.parquet": { + "contents": [ + ("col_bool", + + "col_int8", + "col_int16", + "col_int32", + + "col_uint8", + "col_uint16", + "col_uint32", + "col_uint64", + + "col_float32", + "col_float64", + + "col_string", + + "col_date32", + "col_date64", + + "col_timestamp_without_tz", + "col_timestamp_with_tz", + + "col_time32s", + "col_time32ms", + "col_time64us", + + "col_struct", + "col_list", + "col_duration", + "col_binary", + ), + (True, + + -1, + 1, + 2, + + 2, + 3, + 4, + 5, + + 3.14, + 5.0, + + "2020-01-01", + + datetime.date(2021, 1, 1), + datetime.date(2022, 1, 1), + datetime.datetime(2023, 1, 1, 1, 2, 3), + datetime.datetime(2024, 3, 4, 5, 6, 7, tzinfo=datetime.timezone.utc), + + datetime.time(1, 2, 3), + datetime.time(2, 3, 4), + datetime.time(1, 2, 3, 4), + {"struct_key": "struct_value"}, + [1, 2, 3, 4], + 12345, + b"binary string. Hello world!", + ), + ], + "schema": pa.schema([ + pa.field("col_bool", pa.bool_()), + + pa.field("col_int8", pa.int8()), + pa.field("col_int16", pa.int16()), + pa.field("col_int32", pa.int32()), + + pa.field("col_uint8", pa.uint8()), + pa.field("col_uint16", pa.uint16()), + pa.field("col_uint32", pa.uint32()), + pa.field("col_uint64", pa.uint64()), + + pa.field("col_float32", pa.float32()), + pa.field("col_float64", pa.float64()), + + pa.field("col_string", pa.string()), + + pa.field("col_date32", pa.date32()), + pa.field("col_date64", pa.date64()), + pa.field("col_timestamp_without_tz", pa.timestamp("s")), + pa.field("col_timestamp_with_tz", pa.timestamp("s", tz="UTC")), + + pa.field("col_time32s", pa.time32("s")), + pa.field("col_time32ms", pa.time32("ms")), + pa.field("col_time64us", pa.time64("us")), + + pa.field("col_struct", pa.struct([pa.field("struct_key", pa.string())])), + pa.field("col_list", pa.list_(pa.int32())), + pa.field("col_duration", pa.duration("s")), + pa.field("col_binary", pa.binary()) + ]), + "last_modified": "2023-06-05T03:54:07.000Z", + } +} + +single_parquet_scenario = ( + TestScenarioBuilder() + .set_name("single_parquet_stream") + .set_config( + { + "streams": [ + { + "name": "stream1", + "file_type": "parquet", + "globs": ["*"], + "validation_policy": "emit_record", + } + ] + } + ) + .set_stream_reader(TemporaryParquetFilesStreamReader(files=_single_parquet_file, file_type="parquet")) + .set_file_type("parquet") + .set_expected_records( + [ + {"data": {"col1": "val11", "col2": "val12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.parquet"}, "stream": "stream1"}, + {"data": {"col1": "val21", "col2": "val22", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.parquet"}, "stream": "stream1"}, + ] + ) + .set_expected_catalog( + { + "streams": [ + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "col1": { + "type": "string" + }, + "col2": { + "type": "string" + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + } + }, + "name": "stream1", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + } + ] + } + ) +).build() + +multi_parquet_scenario = ( + TestScenarioBuilder() + .set_name("multi_parquet_stream") + .set_config( + { + "streams": [ + { + "name": "stream1", + "file_type": "parquet", + "globs": ["*"], + "validation_policy": "emit_record", + } + ] + } + ) + .set_file_type("parquet") + .set_stream_reader(TemporaryParquetFilesStreamReader(files=_multiple_parquet_file, file_type="parquet")) + .set_expected_catalog( + { + "streams": [ + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "col1": { + "type": "string" + }, + "col2": { + "type": "string" + }, + "col3": { + "type": "string" + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + } + }, + "name": "stream1", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + } + ] + } + ) + .set_expected_records( + [ + {"data": {"col1": "val11a", "col2": "val12a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.parquet"}, "stream": "stream1"}, + {"data": {"col1": "val21a", "col2": "val22a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.parquet"}, "stream": "stream1"}, + {"data": {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.parquet"}, "stream": "stream1"}, + {"data": {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.parquet"}, "stream": "stream1"}, + ] + ) +).build() + +parquet_various_types_scenario = ( + TestScenarioBuilder() + .set_name("parquet_various_types") + .set_config( + { + "streams": [ + { + "name": "stream1", + "file_type": "parquet", + "globs": ["*"], + "validation_policy": "emit_record", + } + ] + } + ) + .set_stream_reader(TemporaryParquetFilesStreamReader(files=_parquet_file_with_various_types, file_type="parquet")) + .set_file_type("parquet") + .set_expected_catalog( + { + "streams": [ + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "col_bool": { + "type": "boolean" + }, + "col_int8": { + "type": "integer" + }, + "col_int16": { + "type": "integer" + }, + "col_int32": { + "type": "integer" + }, + "col_uint8": { + "type": "integer" + }, + "col_uint16": { + "type": "integer" + }, + "col_uint32": { + "type": "integer" + }, + "col_uint64": { + "type": "integer" + }, + "col_float32": { + "type": "number" + }, + "col_float64": { + "type": "number" + }, + "col_string": { + "type": "string" + }, + "col_date32": { + "type": "string", + "format": "date" + }, + "col_date64": { + "type": "string", + "format": "date" + }, + "col_timestamp_without_tz": { + "type": "string", + "format": "date-time" + }, + "col_timestamp_with_tz": { + "type": "string", + "format": "date-time" + }, + "col_time32s": { + "type": "string", + }, + "col_time32ms": { + "type": "string", + }, + "col_time64us": { + "type": "string", + }, + "col_struct": { + "type": "object", + }, + "col_list": { + "type": "array", + }, + "col_duration": { + "type": "integer", + }, + "col_binary": { + "type": "string", + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + }, + }, + "name": "stream1", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + } + ] + } + ) + .set_expected_records( + [ + {"data": {"col_bool": True, + "col_int8": -1, + "col_int16": 1, + "col_int32": 2, + "col_uint8": 2, + "col_uint16": 3, + "col_uint32": 4, + "col_uint64": 5, + "col_float32": 3.14, + "col_float64": 5.0, + "col_string": "2020-01-01", + "col_date32": "2021-01-01", + "col_date64": "2022-01-01", + "col_timestamp_without_tz": "2023-01-01T01:02:03", + "col_timestamp_with_tz": "2024-03-04T05:06:07+00:00", + "col_time32s": "01:02:03", + "col_time32ms": "02:03:04", + "col_time64us": "01:02:03.000004", + "col_struct": {"struct_key": "struct_value"}, + "col_list": [1, 2, 3, 4], + "col_duration": 12345, + "col_binary": "binary string. Hello world!", + "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.parquet"}, "stream": "stream1" + }, + ] + ) +).build() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py index 6f94945f635a..03570e438775 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py @@ -3,13 +3,15 @@ # import json -from pathlib import Path -from typing import Any, Dict, List, Union +import math +from pathlib import Path, PosixPath +from typing import Any, Dict, List, Mapping, Optional, Union import pytest +from _pytest.capture import CaptureFixture from _pytest.reports import ExceptionInfo from airbyte_cdk.entrypoint import launch -from airbyte_cdk.models.airbyte_protocol import SyncMode +from airbyte_cdk.models import SyncMode from freezegun import freeze_time from unit_tests.sources.file_based.scenarios.check_scenarios import ( error_empty_stream_scenario, @@ -55,6 +57,12 @@ single_csv_input_state_is_later_scenario, single_csv_no_input_state_scenario, ) +from unit_tests.sources.file_based.scenarios.parquet_scenarios import ( + multi_parquet_scenario, + parquet_various_types_scenario, + single_parquet_scenario, +) +from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenario from unit_tests.sources.file_based.scenarios.validation_policy_scenarios import ( emit_record_scenario_multi_stream, emit_record_scenario_single_stream, @@ -91,6 +99,9 @@ csv_custom_format_scenario, multi_stream_custom_format, empty_schema_inference_scenario, + single_parquet_scenario, + multi_parquet_scenario, + parquet_various_types_scenario, schemaless_csv_scenario, schemaless_csv_multi_stream_scenario, schemaless_with_user_input_schema_fails_connection_check_multi_stream_scenario, @@ -99,12 +110,13 @@ @pytest.mark.parametrize("scenario", discover_scenarios, ids=[s.name for s in discover_scenarios]) -def test_discover(capsys, tmp_path, json_spec, scenario): +def test_discover(capsys: CaptureFixture[str], tmp_path: PosixPath, json_spec: Mapping[str, Any], scenario: TestScenario) -> None: expected_exc, expected_msg = scenario.expected_discover_error if expected_exc: with pytest.raises(expected_exc) as exc: discover(capsys, tmp_path, scenario) - assert expected_msg in get_error_message_from_exc(exc) + if expected_msg: + assert expected_msg in get_error_message_from_exc(exc) else: assert discover(capsys, tmp_path, scenario) == scenario.expected_catalog @@ -123,21 +135,22 @@ def test_discover(capsys, tmp_path, json_spec, scenario): @pytest.mark.parametrize("scenario", read_scenarios, ids=[s.name for s in read_scenarios]) @freeze_time("2023-06-09T00:00:00Z") -def test_read(capsys, tmp_path, json_spec, scenario): +def test_read(capsys: CaptureFixture[str], tmp_path: PosixPath, json_spec: Mapping[str, Any], scenario: TestScenario) -> None: if scenario.incremental_scenario_config: run_test_read_incremental(capsys, tmp_path, scenario) else: run_test_read_full_refresh(capsys, tmp_path, scenario) -def run_test_read_full_refresh(capsys, tmp_path, scenario): +def run_test_read_full_refresh(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> None: expected_exc, expected_msg = scenario.expected_read_error expected_records = scenario.expected_records expected_logs = scenario.expected_logs if expected_exc: - with pytest.raises(expected_exc) as exc: + with pytest.raises(expected_exc) as exc: # noqa read(capsys, tmp_path, scenario) - assert expected_msg in get_error_message_from_exc(exc) + if expected_msg: + assert expected_msg in get_error_message_from_exc(exc) else: output = read(capsys, tmp_path, scenario) records, logs = output["records"], output["logs"] @@ -147,19 +160,23 @@ def run_test_read_full_refresh(capsys, tmp_path, scenario): assert_expected_logs_match_output(logs, expected_logs) -def assert_expected_records_match_output(output: List[Dict[str, Any]], expected_output: List[Dict[str, Any]]): +def assert_expected_records_match_output(output: List[Mapping[str, Any]], expected_output: List[Mapping[str, Any]]) -> None: for actual, expected in zip(output, expected_output): - assert actual["record"]["data"] == expected["data"] + for key, value in actual["record"]["data"].items(): + if isinstance(value, float): + assert math.isclose(value, expected["data"][key], abs_tol=1e-06) + else: + assert value == expected["data"][key] assert actual["record"]["stream"] == expected["stream"] -def assert_expected_logs_match_output(logs: List[Dict[str, Any]], expected_logs: List[Dict[str, Any]]): +def assert_expected_logs_match_output(logs: List[Mapping[str, Any]], expected_logs: List[Mapping[str, Any]]) -> None: for actual, expected in zip(logs, expected_logs): assert actual["log"]["level"] == expected["level"] assert actual["log"]["message"] == expected["message"] -def run_test_read_incremental(capsys, tmp_path, scenario): +def run_test_read_incremental(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> None: expected_exc, expected_msg = scenario.expected_read_error if expected_exc: with pytest.raises(expected_exc): @@ -192,14 +209,15 @@ def run_test_read_incremental(capsys, tmp_path, scenario): @pytest.mark.parametrize("scenario", check_scenarios, ids=[c.name for c in check_scenarios]) -def test_check(capsys, tmp_path, json_spec, scenario): +def test_check(capsys: CaptureFixture[str], tmp_path: PosixPath, json_spec: Mapping[str, Any], scenario: TestScenario) -> None: expected_exc, expected_msg = scenario.expected_check_error if expected_exc: with pytest.raises(expected_exc): output = check(capsys, tmp_path, scenario) if expected_msg: - assert expected_msg.value in output["message"] + # expected_msg is a string. what's the expected value field? + assert expected_msg.value in output["message"] # type: ignore assert output["status"] == scenario.expected_check_status else: @@ -207,25 +225,25 @@ def test_check(capsys, tmp_path, json_spec, scenario): assert output["status"] == scenario.expected_check_status -def check(capsys, tmp_path, scenario) -> Dict[str, Any]: +def check(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> Dict[str, Any]: launch( scenario.source, ["check", "--config", make_file(tmp_path / "config.json", scenario.config)], ) captured = capsys.readouterr() - return json.loads(captured.out.splitlines()[0])["connectionStatus"] + return json.loads(captured.out.splitlines()[0])["connectionStatus"] # type: ignore -def discover(capsys, tmp_path, scenario) -> Dict[str, Any]: +def discover(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> Dict[str, Any]: launch( scenario.source, ["discover", "--config", make_file(tmp_path / "config.json", scenario.config)], ) captured = capsys.readouterr() - return json.loads(captured.out.splitlines()[0])["catalog"] + return json.loads(captured.out.splitlines()[0])["catalog"] # type: ignore -def read(capsys, tmp_path, scenario): +def read(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> Dict[str, Any]: launch( scenario.source, [ @@ -251,7 +269,7 @@ def read(capsys, tmp_path, scenario): } -def read_with_state(capsys, tmp_path, scenario): +def read_with_state(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> List[Dict[str, Any]]: launch( scenario.source, [ @@ -272,10 +290,10 @@ def read_with_state(capsys, tmp_path, scenario): ] -def make_file(path: Path, file_contents: Union[Dict, List]) -> str: +def make_file(path: Path, file_contents: Optional[Union[Mapping[str, Any], List[Mapping[str, Any]]]]) -> str: path.write_text(json.dumps(file_contents)) return str(path) -def get_error_message_from_exc(exc: ExceptionInfo) -> str: - return exc.value.args[0] +def get_error_message_from_exc(exc: ExceptionInfo[Any]) -> str: + return str(exc.value.args[0]) From 4c6f14a01614b6b253248a87c68a9accccdb4849 Mon Sep 17 00:00:00 2001 From: Ben Church Date: Wed, 12 Jul 2023 16:39:35 -0600 Subject: [PATCH 48/63] Disable gradle build cache YOLO (#28248) --- .../ci_connector_ops/pipelines/actions/environments.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/ci_connector_ops/ci_connector_ops/pipelines/actions/environments.py b/tools/ci_connector_ops/ci_connector_ops/pipelines/actions/environments.py index e138339415ea..cb21fd46af3d 100644 --- a/tools/ci_connector_ops/ci_connector_ops/pipelines/actions/environments.py +++ b/tools/ci_connector_ops/ci_connector_ops/pipelines/actions/environments.py @@ -527,8 +527,9 @@ def with_gradle( .with_workdir("/airbyte") .with_mounted_directory("/airbyte", context.get_repo_dir(".", include=include)) .with_exec(["mkdir", "-p", consts.GRADLE_READ_ONLY_DEPENDENCY_CACHE_PATH]) - .with_mounted_cache(consts.GRADLE_BUILD_CACHE_PATH, gradle_build_cache, sharing=CacheSharingMode.LOCKED) - .with_mounted_cache(consts.GRADLE_READ_ONLY_DEPENDENCY_CACHE_PATH, gradle_dependency_cache) + # TODO (ben) + # .with_mounted_cache(consts.GRADLE_BUILD_CACHE_PATH, gradle_build_cache, sharing=CacheSharingMode.LOCKED) + # .with_mounted_cache(consts.GRADLE_READ_ONLY_DEPENDENCY_CACHE_PATH, gradle_dependency_cache) .with_env_variable("GRADLE_RO_DEP_CACHE", consts.GRADLE_READ_ONLY_DEPENDENCY_CACHE_PATH) ) From 188782e386580d954367956017d9bd8f8ad89ca7 Mon Sep 17 00:00:00 2001 From: Davin Chia Date: Wed, 12 Jul 2023 16:30:33 -0700 Subject: [PATCH 49/63] Revert delete insert test. (#28253) Unfortunately other tests depend on this. --------- Co-authored-by: davinchia --- ...wflakeInsertDestinationAcceptanceTest.java | 253 ++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 airbyte-integrations/connectors/destination-snowflake/src/test-integration/java/io/airbyte/integrations/destination/snowflake/SnowflakeInsertDestinationAcceptanceTest.java diff --git a/airbyte-integrations/connectors/destination-snowflake/src/test-integration/java/io/airbyte/integrations/destination/snowflake/SnowflakeInsertDestinationAcceptanceTest.java b/airbyte-integrations/connectors/destination-snowflake/src/test-integration/java/io/airbyte/integrations/destination/snowflake/SnowflakeInsertDestinationAcceptanceTest.java new file mode 100644 index 000000000000..d82ac8eed581 --- /dev/null +++ b/airbyte-integrations/connectors/destination-snowflake/src/test-integration/java/io/airbyte/integrations/destination/snowflake/SnowflakeInsertDestinationAcceptanceTest.java @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2023 Airbyte, Inc., all rights reserved. + */ + +package io.airbyte.integrations.destination.snowflake; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.base.Preconditions; +import io.airbyte.commons.io.IOs; +import io.airbyte.commons.json.Jsons; +import io.airbyte.commons.resources.MoreResources; +import io.airbyte.commons.string.Strings; +import io.airbyte.configoss.StandardCheckConnectionOutput; +import io.airbyte.configoss.StandardCheckConnectionOutput.Status; +import io.airbyte.db.factory.DataSourceFactory; +import io.airbyte.db.jdbc.JdbcDatabase; +import io.airbyte.integrations.base.JavaBaseConstants; +import io.airbyte.integrations.destination.NamingConventionTransformer; +import io.airbyte.integrations.standardtest.destination.DestinationAcceptanceTest; +import io.airbyte.integrations.standardtest.destination.argproviders.DataArgumentsProvider; +import io.airbyte.integrations.standardtest.destination.comparator.TestDataComparator; +import io.airbyte.protocol.models.v0.AirbyteCatalog; +import io.airbyte.protocol.models.v0.AirbyteConnectionStatus; +import io.airbyte.protocol.models.v0.AirbyteMessage; +import io.airbyte.protocol.models.v0.CatalogHelpers; +import io.airbyte.protocol.models.v0.ConfiguredAirbyteCatalog; +import java.nio.file.Path; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; +import java.util.stream.Collectors; +import javax.sql.DataSource; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ArgumentsSource; + +public class SnowflakeInsertDestinationAcceptanceTest extends DestinationAcceptanceTest { + + private static final NamingConventionTransformer NAME_TRANSFORMER = new SnowflakeSQLNameTransformer(); + protected static final String NO_ACTIVE_WAREHOUSE_ERR_MSG = + "No active warehouse selected in the current session. Select an active warehouse with the 'use warehouse' command."; + + protected static final String NO_USER_PRIVILEGES_ERR_MSG = + "Encountered Error with Snowflake Configuration: Current role does not have permissions on the target schema please verify your privileges"; + + protected static final String IP_NOT_IN_WHITE_LIST_ERR_MSG = "is not allowed to access Snowflake. Contact your account administrator."; + + // this config is based on the static config, and it contains a random + // schema name that is different for each test run + private JsonNode config; + private JdbcDatabase database; + private DataSource dataSource; + + @Override + protected String getImageName() { + return "airbyte/destination-snowflake:dev"; + } + + @Override + protected JsonNode getConfig() { + return config; + } + + @Override + protected TestDataComparator getTestDataComparator() { + return new SnowflakeTestDataComparator(); + } + + @Override + protected boolean supportBasicDataTypeTest() { + return true; + } + + @Override + protected boolean supportArrayDataTypeTest() { + return true; + } + + @Override + protected boolean supportObjectDataTypeTest() { + return true; + } + + public JsonNode getStaticConfig() { + final JsonNode insertConfig = Jsons.deserialize(IOs.readFile(Path.of("secrets/insert_config.json"))); + Preconditions.checkArgument(!SnowflakeDestinationResolver.isS3Copy(insertConfig)); + Preconditions.checkArgument(!SnowflakeDestinationResolver.isGcsCopy(insertConfig)); + return insertConfig; + } + + @Override + protected JsonNode getFailCheckConfig() { + final JsonNode invalidConfig = Jsons.clone(config); + ((ObjectNode) invalidConfig.get("credentials")).put("password", "wrong password"); + return invalidConfig; + } + + @Override + protected List retrieveRecords(final TestDestinationEnv env, + final String streamName, + final String namespace, + final JsonNode streamSchema) + throws Exception { + return retrieveRecordsFromTable(NAME_TRANSFORMER.getRawTableName(streamName), NAME_TRANSFORMER.getNamespace(namespace)) + .stream() + .map(r -> r.get(JavaBaseConstants.COLUMN_NAME_DATA.toUpperCase())) + .collect(Collectors.toList()); + } + + @Override + protected boolean implementsNamespaces() { + return true; + } + + @Override + protected boolean supportNamespaceTest() { + return true; + } + + @Override + protected Optional getNameTransformer() { + return Optional.of(NAME_TRANSFORMER); + } + + @Override + protected List retrieveNormalizedRecords(final TestDestinationEnv testEnv, final String streamName, final String namespace) + throws Exception { + final String tableName = NAME_TRANSFORMER.getIdentifier(streamName); + final String schema = NAME_TRANSFORMER.getNamespace(namespace); + return retrieveRecordsFromTable(tableName, schema); + } + + private List retrieveRecordsFromTable(final String tableName, final String schema) throws SQLException { + final TimeZone timeZone = TimeZone.getTimeZone("UTC"); + TimeZone.setDefault(timeZone); + + return database.bufferedResultSetQuery( + connection -> { + try (final ResultSet tableInfo = connection.createStatement() + .executeQuery(String.format("SHOW TABLES LIKE '%s' IN SCHEMA %s;", tableName, schema))) { + assertTrue(tableInfo.next()); + // check that we're creating permanent tables. DBT defaults to transient tables, which have + // `TRANSIENT` as the value for the `kind` column. + assertEquals("TABLE", tableInfo.getString("kind")); + connection.createStatement().execute("ALTER SESSION SET TIMEZONE = 'UTC';"); + return connection.createStatement() + .executeQuery(String.format("SELECT * FROM %s.%s ORDER BY %s ASC;", schema, tableName, JavaBaseConstants.COLUMN_NAME_EMITTED_AT)); + } + }, + new SnowflakeTestSourceOperations()::rowToJson); + } + + // for each test we create a new schema in the database. run the test in there and then remove it. + @Override + protected void setup(final TestDestinationEnv testEnv) throws Exception { + final String schemaName = Strings.addRandomSuffix("integration_test", "_", 5); + final String createSchemaQuery = String.format("CREATE SCHEMA %s", schemaName); + + this.config = Jsons.clone(getStaticConfig()); + ((ObjectNode) config).put("schema", schemaName); + + dataSource = SnowflakeDatabase.createDataSource(config, OssCloudEnvVarConsts.AIRBYTE_OSS); + database = SnowflakeDatabase.getDatabase(dataSource); + database.execute(createSchemaQuery); + } + + @Override + protected void tearDown(final TestDestinationEnv testEnv) throws Exception { + final String createSchemaQuery = String.format("DROP SCHEMA IF EXISTS %s", config.get("schema").asText()); + database.execute(createSchemaQuery); + DataSourceFactory.close(dataSource); + } + + @Test + public void testCheckWithNoActiveWarehouseConnection() throws Exception { + // Config to user(creds) that has no warehouse assigned + final JsonNode config = Jsons.deserialize(IOs.readFile( + Path.of("secrets/internal_staging_config_no_active_warehouse.json"))); + + final StandardCheckConnectionOutput standardCheckConnectionOutput = runCheck(config); + + assertEquals(Status.FAILED, standardCheckConnectionOutput.getStatus()); + assertThat(standardCheckConnectionOutput.getMessage()).contains(NO_ACTIVE_WAREHOUSE_ERR_MSG); + } + + @Test + public void testCheckWithNoTextSchemaPermissionConnection() throws Exception { + // Config to user (creds) that has no permission to schema + final JsonNode config = Jsons.deserialize(IOs.readFile( + Path.of("secrets/config_no_text_schema_permission.json"))); + + final StandardCheckConnectionOutput standardCheckConnectionOutput = runCheck(config); + + assertEquals(Status.FAILED, standardCheckConnectionOutput.getStatus()); + assertThat(standardCheckConnectionOutput.getMessage()).contains(NO_USER_PRIVILEGES_ERR_MSG); + } + + @Test + public void testCheckIpNotInWhiteListConnection() throws Exception { + // Config to user(creds) that has no warehouse assigned + final JsonNode config = Jsons.deserialize(IOs.readFile( + Path.of("secrets/insert_ip_not_in_whitelist_config.json"))); + + final StandardCheckConnectionOutput standardCheckConnectionOutput = runCheck(config); + + assertEquals(Status.FAILED, standardCheckConnectionOutput.getStatus()); + assertThat(standardCheckConnectionOutput.getMessage()).contains(IP_NOT_IN_WHITE_LIST_ERR_MSG); + } + + @Test + public void testBackwardCompatibilityAfterAddingOauth() { + final JsonNode deprecatedStyleConfig = Jsons.clone(config); + final JsonNode password = deprecatedStyleConfig.get("credentials").get("password"); + + ((ObjectNode) deprecatedStyleConfig).remove("credentials"); + ((ObjectNode) deprecatedStyleConfig).set("password", password); + + assertEquals(Status.SUCCEEDED, runCheckWithCatchedException(deprecatedStyleConfig)); + } + + @Test + void testCheckWithKeyPairAuth() throws Exception { + final JsonNode credentialsJsonString = Jsons.deserialize(IOs.readFile(Path.of("secrets/config_key_pair.json"))); + final AirbyteConnectionStatus check = new SnowflakeDestination(OssCloudEnvVarConsts.AIRBYTE_OSS).check(credentialsJsonString); + assertEquals(AirbyteConnectionStatus.Status.SUCCEEDED, check.getStatus()); + } + + /** + * This test is disabled because it is very slow, and should only be run manually for now. + */ + @Disabled + @ParameterizedTest + @ArgumentsSource(DataArgumentsProvider.class) + public void testSyncWithBillionRecords(final String messagesFilename, final String catalogFilename) throws Exception { + final AirbyteCatalog catalog = Jsons.deserialize(MoreResources.readResource(catalogFilename), AirbyteCatalog.class); + final ConfiguredAirbyteCatalog configuredCatalog = CatalogHelpers.toDefaultConfiguredCatalog(catalog); + final List messages = MoreResources.readResource(messagesFilename).lines() + .map(record -> Jsons.deserialize(record, AirbyteMessage.class)).toList(); + + final List largeNumberRecords = + Collections.nCopies(15000000, messages).stream().flatMap(List::stream).collect(Collectors.toList()); + + final JsonNode config = getConfig(); + runSyncAndVerifyStateOutput(config, largeNumberRecords, configuredCatalog, false); + } + +} From f0951ffbd8a884dc6784d405cc48a2b45049adde Mon Sep 17 00:00:00 2001 From: Brian Lai <51336873+brianjlai@users.noreply.github.com> Date: Wed, 12 Jul 2023 19:42:50 -0400 Subject: [PATCH 50/63] [file-based cdk] file based spec boilerplate backed by pydantic models (#28139) * file based spec operation backed by pydantic models * pr feedback to clean up various config and the test scenarios * fix tests after rebase --- .../config/abstract_file_based_spec.py | 75 +++++ .../config/file_based_stream_config.py | 7 +- .../sources/file_based/file_based_source.py | 26 +- .../cursor/default_file_based_cursor.py | 5 +- .../utils/spec_schema_transformations.py | 23 ++ .../unit_tests/sources/file_based/conftest.py | 35 --- .../file_based/in_memory_files_source.py | 22 +- .../file_based/scenarios/csv_scenarios.py | 261 +++++++++++++++++- .../scenarios/incremental_scenarios.py | 10 +- .../file_based/scenarios/scenario_builder.py | 20 +- .../sources/file_based/test_scenarios.py | 28 +- 11 files changed, 441 insertions(+), 71 deletions(-) create mode 100644 airbyte-cdk/python/airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py create mode 100644 airbyte-cdk/python/airbyte_cdk/utils/spec_schema_transformations.py delete mode 100644 airbyte-cdk/python/unit_tests/sources/file_based/conftest.py diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py new file mode 100644 index 000000000000..22ef663b0cf1 --- /dev/null +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py @@ -0,0 +1,75 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import copy +from abc import abstractmethod +from typing import Any, Dict, List + +from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig +from airbyte_cdk.sources.utils import schema_helpers +from pydantic import AnyUrl, BaseModel, Field + + +class AbstractFileBasedSpec(BaseModel): + """ + Used during spec; allows the developer to configure the cloud provider specific options + that are needed when users configure a file-based source. + """ + + streams: List[FileBasedStreamConfig] = Field( + title="The list of streams to sync", + description="Streams defines the behavior for grouping files together that will be synced to the downstream destination. Each " + "stream has it own independent configuration to handle which files to sync, how files should be parsed, and the " + "validation of records against the schema.", + order=10, + ) + + @classmethod + @abstractmethod + def documentation_url(cls) -> AnyUrl: + """ + :return: link to docs page for this source e.g. "https://docs.airbyte.com/integrations/sources/s3" + """ + + @classmethod + def schema(cls, *args: Any, **kwargs: Any) -> Dict[str, Any]: + """ + Generates the mapping comprised of the config fields + """ + schema = super().schema(*args, **kwargs) + transformed_schema = copy.deepcopy(schema) + schema_helpers.expand_refs(transformed_schema) + cls.remove_enum_allOf(transformed_schema) + cls.add_legacy_format(transformed_schema) + + return transformed_schema + + @staticmethod + def remove_enum_allOf(schema: dict) -> dict: + """ + allOfs are not supported by the UI, but pydantic is automatically writing them for enums. + Unpacks the enums under allOf and moves them up a level under the enum key + """ + # this will need to add ["anyOf"] once we have more than one format type and loop over the list of elements + objects_to_check = schema["properties"]["streams"]["items"]["properties"]["format"] + if "additionalProperties" in objects_to_check: + for key in objects_to_check["additionalProperties"]["properties"]: + object_property = objects_to_check["additionalProperties"]["properties"][key] + if "allOf" in object_property and "enum" in object_property["allOf"][0]: + object_property["enum"] = object_property["allOf"][0]["enum"] + object_property.pop("allOf") + return schema + + @staticmethod + def add_legacy_format(schema: dict) -> dict: + """ + Because we still need to allow for configs using the legacy format (like source-s3) where file format options + are at the top level and not mapped from file_type -> format options, the json schema used to validate the + config must be adjusted to support the generic mapping object. Once configs no longer adhere to the old + format we can remove this change. + """ + csv_format_options = schema["properties"]["streams"]["items"]["properties"]["format"] + union_format = {"anyOf": [csv_format_options, {"type": "object"}]} + schema["properties"]["streams"]["items"]["properties"]["format"] = union_format + return schema diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py index 5c1313508a9f..b55f98adeef8 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py @@ -6,7 +6,6 @@ from enum import Enum from typing import Any, Dict, List, Mapping, Optional, Union -from airbyte_cdk.models import ConfiguredAirbyteCatalog from pydantic import BaseModel, validator PrimaryKeyType = Optional[Union[str, List[str], List[List[str]]]] @@ -65,12 +64,10 @@ class FileBasedStreamConfig(BaseModel): name: str file_type: str globs: Optional[List[str]] - validation_policy: Union[str, Any] - catalog_schema: Optional[ConfiguredAirbyteCatalog] + validation_policy: str input_schema: Optional[Dict[str, Any]] primary_key: PrimaryKeyType - max_history_size: Optional[int] - days_to_sync_if_history_is_full: Optional[int] + days_to_sync_if_history_is_full: int = 3 format: Optional[Mapping[str, CsvFormat]] # this will eventually be a Union once we have more than one format type schemaless: bool = False diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py index de5b52f3d31a..c456b847acca 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py @@ -5,10 +5,12 @@ import logging import traceback from abc import ABC -from typing import Any, Dict, List, Mapping, Optional, Tuple +from typing import Any, Dict, List, Mapping, Optional, Tuple, Type from airbyte_cdk.models import ConfiguredAirbyteCatalog +from airbyte_cdk.models.airbyte_protocol import ConnectorSpecification from airbyte_cdk.sources import AbstractSource +from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig from airbyte_cdk.sources.file_based.default_file_based_availability_strategy import DefaultFileBasedAvailabilityStrategy from airbyte_cdk.sources.file_based.discovery_policy import AbstractDiscoveryPolicy, DefaultDiscoveryPolicy @@ -22,6 +24,8 @@ from airbyte_cdk.sources.streams.availability_strategy import AvailabilityStrategy from pydantic.error_wrappers import ValidationError +DEFAULT_MAX_HISTORY_SIZE = 10_000 + class FileBasedSource(AbstractSource, ABC): def __init__( @@ -29,16 +33,20 @@ def __init__( stream_reader: AbstractFileBasedStreamReader, catalog: Optional[ConfiguredAirbyteCatalog], availability_strategy: Optional[AvailabilityStrategy], + spec_class: Type[AbstractFileBasedSpec], discovery_policy: AbstractDiscoveryPolicy = DefaultDiscoveryPolicy(), parsers: Dict[str, FileTypeParser] = None, validation_policies: Dict[str, AbstractSchemaValidationPolicy] = DEFAULT_SCHEMA_VALIDATION_POLICIES, + max_history_size: int = DEFAULT_MAX_HISTORY_SIZE, ): self.stream_reader = stream_reader self.availability_strategy = availability_strategy or DefaultFileBasedAvailabilityStrategy(stream_reader) + self.spec_class = spec_class self.discovery_policy = discovery_policy self.parsers = parsers or default_parsers self.validation_policies = validation_policies self.stream_schemas = {s.stream.name: s.stream.json_schema for s in catalog.streams} if catalog else {} + self.max_history_size = max_history_size def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Optional[Any]]: """ @@ -87,9 +95,9 @@ def streams(self, config: Mapping[str, Any]) -> List[AbstractFileBasedStream]: Return a list of this source's streams. """ try: + parsed_config = self.spec_class(**config) streams = [] - for stream in config["streams"]: - stream_config = FileBasedStreamConfig(**stream) + for stream_config in parsed_config.streams: self._validate_stream_config(stream_config) streams.append( DefaultFileBasedStream( @@ -100,10 +108,20 @@ def streams(self, config: Mapping[str, Any]) -> List[AbstractFileBasedStream]: discovery_policy=self.discovery_policy, parsers=self.parsers, validation_policies=self.validation_policies, - cursor=DefaultFileBasedCursor(stream_config.max_history_size, stream_config.days_to_sync_if_history_is_full), + cursor=DefaultFileBasedCursor(self.max_history_size, stream_config.days_to_sync_if_history_is_full), ) ) return streams except ValidationError as exc: raise ConfigValidationError(FileBasedSourceError.CONFIG_VALIDATION_ERROR) from exc + + def spec(self, *args: Any, **kwargs: Any) -> ConnectorSpecification: + """ + Returns the specification describing what fields can be configured by a user when setting up a file-based source. + """ + + return ConnectorSpecification( + documentationUrl=self.spec_class.documentation_url(), + connectionSpecification=self.spec_class.schema(), + ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/cursor/default_file_based_cursor.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/cursor/default_file_based_cursor.py index 1b1c3f26a1b4..1646094487f4 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/cursor/default_file_based_cursor.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/cursor/default_file_based_cursor.py @@ -13,12 +13,11 @@ class DefaultFileBasedCursor(FileBasedCursor): DEFAULT_DAYS_TO_SYNC_IF_HISTORY_IS_FULL = 3 - DEFAULT_MAX_HISTORY_SIZE = 10_000 DATE_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%fZ" - def __init__(self, max_history_size: Optional[int], days_to_sync_if_history_is_full: Optional[int]): + def __init__(self, max_history_size: int, days_to_sync_if_history_is_full: Optional[int]): self._file_to_datetime_history: Mapping[str:datetime] = {} - self._max_history_size = max_history_size or self.DEFAULT_MAX_HISTORY_SIZE + self._max_history_size = max_history_size self._time_window_if_history_is_full = timedelta( days=days_to_sync_if_history_is_full or self.DEFAULT_DAYS_TO_SYNC_IF_HISTORY_IS_FULL ) diff --git a/airbyte-cdk/python/airbyte_cdk/utils/spec_schema_transformations.py b/airbyte-cdk/python/airbyte_cdk/utils/spec_schema_transformations.py new file mode 100644 index 000000000000..2a772d50b6c3 --- /dev/null +++ b/airbyte-cdk/python/airbyte_cdk/utils/spec_schema_transformations.py @@ -0,0 +1,23 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import json +import re + +from jsonschema import RefResolver + + +def resolve_refs(schema: dict) -> dict: + """ + For spec schemas generated using Pydantic models, the resulting JSON schema can contain refs between object + relationships. + """ + json_schema_ref_resolver = RefResolver.from_schema(schema) + str_schema = json.dumps(schema) + for ref_block in re.findall(r'{"\$ref": "#\/definitions\/.+?(?="})"}', str_schema): + ref = json.loads(ref_block)["$ref"] + str_schema = str_schema.replace(ref_block, json.dumps(json_schema_ref_resolver.resolve(ref)[1])) + pyschema: dict = json.loads(str_schema) + del pyschema["definitions"] + return pyschema diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/conftest.py b/airbyte-cdk/python/unit_tests/sources/file_based/conftest.py deleted file mode 100644 index d95b01a46107..000000000000 --- a/airbyte-cdk/python/unit_tests/sources/file_based/conftest.py +++ /dev/null @@ -1,35 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -import json -import os -import sys - -import pytest - -CONNECTION_SPECIFICATION = { - "type": "object", - "additionalProperties": True, -} - - -@pytest.fixture -def json_spec(): - # Our way of resolving the absolute path to root of the airbyte-cdk unit test directory where spec.yaml files should - # be written to (i.e. ~/airbyte/airbyte-cdk/python/unit-tests) because that is where they are read from during testing. - module = sys.modules[__name__] - module_path = os.path.abspath(module.__file__) - test_path = os.path.dirname(module_path) - spec_root = test_path.split("/sources/file_based")[0] - - spec = { - "documentationUrl": "https://airbyte.com/#yaml-from-external", - "connectionSpecification": CONNECTION_SPECIFICATION, - } - - json_path = os.path.join(spec_root, "spec.json") - with open(json_path, "w") as f: - f.write(json.dumps(spec)) - yield - os.remove(json_path) diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/in_memory_files_source.py b/airbyte-cdk/python/unit_tests/sources/file_based/in_memory_files_source.py index 859d7fe56756..e5b2354d8112 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/in_memory_files_source.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/in_memory_files_source.py @@ -13,14 +13,16 @@ import pyarrow as pa import pyarrow.parquet as pq from airbyte_cdk.models import ConfiguredAirbyteCatalog +from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec from airbyte_cdk.sources.file_based.default_file_based_availability_strategy import DefaultFileBasedAvailabilityStrategy from airbyte_cdk.sources.file_based.discovery_policy import AbstractDiscoveryPolicy -from airbyte_cdk.sources.file_based.file_based_source import FileBasedSource +from airbyte_cdk.sources.file_based.file_based_source import DEFAULT_MAX_HISTORY_SIZE, FileBasedSource from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser from airbyte_cdk.sources.file_based.remote_file import RemoteFile from airbyte_cdk.sources.file_based.schema_validation_policies import DEFAULT_SCHEMA_VALIDATION_POLICIES, AbstractSchemaValidationPolicy from airbyte_cdk.sources.streams.availability_strategy import AvailabilityStrategy +from pydantic import AnyUrl, Field class InMemoryFilesSource(FileBasedSource): @@ -35,6 +37,7 @@ def __init__( stream_reader: AbstractFileBasedStreamReader, catalog: Optional[Dict[str, Any]], file_write_options: Dict[str, Any], + max_history_size: int, ): stream_reader = stream_reader or InMemoryFilesStreamReader(files=files, file_type=file_type, file_write_options=file_write_options) availability_strategy = availability_strategy or DefaultFileBasedAvailabilityStrategy(stream_reader) @@ -42,9 +45,11 @@ def __init__( stream_reader, catalog=ConfiguredAirbyteCatalog(streams=catalog["streams"]) if catalog else None, availability_strategy=availability_strategy, + spec_class=InMemorySpec, discovery_policy=discovery_policy, parsers=parsers, validation_policies=validation_policies or DEFAULT_SCHEMA_VALIDATION_POLICIES, + max_history_size=max_history_size or DEFAULT_MAX_HISTORY_SIZE ) # Attributes required for test purposes @@ -88,6 +93,21 @@ def _make_csv_file_contents(self, file_name: str) -> str: return fh.getvalue() +class InMemorySpec(AbstractFileBasedSpec): + @classmethod + def documentation_url(cls) -> AnyUrl: + return AnyUrl(scheme="https", url="https://docs.airbyte.com/integrations/sources/in_memory_files") + + start_date: Optional[str] = Field( + title="Start Date", + description="UTC date and time in the format 2017-01-25T00:00:00Z. Any file modified before this date will not be replicated.", + examples=["2021-01-01T00:00:00Z"], + format="date-time", + pattern="^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$", + order=1, + ) + + class TemporaryParquetFilesStreamReader(InMemoryFilesStreamReader): """ A file reader that writes RemoteFiles to a temporary file and then reads them back. diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py index abae2caf3b66..2edc40b0ebac 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py @@ -18,7 +18,8 @@ "globs": ["*"], "validation_policy": "emit_record", } - ] + ], + "start_date": "2023-06-04T03:54:07Z" } ) .set_files( @@ -34,6 +35,146 @@ } ) .set_file_type("csv") + .set_expected_spec( + { + "documentationUrl": "https://docs.airbyte.com/integrations/sources/in_memory_files", + "connectionSpecification": { + "title": "InMemorySpec", + "description": "Used during spec; allows the developer to configure the cloud provider specific options\nthat are needed " + "when users configure a file-based source.", + "type": "object", + "properties": { + "streams": { + "title": "The list of streams to sync", + "description": "Streams defines the behavior for grouping files together that will be synced to the downstream " + "destination. Each stream has it own independent configuration to handle which files to sync, " + "how files should be parsed, and the validation of records against the schema.", + "order": 10, + "type": "array", + "items": { + "title": "FileBasedStreamConfig", + "type": "object", + "properties": { + "name": { + "title": "Name", + "type": "string" + }, + "file_type": { + "title": "File Type", + "type": "string" + }, + "globs": { + "title": "Globs", + "type": "array", + "items": { + "type": "string" + } + }, + "schemaless": { + "title": "Schemaless", + "default": False, + "type": "boolean" + }, + "validation_policy": { + "title": "Validation Policy", + "type": "string" + }, + "input_schema": { + "title": "Input Schema", + "type": "object" + }, + "primary_key": { + "title": "Primary Key", + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + }, + { + "type": "array", + "items": { + "type": "array", + "items": { + "type": "string" + } + } + } + ] + }, + "days_to_sync_if_history_is_full": { + "title": "Days To Sync If History Is Full", + "default": 3, + "type": "integer" + }, + "format": { + "anyOf": [ + { + "title": "Format", + "type": "object", + "additionalProperties": { + "title": "CsvFormat", + "type": "object", + "properties": { + "delimiter": { + "title": "Delimiter", + "default": ",", + "type": "string" + }, + "quote_char": { + "title": "Quote Char", + "default": "\"", + "type": "string" + }, + "escape_char": { + "title": "Escape Char", + "type": "string" + }, + "encoding": { + "title": "Encoding", + "default": "utf8", + "type": "string" + }, + "double_quote": { + "title": "Double Quote", + "type": "boolean" + }, + "quoting_behavior": { + "default": "Quote Special Characters", + "enum": ["Quote All", "Quote Special Characters", "Quote Non-numeric", "Quote None"] + } + }, + "required": ["double_quote"] + } + }, + { + "type": "object" + } + ] + } + }, + "required": ["name", "file_type", "validation_policy"] + } + }, + "start_date": { + "title": "Start Date", + "description": "UTC date and time in the format 2017-01-25T00:00:00Z. Any file modified before this date will not " + "be replicated.", + "examples": ["2021-01-01T00:00:00Z"], + "format": "date-time", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$", + "order": 1, + "type": "string" + } + }, + "required": ["streams"] + }, + } + ) .set_expected_catalog( { "streams": [ @@ -492,6 +633,96 @@ csv_custom_format_scenario = ( TestScenarioBuilder() .set_name("csv_custom_format") + .set_config( + { + "streams": [ + { + "name": "stream1", + "file_type": "csv", + "globs": ["*"], + "validation_policy": "emit_record", + "format": { + "csv": { + "filetype": "csv", + "delimiter": "#", + "quote_char": "|", + "escape_char": "!", + "double_quote": True, + "quoting_behavior": "Quote Special Characters" + } + } + } + ] + } + ) + .set_files( + { + "a.csv": { + "contents": [ + ("col1", "col2", "col3"), + ("val11", "val12", "val |13|"), + ("val21", "val22", "val23"), + ("val,31", "val |,32|", "val, !!!! 33"), + ], + "last_modified": "2023-06-05T03:54:07.000Z", + } + } + ) + .set_file_type("csv") + .set_expected_catalog( + { + "streams": [ + { + "json_schema": { + "type": "object", + "properties": { + "col1": { + "type": "string", + }, + "col2": { + "type": "string", + }, + "col3": { + "type": "string", + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + }, + }, + "name": "stream1", + "source_defined_cursor": True, + "default_cursor_field": ["_ab_source_file_last_modified"], + "supported_sync_modes": ["full_refresh", "incremental"], + } + ] + } + ) + .set_expected_records( + [ + {"data": {"col1": "val11", "col2": "val12", "col3": "val |13|", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21", "col2": "val22", "col3": "val23", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val,31", "col2": "val |,32|", "col3": "val, !! 33", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + ] + ) + .set_file_write_options( + { + "delimiter": "#", + "quotechar": "|", + } + ) +).build() + + +csv_legacy_format_scenario = ( + TestScenarioBuilder() + .set_name("csv_legacy_format") .set_config( { "streams": [ @@ -506,7 +737,7 @@ "quote_char": "|", "escape_char": "!", "double_quote": True, - "quoting_behavior": "Quote Special Characters" + "quoting_behavior": "Quote All" } } ] @@ -589,11 +820,13 @@ "globs": ["*.csv"], "validation_policy": "emit_record", "format": { - "filetype": "csv", - "delimiter": "#", - "escape_char": "!", - "double_quote": True, - "newlines_in_values": False + "csv": { + "filetype": "csv", + "delimiter": "#", + "escape_char": "!", + "double_quote": True, + "newlines_in_values": False + } } }, { @@ -602,12 +835,14 @@ "globs": ["b.csv"], "validation_policy": "emit_record", "format": { - "filetype": "csv", - "delimiter": "#", - "escape_char": "@", - "double_quote": True, - "newlines_in_values": False, - "quoting_behavior": "Quote All" + "csv": { + "filetype": "csv", + "delimiter": "#", + "escape_char": "@", + "double_quote": True, + "newlines_in_values": False, + "quoting_behavior": "Quote All" + } } } ] diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/incremental_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/incremental_scenarios.py index 654a9904478e..865ee9ad59be 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/incremental_scenarios.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/incremental_scenarios.py @@ -958,7 +958,6 @@ "file_type": "csv", "globs": ["*.csv"], "validation_policy": "emit_record", - "max_history_size": 3, } ] } @@ -992,6 +991,7 @@ } ) .set_file_type("csv") + .set_max_history_size(3) .set_expected_catalog( { "streams": [ @@ -1093,7 +1093,6 @@ "file_type": "csv", "globs": ["*.csv"], "validation_policy": "emit_record", - "max_history_size": 3, "days_to_sync_if_history_is_full": 3, } ] @@ -1136,6 +1135,7 @@ } ) .set_file_type("csv") + .set_max_history_size(3) .set_expected_catalog( { "streams": [ @@ -1210,7 +1210,6 @@ "file_type": "csv", "globs": ["*.csv"], "validation_policy": "emit_record", - "max_history_size": 3, "days_to_sync_if_history_is_full": 3, } ] @@ -1252,6 +1251,7 @@ }, } ) + .set_max_history_size(3) .set_file_type("csv") .set_expected_catalog( { @@ -1326,7 +1326,6 @@ "file_type": "csv", "globs": ["*.csv"], "validation_policy": "emit_record", - "max_history_size": 3, "days_to_sync_if_history_is_full": 3, } ] @@ -1369,6 +1368,7 @@ } ) .set_file_type("csv") + .set_max_history_size(3) .set_expected_catalog( { "streams": [ @@ -1448,7 +1448,6 @@ "file_type": "csv", "globs": ["*.csv"], "validation_policy": "emit_record", - "max_history_size": 3, "days_to_sync_if_history_is_full": 3, } ] @@ -1491,6 +1490,7 @@ } ) .set_file_type("csv") + .set_max_history_size(3) .set_expected_catalog( { "streams": [ diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/scenario_builder.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/scenario_builder.py index 78e2691ae01d..831071cf5277 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/scenario_builder.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/scenario_builder.py @@ -8,7 +8,7 @@ from airbyte_cdk.models.airbyte_protocol import SyncMode from airbyte_cdk.sources.file_based.discovery_policy import AbstractDiscoveryPolicy, DefaultDiscoveryPolicy -from airbyte_cdk.sources.file_based.file_based_source import default_parsers +from airbyte_cdk.sources.file_based.file_based_source import DEFAULT_MAX_HISTORY_SIZE, default_parsers from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser from airbyte_cdk.sources.file_based.schema_validation_policies import AbstractSchemaValidationPolicy @@ -29,6 +29,7 @@ def __init__( config: Mapping[str, Any], files: Dict[str, Any], file_type: str, + expected_spec: Optional[Dict[str, Any]], expected_check_status: Optional[str], expected_catalog: Optional[Dict[str, Any]], expected_logs: Optional[Dict[str, Any]], @@ -42,10 +43,12 @@ def __init__( expected_discover_error: Tuple[Optional[Type[Exception]], Optional[str]], expected_read_error: Tuple[Optional[Type[Exception]], Optional[str]], incremental_scenario_config: Optional[IncrementalScenarioConfig], - file_write_options: Dict[str, Any] + file_write_options: Dict[str, Any], + max_history_size: int, ): self.name = name self.config = config + self.expected_spec = expected_spec self.expected_check_status = expected_check_status self.expected_catalog = expected_catalog self.expected_logs = expected_logs @@ -63,6 +66,7 @@ def __init__( stream_reader, self.configured_catalog(SyncMode.incremental if incremental_scenario_config else SyncMode.full_refresh), file_write_options, + max_history_size, ) self.incremental_scenario_config = incremental_scenario_config self.validate() @@ -103,6 +107,7 @@ def __init__(self): self._config = {} self._files = {} self._file_type = None + self._expected_spec = None self._expected_check_status = None self._expected_catalog = {} self._expected_logs = {} @@ -117,6 +122,7 @@ def __init__(self): self._expected_read_error = None, None self._incremental_scenario_config = None self._file_write_options = {} + self._max_history_size = DEFAULT_MAX_HISTORY_SIZE def set_name(self, name: str): self._name = name @@ -134,6 +140,10 @@ def set_file_type(self, file_type: str): self._file_type = file_type return self + def set_expected_spec(self, expected_spec: Dict[str, Any]): + self._expected_spec = expected_spec + return self + def set_expected_check_status(self, expected_check_status: str): self._expected_check_status = expected_check_status return self @@ -170,6 +180,10 @@ def set_stream_reader(self, stream_reader: AbstractFileBasedStreamReader): self._stream_reader = stream_reader return self + def set_max_history_size(self, max_history_size: int): + self._max_history_size = max_history_size + return self + def set_incremental_scenario_config(self, incremental_scenario_config: IncrementalScenarioConfig): self._incremental_scenario_config = incremental_scenario_config return self @@ -199,6 +213,7 @@ def build(self): self._config, self._files, self._file_type, + self._expected_spec, self._expected_check_status, self._expected_catalog, self._expected_logs, @@ -213,4 +228,5 @@ def build(self): self._expected_read_error, self._incremental_scenario_config, self._file_write_options, + self._max_history_size, ) diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py index 03570e438775..16f7efdf3a47 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py @@ -27,6 +27,7 @@ ) from unit_tests.sources.file_based.scenarios.csv_scenarios import ( csv_custom_format_scenario, + csv_legacy_format_scenario, csv_multi_stream_scenario, csv_single_stream_scenario, empty_schema_inference_scenario, @@ -97,6 +98,7 @@ single_csv_file_is_skipped_if_same_modified_at_as_in_history, single_csv_file_is_synced_if_modified_at_is_more_recent_than_in_history, csv_custom_format_scenario, + csv_legacy_format_scenario, multi_stream_custom_format, empty_schema_inference_scenario, single_parquet_scenario, @@ -110,7 +112,7 @@ @pytest.mark.parametrize("scenario", discover_scenarios, ids=[s.name for s in discover_scenarios]) -def test_discover(capsys: CaptureFixture[str], tmp_path: PosixPath, json_spec: Mapping[str, Any], scenario: TestScenario) -> None: +def test_discover(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> None: expected_exc, expected_msg = scenario.expected_discover_error if expected_exc: with pytest.raises(expected_exc) as exc: @@ -135,7 +137,7 @@ def test_discover(capsys: CaptureFixture[str], tmp_path: PosixPath, json_spec: M @pytest.mark.parametrize("scenario", read_scenarios, ids=[s.name for s in read_scenarios]) @freeze_time("2023-06-09T00:00:00Z") -def test_read(capsys: CaptureFixture[str], tmp_path: PosixPath, json_spec: Mapping[str, Any], scenario: TestScenario) -> None: +def test_read(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> None: if scenario.incremental_scenario_config: run_test_read_incremental(capsys, tmp_path, scenario) else: @@ -192,6 +194,17 @@ def run_test_read_incremental(capsys: CaptureFixture[str], tmp_path: PosixPath, assert actual["state"]["data"] == expected +spec_scenarios = [ + csv_multi_stream_scenario, + csv_single_stream_scenario, +] + + +@pytest.mark.parametrize("scenario", spec_scenarios, ids=[c.name for c in spec_scenarios]) +def test_spec(capsys, scenario): + assert spec(capsys, single_csv_scenario) == single_csv_scenario.expected_spec + + check_scenarios = [ error_empty_stream_scenario, error_extension_mismatch_scenario, @@ -209,7 +222,7 @@ def run_test_read_incremental(capsys: CaptureFixture[str], tmp_path: PosixPath, @pytest.mark.parametrize("scenario", check_scenarios, ids=[c.name for c in check_scenarios]) -def test_check(capsys: CaptureFixture[str], tmp_path: PosixPath, json_spec: Mapping[str, Any], scenario: TestScenario) -> None: +def test_check(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> None: expected_exc, expected_msg = scenario.expected_check_error if expected_exc: @@ -225,6 +238,15 @@ def test_check(capsys: CaptureFixture[str], tmp_path: PosixPath, json_spec: Mapp assert output["status"] == scenario.expected_check_status +def spec(capsys, scenario): + launch( + scenario.source, + ["spec"], + ) + captured = capsys.readouterr() + return json.loads(captured.out.splitlines()[0])["spec"] + + def check(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> Dict[str, Any]: launch( scenario.source, From 507ad698f3c20c083e2636e7027d108cc6cb530d Mon Sep 17 00:00:00 2001 From: Anatolii Yatsuk <35109939+tolik0@users.noreply.github.com> Date: Thu, 13 Jul 2023 12:13:47 +0300 Subject: [PATCH 51/63] =?UTF-8?q?=E2=9C=A8=20Source=20Monday:=20Add=20incr?= =?UTF-8?q?emental=20sync=20for=20Items=20and=20Boards=20stream=20(#27944)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add incremental sync for the Boards and Items streams using Activity logs --------- Co-authored-by: Oleksandr Bazarnov Co-authored-by: Sherif A. Nada --- .../connectors/source-monday/Dockerfile | 2 +- .../source-monday/acceptance-test-config.yml | 16 +- .../integration_tests/abnormal_state.json | 44 ++- .../integration_tests/configured_catalog.json | 34 +- .../integration_tests/expected_records.jsonl | 304 ++++++++++++------ .../incremental_catalog.json | 46 +++ .../integration_tests/sample_state.json | 44 ++- .../connectors/source-monday/metadata.yaml | 2 +- .../connectors/source-monday/setup.py | 2 +- .../source-monday/source_monday/components.py | 217 +++++++++++++ .../source-monday/source_monday/extractor.py | 105 ++++++ .../source_monday/graphql_requester.py | 70 +++- .../source_monday/item_pagination_strategy.py | 2 +- .../source-monday/source_monday/manifest.yaml | 114 +++++-- .../source_monday/schemas/activity_logs.json | 14 + .../source_monday/schemas/boards.json | 1 + .../source_monday/schemas/items.json | 1 + .../source_monday/schemas/tags.json | 2 +- .../source_monday/schemas/workspaces.json | 2 +- .../unit_tests/test_components.py | 55 ++++ .../unit_tests/test_graphql_requester.py | 3 +- docs/integrations/sources/monday.md | 39 ++- 22 files changed, 952 insertions(+), 167 deletions(-) create mode 100644 airbyte-integrations/connectors/source-monday/integration_tests/incremental_catalog.json create mode 100644 airbyte-integrations/connectors/source-monday/source_monday/components.py create mode 100644 airbyte-integrations/connectors/source-monday/source_monday/extractor.py create mode 100644 airbyte-integrations/connectors/source-monday/source_monday/schemas/activity_logs.json create mode 100644 airbyte-integrations/connectors/source-monday/unit_tests/test_components.py diff --git a/airbyte-integrations/connectors/source-monday/Dockerfile b/airbyte-integrations/connectors/source-monday/Dockerfile index f8210bd6dbf2..0cc5b9767af6 100644 --- a/airbyte-integrations/connectors/source-monday/Dockerfile +++ b/airbyte-integrations/connectors/source-monday/Dockerfile @@ -34,5 +34,5 @@ COPY source_monday ./source_monday ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=1.0.0 +LABEL io.airbyte.version=1.1.0 LABEL io.airbyte.name=airbyte/source-monday diff --git a/airbyte-integrations/connectors/source-monday/acceptance-test-config.yml b/airbyte-integrations/connectors/source-monday/acceptance-test-config.yml index a3975fc4d233..16ea6d61a9d4 100644 --- a/airbyte-integrations/connectors/source-monday/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-monday/acceptance-test-config.yml @@ -1,6 +1,7 @@ # See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) # for more information about how to configure these tests connector_image: airbyte/source-monday:dev +test_strictness_level: "high" acceptance_tests: spec: tests: @@ -18,10 +19,7 @@ acceptance_tests: discovery: tests: - config_path: "secrets/config.json" - # `boards`, `items`, `updates` streams schemas were modified - # changed type of id for assets in items and updates - # change deprecated owner to owners in boards - # All changes described in corresponding pr + # `boards`, `items`, `updates` streams schemas were modified. PR: https://github.com/airbytehq/airbyte/pull/27410 # Changes applies to all configs backward_compatibility_tests_config: disable_for_version: "0.2.6" @@ -69,4 +67,12 @@ acceptance_tests: tests: - config_path: "secrets/config_api_token.json" incremental: - bypass_reason: "Incremental syncs are not supported on this connector." + tests: + - config_path: "secrets/config_api_token.json" + configured_catalog_path: "integration_tests/incremental_catalog.json" + future_state: + future_state_path: "integration_tests/abnormal_state.json" + cursor_paths: + items: [ "updated_at_int" ] + boards: [ "updated_at_int" ] + activity_logs: [ "created_at_int" ] diff --git a/airbyte-integrations/connectors/source-monday/integration_tests/abnormal_state.json b/airbyte-integrations/connectors/source-monday/integration_tests/abnormal_state.json index 52b0f2c2118f..cf6aa56ba36c 100644 --- a/airbyte-integrations/connectors/source-monday/integration_tests/abnormal_state.json +++ b/airbyte-integrations/connectors/source-monday/integration_tests/abnormal_state.json @@ -1,5 +1,41 @@ -{ - "todo-stream-name": { - "todo-field-name": "todo-abnormal-value" +[ + { + "type" : "STREAM", + "stream" : { + "stream_descriptor" : { + "name" : "items" + }, + "stream_state" : { + "updated_at" : 1699041749, + "activity_logs" : { + "created_at_int" : 1699041749 + } + } + } + }, + { + "type" : "STREAM", + "stream" : { + "stream_descriptor" : { + "name" : "boards" + }, + "stream_state" : { + "updated_at_int" : 1699041749, + "activity_logs" : { + "created_at_int" : 1699041749 + } + } + } + }, + { + "type" : "STREAM", + "stream" : { + "stream_descriptor" : { + "name" : "activity_logs" + }, + "stream_state" : { + "created_at_int" : 1699041749 + } + } } -} +] diff --git a/airbyte-integrations/connectors/source-monday/integration_tests/configured_catalog.json b/airbyte-integrations/connectors/source-monday/integration_tests/configured_catalog.json index df3c46a3e156..91fa7d7b5c01 100644 --- a/airbyte-integrations/connectors/source-monday/integration_tests/configured_catalog.json +++ b/airbyte-integrations/connectors/source-monday/integration_tests/configured_catalog.json @@ -4,21 +4,29 @@ "stream": { "name": "items", "json_schema": {}, - "supported_sync_modes": ["full_refresh"], + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated_at_int"], "source_defined_primary_key": [["id"]] }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" + "sync_mode": "incremental", + "cursor_field": ["updated_at_int"], + "destination_sync_mode": "overwrite", + "primary_key": [["id"]] }, { "stream": { "name": "boards", "json_schema": {}, - "supported_sync_modes": ["full_refresh"], + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated_at_int"], "source_defined_primary_key": [["id"]] }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" + "sync_mode": "incremental", + "cursor_field": ["updated_at_int"], + "destination_sync_mode": "overwrite", + "primary_key": [["id"]] }, { "stream": { @@ -69,6 +77,20 @@ }, "sync_mode": "full_refresh", "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "activity_logs", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["created_at_int"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["created_at_int"], + "destination_sync_mode": "overwrite", + "primary_key": [["id"]] } ] } diff --git a/airbyte-integrations/connectors/source-monday/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-monday/integration_tests/expected_records.jsonl index a1fbe20708fd..da37ac33ab11 100644 --- a/airbyte-integrations/connectors/source-monday/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-monday/integration_tests/expected_records.jsonl @@ -1,92 +1,212 @@ -{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2019-03-01T17:24:57.321Z\"}", "description": null, "id": "status", "text": "Working on it", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2019-03-01T17:24:57.321Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2023-06-11", "title": "Date", "type": "date", "value": "{\"date\":\"2023-06-11\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:25.871Z\"}"}, {"additional_info": null, "description": null, "id": "tags", "text": "open", "title": "Tags", "type": "tag", "value": "{\"tag_ids\":[19038090]}"}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "4635211945", "name": "Item 1", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-15T16:19:37Z", "updates": [{"id": "2223820299"}, {"id": "2223818363"}]}, "emitted_at": 1687273314210} -{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2019-03-01T17:28:23.178Z\"}", "description": null, "id": "status", "text": "Done", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-03-01T17:28:23.178Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2023-06-11", "title": "Date", "type": "date", "value": "{\"date\":\"2023-06-11\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:25.871Z\"}"}, {"additional_info": null, "description": null, "id": "tags", "text": "closed", "title": "Tags", "type": "tag", "value": "{\"tag_ids\":[19038091]}"}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "4635211964", "name": "Item 2", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-13T13:59:36Z", "updates": []}, "emitted_at": 1687273314214} -{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":null,\"color\":\"#c4c4c4\",\"changed_at\":\"2019-03-01T17:25:02.248Z\"}", "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": "{\"index\":5,\"post_id\":null,\"changed_at\":\"2019-03-01T17:25:02.248Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2023-06-13", "title": "Date", "type": "date", "value": "{\"date\":\"2023-06-13\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:26.291Z\"}"}, {"additional_info": null, "description": null, "id": "tags", "text": "", "title": "Tags", "type": "tag", "value": null}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "4635211977", "name": "Item 3", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-13T13:58:26Z", "updates": []}, "emitted_at": 1687273314216} -{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2023-06-13", "title": "Date", "type": "date", "value": "{\"date\":\"2023-06-13\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:25.469Z\"}"}, {"additional_info": null, "description": null, "id": "tags", "text": "", "title": "Tags", "type": "tag", "value": null}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "4635212008", "name": "Item 4", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-13T13:58:25Z", "updates": []}, "emitted_at": 1687273314218} -{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2023-06-13", "title": "Date", "type": "date", "value": "{\"date\":\"2023-06-13\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:25.469Z\"}"}, {"additional_info": null, "description": null, "id": "tags", "text": "", "title": "Tags", "type": "tag", "value": null}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "4635211995", "name": "Item 5", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-13T13:58:25Z", "updates": []}, "emitted_at": 1687273314220} -{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2023-06-20T12:12:53.948Z\"}", "description": null, "id": "status", "text": "Done", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2023-06-20T12:12:53.948Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "tags", "text": "", "title": "Tags", "type": "tag", "value": null}], "created_at": "2023-06-20T12:12:51Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "4672922929", "name": "Item 6", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-20T12:12:54Z", "updates": []}, "emitted_at": 1687273314222} -{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "tags", "text": "", "title": "Tags", "type": "tag", "value": null}], "created_at": "2023-06-20T12:13:03Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "4672924165", "name": "Item 7", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-20T12:13:03Z", "updates": []}, "emitted_at": 1687273314224} -{"stream": "items", "data": {"assets": [{"created_at": "2023-06-14T12:30:13Z", "file_extension": ".jpg", "file_size": 116107, "id": "916811099", "name": "black_cat.jpg", "original_geometry": "473x600", "public_url": "https://files-monday-com.s3.amazonaws.com/14202902/resources/916811099/black_cat.jpg?response-content-disposition=attachment&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA4MPVJMFXGWGLJTLY%2F20230620%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230620T150154Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=8ea33a5b6d6eeff76cb887301b5bbad7ee0617efa2357e0e078687d80f8d2385", "uploaded_by": {"id": 36694549}, "url": "https://airbyte-unit.monday.com/protected_static/14202902/resources/916811099/black_cat.jpg", "url_thumbnail": "https://airbyte-unit.monday.com/protected_static/14202902/resources/916811099/thumb_small-black_cat.jpg"}], "board": {"id": "4634950289"}, "column_values": [{"additional_info": null, "description": null, "id": "files", "text": "https://airbyte-unit.monday.com/protected_static/14202902/resources/916811099/black_cat.jpg", "title": "Files", "type": "file", "value": "{\"files\":[{\"name\":\"black_cat.jpg\",\"assetId\":916811099,\"isImage\":\"true\",\"fileType\":\"ASSET\",\"createdAt\":1686745812452,\"createdBy\":\"36694549\"}]}"}], "created_at": "2023-06-13T13:28:32Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "4634950329", "name": "Doc Comments", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-14T12:30:14Z", "updates": []}, "emitted_at": 1687273314762} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2019-04-11", "title": "Request date", "type": "date", "value": "{\"date\":\"2019-04-11\",\"icon\":null,\"changed_at\":\"2019-04-10 08:06:40 UTC\"}"}, {"additional_info": "{\"label\":\"Evaluating\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-07-22T06:28:36.561Z\"}", "description": null, "id": "status1", "text": "Evaluating", "title": "Procurement status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:36.561Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:09:58.545Z\"}", "description": null, "id": "status", "text": "Approved", "title": "Manager approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:09:58.545Z\"}"}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:11:20.855Z\"}", "description": null, "id": "status4", "text": "Approved", "title": "Budget owner approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:11:20.855Z\"}"}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:14:00.506Z\"}", "description": null, "id": "budget_owner_approval", "text": "Approved", "title": "Procurement approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:14:00.506Z\"}"}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Declined\",\"color\":\"#e2445c\",\"changed_at\":\"2019-05-15T14:34:59.145Z\"}", "description": null, "id": "procurement_approval", "text": "Declined", "title": "Finance approval", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2019-05-15T14:34:59.145Z\"}"}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"On Hold\",\"color\":\"#fdab3d\",\"changed_at\":\"2019-04-10T08:17:41.900Z\"}", "description": null, "id": "finance_approval", "text": "On Hold", "title": "Legal approval", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2019-04-10T08:17:41.900Z\"}"}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": "{\"files\":null}"}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Declined\",\"color\":\"#e2445c\",\"changed_at\":\"2019-04-30T15:43:35.438Z\"}", "description": null, "id": "legal_approval", "text": "Declined", "title": "Security approval", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2019-04-30T15:43:35.438Z\"}"}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:51 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:51Z", "creator_id": "25479561", "group": {"id": "topics"}, "id": "3555407934", "name": "Zendesk", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:51Z", "updates": []}, "emitted_at": 1687273317078} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2019-04-11", "title": "Request date", "type": "date", "value": "{\"date\":\"2019-04-11\",\"changed_at\":\"2019-04-02T07:03:23.375Z\"}"}, {"additional_info": "{\"label\":\"On hold\",\"color\":\"#BB3354\",\"changed_at\":\"2020-06-25T11:41:22.421Z\"}", "description": null, "id": "status1", "text": "On hold", "title": "Procurement status", "type": "color", "value": "{\"index\":11,\"post_id\":null,\"changed_at\":\"2020-06-25T11:41:22.421Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-03-01T17:28:23.178Z\"}", "description": null, "id": "status", "text": "Approved", "title": "Manager approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-03-01T17:28:23.178Z\"}"}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Declined\",\"color\":\"#e2445c\",\"changed_at\":\"2019-04-10T08:11:26.186Z\"}", "description": null, "id": "status4", "text": "Declined", "title": "Budget owner approval", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2019-04-10T08:11:26.186Z\"}"}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": "{\"files\":null}"}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"On Hold\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-25T06:36:38.993Z\"}", "description": null, "id": "legal_approval", "text": "On Hold", "title": "Security approval", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-25T06:36:38.993Z\"}"}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:52 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "25479561", "group": {"id": "topics"}, "id": "3555407944", "name": "Salesforce", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273317080} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2019-04-17", "title": "Request date", "type": "date", "value": "{\"date\":\"2019-04-17\",\"changed_at\":\"2019-04-02T07:03:25.251Z\"}"}, {"additional_info": "{\"label\":\"Waiting for vendor\",\"color\":\"#784BD1\",\"changed_at\":\"2020-07-22T06:28:39.711Z\"}", "description": null, "id": "status1", "text": "Waiting for vendor", "title": "Procurement status", "type": "color", "value": "{\"index\":14,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:39.711Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:10:00.038Z\"}", "description": null, "id": "status", "text": "Approved", "title": "Manager approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:10:00.038Z\"}"}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:11:23.942Z\"}", "description": null, "id": "status4", "text": "Approved", "title": "Budget owner approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:11:23.942Z\"}"}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:14:02.186Z\"}", "description": null, "id": "budget_owner_approval", "text": "Approved", "title": "Procurement approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:14:02.186Z\"}"}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:16:19.222Z\"}", "description": null, "id": "procurement_approval", "text": "Approved", "title": "Finance approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:16:19.222Z\"}"}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:17:46.022Z\"}", "description": null, "id": "finance_approval", "text": "Approved", "title": "Legal approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:17:46.022Z\"}"}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": "{\"files\":null}"}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-25T06:36:40.961Z\"}", "description": null, "id": "legal_approval", "text": "Approved", "title": "Security approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-25T06:36:40.961Z\"}"}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:52 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "25479561", "group": {"id": "topics"}, "id": "3555407952", "name": "YouCanBookMe", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273317082} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-25T11:41:48.118Z\"}", "description": null, "id": "status1", "text": "Done", "title": "Procurement status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-25T11:41:48.118Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408067", "name": "Box", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273317084} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Approved for use\",\"color\":\"#4eccc6\",\"changed_at\":\"2020-07-22T06:27:41.551Z\"}", "description": null, "id": "status1", "text": "Approved for use", "title": "Procurement status", "type": "color", "value": "{\"index\":108,\"post_id\":null,\"changed_at\":\"2020-07-22T06:27:41.551Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408077", "name": "Slack", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273317086} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Approved for use\",\"color\":\"#4eccc6\",\"changed_at\":\"2020-07-22T06:26:53.835Z\"}", "description": null, "id": "status1", "text": "Approved for use", "title": "Procurement status", "type": "color", "value": "{\"index\":108,\"post_id\":null,\"changed_at\":\"2020-07-22T06:26:53.835Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408088", "name": "HelpJuice", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273317087} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Approved for use\",\"color\":\"#4eccc6\",\"changed_at\":\"2020-07-22T06:28:31.709Z\"}", "description": null, "id": "status1", "text": "Approved for use", "title": "Procurement status", "type": "color", "value": "{\"index\":108,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:31.709Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408094", "name": "LucidChart", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273317089} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2019-04-11", "title": "Request date", "type": "date", "value": "{\"date\":\"2019-04-11\",\"changed_at\":\"2019-04-02T07:03:23.375Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-07-22T06:28:25.645Z\"}", "description": null, "id": "status1", "text": "Done", "title": "Procurement status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:25.645Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-03-01T17:28:23.178Z\"}", "description": null, "id": "status", "text": "Approved", "title": "Manager approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-03-01T17:28:23.178Z\"}"}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:06.894Z\"}", "description": null, "id": "status4", "text": "Approved", "title": "Budget owner approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:06.894Z\"}"}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:08.700Z\"}", "description": null, "id": "budget_owner_approval", "text": "Approved", "title": "Procurement approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:08.700Z\"}"}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:10.209Z\"}", "description": null, "id": "procurement_approval", "text": "Approved", "title": "Finance approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:10.209Z\"}"}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:11.909Z\"}", "description": null, "id": "finance_approval", "text": "Approved", "title": "Legal approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:11.909Z\"}"}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": "{\"files\":null}"}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:15.385Z\"}", "description": null, "id": "legal_approval", "text": "Approved", "title": "Security approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:15.385Z\"}"}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "25479561", "group": {"id": "new_group"}, "id": "3555408048", "name": "Aircall", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273317091} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2019-04-17", "title": "Request date", "type": "date", "value": "{\"date\":\"2019-04-17\",\"changed_at\":\"2019-04-02T07:03:25.251Z\"}"}, {"additional_info": "{\"label\":\"Approved for use\",\"color\":\"#4eccc6\",\"changed_at\":\"2020-07-22T06:28:29.177Z\"}", "description": null, "id": "status1", "text": "Approved for use", "title": "Procurement status", "type": "color", "value": "{\"index\":108,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:29.177Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:10:00.038Z\"}", "description": null, "id": "status", "text": "Approved", "title": "Manager approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:10:00.038Z\"}"}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:11:23.942Z\"}", "description": null, "id": "status4", "text": "Approved", "title": "Budget owner approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:11:23.942Z\"}"}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:14:02.186Z\"}", "description": null, "id": "budget_owner_approval", "text": "Approved", "title": "Procurement approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:14:02.186Z\"}"}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:16:19.222Z\"}", "description": null, "id": "procurement_approval", "text": "Approved", "title": "Finance approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:16:19.222Z\"}"}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:17:46.022Z\"}", "description": null, "id": "finance_approval", "text": "Approved", "title": "Legal approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:17:46.022Z\"}"}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": "{\"files\":null}"}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:17.250Z\"}", "description": null, "id": "legal_approval", "text": "Approved", "title": "Security approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:17.250Z\"}"}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "25479561", "group": {"id": "new_group"}, "id": "3555408057", "name": "Zoom", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273317093} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Waiting for legal\",\"color\":\"#0086c0\",\"changed_at\":\"2020-07-22T06:27:17.793Z\"}", "description": null, "id": "status1", "text": "Waiting for legal", "title": "Procurement status", "type": "color", "value": "{\"index\":3,\"post_id\":null,\"changed_at\":\"2020-07-22T06:27:17.793Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group2816"}, "id": "3555408102", "name": "Gaviti", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273317095} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Negotiation\",\"color\":\"#9CD326\",\"changed_at\":\"2020-07-22T06:27:22.578Z\"}", "description": null, "id": "status1", "text": "Negotiation", "title": "Procurement status", "type": "color", "value": "{\"index\":15,\"post_id\":null,\"changed_at\":\"2020-07-22T06:27:22.578Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group2816"}, "id": "3555408118", "name": "Priority", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273317096} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN56456", "title": "SN", "type": "text", "value": "\"SN56456\""}, {"additional_info": "{\"label\":\"Needs replacement\",\"color\":\"#e2445c\",\"changed_at\":\"2020-06-22T08:37:41.248Z\"}", "description": null, "id": "status", "text": "Needs replacement", "title": "Status", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2020-06-22T08:37:41.248Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-05-14", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-05-14\",\"changed_at\":\"2020-06-22T11:25:44.457Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Zakariah Macleod", "title": "Current owner", "type": "text", "value": "\"Zakariah Macleod\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-10", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-10\",\"changed_at\":\"2020-06-24T10:59:53.938Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_tvs___projectors"}, "id": "3555407991", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318766} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN 94-34-AS-GT-66", "title": "SN", "type": "text", "value": "\"SN 94-34-AS-GT-66\""}, {"additional_info": "{\"label\":\"Out for repair\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-22T08:37:42.971Z\"}", "description": null, "id": "status", "text": "Out for repair", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-22T08:37:42.971Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-10", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-10\",\"changed_at\":\"2020-06-22T11:25:46.599Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Corbin Blackburn", "title": "Current owner", "type": "text", "value": "\"Corbin Blackburn\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-11", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-11\",\"changed_at\":\"2020-06-24T10:59:55.752Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_tvs___projectors"}, "id": "3555407997", "name": "Sonos One", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318769} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "P2219G", "title": "SN", "type": "text", "value": "\"P2219G\""}, {"additional_info": "{\"label\":\"Out for repair\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-22T08:37:44.792Z\"}", "description": null, "id": "status", "text": "Out for repair", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-22T08:37:44.792Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-02", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-02\",\"changed_at\":\"2020-06-22T11:25:48.402Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Jorge Mcgowan", "title": "Current owner", "type": "text", "value": "\"Jorge Mcgowan\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-28", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-28\",\"changed_at\":\"2020-06-24T10:59:57.460Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_tvs___projectors"}, "id": "3555408009", "name": "Dell", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318771} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE57L21Y", "title": "SN", "type": "text", "value": "\"SN FVFYVE57L21Y\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-03", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-22T11:25:52.834Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Rylee Pham", "title": "Current owner", "type": "text", "value": "\"Rylee Pham\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-03-11", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-03-11\",\"changed_at\":\"2020-06-24T11:00:01.660Z\"}"}], "created_at": "2022-11-21T14:36:51Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407931", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:51Z", "updates": []}, "emitted_at": 1687273318773} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE57L22Y", "title": "SN", "type": "text", "value": "\"SN FVFYVE57L22Y\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-03", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-22T11:25:56.327Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Kaydon Gamble", "title": "Current owner", "type": "text", "value": "\"Kaydon Gamble\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-02-19", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-02-19\",\"changed_at\":\"2020-06-24T11:00:06.248Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407941", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318774} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE57L23W", "title": "SN", "type": "text", "value": "\"SN FVFYVE57L23W\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-04", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-04\",\"changed_at\":\"2020-06-22T11:25:58.156Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Eli Reyes", "title": "Current owner", "type": "text", "value": "\"Eli Reyes\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-03-26", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-03-26\",\"changed_at\":\"2020-06-24T11:00:13.482Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407947", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318776} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE57L41V", "title": "SN", "type": "text", "value": "\"SN FVFYVE57L41V\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-11", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-11\",\"changed_at\":\"2020-06-22T11:26:00.305Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Finley Hilton", "title": "Current owner", "type": "text", "value": "\"Finley Hilton\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-03-12", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-03-12\",\"changed_at\":\"2020-06-24T11:00:09.820Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407961", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318778} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE67L21Y", "title": "SN", "type": "text", "value": "\"SN FVFYVE67L21Y\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-17", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-17\",\"changed_at\":\"2020-06-22T11:26:02.141Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Fabien Morton", "title": "Current owner", "type": "text", "value": "\"Fabien Morton\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-04-21", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-04-21\",\"changed_at\":\"2020-06-24T11:00:17.305Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407968", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318779} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE57L28Y", "title": "SN", "type": "text", "value": "\"SN FVFYVE57L28Y\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-18", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-18\",\"changed_at\":\"2020-06-22T11:26:04.062Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Amelia-Mae Flower", "title": "Current owner", "type": "text", "value": "\"Amelia-Mae Flower\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-04", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-04\",\"changed_at\":\"2020-06-24T11:00:21.416Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407977", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318781} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "", "title": "SN", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date given to current owner", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Current owner", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "", "title": "Last checked", "type": "date", "value": null}], "created_at": "2023-06-20T12:21:27Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "4672979272", "name": "Macbook", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-20T12:21:27Z", "updates": []}, "emitted_at": 1687273318783} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "3sBeKstD", "title": "SN", "type": "text", "value": "\"3sBeKstD\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-03", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-22T11:26:06.624Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Masuma Carver", "title": "Current owner", "type": "text", "value": "\"Masuma Carver\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-04-07", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-04-07\",\"changed_at\":\"2020-06-24T11:00:35.389Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408016", "name": "Dell - U2417H", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273318784} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "eqK2M67W", "title": "SN", "type": "text", "value": "\"eqK2M67W\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-10", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-10\",\"changed_at\":\"2020-06-22T11:26:08.798Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Tadhg Hensley", "title": "Current owner", "type": "text", "value": "\"Tadhg Hensley\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-04", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-04\",\"changed_at\":\"2020-06-24T11:00:23.245Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408058", "name": "Dell - U2418H", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273318786} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "39QTALuj", "title": "SN", "type": "text", "value": "\"39QTALuj\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-09", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-09\",\"changed_at\":\"2020-06-22T11:26:10.906Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Aanya Booth", "title": "Current owner", "type": "text", "value": "\"Aanya Booth\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-05", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-05\",\"changed_at\":\"2020-06-24T11:00:25.468Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408070", "name": "Dell - U2416H", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273318788} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "LTgqT9cY", "title": "SN", "type": "text", "value": "\"LTgqT9cY\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-03", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-22T11:26:12.701Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Kiana Burnett", "title": "Current owner", "type": "text", "value": "\"Kiana Burnett\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-20", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-20\",\"changed_at\":\"2020-06-24T11:00:27.706Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408083", "name": "Dell - U2419HX", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273318789} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "FjE7nsrs", "title": "SN", "type": "text", "value": "\"FjE7nsrs\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-10", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-10\",\"changed_at\":\"2020-06-22T11:26:17.156Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Roxie Forbes", "title": "Current owner", "type": "text", "value": "\"Roxie Forbes\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-05-06", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-05-06\",\"changed_at\":\"2020-06-24T11:00:31.519Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408091", "name": "Dell - P2219H", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273318791} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN32456", "title": "SN", "type": "text", "value": "\"SN32456\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date given to current owner", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Current owner", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-05-05", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-05-05\",\"changed_at\":\"2020-06-24T11:00:39.214Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408021", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273318793} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN32457", "title": "SN", "type": "text", "value": "\"SN32457\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date given to current owner", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Current owner", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-05-07", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-05-07\",\"changed_at\":\"2020-06-24T11:00:42.752Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408033", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273318794} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN32458", "title": "SN", "type": "text", "value": "\"SN32458\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date given to current owner", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Current owner", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-05-21", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-05-21\",\"changed_at\":\"2020-06-24T11:00:46.170Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408041", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273318796} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN32458", "title": "SN", "type": "text", "value": "\"SN32458\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date given to current owner", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Current owner", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-03", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-24T11:00:48.979Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408052", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": []}, "emitted_at": 1687273318798} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Start date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Team", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status8", "text": null, "title": "Site", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status1", "text": null, "title": "Computer type", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status2", "text": null, "title": "Computer setup", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "computer_setup", "text": null, "title": "Google account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "google_account", "text": null, "title": "Zoom account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "zoom_account", "text": null, "title": "365 account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "365_account3", "text": null, "title": "Setup desk monitor", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "set_up_desk_monitor", "text": null, "title": "Setup entrance tag", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "email", "text": "", "title": "Email", "type": "email", "value": null}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "25479561", "group": {"id": "airbyte_group"}, "id": "3555408019", "name": "new item", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:56Z", "updates": [{"id": "1825289531"}]}, "emitted_at": 1687273381500} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Start date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Team", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status8", "text": null, "title": "Site", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status1", "text": null, "title": "Computer type", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status2", "text": null, "title": "Computer setup", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "computer_setup", "text": null, "title": "Google account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "google_account", "text": null, "title": "Zoom account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "zoom_account", "text": null, "title": "365 account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "365_account3", "text": null, "title": "Setup desk monitor", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "set_up_desk_monitor", "text": null, "title": "Setup entrance tag", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "email", "text": "", "title": "Email", "type": "email", "value": null}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555407986", "name": "Hi there! \ud83d\udc4b Click here for more information \u27a1\ufe0f", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [{"id": "1825289518"}]}, "emitted_at": 1687273381502} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-23", "title": "Start date", "type": "date", "value": "{\"date\":\"2020-06-23\"}"}, {"additional_info": "{\"label\":\"Finance\",\"color\":\"#579bfc\",\"changed_at\":null}", "description": null, "id": "status", "text": "Finance", "title": "Team", "type": "color", "value": "{\"index\":7,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Denver\",\"color\":\"#225091\",\"changed_at\":null}", "description": null, "id": "status8", "text": "Denver", "title": "Site", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"PC\",\"color\":\"#784BD1\",\"changed_at\":null}", "description": null, "id": "status1", "text": "PC", "title": "Computer type", "type": "color", "value": "{\"index\":14,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-21T13:46:33.895Z\"}", "description": null, "id": "status2", "text": "Working on it", "title": "Computer setup", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-21T13:46:33.895Z\"}"}, {"additional_info": null, "description": null, "id": "computer_setup", "text": null, "title": "Google account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "google_account", "text": null, "title": "Zoom account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "zoom_account", "text": null, "title": "365 account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "365_account3", "text": null, "title": "Setup desk monitor", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "set_up_desk_monitor", "text": null, "title": "Setup entrance tag", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "email", "text": "bjornk@yahoo.com", "title": "Email", "type": "email", "value": "{\"text\":\"bjornk@yahoo.com\",\"email\":\"bjornk@yahoo.com\"}"}], "created_at": "2022-11-21T14:36:51Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407939", "name": "Employee name 3", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273381504} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-19", "title": "Start date", "type": "date", "value": "{\"date\":\"2020-06-19\"}"}, {"additional_info": "{\"label\":\"Sales\",\"color\":\"#a25ddc\",\"changed_at\":null}", "description": null, "id": "status", "text": "Sales", "title": "Team", "type": "color", "value": "{\"index\":4,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Denver\",\"color\":\"#225091\",\"changed_at\":null}", "description": null, "id": "status8", "text": "Denver", "title": "Site", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"PC\",\"color\":\"#784BD1\",\"changed_at\":null}", "description": null, "id": "status1", "text": "PC", "title": "Computer type", "type": "color", "value": "{\"index\":14,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:46:39.331Z\"}", "description": null, "id": "status2", "text": "Done", "title": "Computer setup", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:46:39.331Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:46:40.460Z\"}", "description": null, "id": "computer_setup", "text": "Done", "title": "Google account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:46:40.460Z\"}"}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-21T13:46:41.571Z\"}", "description": null, "id": "google_account", "text": "Working on it", "title": "Zoom account", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-21T13:46:41.571Z\"}"}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-21T13:49:15.506Z\"}", "description": null, "id": "zoom_account", "text": "Working on it", "title": "365 account", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:15.506Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T06:24:56.006Z\"}", "description": null, "id": "365_account3", "text": "Done", "title": "Setup desk monitor", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T06:24:56.006Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T06:24:57.281Z\"}", "description": null, "id": "set_up_desk_monitor", "text": "Done", "title": "Setup entrance tag", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T06:24:57.281Z\"}"}, {"additional_info": null, "description": null, "id": "email", "text": "fangorn@att.net", "title": "Email", "type": "email", "value": "{\"text\":\"fangorn@att.net\",\"email\":\"fangorn@att.net\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407955", "name": "Employee name 5", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273381506} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-05-15", "title": "Start date", "type": "date", "value": "{\"date\":\"2020-05-15\"}"}, {"additional_info": "{\"label\":\"Partners\",\"color\":\"#037f4c\",\"changed_at\":null}", "description": null, "id": "status", "text": "Partners", "title": "Team", "type": "color", "value": "{\"index\":6,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Florida\",\"color\":\"#FF642E\",\"changed_at\":null}", "description": null, "id": "status8", "text": "Florida", "title": "Site", "type": "color", "value": "{\"index\":2,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Mac\",\"color\":\"#00c875\",\"changed_at\":null}", "description": null, "id": "status1", "text": "Mac", "title": "Computer type", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:51.414Z\"}", "description": null, "id": "status2", "text": "Done", "title": "Computer setup", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:51.414Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:52.581Z\"}", "description": null, "id": "computer_setup", "text": "Done", "title": "Google account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:52.581Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:54.106Z\"}", "description": null, "id": "google_account", "text": "Done", "title": "Zoom account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:54.106Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:55.348Z\"}", "description": null, "id": "zoom_account", "text": "Done", "title": "365 account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:55.348Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:55.348Z\"}", "description": null, "id": "365_account3", "text": "Done", "title": "Setup desk monitor", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:55.348Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:55.348Z\"}", "description": null, "id": "set_up_desk_monitor", "text": "Done", "title": "Setup entrance tag", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:55.348Z\"}"}, {"additional_info": null, "description": null, "id": "email", "text": "mdielmann@me.com", "title": "Email", "type": "email", "value": "{\"text\":\"mdielmann@me.com\",\"email\":\"mdielmann@me.com\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555407946", "name": "Employee name 4", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273381508} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-04-16", "title": "Start date", "type": "date", "value": "{\"date\":\"2020-04-16\"}"}, {"additional_info": "{\"label\":\"R&D\",\"color\":\"#0086c0\",\"changed_at\":null}", "description": null, "id": "status", "text": "R&D", "title": "Team", "type": "color", "value": "{\"index\":3,\"post_id\":null}"}, {"additional_info": "{\"label\":\"New York\",\"color\":\"#784BD1\",\"changed_at\":null}", "description": null, "id": "status8", "text": "New York", "title": "Site", "type": "color", "value": "{\"index\":14,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Mac\",\"color\":\"#00c875\",\"changed_at\":null}", "description": null, "id": "status1", "text": "Mac", "title": "Computer type", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:57.121Z\"}", "description": null, "id": "status2", "text": "Done", "title": "Computer setup", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:57.121Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:59.755Z\"}", "description": null, "id": "computer_setup", "text": "Done", "title": "Google account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:59.755Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:02.766Z\"}", "description": null, "id": "google_account", "text": "Done", "title": "Zoom account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:02.766Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:06.494Z\"}", "description": null, "id": "zoom_account", "text": "Done", "title": "365 account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:06.494Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:06.494Z\"}", "description": null, "id": "365_account3", "text": "Done", "title": "Setup desk monitor", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:06.494Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:06.494Z\"}", "description": null, "id": "set_up_desk_monitor", "text": "Done", "title": "Setup entrance tag", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:06.494Z\"}"}, {"additional_info": null, "description": null, "id": "email", "text": "bjornk@outlook.com", "title": "Email", "type": "email", "value": "{\"text\":\"bjornk@outlook.com\",\"email\":\"bjornk@outlook.com\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_new_hires___6_25_"}, "id": "3555407966", "name": "Employee name 6", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273381509} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-04-29", "title": "Start date", "type": "date", "value": "{\"date\":\"2020-04-29\"}"}, {"additional_info": "{\"label\":\"Sales\",\"color\":\"#a25ddc\",\"changed_at\":null}", "description": null, "id": "status", "text": "Sales", "title": "Team", "type": "color", "value": "{\"index\":4,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Denver\",\"color\":\"#225091\",\"changed_at\":null}", "description": null, "id": "status8", "text": "Denver", "title": "Site", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Mac\",\"color\":\"#00c875\",\"changed_at\":null}", "description": null, "id": "status1", "text": "Mac", "title": "Computer type", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:58.600Z\"}", "description": null, "id": "status2", "text": "Done", "title": "Computer setup", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:58.600Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:01.489Z\"}", "description": null, "id": "computer_setup", "text": "Done", "title": "Google account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:01.489Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:04.009Z\"}", "description": null, "id": "google_account", "text": "Done", "title": "Zoom account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:04.009Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:05.324Z\"}", "description": null, "id": "zoom_account", "text": "Done", "title": "365 account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:05.324Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:05.324Z\"}", "description": null, "id": "365_account3", "text": "Done", "title": "Setup desk monitor", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:05.324Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:05.324Z\"}", "description": null, "id": "set_up_desk_monitor", "text": "Done", "title": "Setup entrance tag", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:05.324Z\"}"}, {"additional_info": null, "description": null, "id": "email", "text": "mcmillan@gmail.com", "title": "Email", "type": "email", "value": "{\"text\":\"mcmillan@gmail.com\",\"email\":\"mcmillan@gmail.com\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_new_hires___6_25_"}, "id": "3555407969", "name": "Employee name 7", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": []}, "emitted_at": 1687273381511} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://drive.google.com/file/d/1wC5EQFsISkGAYLTKtcw1sG3ppHNLwESl/view", "title": "Link", "type": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1wC5EQFsISkGAYLTKtcw1sG3ppHNLwESl/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:27.555Z\"}"}, {"additional_info": null, "description": "", "id": "label", "text": null, "title": "Label", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Text", "type": "text", "value": null}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179394", "name": "API session", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": []}, "emitted_at": 1687273382214} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://drive.google.com/file/d/1BbEblAXGDOxTiTIDIcqOzfhAh43IyuTu/view", "title": "Link", "type": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1BbEblAXGDOxTiTIDIcqOzfhAh43IyuTu/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:31.968Z\"}"}, {"additional_info": null, "description": "", "id": "label", "text": null, "title": "Label", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Text", "type": "text", "value": null}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179405", "name": "Build a view", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": []}, "emitted_at": 1687273382217} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://drive.google.com/file/d/1ByMoeo2yhQcZfEOLhPP_iTjhutsLHipO/view", "title": "Link", "type": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1ByMoeo2yhQcZfEOLhPP_iTjhutsLHipO/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:38.402Z\"}"}, {"additional_info": null, "description": "", "id": "label", "text": null, "title": "Label", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Text", "type": "text", "value": null}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179418", "name": "Build an integration", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": []}, "emitted_at": 1687273382219} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://drive.google.com/file/d/1MbhkWgJY8piKmH0uivIHaKnwYPyNr3rS/view", "title": "Link", "type": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1MbhkWgJY8piKmH0uivIHaKnwYPyNr3rS/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:48.148Z\"}"}, {"additional_info": null, "description": "", "id": "label", "text": null, "title": "Label", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Text", "type": "text", "value": null}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179422", "name": "Authentication", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": []}, "emitted_at": 1687273382221} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://drive.google.com/file/d/1ZUwXi9VA7MfD3JZJgvVXmpdvaosHJIKm/view", "title": "Link", "type": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1ZUwXi9VA7MfD3JZJgvVXmpdvaosHJIKm/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:53.319Z\"}"}, {"additional_info": null, "description": "", "id": "label", "text": null, "title": "Label", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Text", "type": "text", "value": null}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179431", "name": "Build a Workspace template", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": []}, "emitted_at": 1687273382223} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2022-11-21T14:40:58.550Z\"}", "description": null, "id": "status", "text": "Done", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-11-21T14:40:58.550Z\"}"}, {"additional_info": null, "description": null, "id": "link", "text": "Airbyte - https://airbyte.com/", "title": "Link", "type": "link", "value": "{\"url\":\"https://airbyte.com/\",\"text\":\"Airbyte\",\"changed_at\":\"2022-11-21T14:40:42.184Z\"}"}, {"additional_info": "{\"label\":\"Label 3\",\"color\":\"#9D99B9\",\"changed_at\":\"2022-11-21T14:41:45.550Z\"}", "description": "", "id": "label", "text": "Label 3", "title": "Label", "type": "color", "value": "{\"index\":156,\"post_id\":null,\"changed_at\":\"2022-11-21T14:41:45.550Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Test test test", "title": "Text", "type": "text", "value": "\"Test test test\""}], "created_at": "2022-11-21T14:40:34Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555433784", "name": "Test", "parent_item": {"id": "3555179351"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:42:01Z", "updates": []}, "emitted_at": 1687273382224} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2022-11-21T14:41:32.359Z\"}", "description": null, "id": "status", "text": "Working on it", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-11-21T14:41:32.359Z\"}"}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": "{\"label\":\"Label 1\",\"color\":\"#9AADBD\",\"changed_at\":\"2022-11-21T14:41:43.450Z\"}", "description": "", "id": "label", "text": "Label 1", "title": "Label", "type": "color", "value": "{\"index\":105,\"post_id\":null,\"changed_at\":\"2022-11-21T14:41:43.450Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "one two three #!!", "title": "Text", "type": "text", "value": "\"one two three #!!\""}], "created_at": "2022-11-21T14:41:12Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555437747", "name": "Test1", "parent_item": {"id": "3555179351"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-15T16:14:33Z", "updates": [{"id": "1825302913"}]}, "emitted_at": 1687273382226} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": "{\"label\":\"Done!\",\"color\":\"#00c875\",\"changed_at\":\"2022-06-07T11:29:38.019Z\"}", "description": null, "id": "status_1", "text": "Done!", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-06-07T11:29:38.019Z\"}"}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179259", "name": "Create a dev account", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384036} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "Test, Test1", "title": "Subitems", "type": "subtasks", "value": "{\"linkedPulseIds\":[{\"linkedPulseId\":3555433784},{\"linkedPulseId\":3555437747}]}"}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2022-06-07T11:29:19.711Z\"}", "description": null, "id": "status_1", "text": "Working on it", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:29:19.711Z\"}"}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179351", "name": "Click to read this update \ud83e\udd29", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:41:13Z", "updates": [{"id": "1825206780"}]}, "emitted_at": 1687273384038} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://www.youtube.com/watch?v=nUMK6d1JcCY", "title": "Link", "type": "link", "value": "{\"url\":\"https://www.youtube.com/watch?v=nUMK6d1JcCY\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:16:13.208Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "You can write you notes here", "title": "My notes", "type": "text", "value": "\"You can write you notes here\""}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Video\",\"color\":\"#e2445c\",\"changed_at\":\"2022-06-07T11:16:08.728Z\"}", "description": null, "id": "status_10", "text": "Video", "title": "Type", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2022-06-07T11:16:08.728Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "14293832", "group": {"id": "topics"}, "id": "3555179247", "name": "What is monday - 2 min video \ud83c\udfa5 (Very cool)", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384040} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "Notes", "title": "My notes", "type": "text", "value": "\"Notes\""}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2022-11-21T14:42:28.383Z\"}", "description": null, "id": "status_1", "text": "Working on it", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-11-21T14:42:28.383Z\"}"}, {"additional_info": "{\"label\":\"Documentation\",\"color\":\"#175A63\",\"changed_at\":\"2022-11-21T14:42:31.122Z\"}", "description": null, "id": "status_10", "text": "Documentation", "title": "Type", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-11-21T14:42:31.122Z\"}"}], "created_at": "2022-11-21T14:42:29Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555446655", "name": "Item 1", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:42:42Z", "updates": []}, "emitted_at": 1687273384042} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "Note 2", "title": "My notes", "type": "text", "value": "\"Note 2\""}, {"additional_info": "{\"label\":\"Stuck\",\"color\":\"#e2445c\",\"changed_at\":\"2022-11-21T14:42:44.903Z\"}", "description": null, "id": "status_1", "text": "Stuck", "title": "Status", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2022-11-21T14:42:44.903Z\"}"}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-11-21T14:42:47.315Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-11-21T14:42:47.315Z\"}"}], "created_at": "2022-11-21T14:42:48Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555448801", "name": "Item 2", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:42:58Z", "updates": []}, "emitted_at": 1687273384043} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "LInk - https://support.monday.com/hc/en-us/articles/360001267945-The-board-views", "title": "Link", "type": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360001267945-The-board-views\",\"text\":\"LInk\",\"changed_at\":\"2022-06-07T11:18:26.141Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:17:57.718Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:17:57.718Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "new_group37570"}, "id": "3555179253", "name": "Board views", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384045} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://support.monday.com/hc/en-us/articles/360017143959-The-Item-Card-", "title": "Link", "type": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360017143959-The-Item-Card-\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:57:42.870Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:22:29.156Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:22:29.156Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group37570"}, "id": "3555179292", "name": "Item views", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384047} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://support.monday.com/hc/en-us/articles/360003445540-monday-com-Integrations", "title": "Link", "type": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360003445540-monday-com-Integrations\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:51:35.374Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:22:29.156Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:22:29.156Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group37570"}, "id": "3555179262", "name": "Integrations", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384048} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://support.monday.com/hc/en-us/articles/360002187819-The-Dashboards", "title": "Link", "type": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360002187819-The-Dashboards\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:54:50.218Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:22:29.156Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:22:29.156Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group37570"}, "id": "3555179270", "name": "Dashboard widgets", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384050} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://support.monday.com/hc/en-us/articles/360001362625-monday-com-board-templates", "title": "Link", "type": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360001362625-monday-com-board-templates\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:56:20.627Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:56:23.316Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:56:23.316Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group37570"}, "id": "3555179288", "name": "Workspace template", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384052} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Apps marketplace - https://monday.com/marketplace", "title": "Link", "type": "link", "value": "{\"url\":\"https://monday.com/marketplace\",\"text\":\"Apps marketplace\",\"changed_at\":\"2022-04-12T13:55:17.553Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:38Z", "creator_id": "14293832", "group": {"id": "group_title"}, "id": "3555179185", "name": "Check out our marketplace - The puzzle icon on the left pane", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:38Z", "updates": []}, "emitted_at": 1687273384054} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://apps.developer.monday.com/docs/monday-app-development-process", "title": "Link", "type": "link", "value": "{\"url\":\"https://apps.developer.monday.com/docs/monday-app-development-process\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:58:53.115Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:58:38.720Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:58:38.720Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "14293832", "group": {"id": "group_title"}, "id": "3555179305", "name": "Plan your app", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384055} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://monday.com/developers/apps/intro", "title": "Link", "type": "link", "value": "{\"url\":\"https://monday.com/developers/apps/intro\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:59:07.145Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Documentation\",\"color\":\"#175A63\",\"changed_at\":\"2022-06-07T11:58:40.733Z\"}", "description": null, "id": "status_10", "text": "Documentation", "title": "Type", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-06-07T11:58:40.733Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555179310", "name": "Check out our monday apps documentation", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": []}, "emitted_at": 1687273384057} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://apps.developer.monday.com/docs/workspace-templates", "title": "Link", "type": "link", "value": "{\"url\":\"https://apps.developer.monday.com/docs/workspace-templates\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:59:30.527Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Documentation\",\"color\":\"#175A63\",\"changed_at\":\"2022-06-07T11:58:43.818Z\"}", "description": null, "id": "status_10", "text": "Documentation", "title": "Type", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-06-07T11:58:43.818Z\"}"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555179318", "name": "Bundling templates with your app", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": []}, "emitted_at": 1687273384059} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "API session, Build a view, Build an integration, Authentication, Build a Workspace template", "title": "Subitems", "type": "subtasks", "value": "{\"linkedPulseIds\":[{\"linkedPulseId\":3555179394},{\"linkedPulseId\":3555179405},{\"linkedPulseId\":3555179418},{\"linkedPulseId\":3555179422},{\"linkedPulseId\":3555179431}]}"}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Video\",\"color\":\"#e2445c\",\"changed_at\":\"2022-06-07T11:59:35.220Z\"}", "description": null, "id": "status_10", "text": "Video", "title": "Type", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2022-06-07T11:59:35.220Z\"}"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "29814928", "group": {"id": "group_title"}, "id": "3555179341", "name": "Sessions recordings - See the framework in action (Subitems)", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:42Z", "updates": []}, "emitted_at": 1687273384060} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://apps.developer.monday.com/docs/submit-your-app", "title": "Link", "type": "link", "value": "{\"url\":\"https://apps.developer.monday.com/docs/submit-your-app\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T12:06:37.152Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T12:06:30.006Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T12:06:30.006Z\"}"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "36694549", "group": {"id": "new_group45036"}, "id": "3555179324", "name": "Prepare for marketplace review", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": []}, "emitted_at": 1687273384062} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link to board - https://view.monday.com/2586384041-f47a2dae812b0a295f0a974bfc39b42d?r=use1", "title": "Link", "type": "link", "value": "{\"url\":\"https://view.monday.com/2586384041-f47a2dae812b0a295f0a974bfc39b42d?r=use1\",\"text\":\"Link to board\",\"changed_at\":\"2022-04-25T09:16:11.585Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group45036"}, "id": "3555179218", "name": "App review template board", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384064} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Submission form - https://forms.monday.com/forms/c390831d51274ee8882bf4fc96a6fb17", "title": "Link", "type": "link", "value": "{\"url\":\"https://forms.monday.com/forms/c390831d51274ee8882bf4fc96a6fb17\",\"text\":\"Submission form\",\"changed_at\":\"2022-04-12T14:04:58.308Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "new_group45036"}, "id": "3555179230", "name": "Submit your app to review", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384065} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://community.monday.com/c/developers/8", "title": "Link", "type": "link", "value": "{\"url\":\"https://community.monday.com/c/developers/8\",\"text\":\"Link \",\"changed_at\":\"2022-04-12T14:02:46.916Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:38Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555179200", "name": "Developers community \ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:38Z", "updates": []}, "emitted_at": 1687273384067} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://style.monday.com/?path=/docs/welcome--page", "title": "Link", "type": "link", "value": "{\"url\":\"https://style.monday.com/?path=/docs/welcome--page\",\"text\":\"Link\",\"changed_at\":\"2022-04-12T14:03:00.031Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555179207", "name": "Design kit \ud83d\udc69\ud83c\udffb\u200d\ud83c\udfa8", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384069} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://apps.developer.monday.com/docs/monetization", "title": "Link", "type": "link", "value": "{\"url\":\"https://apps.developer.monday.com/docs/monetization\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T12:07:37.151Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Documentation\",\"color\":\"#175A63\",\"changed_at\":\"2022-06-07T12:07:24.046Z\"}", "description": null, "id": "status_10", "text": "Documentation", "title": "Type", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-06-07T12:07:24.046Z\"}"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555179327", "name": "monday apps monetization \ud83d\udcb0", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": []}, "emitted_at": 1687273384070} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "appsupport@monday.com - mailto:appsupport@monday.com/", "title": "Link", "type": "link", "value": "{\"url\":\"mailto:appsupport@monday.com/\",\"text\":\"appsupport@monday.com\",\"changed_at\":\"2022-04-13T20:54:57.089Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555179211", "name": "Technical support team \ud83e\udd70", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": []}, "emitted_at": 1687273384072} -{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://mondayclimatechallenge.devpost.com/", "title": "Link", "type": "link", "value": "{\"url\":\"https://mondayclimatechallenge.devpost.com/\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T13:40:18.751Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "29814928", "group": {"id": "new_group"}, "id": "3555179334", "name": "Make sure you saw to see challenge post (awesome prizes included)", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": []}, "emitted_at": 1687273384074} -{"stream": "updates", "data": {"assets": [{"created_at": "2023-06-15T16:19:31Z", "file_extension": ".jpg", "file_size": 116107, "id": "919077184", "name": "black_cat.jpg", "original_geometry": "473x600", "public_url": "https://files-monday-com.s3.amazonaws.com/14202902/resources/919077184/black_cat.jpg?response-content-disposition=attachment&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA4MPVJMFXGWGLJTLY%2F20230620%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230620T150408Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=9566e1bf805b4cbddada084f15418ea7bb7f07b62e7c27cd068ca465c170375d", "uploaded_by": {"id": 36694549}, "url": "https://airbyte-unit.monday.com/protected_static/14202902/resources/919077184/black_cat.jpg", "url_thumbnail": "https://airbyte-unit.monday.com/protected_static/14202902/resources/919077184/thumb_small-black_cat.jpg"}], "body": "", "created_at": "2023-06-15T16:19:36Z", "creator_id": "36694549", "id": "2223820299", "item_id": "4635211945", "replies": [], "text_body": "", "updated_at": "2023-06-15T16:19:36Z"}, "emitted_at": 1687273448305} -{"stream": "updates", "data": {"assets": [], "body": "



", "created_at": "2023-06-15T16:18:50Z", "creator_id": "36694549", "id": "2223818363", "item_id": "4635211945", "replies": [], "text_body": "", "updated_at": "2023-06-15T16:18:50Z"}, "emitted_at": 1687273448308} -{"stream": "updates", "data": {"assets": [], "body": "

\ufeffTest

", "created_at": "2022-11-21T14:41:21Z", "creator_id": "36694549", "id": "1825302913", "item_id": "3555437747", "replies": [{"id": "1825303266", "creator_id": "36694549", "created_at": "2022-11-21T14:41:29Z", "text_body": "Test test", "updated_at": "2022-11-21T14:41:29Z", "body": "

\ufeffTest test

"}, {"id": "2223806079", "creator_id": "36694549", "created_at": "2023-06-15T16:14:13Z", "text_body": "", "updated_at": "2023-06-15T16:14:13Z", "body": "



"}], "text_body": "Test", "updated_at": "2023-06-15T16:14:13Z"}, "emitted_at": 1687273448310} -{"stream": "updates", "data": {"assets": [], "body": "

\ufeffHey there \ud83d\udc4b

\ufeffThis is an update, we usually use this to...update \ud83d\ude04

\ufeffWe love to communicate with the context of a specific item.

\ufeff

\ufeffRight above this box, there are tabs for different item views which can also be used for apps.

", "created_at": "2022-06-08T12:53:39Z", "creator_id": "-7", "id": "1825206780", "item_id": "3555179351", "replies": [], "text_body": "Hey there \ud83d\udc4b\n\nThis is an update, we usually use this to...update \ud83d\ude04\n\nWe love to communicate with the context of a specific item.\n\n\n\nRight above this box, there are tabs for different item views which can also be used for apps.", "updated_at": "2022-11-21T14:04:40Z"}, "emitted_at": 1687273448312} -{"stream": "updates", "data": {"assets": [], "body": "

@Airbyte Testin \ufeffhi\ufeff

", "created_at": "2021-10-22T17:02:22Z", "creator_id": "-7", "id": "1825289531", "item_id": "3555408019", "replies": [], "text_body": "@Airbyte Testin hi", "updated_at": "2022-11-21T14:36:53Z"}, "emitted_at": 1687273448314} -{"stream": "users", "data": {"birthday": null, "country_code": "UA", "created_at": "2022-11-21T14:03:00Z", "join_date": null, "email": "integration-test@airbyte.io", "enabled": true, "id": 36694549, "is_admin": true, "is_guest": false, "is_pending": false, "is_view_only": false, "is_verified": true, "location": null, "mobile_phone": null, "name": "Airbyte Team", "phone": "", "photo_original": "https://files.monday.com/use1/photos/36694549/original/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "photo_small": "https://files.monday.com/use1/photos/36694549/small/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "photo_thumb": "https://files.monday.com/use1/photos/36694549/thumb/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "photo_thumb_small": "https://files.monday.com/use1/photos/36694549/thumb_small/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "photo_tiny": "https://files.monday.com/use1/photos/36694549/tiny/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "time_zone_identifier": "Europe/Kiev", "title": "Airbyte Developer Account", "url": "https://airbyte-unit.monday.com/users/36694549", "utc_hours_diff": 3}, "emitted_at": 1687273448747} -{"stream": "users", "data": {"birthday": null, "country_code": "UA", "created_at": "2022-11-21T14:33:18Z", "join_date": null, "email": "iryna.grankova@airbyte.io", "enabled": true, "id": 36695702, "is_admin": false, "is_guest": false, "is_pending": false, "is_view_only": false, "is_verified": true, "location": null, "mobile_phone": null, "name": "Iryna Grankova", "phone": null, "photo_original": "https://files.monday.com/use1/photos/36695702/original/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "photo_small": "https://files.monday.com/use1/photos/36695702/small/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "photo_thumb": "https://files.monday.com/use1/photos/36695702/thumb/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "photo_thumb_small": "https://files.monday.com/use1/photos/36695702/thumb_small/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "photo_tiny": "https://files.monday.com/use1/photos/36695702/tiny/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "time_zone_identifier": "Europe/Athens", "title": null, "url": "https://airbyte-unit.monday.com/users/36695702", "utc_hours_diff": 3}, "emitted_at": 1687273448751} -{"stream": "workspaces", "data": {"created_at": "2023-06-08T11:26:44Z", "description": null, "id": 2845647, "kind": "open", "name": "Test workspace", "state": "active", "account_product": {"id": 2248222, "kind": "core"}, "owners_subscribers": [{"id": 36694549}], "settings": {"icon": {"color": "#FDAB3D", "image": null}}, "team_owners_subscribers": [], "teams_subscribers": [], "users_subscribers": [{"id": 36694549}]}, "emitted_at": 1687273449181} -{"stream": "tags", "data": {"color": "#00c875", "id": 19038090, "name": "open"}, "emitted_at": 1687273449547} -{"stream": "tags", "data": {"color": "#fdab3d", "id": 19038091, "name": "closed"}, "emitted_at": 1687273449550} -{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 400}, {"archived": false, "description": null, "id": "person", "settings_str": "{}", "title": "Person", "type": "multiple-person", "width": null}, {"archived": false, "description": null, "id": "status", "settings_str": "{\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "date4", "settings_str": "{}", "title": "Date", "type": "date", "width": null}, {"archived": false, "description": null, "id": "tags", "settings_str": "{\"hide_footer\":false}", "title": "Tags", "type": "tag", "width": null}], "communication": null, "description": null, "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Group Title"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "group_title", "position": "98304", "title": "Group Title"}, {"archived": null, "color": "#808080", "deleted": null, "id": "new_group", "position": "163840.0", "title": "New Group unit board"}], "id": "4635211873", "name": "New Board", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2023-06-20T12:13:03Z", "updates": [{"id": "2223820299"}, {"id": "2223818363"}], "views": [], "workspace": {"id": 2845647, "name": "Test workspace", "kind": "open", "description": null}}, "emitted_at": 1687273446935} -{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 400}, {"archived": false, "description": null, "id": "files", "settings_str": "{\"hide_footer\":false}", "title": "Files", "type": "file", "width": null}], "communication": null, "description": null, "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Group Title"}], "id": "4634950289", "name": "test doc", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2023-06-14T12:30:14Z", "updates": [], "views": [{"id": "103920755", "name": "Table", "settings_str": "{}", "type": "FeatureBoardView", "view_specific_data_str": "{}"}], "workspace": {"id": 2845647, "name": "Test workspace", "kind": "open", "description": null}}, "emitted_at": 1687273446940} -{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 380}, {"archived": false, "description": null, "id": "manager1", "settings_str": "{}", "title": "Owner", "type": "multiple-person", "width": 80}, {"archived": false, "description": null, "id": "date4", "settings_str": "{}", "title": "Request date", "type": "date", "width": null}, {"archived": false, "description": null, "id": "status1", "settings_str": "{\"labels\":{\"0\":\"Evaluating\",\"1\":\"Done\",\"2\":\"Denied\",\"3\":\"Waiting for legal\",\"6\":\"Approved for POC\",\"11\":\"On hold\",\"14\":\"Waiting for vendor\",\"15\":\"Negotiation\",\"108\":\"Approved for use\"},\"labels_positions_v2\":{\"0\":0,\"1\":1,\"2\":7,\"3\":8,\"5\":9,\"6\":3,\"11\":6,\"14\":5,\"15\":4,\"108\":2},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"3\":{\"color\":\"#0086c0\",\"border\":\"#3DB0DF\",\"var_name\":\"blue-links\"},\"6\":{\"color\":\"#037f4c\",\"border\":\"#006B38\",\"var_name\":\"grass-green\"},\"11\":{\"color\":\"#BB3354\",\"border\":\"#A42D4A\",\"var_name\":\"dark-red\"},\"14\":{\"color\":\"#784BD1\",\"border\":\"#8F4DC4\",\"var_name\":\"dark-purple\"},\"15\":{\"color\":\"#9CD326\",\"border\":\"#89B921\",\"var_name\":\"lime-green\"},\"108\":{\"color\":\"#4eccc6\",\"border\":\"#4eccc6\",\"var_name\":\"australia\"}}}", "title": "Procurement status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "person", "settings_str": "{}", "title": "Manager", "type": "multiple-person", "width": 80}, {"archived": false, "description": null, "id": "status", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Manager approval", "type": "color", "width": null}, {"archived": false, "description": null, "id": "budget_owner", "settings_str": "{}", "title": "POC owner", "type": "multiple-person", "width": 80}, {"archived": false, "description": null, "id": "budget_owner_approval4", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "POC status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "manager", "settings_str": "{}", "title": "Budget owner", "type": "multiple-person", "width": 80}, {"archived": false, "description": null, "id": "status4", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Budget owner approval", "type": "color", "width": 185}, {"archived": false, "description": null, "id": "people", "settings_str": "{}", "title": "Procurement team", "type": "multiple-person", "width": null}, {"archived": false, "description": null, "id": "budget_owner_approval", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Procurement approval", "type": "color", "width": null}, {"archived": false, "description": null, "id": "procurement_team", "settings_str": "{}", "title": "Finance", "type": "multiple-person", "width": null}, {"archived": false, "description": null, "id": "procurement_approval", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Finance approval", "type": "color", "width": null}, {"archived": false, "description": null, "id": "finance", "settings_str": "{}", "title": "Legal", "type": "multiple-person", "width": null}, {"archived": false, "description": null, "id": "finance_approval", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Redlines\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Legal approval", "type": "color", "width": null}, {"archived": false, "description": null, "id": "file", "settings_str": "{}", "title": "File", "type": "file", "width": null}, {"archived": false, "description": null, "id": "legal", "settings_str": "{}", "title": "Security", "type": "multiple-person", "width": null}, {"archived": false, "description": null, "id": "legal_approval", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Security approval", "type": "color", "width": null}, {"archived": false, "description": null, "id": "date", "settings_str": "{\"hide_footer\":false}", "title": "Renewal date", "type": "date", "width": null}, {"archived": false, "description": null, "id": "last_updated", "settings_str": "{}", "title": "Last updated", "type": "pulse-updated", "width": 129}], "communication": null, "description": "Many IT departments need to handle the procurement process for new services. The essence of this board is to streamline this process by providing an intuitive structure that supports collaboration and efficiency.", "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Reviewing"}, {"archived": null, "color": "#FF642E", "deleted": null, "id": "new_group", "position": "98304.0", "title": "Corporate IT"}, {"archived": null, "color": "#037f4c", "deleted": null, "id": "new_group2816", "position": "114688.0", "title": "Finance"}], "id": "3555407826", "name": "Procurement process", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2022-11-21T14:36:50Z", "updates": [], "views": [{"id": "80969928", "name": "Chart", "settings_str": "{\"x_axis_columns\":{\"status1\":true},\"y_axis_columns\":{\"default-label-count\":true},\"z_axis_columns\":{},\"guideline_base\":{},\"graph_type\":\"column\",\"empty_values\":false,\"group_by\":\"month\"}", "type": "GraphBoardView", "view_specific_data_str": "{}"}], "workspace": null}, "emitted_at": 1687273446943} -{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 523}, {"archived": false, "description": null, "id": "text4", "settings_str": "{}", "title": "SN", "type": "text", "width": null}, {"archived": false, "description": null, "id": "status", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Out for repair\",\"1\":\"Working well\",\"2\":\"Needs replacement\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "date4", "settings_str": "{}", "title": "Date given to current owner", "type": "date", "width": 204}, {"archived": false, "description": null, "id": "text", "settings_str": "{}", "title": "Current owner", "type": "text", "width": null}, {"archived": false, "description": null, "id": "date_given_to_current_owner", "settings_str": "{}", "title": "Last checked", "type": "date", "width": 129}], "communication": null, "description": "Welcome to your inventory management board. This is the place to track and manage all of your IT equipment inventory.", "groups": [{"archived": null, "color": "#BB3354", "deleted": null, "id": "duplicate_of_tvs___projectors", "position": "65408", "title": "Out of service"}, {"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Laptops"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "group_title", "position": "98304", "title": "Monitors"}, {"archived": null, "color": "#037f4c", "deleted": null, "id": "new_group", "position": "163840.0", "title": "TVs & projectors"}], "id": "3555407785", "name": "Inventory management", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "duplicate_of_tvs___projectors"}, "updated_at": "2023-06-20T12:21:27Z", "updates": [], "views": [], "workspace": null}, "emitted_at": 1687273446945} -{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 347}, {"archived": false, "description": null, "id": "people", "settings_str": "{}", "title": "IT owner", "type": "multiple-person", "width": 98}, {"archived": false, "description": null, "id": "person", "settings_str": "{}", "title": "Responsible HR", "type": "multiple-person", "width": 112}, {"archived": false, "description": null, "id": "date4", "settings_str": "{}", "title": "Start date", "type": "date", "width": 114}, {"archived": false, "description": null, "id": "status", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"color_mapping\":{\"0\":16,\"1\":11,\"11\":1,\"16\":0},\"labels\":{\"0\":\"Product\",\"1\":\"Design\",\"2\":\"HR\",\"3\":\"R\\u0026D\",\"4\":\"Sales\",\"6\":\"Partners\",\"7\":\"Finance\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"3\":3,\"4\":4,\"5\":7,\"6\":5,\"7\":6},\"labels_colors\":{\"0\":{\"color\":\"#66CCFF\",\"border\":\"#5AB3E0\",\"var_name\":\"turquoise\"},\"1\":{\"color\":\"#BB3354\",\"border\":\"#A42D4A\",\"var_name\":\"dark-red\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"3\":{\"color\":\"#0086c0\",\"border\":\"#3DB0DF\",\"var_name\":\"blue-links\"},\"4\":{\"color\":\"#a25ddc\",\"border\":\"#9238AF\",\"var_name\":\"purple\"},\"6\":{\"color\":\"#037f4c\",\"border\":\"#006B38\",\"var_name\":\"grass-green\"},\"7\":{\"color\":\"#579bfc\",\"border\":\"#4387E8\",\"var_name\":\"bright-blue\"}}}", "title": "Team", "type": "color", "width": 103}, {"archived": false, "description": null, "id": "status8", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"color_mapping\":{\"1\":107,\"2\":19,\"3\":1,\"19\":2,\"107\":3},\"labels\":{\"1\":\"Denver\",\"2\":\"Florida\",\"14\":\"New York\"},\"labels_positions_v2\":{\"1\":2,\"2\":0,\"5\":3,\"14\":1},\"labels_colors\":{\"1\":{\"color\":\"#225091\",\"border\":\"#225091\",\"var_name\":\"navy\"},\"2\":{\"color\":\"#FF642E\",\"border\":\"#E05828\",\"var_name\":\"dark-orange\"},\"14\":{\"color\":\"#784BD1\",\"border\":\"#8F4DC4\",\"var_name\":\"dark-purple\"}}}", "title": "Site", "type": "color", "width": 80}, {"archived": false, "description": null, "id": "status1", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"1\":\"Mac\",\"14\":\"PC\"},\"labels_positions_v2\":{\"1\":0,\"5\":2,\"14\":1},\"labels_colors\":{\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"14\":{\"color\":\"#784BD1\",\"border\":\"#8F4DC4\",\"var_name\":\"dark-purple\"}}}", "title": "Computer type", "type": "color", "width": 107}, {"archived": false, "description": null, "id": "status2", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Computer setup", "type": "color", "width": 116}, {"archived": false, "description": null, "id": "computer_setup", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Google account", "type": "color", "width": 110}, {"archived": false, "description": null, "id": "google_account", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Zoom account", "type": "color", "width": 104}, {"archived": false, "description": null, "id": "zoom_account", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "365 account", "type": "color", "width": 102}, {"archived": false, "description": null, "id": "365_account3", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Setup desk monitor", "type": "color", "width": 132}, {"archived": false, "description": null, "id": "set_up_desk_monitor", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Setup entrance tag", "type": "color", "width": null}, {"archived": false, "description": null, "id": "email", "settings_str": "{}", "title": "Email", "type": "email", "width": null}], "communication": null, "description": "This is an IT onboarding process board. The essence of this board is to track the IT onboarding process of new employees.", "groups": [{"archived": null, "color": "#037f4c", "deleted": null, "id": "airbyte_group27398", "position": "16352.0", "title": "Airbyte group"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "airbyte_group", "position": "32704.0", "title": "Airbyte group"}, {"archived": null, "color": "#FF642E", "deleted": null, "id": "new_group", "position": "65408", "title": "More information about this template:"}, {"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "New Hires - June"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "group_title", "position": "98304", "title": "New Hires - May"}, {"archived": null, "color": "#037f4c", "deleted": null, "id": "duplicate_of_new_hires___6_25_", "position": "196608.0", "title": "New Hires - April"}], "id": "3555407698", "name": "IT Onboarding", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "airbyte_group27398"}, "updated_at": "2022-11-21T14:36:49Z", "updates": [{"id": "1825289531"}], "views": [{"id": "80969927", "name": "Timeline", "settings_str": "{\"group_by_id\":{\"people\":true},\"columns\":{\"all\":true},\"show_today_line\":true,\"show_weekends\":true,\"show_rollup\":true,\"enable_visual_dependencies\":true,\"display_legend\":true,\"color_by_id\":{\"people\":true},\"label_by_id\":{\"name\":true}}", "type": "TimelineGanttBoardView", "view_specific_data_str": "{}"}, {"id": "80969929", "name": "Hires by month", "settings_str": "{\"x_axis_columns\":{\"group\":true},\"y_axis_columns\":{\"default-label-count\":true},\"z_axis_columns\":{},\"guideline_base\":{},\"graph_type\":\"column\",\"empty_values\":false,\"group_by\":\"month\"}", "type": "GraphBoardView", "view_specific_data_str": "{}"}], "workspace": null}, "emitted_at": 1687273446947} -{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 414}, {"archived": false, "description": null, "id": "status", "settings_str": "{\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "link", "settings_str": "{}", "title": "Link", "type": "link", "width": null}, {"archived": false, "description": "", "id": "label", "settings_str": "{\"done_colors\":[1],\"labels\":{\"3\":\"Label 2\",\"105\":\"Label 1\",\"156\":\"Label 3\"},\"labels_positions_v2\":{\"3\":1,\"5\":3,\"105\":0,\"156\":2},\"labels_colors\":{\"3\":{\"color\":\"#0086c0\",\"border\":\"#3DB0DF\",\"var_name\":\"blue-links\"},\"105\":{\"color\":\"#9AADBD\",\"border\":\"#9AADBD\",\"var_name\":\"winter\"},\"156\":{\"color\":\"#9D99B9\",\"border\":\"#9D99B9\",\"var_name\":\"purple_gray\"}}}", "title": "Label", "type": "color", "width": null}, {"archived": false, "description": null, "id": "text", "settings_str": "{}", "title": "Text", "type": "text", "width": null}], "communication": null, "description": null, "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Subitems"}], "id": "3555179105", "name": "Subitems of Welcome to your monday dev account \ud83d\ude0d", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2022-11-21T14:42:06Z", "updates": [{"id": "1825302913"}], "views": [], "workspace": null}, "emitted_at": 1687273446949} -{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 596}, {"archived": false, "description": null, "id": "subitems", "settings_str": "{\"allowMultipleItems\":true,\"itemTypeName\":\"column.subtasks.title\",\"displayType\":\"BOARD_INLINE\",\"boardIds\":[3555179105]}", "title": "Subitems", "type": "subtasks", "width": null}, {"archived": false, "description": null, "id": "link", "settings_str": "{}", "title": "Link", "type": "link", "width": 168}, {"archived": false, "description": null, "id": "text", "settings_str": "{}", "title": "My notes", "type": "text", "width": 262}, {"archived": false, "description": null, "id": "status_1", "settings_str": "{\"labels\":{\"0\":\"Working on it\",\"1\":\"Done!\",\"2\":\"Stuck\",\"5\":\"Need to review\"},\"labels_positions_v2\":{\"0\":0,\"1\":1,\"2\":2,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"5\":{\"color\":\"#c4c4c4\",\"border\":\"#B0B0B0\",\"var_name\":\"grey\"}}}", "title": "Status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "status_10", "settings_str": "{\"done_colors\":[1],\"color_mapping\":{\"0\":16,\"1\":160,\"16\":0,\"160\":1},\"labels\":{\"0\":\"Article\",\"1\":\"Documentation\",\"2\":\"Video\",\"5\":\"Other\"},\"labels_colors\":{\"0\":{\"color\":\"#66CCFF\",\"border\":\"#5AB3E0\",\"var_name\":\"turquoise\"},\"1\":{\"color\":\"#175A63\",\"border\":\"#175A63\",\"var_name\":\"eden\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"5\":{\"color\":\"#c4c4c4\",\"border\":\"#B0B0B0\",\"var_name\":\"grey\"}}}", "title": "Type", "type": "color", "width": null}], "communication": null, "description": null, "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "81920", "title": "Get to know monday.com"}, {"archived": null, "color": "#FF158A", "deleted": null, "id": "new_group37570", "position": "90112", "title": "What can be developed on monday.com"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "group_title", "position": "98304", "title": "Build your monday app"}, {"archived": null, "color": "#fdab3d", "deleted": null, "id": "new_group45036", "position": "131072.0", "title": "Prepare for app submission"}, {"archived": null, "color": "#0086c0", "deleted": null, "id": "new_group", "position": "163840.0", "title": "Helpful resources"}], "id": "3555179067", "name": "Welcome to your monday dev account \ud83d\ude0d", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2022-11-21T14:04:38Z", "updates": [{"id": "1825206780"}], "views": [{"id": "80965788", "name": "Table", "settings_str": "{}", "type": "TableBoardView", "view_specific_data_str": "{}"}], "workspace": null}, "emitted_at": 1687273446951} +{"stream": "workspaces", "data": {"created_at": "2023-06-08T11:26:44Z", "description": null, "id": 2845647, "kind": "open", "name": "Test workspace", "state": "active", "account_product": {"id": 2248222, "kind": "core"}, "owners_subscribers": [{"id": 36694549}], "settings": {"icon": {"color": "#FDAB3D", "image": null}}, "team_owners_subscribers": [], "teams_subscribers": [], "users_subscribers": [{"id": 36694549}]}, "emitted_at": 1689087827960} +{"stream": "updates", "data": {"assets": [{"created_at": "2023-06-15T16:19:31Z", "file_extension": ".jpg", "file_size": 116107, "id": "919077184", "name": "black_cat.jpg", "original_geometry": "473x600", "public_url": "https://files-monday-com.s3.amazonaws.com/14202902/resources/919077184/black_cat.jpg?response-content-disposition=attachment&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA4MPVJMFXGWGLJTLY%2F20230711%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230711T150346Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=14911e73a6663cdd5ba9c199c3c7520807115e5df86ea02e382237506b49c133", "uploaded_by": {"id": 36694549}, "url": "https://airbyte-unit.monday.com/protected_static/14202902/resources/919077184/black_cat.jpg", "url_thumbnail": "https://airbyte-unit.monday.com/protected_static/14202902/resources/919077184/thumb_small-black_cat.jpg"}], "body": "", "created_at": "2023-06-15T16:19:36Z", "creator_id": "36694549", "id": "2223820299", "item_id": "4635211945", "replies": [], "text_body": "", "updated_at": "2023-06-15T16:19:36Z"}, "emitted_at": 1689087826728} +{"stream": "updates", "data": {"assets": [], "body": "



", "created_at": "2023-06-15T16:18:50Z", "creator_id": "36694549", "id": "2223818363", "item_id": "4635211945", "replies": [], "text_body": "", "updated_at": "2023-06-15T16:18:50Z"}, "emitted_at": 1689087826732} +{"stream": "updates", "data": {"assets": [], "body": "

\ufeffTest

", "created_at": "2022-11-21T14:41:21Z", "creator_id": "36694549", "id": "1825302913", "item_id": "3555437747", "replies": [{"id": "1825303266", "creator_id": "36694549", "created_at": "2022-11-21T14:41:29Z", "text_body": "Test test", "updated_at": "2022-11-21T14:41:29Z", "body": "

\ufeffTest test

"}, {"id": "2223806079", "creator_id": "36694549", "created_at": "2023-06-15T16:14:13Z", "text_body": "", "updated_at": "2023-06-15T16:14:13Z", "body": "



"}], "text_body": "Test", "updated_at": "2023-06-15T16:14:13Z"}, "emitted_at": 1689087826734} +{"stream": "updates", "data": {"assets": [], "body": "

\ufeffHey there \ud83d\udc4b

\ufeffThis is an update, we usually use this to...update \ud83d\ude04

\ufeffWe love to communicate with the context of a specific item.

\ufeff

\ufeffRight above this box, there are tabs for different item views which can also be used for apps.

", "created_at": "2022-06-08T12:53:39Z", "creator_id": "-7", "id": "1825206780", "item_id": "3555179351", "replies": [], "text_body": "Hey there \ud83d\udc4b\n\nThis is an update, we usually use this to...update \ud83d\ude04\n\nWe love to communicate with the context of a specific item.\n\n\n\nRight above this box, there are tabs for different item views which can also be used for apps.", "updated_at": "2022-11-21T14:04:40Z"}, "emitted_at": 1689087826735} +{"stream": "updates", "data": {"assets": [], "body": "

@Airbyte Testin \ufeffhi\ufeff

", "created_at": "2021-10-22T17:02:22Z", "creator_id": "-7", "id": "1825289531", "item_id": "3555408019", "replies": [], "text_body": "@Airbyte Testin hi", "updated_at": "2022-11-21T14:36:53Z"}, "emitted_at": 1689087826737} +{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 400}, {"archived": false, "description": null, "id": "person", "settings_str": "{}", "title": "Person", "type": "multiple-person", "width": null}, {"archived": false, "description": null, "id": "status", "settings_str": "{\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "date4", "settings_str": "{}", "title": "Date", "type": "date", "width": null}, {"archived": false, "description": null, "id": "tags", "settings_str": "{\"hide_footer\":false}", "title": "Tags", "type": "tag", "width": null}], "communication": null, "description": null, "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Group Title"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "group_title", "position": "98304", "title": "Group Title"}, {"archived": null, "color": "#808080", "deleted": null, "id": "new_group", "position": "163840.0", "title": "New Group unit board"}], "id": "4635211873", "name": "New Board", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2023-06-20T12:12:46Z", "updates": [{"id": "2223820299"}, {"id": "2223818363"}], "views": [], "workspace": {"id": 2845647, "name": "Test workspace", "kind": "open", "description": null}, "updated_at_int": 1687263166}, "emitted_at": 1689087821917} +{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 400}, {"archived": false, "description": null, "id": "files", "settings_str": "{\"hide_footer\":false}", "title": "Files", "type": "file", "width": null}], "communication": null, "description": null, "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Group Title"}], "id": "4634950289", "name": "test doc", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2023-06-13T13:28:31Z", "updates": [], "views": [{"id": "103920755", "name": "Table", "settings_str": "{}", "type": "FeatureBoardView", "view_specific_data_str": "{}"}], "workspace": {"id": 2845647, "name": "Test workspace", "kind": "open", "description": null}, "updated_at_int": 1686662911}, "emitted_at": 1689087822246} +{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 380}, {"archived": false, "description": null, "id": "manager1", "settings_str": "{}", "title": "Owner", "type": "multiple-person", "width": 80}, {"archived": false, "description": null, "id": "date4", "settings_str": "{}", "title": "Request date", "type": "date", "width": null}, {"archived": false, "description": null, "id": "status1", "settings_str": "{\"labels\":{\"0\":\"Evaluating\",\"1\":\"Done\",\"2\":\"Denied\",\"3\":\"Waiting for legal\",\"6\":\"Approved for POC\",\"11\":\"On hold\",\"14\":\"Waiting for vendor\",\"15\":\"Negotiation\",\"108\":\"Approved for use\"},\"labels_positions_v2\":{\"0\":0,\"1\":1,\"2\":7,\"3\":8,\"5\":9,\"6\":3,\"11\":6,\"14\":5,\"15\":4,\"108\":2},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"3\":{\"color\":\"#0086c0\",\"border\":\"#3DB0DF\",\"var_name\":\"blue-links\"},\"6\":{\"color\":\"#037f4c\",\"border\":\"#006B38\",\"var_name\":\"grass-green\"},\"11\":{\"color\":\"#BB3354\",\"border\":\"#A42D4A\",\"var_name\":\"dark-red\"},\"14\":{\"color\":\"#784BD1\",\"border\":\"#8F4DC4\",\"var_name\":\"dark-purple\"},\"15\":{\"color\":\"#9CD326\",\"border\":\"#89B921\",\"var_name\":\"lime-green\"},\"108\":{\"color\":\"#4eccc6\",\"border\":\"#4eccc6\",\"var_name\":\"australia\"}}}", "title": "Procurement status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "person", "settings_str": "{}", "title": "Manager", "type": "multiple-person", "width": 80}, {"archived": false, "description": null, "id": "status", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Manager approval", "type": "color", "width": null}, {"archived": false, "description": null, "id": "budget_owner", "settings_str": "{}", "title": "POC owner", "type": "multiple-person", "width": 80}, {"archived": false, "description": null, "id": "budget_owner_approval4", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "POC status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "manager", "settings_str": "{}", "title": "Budget owner", "type": "multiple-person", "width": 80}, {"archived": false, "description": null, "id": "status4", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Budget owner approval", "type": "color", "width": 185}, {"archived": false, "description": null, "id": "people", "settings_str": "{}", "title": "Procurement team", "type": "multiple-person", "width": null}, {"archived": false, "description": null, "id": "budget_owner_approval", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Procurement approval", "type": "color", "width": null}, {"archived": false, "description": null, "id": "procurement_team", "settings_str": "{}", "title": "Finance", "type": "multiple-person", "width": null}, {"archived": false, "description": null, "id": "procurement_approval", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Finance approval", "type": "color", "width": null}, {"archived": false, "description": null, "id": "finance", "settings_str": "{}", "title": "Legal", "type": "multiple-person", "width": null}, {"archived": false, "description": null, "id": "finance_approval", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Redlines\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Legal approval", "type": "color", "width": null}, {"archived": false, "description": null, "id": "file", "settings_str": "{}", "title": "File", "type": "file", "width": null}, {"archived": false, "description": null, "id": "legal", "settings_str": "{}", "title": "Security", "type": "multiple-person", "width": null}, {"archived": false, "description": null, "id": "legal_approval", "settings_str": "{\"labels\":{\"0\":\"On Hold\",\"1\":\"Approved\",\"2\":\"Declined\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Security approval", "type": "color", "width": null}, {"archived": false, "description": null, "id": "date", "settings_str": "{\"hide_footer\":false}", "title": "Renewal date", "type": "date", "width": null}, {"archived": false, "description": null, "id": "last_updated", "settings_str": "{}", "title": "Last updated", "type": "pulse-updated", "width": 129}], "communication": null, "description": "Many IT departments need to handle the procurement process for new services. The essence of this board is to streamline this process by providing an intuitive structure that supports collaboration and efficiency.", "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Reviewing"}, {"archived": null, "color": "#FF642E", "deleted": null, "id": "new_group", "position": "98304.0", "title": "Corporate IT"}, {"archived": null, "color": "#037f4c", "deleted": null, "id": "new_group2816", "position": "114688.0", "title": "Finance"}], "id": "3555407826", "name": "Procurement process", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2022-11-21T14:36:50Z", "updates": [], "views": [{"id": "80969928", "name": "Chart", "settings_str": "{\"x_axis_columns\":{\"status1\":true},\"y_axis_columns\":{\"default-label-count\":true},\"z_axis_columns\":{},\"guideline_base\":{},\"graph_type\":\"column\",\"empty_values\":false,\"group_by\":\"month\"}", "type": "GraphBoardView", "view_specific_data_str": "{}"}], "workspace": null, "updated_at_int": 1669041410}, "emitted_at": 1689087822838} +{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 523}, {"archived": false, "description": null, "id": "text4", "settings_str": "{}", "title": "SN", "type": "text", "width": null}, {"archived": false, "description": null, "id": "status", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Out for repair\",\"1\":\"Working well\",\"2\":\"Needs replacement\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "date4", "settings_str": "{}", "title": "Date given to current owner", "type": "date", "width": 204}, {"archived": false, "description": null, "id": "text", "settings_str": "{}", "title": "Current owner", "type": "text", "width": null}, {"archived": false, "description": null, "id": "date_given_to_current_owner", "settings_str": "{}", "title": "Last checked", "type": "date", "width": 129}], "communication": null, "description": "Welcome to your inventory management board. This is the place to track and manage all of your IT equipment inventory.", "groups": [{"archived": null, "color": "#BB3354", "deleted": null, "id": "duplicate_of_tvs___projectors", "position": "65408", "title": "Out of service"}, {"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Laptops"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "group_title", "position": "98304", "title": "Monitors"}, {"archived": null, "color": "#037f4c", "deleted": null, "id": "new_group", "position": "163840.0", "title": "TVs & projectors"}], "id": "3555407785", "name": "Inventory management", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "duplicate_of_tvs___projectors"}, "updated_at": "2022-11-21T14:36:49Z", "updates": [], "views": [], "workspace": null, "updated_at_int": 1669041409}, "emitted_at": 1689087823252} +{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 347}, {"archived": false, "description": null, "id": "people", "settings_str": "{}", "title": "IT owner", "type": "multiple-person", "width": 98}, {"archived": false, "description": null, "id": "person", "settings_str": "{}", "title": "Responsible HR", "type": "multiple-person", "width": 112}, {"archived": false, "description": null, "id": "date4", "settings_str": "{}", "title": "Start date", "type": "date", "width": 114}, {"archived": false, "description": null, "id": "status", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"color_mapping\":{\"0\":16,\"1\":11,\"11\":1,\"16\":0},\"labels\":{\"0\":\"Product\",\"1\":\"Design\",\"2\":\"HR\",\"3\":\"R\\u0026D\",\"4\":\"Sales\",\"6\":\"Partners\",\"7\":\"Finance\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"3\":3,\"4\":4,\"5\":7,\"6\":5,\"7\":6},\"labels_colors\":{\"0\":{\"color\":\"#66CCFF\",\"border\":\"#5AB3E0\",\"var_name\":\"turquoise\"},\"1\":{\"color\":\"#BB3354\",\"border\":\"#A42D4A\",\"var_name\":\"dark-red\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"3\":{\"color\":\"#0086c0\",\"border\":\"#3DB0DF\",\"var_name\":\"blue-links\"},\"4\":{\"color\":\"#a25ddc\",\"border\":\"#9238AF\",\"var_name\":\"purple\"},\"6\":{\"color\":\"#037f4c\",\"border\":\"#006B38\",\"var_name\":\"grass-green\"},\"7\":{\"color\":\"#579bfc\",\"border\":\"#4387E8\",\"var_name\":\"bright-blue\"}}}", "title": "Team", "type": "color", "width": 103}, {"archived": false, "description": null, "id": "status8", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"color_mapping\":{\"1\":107,\"2\":19,\"3\":1,\"19\":2,\"107\":3},\"labels\":{\"1\":\"Denver\",\"2\":\"Florida\",\"14\":\"New York\"},\"labels_positions_v2\":{\"1\":2,\"2\":0,\"5\":3,\"14\":1},\"labels_colors\":{\"1\":{\"color\":\"#225091\",\"border\":\"#225091\",\"var_name\":\"navy\"},\"2\":{\"color\":\"#FF642E\",\"border\":\"#E05828\",\"var_name\":\"dark-orange\"},\"14\":{\"color\":\"#784BD1\",\"border\":\"#8F4DC4\",\"var_name\":\"dark-purple\"}}}", "title": "Site", "type": "color", "width": 80}, {"archived": false, "description": null, "id": "status1", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"1\":\"Mac\",\"14\":\"PC\"},\"labels_positions_v2\":{\"1\":0,\"5\":2,\"14\":1},\"labels_colors\":{\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"14\":{\"color\":\"#784BD1\",\"border\":\"#8F4DC4\",\"var_name\":\"dark-purple\"}}}", "title": "Computer type", "type": "color", "width": 107}, {"archived": false, "description": null, "id": "status2", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Computer setup", "type": "color", "width": 116}, {"archived": false, "description": null, "id": "computer_setup", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Google account", "type": "color", "width": 110}, {"archived": false, "description": null, "id": "google_account", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Zoom account", "type": "color", "width": 104}, {"archived": false, "description": null, "id": "zoom_account", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "365 account", "type": "color", "width": 102}, {"archived": false, "description": null, "id": "365_account3", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Setup desk monitor", "type": "color", "width": 132}, {"archived": false, "description": null, "id": "set_up_desk_monitor", "settings_str": "{\"done_colors\":[1],\"hide_footer\":true,\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_positions_v2\":{\"0\":0,\"1\":2,\"2\":1,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Setup entrance tag", "type": "color", "width": null}, {"archived": false, "description": null, "id": "email", "settings_str": "{}", "title": "Email", "type": "email", "width": null}], "communication": null, "description": "This is an IT onboarding process board. The essence of this board is to track the IT onboarding process of new employees.", "groups": [{"archived": null, "color": "#037f4c", "deleted": null, "id": "airbyte_group27398", "position": "16352.0", "title": "Airbyte group"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "airbyte_group", "position": "32704.0", "title": "Airbyte group"}, {"archived": null, "color": "#FF642E", "deleted": null, "id": "new_group", "position": "65408", "title": "More information about this template:"}, {"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "New Hires - June"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "group_title", "position": "98304", "title": "New Hires - May"}, {"archived": null, "color": "#037f4c", "deleted": null, "id": "duplicate_of_new_hires___6_25_", "position": "196608.0", "title": "New Hires - April"}], "id": "3555407698", "name": "IT Onboarding", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "airbyte_group27398"}, "updated_at": "2022-11-21T14:36:49Z", "updates": [{"id": "1825289531"}], "views": [{"id": "80969927", "name": "Timeline", "settings_str": "{\"group_by_id\":{\"people\":true},\"columns\":{\"all\":true},\"show_today_line\":true,\"show_weekends\":true,\"show_rollup\":true,\"enable_visual_dependencies\":true,\"display_legend\":true,\"color_by_id\":{\"people\":true},\"label_by_id\":{\"name\":true}}", "type": "TimelineGanttBoardView", "view_specific_data_str": "{}"}, {"id": "80969929", "name": "Hires by month", "settings_str": "{\"x_axis_columns\":{\"group\":true},\"y_axis_columns\":{\"default-label-count\":true},\"z_axis_columns\":{},\"guideline_base\":{},\"graph_type\":\"column\",\"empty_values\":false,\"group_by\":\"month\"}", "type": "GraphBoardView", "view_specific_data_str": "{}"}], "workspace": null, "updated_at_int": 1669041409}, "emitted_at": 1689087823762} +{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 414}, {"archived": false, "description": null, "id": "status", "settings_str": "{\"labels\":{\"0\":\"Working on it\",\"1\":\"Done\",\"2\":\"Stuck\"},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"}}}", "title": "Status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "link", "settings_str": "{}", "title": "Link", "type": "link", "width": null}, {"archived": false, "description": "", "id": "label", "settings_str": "{\"done_colors\":[1],\"labels\":{\"3\":\"Label 2\",\"105\":\"Label 1\",\"156\":\"Label 3\"},\"labels_positions_v2\":{\"3\":1,\"5\":3,\"105\":0,\"156\":2},\"labels_colors\":{\"3\":{\"color\":\"#0086c0\",\"border\":\"#3DB0DF\",\"var_name\":\"blue-links\"},\"105\":{\"color\":\"#9AADBD\",\"border\":\"#9AADBD\",\"var_name\":\"winter\"},\"156\":{\"color\":\"#9D99B9\",\"border\":\"#9D99B9\",\"var_name\":\"purple_gray\"}}}", "title": "Label", "type": "color", "width": null}, {"archived": false, "description": null, "id": "text", "settings_str": "{}", "title": "Text", "type": "text", "width": null}], "communication": null, "description": null, "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "65536", "title": "Subitems"}], "id": "3555179105", "name": "Subitems of Welcome to your monday dev account \ud83d\ude0d", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2022-11-21T14:42:06Z", "updates": [{"id": "1825302913"}], "views": [], "workspace": null, "updated_at_int": 1669041726}, "emitted_at": 1689087824464} +{"stream": "boards", "data": {"board_kind": "public", "columns": [{"archived": false, "description": null, "id": "name", "settings_str": "{}", "title": "Name", "type": "name", "width": 596}, {"archived": false, "description": null, "id": "subitems", "settings_str": "{\"allowMultipleItems\":true,\"itemTypeName\":\"column.subtasks.title\",\"displayType\":\"BOARD_INLINE\",\"boardIds\":[3555179105]}", "title": "Subitems", "type": "subtasks", "width": null}, {"archived": false, "description": null, "id": "link", "settings_str": "{}", "title": "Link", "type": "link", "width": 168}, {"archived": false, "description": null, "id": "text", "settings_str": "{}", "title": "My notes", "type": "text", "width": 262}, {"archived": false, "description": null, "id": "status_1", "settings_str": "{\"labels\":{\"0\":\"Working on it\",\"1\":\"Done!\",\"2\":\"Stuck\",\"5\":\"Need to review\"},\"labels_positions_v2\":{\"0\":0,\"1\":1,\"2\":2,\"5\":3},\"labels_colors\":{\"0\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"1\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"5\":{\"color\":\"#c4c4c4\",\"border\":\"#B0B0B0\",\"var_name\":\"grey\"}}}", "title": "Status", "type": "color", "width": null}, {"archived": false, "description": null, "id": "status_10", "settings_str": "{\"done_colors\":[1],\"color_mapping\":{\"0\":16,\"1\":160,\"16\":0,\"160\":1},\"labels\":{\"0\":\"Article\",\"1\":\"Documentation\",\"2\":\"Video\",\"5\":\"Other\"},\"labels_colors\":{\"0\":{\"color\":\"#66CCFF\",\"border\":\"#5AB3E0\",\"var_name\":\"turquoise\"},\"1\":{\"color\":\"#175A63\",\"border\":\"#175A63\",\"var_name\":\"eden\"},\"2\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"5\":{\"color\":\"#c4c4c4\",\"border\":\"#B0B0B0\",\"var_name\":\"grey\"}}}", "title": "Type", "type": "color", "width": null}], "communication": null, "description": null, "groups": [{"archived": null, "color": "#579bfc", "deleted": null, "id": "topics", "position": "81920", "title": "Get to know monday.com"}, {"archived": null, "color": "#FF158A", "deleted": null, "id": "new_group37570", "position": "90112", "title": "What can be developed on monday.com"}, {"archived": null, "color": "#a25ddc", "deleted": null, "id": "group_title", "position": "98304", "title": "Build your monday app"}, {"archived": null, "color": "#fdab3d", "deleted": null, "id": "new_group45036", "position": "131072.0", "title": "Prepare for app submission"}, {"archived": null, "color": "#0086c0", "deleted": null, "id": "new_group", "position": "163840.0", "title": "Helpful resources"}], "id": "3555179067", "name": "Welcome to your monday dev account \ud83d\ude0d", "owners": [{"id": 36694549}], "creator": {"id": 36694549}, "permissions": "everyone", "pos": null, "state": "active", "subscribers": [{"id": 36694549}], "tags": [], "top_group": {"id": "topics"}, "updated_at": "2022-11-21T14:04:38Z", "updates": [{"id": "1825206780"}], "views": [{"id": "80965788", "name": "Table", "settings_str": "{}", "type": "TableBoardView", "view_specific_data_str": "{}"}], "workspace": null, "updated_at_int": 1669039478}, "emitted_at": 1689087824878} +{"stream": "tags", "data": {"color": "#00c875", "id": 19038090, "name": "open"}, "emitted_at": 1689087828299} +{"stream": "tags", "data": {"color": "#fdab3d", "id": 19038091, "name": "closed"}, "emitted_at": 1689087828302} +{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2019-03-01T17:24:57.321Z\"}", "description": null, "id": "status", "text": "Working on it", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2019-03-01T17:24:57.321Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2023-06-11", "title": "Date", "type": "date", "value": "{\"date\":\"2023-06-11\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:25.871Z\"}"}, {"additional_info": null, "description": null, "id": "tags", "text": "open", "title": "Tags", "type": "tag", "value": "{\"tag_ids\":[19038090]}"}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "4635211945", "name": "Item 1", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-15T16:19:37Z", "updates": [{"id": "2223820299"}, {"id": "2223818363"}], "updated_at_int": 1686845977}, "emitted_at": 1689087812103} +{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2019-03-01T17:28:23.178Z\"}", "description": null, "id": "status", "text": "Done", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-03-01T17:28:23.178Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2023-06-11", "title": "Date", "type": "date", "value": "{\"date\":\"2023-06-11\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:25.871Z\"}"}, {"additional_info": null, "description": null, "id": "tags", "text": "closed", "title": "Tags", "type": "tag", "value": "{\"tag_ids\":[19038091]}"}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "4635211964", "name": "Item 2", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-13T13:59:36Z", "updates": [], "updated_at_int": 1686664776}, "emitted_at": 1689087812106} +{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":null,\"color\":\"#c4c4c4\",\"changed_at\":\"2019-03-01T17:25:02.248Z\"}", "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": "{\"index\":5,\"post_id\":null,\"changed_at\":\"2019-03-01T17:25:02.248Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2023-06-13", "title": "Date", "type": "date", "value": "{\"date\":\"2023-06-13\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:26.291Z\"}"}, {"additional_info": null, "description": null, "id": "tags", "text": "", "title": "Tags", "type": "tag", "value": null}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "4635211977", "name": "Item 3", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-13T13:58:26Z", "updates": [], "updated_at_int": 1686664706}, "emitted_at": 1689087812109} +{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2023-06-13", "title": "Date", "type": "date", "value": "{\"date\":\"2023-06-13\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:25.469Z\"}"}, {"additional_info": null, "description": null, "id": "tags", "text": "", "title": "Tags", "type": "tag", "value": null}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "4635212008", "name": "Item 4", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-13T13:58:25Z", "updates": [], "updated_at_int": 1686664705}, "emitted_at": 1689087812111} +{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2023-06-13", "title": "Date", "type": "date", "value": "{\"date\":\"2023-06-13\",\"icon\":null,\"changed_at\":\"2023-06-13T13:58:25.469Z\"}"}, {"additional_info": null, "description": null, "id": "tags", "text": "", "title": "Tags", "type": "tag", "value": null}], "created_at": "2023-06-13T13:58:24Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "4635211995", "name": "Item 5", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-13T13:58:25Z", "updates": [], "updated_at_int": 1686664705}, "emitted_at": 1689087812114} +{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2023-06-20T12:12:53.948Z\"}", "description": null, "id": "status", "text": "Done", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2023-06-20T12:12:53.948Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "tags", "text": "", "title": "Tags", "type": "tag", "value": null}], "created_at": "2023-06-20T12:12:51Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "4672922929", "name": "Item 6", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-20T12:12:54Z", "updates": [], "updated_at_int": 1687263174}, "emitted_at": 1689087812116} +{"stream": "items", "data": {"assets": [], "board": {"id": "4635211873"}, "column_values": [{"additional_info": null, "description": null, "id": "person", "text": "", "title": "Person", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "tags", "text": "", "title": "Tags", "type": "tag", "value": null}], "created_at": "2023-06-20T12:13:03Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "4672924165", "name": "Item 7", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-20T12:13:03Z", "updates": [], "updated_at_int": 1687263183}, "emitted_at": 1689087812119} +{"stream": "items", "data": {"assets": [{"created_at": "2023-06-14T12:30:13Z", "file_extension": ".jpg", "file_size": 116107, "id": "916811099", "name": "black_cat.jpg", "original_geometry": "473x600", "public_url": "https://files-monday-com.s3.amazonaws.com/14202902/resources/916811099/black_cat.jpg?response-content-disposition=attachment&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIA4MPVJMFXGWGLJTLY%2F20230711%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230711T150332Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=host&X-Amz-Signature=efc3e9b76bdb87129eaf5b01cefda28e76425674b150991ae356a0213c1e4088", "uploaded_by": {"id": 36694549}, "url": "https://airbyte-unit.monday.com/protected_static/14202902/resources/916811099/black_cat.jpg", "url_thumbnail": "https://airbyte-unit.monday.com/protected_static/14202902/resources/916811099/thumb_small-black_cat.jpg"}], "board": {"id": "4634950289"}, "column_values": [{"additional_info": null, "description": null, "id": "files", "text": "https://airbyte-unit.monday.com/protected_static/14202902/resources/916811099/black_cat.jpg", "title": "Files", "type": "file", "value": "{\"files\":[{\"name\":\"black_cat.jpg\",\"assetId\":916811099,\"isImage\":\"true\",\"fileType\":\"ASSET\",\"createdAt\":1686745812452,\"createdBy\":\"36694549\"}]}"}], "created_at": "2023-06-13T13:28:32Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "4634950329", "name": "Doc Comments", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-14T12:30:14Z", "updates": [], "updated_at_int": 1686745814}, "emitted_at": 1689087812607} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2019-04-11", "title": "Request date", "type": "date", "value": "{\"date\":\"2019-04-11\",\"icon\":null,\"changed_at\":\"2019-04-10 08:06:40 UTC\"}"}, {"additional_info": "{\"label\":\"Evaluating\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-07-22T06:28:36.561Z\"}", "description": null, "id": "status1", "text": "Evaluating", "title": "Procurement status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:36.561Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:09:58.545Z\"}", "description": null, "id": "status", "text": "Approved", "title": "Manager approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:09:58.545Z\"}"}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:11:20.855Z\"}", "description": null, "id": "status4", "text": "Approved", "title": "Budget owner approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:11:20.855Z\"}"}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:14:00.506Z\"}", "description": null, "id": "budget_owner_approval", "text": "Approved", "title": "Procurement approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:14:00.506Z\"}"}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Declined\",\"color\":\"#e2445c\",\"changed_at\":\"2019-05-15T14:34:59.145Z\"}", "description": null, "id": "procurement_approval", "text": "Declined", "title": "Finance approval", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2019-05-15T14:34:59.145Z\"}"}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"On Hold\",\"color\":\"#fdab3d\",\"changed_at\":\"2019-04-10T08:17:41.900Z\"}", "description": null, "id": "finance_approval", "text": "On Hold", "title": "Legal approval", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2019-04-10T08:17:41.900Z\"}"}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": "{\"files\":null}"}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Declined\",\"color\":\"#e2445c\",\"changed_at\":\"2019-04-30T15:43:35.438Z\"}", "description": null, "id": "legal_approval", "text": "Declined", "title": "Security approval", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2019-04-30T15:43:35.438Z\"}"}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:51 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:51Z", "creator_id": "25479561", "group": {"id": "topics"}, "id": "3555407934", "name": "Zendesk", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:51Z", "updates": [], "updated_at_int": 1669041411}, "emitted_at": 1689087814282} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2019-04-11", "title": "Request date", "type": "date", "value": "{\"date\":\"2019-04-11\",\"changed_at\":\"2019-04-02T07:03:23.375Z\"}"}, {"additional_info": "{\"label\":\"On hold\",\"color\":\"#BB3354\",\"changed_at\":\"2020-06-25T11:41:22.421Z\"}", "description": null, "id": "status1", "text": "On hold", "title": "Procurement status", "type": "color", "value": "{\"index\":11,\"post_id\":null,\"changed_at\":\"2020-06-25T11:41:22.421Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-03-01T17:28:23.178Z\"}", "description": null, "id": "status", "text": "Approved", "title": "Manager approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-03-01T17:28:23.178Z\"}"}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Declined\",\"color\":\"#e2445c\",\"changed_at\":\"2019-04-10T08:11:26.186Z\"}", "description": null, "id": "status4", "text": "Declined", "title": "Budget owner approval", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2019-04-10T08:11:26.186Z\"}"}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": "{\"files\":null}"}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"On Hold\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-25T06:36:38.993Z\"}", "description": null, "id": "legal_approval", "text": "On Hold", "title": "Security approval", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-25T06:36:38.993Z\"}"}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:52 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "25479561", "group": {"id": "topics"}, "id": "3555407944", "name": "Salesforce", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [], "updated_at_int": 1669041412}, "emitted_at": 1689087814285} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2019-04-17", "title": "Request date", "type": "date", "value": "{\"date\":\"2019-04-17\",\"changed_at\":\"2019-04-02T07:03:25.251Z\"}"}, {"additional_info": "{\"label\":\"Waiting for vendor\",\"color\":\"#784BD1\",\"changed_at\":\"2020-07-22T06:28:39.711Z\"}", "description": null, "id": "status1", "text": "Waiting for vendor", "title": "Procurement status", "type": "color", "value": "{\"index\":14,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:39.711Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:10:00.038Z\"}", "description": null, "id": "status", "text": "Approved", "title": "Manager approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:10:00.038Z\"}"}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:11:23.942Z\"}", "description": null, "id": "status4", "text": "Approved", "title": "Budget owner approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:11:23.942Z\"}"}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:14:02.186Z\"}", "description": null, "id": "budget_owner_approval", "text": "Approved", "title": "Procurement approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:14:02.186Z\"}"}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:16:19.222Z\"}", "description": null, "id": "procurement_approval", "text": "Approved", "title": "Finance approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:16:19.222Z\"}"}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:17:46.022Z\"}", "description": null, "id": "finance_approval", "text": "Approved", "title": "Legal approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:17:46.022Z\"}"}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": "{\"files\":null}"}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-25T06:36:40.961Z\"}", "description": null, "id": "legal_approval", "text": "Approved", "title": "Security approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-25T06:36:40.961Z\"}"}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:52 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "25479561", "group": {"id": "topics"}, "id": "3555407952", "name": "YouCanBookMe", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [], "updated_at_int": 1669041412}, "emitted_at": 1689087814288} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-25T11:41:48.118Z\"}", "description": null, "id": "status1", "text": "Done", "title": "Procurement status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-25T11:41:48.118Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408067", "name": "Box", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": [], "updated_at_int": 1669041413}, "emitted_at": 1689087814291} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Approved for use\",\"color\":\"#4eccc6\",\"changed_at\":\"2020-07-22T06:27:41.551Z\"}", "description": null, "id": "status1", "text": "Approved for use", "title": "Procurement status", "type": "color", "value": "{\"index\":108,\"post_id\":null,\"changed_at\":\"2020-07-22T06:27:41.551Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408077", "name": "Slack", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": [], "updated_at_int": 1669041413}, "emitted_at": 1689087814293} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Approved for use\",\"color\":\"#4eccc6\",\"changed_at\":\"2020-07-22T06:26:53.835Z\"}", "description": null, "id": "status1", "text": "Approved for use", "title": "Procurement status", "type": "color", "value": "{\"index\":108,\"post_id\":null,\"changed_at\":\"2020-07-22T06:26:53.835Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408088", "name": "HelpJuice", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": [], "updated_at_int": 1669041413}, "emitted_at": 1689087814296} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Approved for use\",\"color\":\"#4eccc6\",\"changed_at\":\"2020-07-22T06:28:31.709Z\"}", "description": null, "id": "status1", "text": "Approved for use", "title": "Procurement status", "type": "color", "value": "{\"index\":108,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:31.709Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408094", "name": "LucidChart", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": [], "updated_at_int": 1669041413}, "emitted_at": 1689087814299} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2019-04-11", "title": "Request date", "type": "date", "value": "{\"date\":\"2019-04-11\",\"changed_at\":\"2019-04-02T07:03:23.375Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-07-22T06:28:25.645Z\"}", "description": null, "id": "status1", "text": "Done", "title": "Procurement status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:25.645Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-03-01T17:28:23.178Z\"}", "description": null, "id": "status", "text": "Approved", "title": "Manager approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-03-01T17:28:23.178Z\"}"}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:06.894Z\"}", "description": null, "id": "status4", "text": "Approved", "title": "Budget owner approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:06.894Z\"}"}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:08.700Z\"}", "description": null, "id": "budget_owner_approval", "text": "Approved", "title": "Procurement approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:08.700Z\"}"}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:10.209Z\"}", "description": null, "id": "procurement_approval", "text": "Approved", "title": "Finance approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:10.209Z\"}"}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:11.909Z\"}", "description": null, "id": "finance_approval", "text": "Approved", "title": "Legal approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:11.909Z\"}"}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": "{\"files\":null}"}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:15.385Z\"}", "description": null, "id": "legal_approval", "text": "Approved", "title": "Security approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:15.385Z\"}"}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "25479561", "group": {"id": "new_group"}, "id": "3555408048", "name": "Aircall", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": [], "updated_at_int": 1669041413}, "emitted_at": 1689087814302} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2019-04-17", "title": "Request date", "type": "date", "value": "{\"date\":\"2019-04-17\",\"changed_at\":\"2019-04-02T07:03:25.251Z\"}"}, {"additional_info": "{\"label\":\"Approved for use\",\"color\":\"#4eccc6\",\"changed_at\":\"2020-07-22T06:28:29.177Z\"}", "description": null, "id": "status1", "text": "Approved for use", "title": "Procurement status", "type": "color", "value": "{\"index\":108,\"post_id\":null,\"changed_at\":\"2020-07-22T06:28:29.177Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:10:00.038Z\"}", "description": null, "id": "status", "text": "Approved", "title": "Manager approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:10:00.038Z\"}"}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:11:23.942Z\"}", "description": null, "id": "status4", "text": "Approved", "title": "Budget owner approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:11:23.942Z\"}"}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:14:02.186Z\"}", "description": null, "id": "budget_owner_approval", "text": "Approved", "title": "Procurement approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:14:02.186Z\"}"}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:16:19.222Z\"}", "description": null, "id": "procurement_approval", "text": "Approved", "title": "Finance approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:16:19.222Z\"}"}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-04-10T08:17:46.022Z\"}", "description": null, "id": "finance_approval", "text": "Approved", "title": "Legal approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-04-10T08:17:46.022Z\"}"}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": "{\"files\":null}"}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": "{\"label\":\"Approved\",\"color\":\"#00c875\",\"changed_at\":\"2019-05-15T12:27:17.250Z\"}", "description": null, "id": "legal_approval", "text": "Approved", "title": "Security approval", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2019-05-15T12:27:17.250Z\"}"}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "25479561", "group": {"id": "new_group"}, "id": "3555408057", "name": "Zoom", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": [], "updated_at_int": 1669041413}, "emitted_at": 1689087814305} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Waiting for legal\",\"color\":\"#0086c0\",\"changed_at\":\"2020-07-22T06:27:17.793Z\"}", "description": null, "id": "status1", "text": "Waiting for legal", "title": "Procurement status", "type": "color", "value": "{\"index\":3,\"post_id\":null,\"changed_at\":\"2020-07-22T06:27:17.793Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group2816"}, "id": "3555408102", "name": "Gaviti", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": [], "updated_at_int": 1669041413}, "emitted_at": 1689087814308} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407826"}, "column_values": [{"additional_info": null, "description": null, "id": "manager1", "text": "", "title": "Owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Request date", "type": "date", "value": null}, {"additional_info": "{\"label\":\"Negotiation\",\"color\":\"#9CD326\",\"changed_at\":\"2020-07-22T06:27:22.578Z\"}", "description": null, "id": "status1", "text": "Negotiation", "title": "Procurement status", "type": "color", "value": "{\"index\":15,\"post_id\":null,\"changed_at\":\"2020-07-22T06:27:22.578Z\"}"}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Manager", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Manager approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner", "text": "", "title": "POC owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval4", "text": null, "title": "POC status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "manager", "text": "", "title": "Budget owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "status4", "text": null, "title": "Budget owner approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "people", "text": "", "title": "Procurement team", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "budget_owner_approval", "text": null, "title": "Procurement approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "procurement_team", "text": "", "title": "Finance", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "procurement_approval", "text": null, "title": "Finance approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "finance", "text": "", "title": "Legal", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "finance_approval", "text": null, "title": "Legal approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "file", "text": "", "title": "File", "type": "file", "value": null}, {"additional_info": null, "description": null, "id": "legal", "text": "", "title": "Security", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "legal_approval", "text": null, "title": "Security approval", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date", "text": "", "title": "Renewal date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "last_updated", "text": "2022-11-21 14:36:53 UTC", "title": "Last updated", "type": "pulse-updated", "value": null}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group2816"}, "id": "3555408118", "name": "Priority", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": [], "updated_at_int": 1669041413}, "emitted_at": 1689087814311} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN56456", "title": "SN", "type": "text", "value": "\"SN56456\""}, {"additional_info": "{\"label\":\"Needs replacement\",\"color\":\"#e2445c\",\"changed_at\":\"2020-06-22T08:37:41.248Z\"}", "description": null, "id": "status", "text": "Needs replacement", "title": "Status", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2020-06-22T08:37:41.248Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-05-14", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-05-14\",\"changed_at\":\"2020-06-22T11:25:44.457Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Zakariah Macleod", "title": "Current owner", "type": "text", "value": "\"Zakariah Macleod\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-10", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-10\",\"changed_at\":\"2020-06-24T10:59:53.938Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_tvs___projectors"}, "id": "3555407991", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [], "updated_at_int": 1669041412}, "emitted_at": 1689087816087} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN 94-34-AS-GT-66", "title": "SN", "type": "text", "value": "\"SN 94-34-AS-GT-66\""}, {"additional_info": "{\"label\":\"Out for repair\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-22T08:37:42.971Z\"}", "description": null, "id": "status", "text": "Out for repair", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-22T08:37:42.971Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-10", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-10\",\"changed_at\":\"2020-06-22T11:25:46.599Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Corbin Blackburn", "title": "Current owner", "type": "text", "value": "\"Corbin Blackburn\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-11", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-11\",\"changed_at\":\"2020-06-24T10:59:55.752Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_tvs___projectors"}, "id": "3555407997", "name": "Sonos One", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [], "updated_at_int": 1669041412}, "emitted_at": 1689087816089} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "P2219G", "title": "SN", "type": "text", "value": "\"P2219G\""}, {"additional_info": "{\"label\":\"Out for repair\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-22T08:37:44.792Z\"}", "description": null, "id": "status", "text": "Out for repair", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-22T08:37:44.792Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-02", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-02\",\"changed_at\":\"2020-06-22T11:25:48.402Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Jorge Mcgowan", "title": "Current owner", "type": "text", "value": "\"Jorge Mcgowan\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-28", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-28\",\"changed_at\":\"2020-06-24T10:59:57.460Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_tvs___projectors"}, "id": "3555408009", "name": "Dell", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [], "updated_at_int": 1669041412}, "emitted_at": 1689087816092} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE57L21Y", "title": "SN", "type": "text", "value": "\"SN FVFYVE57L21Y\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-03", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-22T11:25:52.834Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Rylee Pham", "title": "Current owner", "type": "text", "value": "\"Rylee Pham\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-03-11", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-03-11\",\"changed_at\":\"2020-06-24T11:00:01.660Z\"}"}], "created_at": "2022-11-21T14:36:51Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407931", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:51Z", "updates": [], "updated_at_int": 1669041411}, "emitted_at": 1689087816095} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE57L22Y", "title": "SN", "type": "text", "value": "\"SN FVFYVE57L22Y\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-03", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-22T11:25:56.327Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Kaydon Gamble", "title": "Current owner", "type": "text", "value": "\"Kaydon Gamble\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-02-19", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-02-19\",\"changed_at\":\"2020-06-24T11:00:06.248Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407941", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [], "updated_at_int": 1669041412}, "emitted_at": 1689087816097} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE57L23W", "title": "SN", "type": "text", "value": "\"SN FVFYVE57L23W\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-04", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-04\",\"changed_at\":\"2020-06-22T11:25:58.156Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Eli Reyes", "title": "Current owner", "type": "text", "value": "\"Eli Reyes\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-03-26", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-03-26\",\"changed_at\":\"2020-06-24T11:00:13.482Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407947", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [], "updated_at_int": 1669041412}, "emitted_at": 1689087816100} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE57L41V", "title": "SN", "type": "text", "value": "\"SN FVFYVE57L41V\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-11", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-11\",\"changed_at\":\"2020-06-22T11:26:00.305Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Finley Hilton", "title": "Current owner", "type": "text", "value": "\"Finley Hilton\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-03-12", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-03-12\",\"changed_at\":\"2020-06-24T11:00:09.820Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407961", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [], "updated_at_int": 1669041412}, "emitted_at": 1689087816103} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE67L21Y", "title": "SN", "type": "text", "value": "\"SN FVFYVE67L21Y\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-17", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-17\",\"changed_at\":\"2020-06-22T11:26:02.141Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Fabien Morton", "title": "Current owner", "type": "text", "value": "\"Fabien Morton\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-04-21", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-04-21\",\"changed_at\":\"2020-06-24T11:00:17.305Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407968", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [], "updated_at_int": 1669041412}, "emitted_at": 1689087816105} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN FVFYVE57L28Y", "title": "SN", "type": "text", "value": "\"SN FVFYVE57L28Y\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-18", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-18\",\"changed_at\":\"2020-06-22T11:26:04.062Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Amelia-Mae Flower", "title": "Current owner", "type": "text", "value": "\"Amelia-Mae Flower\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-04", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-04\",\"changed_at\":\"2020-06-24T11:00:21.416Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407977", "name": "Macbook Pro", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [], "updated_at_int": 1669041412}, "emitted_at": 1689087816108} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "", "title": "SN", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date given to current owner", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Current owner", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "", "title": "Last checked", "type": "date", "value": null}], "created_at": "2023-06-20T12:21:27Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "4672979272", "name": "Macbook", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-20T12:21:27Z", "updates": [], "updated_at_int": 1687263687}, "emitted_at": 1689087816110} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "3sBeKstD", "title": "SN", "type": "text", "value": "\"3sBeKstD\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-03", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-22T11:26:06.624Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Masuma Carver", "title": "Current owner", "type": "text", "value": "\"Masuma Carver\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-04-07", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-04-07\",\"changed_at\":\"2020-06-24T11:00:35.389Z\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408016", "name": "Dell - U2417H", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [], "updated_at_int": 1669041412}, "emitted_at": 1689087816113} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "eqK2M67W", "title": "SN", "type": "text", "value": "\"eqK2M67W\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-10", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-10\",\"changed_at\":\"2020-06-22T11:26:08.798Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Tadhg Hensley", "title": "Current owner", "type": "text", "value": "\"Tadhg Hensley\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-04", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-04\",\"changed_at\":\"2020-06-24T11:00:23.245Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408058", "name": "Dell - U2418H", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": [], "updated_at_int": 1669041413}, "emitted_at": 1689087816116} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "39QTALuj", "title": "SN", "type": "text", "value": "\"39QTALuj\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-09", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-09\",\"changed_at\":\"2020-06-22T11:26:10.906Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Aanya Booth", "title": "Current owner", "type": "text", "value": "\"Aanya Booth\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-05", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-05\",\"changed_at\":\"2020-06-24T11:00:25.468Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408070", "name": "Dell - U2416H", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": [], "updated_at_int": 1669041413}, "emitted_at": 1689087816118} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "LTgqT9cY", "title": "SN", "type": "text", "value": "\"LTgqT9cY\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-03", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-22T11:26:12.701Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Kiana Burnett", "title": "Current owner", "type": "text", "value": "\"Kiana Burnett\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-20", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-20\",\"changed_at\":\"2020-06-24T11:00:27.706Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408083", "name": "Dell - U2419HX", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": [], "updated_at_int": 1669041413}, "emitted_at": 1689087816121} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "FjE7nsrs", "title": "SN", "type": "text", "value": "\"FjE7nsrs\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-10", "title": "Date given to current owner", "type": "date", "value": "{\"date\":\"2020-06-10\",\"changed_at\":\"2020-06-22T11:26:17.156Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Roxie Forbes", "title": "Current owner", "type": "text", "value": "\"Roxie Forbes\""}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-05-06", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-05-06\",\"changed_at\":\"2020-06-24T11:00:31.519Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555408091", "name": "Dell - P2219H", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": [], "updated_at_int": 1669041413}, "emitted_at": 1689087816123} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN32456", "title": "SN", "type": "text", "value": "\"SN32456\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date given to current owner", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Current owner", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-05-05", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-05-05\",\"changed_at\":\"2020-06-24T11:00:39.214Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408021", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": [], "updated_at_int": 1669041413}, "emitted_at": 1689087816126} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN32457", "title": "SN", "type": "text", "value": "\"SN32457\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date given to current owner", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Current owner", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-05-07", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-05-07\",\"changed_at\":\"2020-06-24T11:00:42.752Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408033", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": [], "updated_at_int": 1669041413}, "emitted_at": 1689087816129} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN32458", "title": "SN", "type": "text", "value": "\"SN32458\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date given to current owner", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Current owner", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-05-21", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-05-21\",\"changed_at\":\"2020-06-24T11:00:46.170Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408041", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": [], "updated_at_int": 1669041413}, "emitted_at": 1689087816131} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407785"}, "column_values": [{"additional_info": null, "description": null, "id": "text4", "text": "SN32458", "title": "SN", "type": "text", "value": "\"SN32458\""}, {"additional_info": "{\"label\":\"Working well\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T08:41:28.806Z\"}", "description": null, "id": "status", "text": "Working well", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T08:41:28.806Z\"}"}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Date given to current owner", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Current owner", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "date_given_to_current_owner", "text": "2020-06-03", "title": "Last checked", "type": "date", "value": "{\"date\":\"2020-06-03\",\"changed_at\":\"2020-06-24T11:00:48.979Z\"}"}], "created_at": "2022-11-21T14:36:53Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555408052", "name": "Samsung", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:53Z", "updates": [], "updated_at_int": 1669041413}, "emitted_at": 1689087816134} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Start date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Team", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status8", "text": null, "title": "Site", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status1", "text": null, "title": "Computer type", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status2", "text": null, "title": "Computer setup", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "computer_setup", "text": null, "title": "Google account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "google_account", "text": null, "title": "Zoom account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "zoom_account", "text": null, "title": "365 account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "365_account3", "text": null, "title": "Setup desk monitor", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "set_up_desk_monitor", "text": null, "title": "Setup entrance tag", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "email", "text": "", "title": "Email", "type": "email", "value": null}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "25479561", "group": {"id": "airbyte_group"}, "id": "3555408019", "name": "new item", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:56Z", "updates": [{"id": "1825289531"}], "updated_at_int": 1669041416}, "emitted_at": 1689087817315} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "", "title": "Start date", "type": "date", "value": null}, {"additional_info": null, "description": null, "id": "status", "text": null, "title": "Team", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status8", "text": null, "title": "Site", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status1", "text": null, "title": "Computer type", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status2", "text": null, "title": "Computer setup", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "computer_setup", "text": null, "title": "Google account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "google_account", "text": null, "title": "Zoom account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "zoom_account", "text": null, "title": "365 account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "365_account3", "text": null, "title": "Setup desk monitor", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "set_up_desk_monitor", "text": null, "title": "Setup entrance tag", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "email", "text": "", "title": "Email", "type": "email", "value": null}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555407986", "name": "Hi there! \ud83d\udc4b Click here for more information \u27a1\ufe0f", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [{"id": "1825289518"}], "updated_at_int": 1669041412}, "emitted_at": 1689087817318} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-23", "title": "Start date", "type": "date", "value": "{\"date\":\"2020-06-23\"}"}, {"additional_info": "{\"label\":\"Finance\",\"color\":\"#579bfc\",\"changed_at\":null}", "description": null, "id": "status", "text": "Finance", "title": "Team", "type": "color", "value": "{\"index\":7,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Denver\",\"color\":\"#225091\",\"changed_at\":null}", "description": null, "id": "status8", "text": "Denver", "title": "Site", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"PC\",\"color\":\"#784BD1\",\"changed_at\":null}", "description": null, "id": "status1", "text": "PC", "title": "Computer type", "type": "color", "value": "{\"index\":14,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-21T13:46:33.895Z\"}", "description": null, "id": "status2", "text": "Working on it", "title": "Computer setup", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-21T13:46:33.895Z\"}"}, {"additional_info": null, "description": null, "id": "computer_setup", "text": null, "title": "Google account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "google_account", "text": null, "title": "Zoom account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "zoom_account", "text": null, "title": "365 account", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "365_account3", "text": null, "title": "Setup desk monitor", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "set_up_desk_monitor", "text": null, "title": "Setup entrance tag", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "email", "text": "bjornk@yahoo.com", "title": "Email", "type": "email", "value": "{\"text\":\"bjornk@yahoo.com\",\"email\":\"bjornk@yahoo.com\"}"}], "created_at": "2022-11-21T14:36:51Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407939", "name": "Employee name 3", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [], "updated_at_int": 1669041412}, "emitted_at": 1689087817321} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-06-19", "title": "Start date", "type": "date", "value": "{\"date\":\"2020-06-19\"}"}, {"additional_info": "{\"label\":\"Sales\",\"color\":\"#a25ddc\",\"changed_at\":null}", "description": null, "id": "status", "text": "Sales", "title": "Team", "type": "color", "value": "{\"index\":4,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Denver\",\"color\":\"#225091\",\"changed_at\":null}", "description": null, "id": "status8", "text": "Denver", "title": "Site", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"PC\",\"color\":\"#784BD1\",\"changed_at\":null}", "description": null, "id": "status1", "text": "PC", "title": "Computer type", "type": "color", "value": "{\"index\":14,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:46:39.331Z\"}", "description": null, "id": "status2", "text": "Done", "title": "Computer setup", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:46:39.331Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:46:40.460Z\"}", "description": null, "id": "computer_setup", "text": "Done", "title": "Google account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:46:40.460Z\"}"}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-21T13:46:41.571Z\"}", "description": null, "id": "google_account", "text": "Working on it", "title": "Zoom account", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-21T13:46:41.571Z\"}"}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2020-06-21T13:49:15.506Z\"}", "description": null, "id": "zoom_account", "text": "Working on it", "title": "365 account", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:15.506Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T06:24:56.006Z\"}", "description": null, "id": "365_account3", "text": "Done", "title": "Setup desk monitor", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T06:24:56.006Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-22T06:24:57.281Z\"}", "description": null, "id": "set_up_desk_monitor", "text": "Done", "title": "Setup entrance tag", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-22T06:24:57.281Z\"}"}, {"additional_info": null, "description": null, "id": "email", "text": "fangorn@att.net", "title": "Email", "type": "email", "value": "{\"text\":\"fangorn@att.net\",\"email\":\"fangorn@att.net\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555407955", "name": "Employee name 5", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [], "updated_at_int": 1669041412}, "emitted_at": 1689087817323} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-05-15", "title": "Start date", "type": "date", "value": "{\"date\":\"2020-05-15\"}"}, {"additional_info": "{\"label\":\"Partners\",\"color\":\"#037f4c\",\"changed_at\":null}", "description": null, "id": "status", "text": "Partners", "title": "Team", "type": "color", "value": "{\"index\":6,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Florida\",\"color\":\"#FF642E\",\"changed_at\":null}", "description": null, "id": "status8", "text": "Florida", "title": "Site", "type": "color", "value": "{\"index\":2,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Mac\",\"color\":\"#00c875\",\"changed_at\":null}", "description": null, "id": "status1", "text": "Mac", "title": "Computer type", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:51.414Z\"}", "description": null, "id": "status2", "text": "Done", "title": "Computer setup", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:51.414Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:52.581Z\"}", "description": null, "id": "computer_setup", "text": "Done", "title": "Google account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:52.581Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:54.106Z\"}", "description": null, "id": "google_account", "text": "Done", "title": "Zoom account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:54.106Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:55.348Z\"}", "description": null, "id": "zoom_account", "text": "Done", "title": "365 account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:55.348Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:55.348Z\"}", "description": null, "id": "365_account3", "text": "Done", "title": "Setup desk monitor", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:55.348Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:55.348Z\"}", "description": null, "id": "set_up_desk_monitor", "text": "Done", "title": "Setup entrance tag", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:55.348Z\"}"}, {"additional_info": null, "description": null, "id": "email", "text": "mdielmann@me.com", "title": "Email", "type": "email", "value": "{\"text\":\"mdielmann@me.com\",\"email\":\"mdielmann@me.com\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555407946", "name": "Employee name 4", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [], "updated_at_int": 1669041412}, "emitted_at": 1689087817326} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-04-16", "title": "Start date", "type": "date", "value": "{\"date\":\"2020-04-16\"}"}, {"additional_info": "{\"label\":\"R&D\",\"color\":\"#0086c0\",\"changed_at\":null}", "description": null, "id": "status", "text": "R&D", "title": "Team", "type": "color", "value": "{\"index\":3,\"post_id\":null}"}, {"additional_info": "{\"label\":\"New York\",\"color\":\"#784BD1\",\"changed_at\":null}", "description": null, "id": "status8", "text": "New York", "title": "Site", "type": "color", "value": "{\"index\":14,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Mac\",\"color\":\"#00c875\",\"changed_at\":null}", "description": null, "id": "status1", "text": "Mac", "title": "Computer type", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:57.121Z\"}", "description": null, "id": "status2", "text": "Done", "title": "Computer setup", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:57.121Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:59.755Z\"}", "description": null, "id": "computer_setup", "text": "Done", "title": "Google account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:59.755Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:02.766Z\"}", "description": null, "id": "google_account", "text": "Done", "title": "Zoom account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:02.766Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:06.494Z\"}", "description": null, "id": "zoom_account", "text": "Done", "title": "365 account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:06.494Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:06.494Z\"}", "description": null, "id": "365_account3", "text": "Done", "title": "Setup desk monitor", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:06.494Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:06.494Z\"}", "description": null, "id": "set_up_desk_monitor", "text": "Done", "title": "Setup entrance tag", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:06.494Z\"}"}, {"additional_info": null, "description": null, "id": "email", "text": "bjornk@outlook.com", "title": "Email", "type": "email", "value": "{\"text\":\"bjornk@outlook.com\",\"email\":\"bjornk@outlook.com\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_new_hires___6_25_"}, "id": "3555407966", "name": "Employee name 6", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [], "updated_at_int": 1669041412}, "emitted_at": 1689087817329} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555407698"}, "column_values": [{"additional_info": null, "description": null, "id": "people", "text": "", "title": "IT owner", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "person", "text": "", "title": "Responsible HR", "type": "multiple-person", "value": null}, {"additional_info": null, "description": null, "id": "date4", "text": "2020-04-29", "title": "Start date", "type": "date", "value": "{\"date\":\"2020-04-29\"}"}, {"additional_info": "{\"label\":\"Sales\",\"color\":\"#a25ddc\",\"changed_at\":null}", "description": null, "id": "status", "text": "Sales", "title": "Team", "type": "color", "value": "{\"index\":4,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Denver\",\"color\":\"#225091\",\"changed_at\":null}", "description": null, "id": "status8", "text": "Denver", "title": "Site", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Mac\",\"color\":\"#00c875\",\"changed_at\":null}", "description": null, "id": "status1", "text": "Mac", "title": "Computer type", "type": "color", "value": "{\"index\":1,\"post_id\":null}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:48:58.600Z\"}", "description": null, "id": "status2", "text": "Done", "title": "Computer setup", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:48:58.600Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:01.489Z\"}", "description": null, "id": "computer_setup", "text": "Done", "title": "Google account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:01.489Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:04.009Z\"}", "description": null, "id": "google_account", "text": "Done", "title": "Zoom account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:04.009Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:05.324Z\"}", "description": null, "id": "zoom_account", "text": "Done", "title": "365 account", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:05.324Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:05.324Z\"}", "description": null, "id": "365_account3", "text": "Done", "title": "Setup desk monitor", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:05.324Z\"}"}, {"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2020-06-21T13:49:05.324Z\"}", "description": null, "id": "set_up_desk_monitor", "text": "Done", "title": "Setup entrance tag", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2020-06-21T13:49:05.324Z\"}"}, {"additional_info": null, "description": null, "id": "email", "text": "mcmillan@gmail.com", "title": "Email", "type": "email", "value": "{\"text\":\"mcmillan@gmail.com\",\"email\":\"mcmillan@gmail.com\"}"}], "created_at": "2022-11-21T14:36:52Z", "creator_id": "36694549", "group": {"id": "duplicate_of_new_hires___6_25_"}, "id": "3555407969", "name": "Employee name 7", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:36:52Z", "updates": [], "updated_at_int": 1669041412}, "emitted_at": 1689087817332} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://drive.google.com/file/d/1wC5EQFsISkGAYLTKtcw1sG3ppHNLwESl/view", "title": "Link", "type": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1wC5EQFsISkGAYLTKtcw1sG3ppHNLwESl/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:27.555Z\"}"}, {"additional_info": null, "description": "", "id": "label", "text": null, "title": "Label", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Text", "type": "text", "value": null}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179394", "name": "API session", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": [], "updated_at_int": 1669039481}, "emitted_at": 1689087818540} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://drive.google.com/file/d/1BbEblAXGDOxTiTIDIcqOzfhAh43IyuTu/view", "title": "Link", "type": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1BbEblAXGDOxTiTIDIcqOzfhAh43IyuTu/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:31.968Z\"}"}, {"additional_info": null, "description": "", "id": "label", "text": null, "title": "Label", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Text", "type": "text", "value": null}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179405", "name": "Build a view", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": [], "updated_at_int": 1669039481}, "emitted_at": 1689087818543} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://drive.google.com/file/d/1ByMoeo2yhQcZfEOLhPP_iTjhutsLHipO/view", "title": "Link", "type": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1ByMoeo2yhQcZfEOLhPP_iTjhutsLHipO/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:38.402Z\"}"}, {"additional_info": null, "description": "", "id": "label", "text": null, "title": "Label", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Text", "type": "text", "value": null}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179418", "name": "Build an integration", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": [], "updated_at_int": 1669039481}, "emitted_at": 1689087818545} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://drive.google.com/file/d/1MbhkWgJY8piKmH0uivIHaKnwYPyNr3rS/view", "title": "Link", "type": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1MbhkWgJY8piKmH0uivIHaKnwYPyNr3rS/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:48.148Z\"}"}, {"additional_info": null, "description": "", "id": "label", "text": null, "title": "Label", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Text", "type": "text", "value": null}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179422", "name": "Authentication", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": [], "updated_at_int": 1669039481}, "emitted_at": 1689087818548} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": null, "description": null, "id": "status", "text": null, "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://drive.google.com/file/d/1ZUwXi9VA7MfD3JZJgvVXmpdvaosHJIKm/view", "title": "Link", "type": "link", "value": "{\"url\":\"https://drive.google.com/file/d/1ZUwXi9VA7MfD3JZJgvVXmpdvaosHJIKm/view\",\"text\":\"Link\",\"changed_at\":\"2022-06-08T12:54:53.319Z\"}"}, {"additional_info": null, "description": "", "id": "label", "text": null, "title": "Label", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "Text", "type": "text", "value": null}], "created_at": "2022-11-21T14:04:41Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179431", "name": "Build a Workspace template", "parent_item": {"id": "3555179341"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:41Z", "updates": [], "updated_at_int": 1669039481}, "emitted_at": 1689087818551} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": "{\"label\":\"Done\",\"color\":\"#00c875\",\"changed_at\":\"2022-11-21T14:40:58.550Z\"}", "description": null, "id": "status", "text": "Done", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-11-21T14:40:58.550Z\"}"}, {"additional_info": null, "description": null, "id": "link", "text": "Airbyte - https://airbyte.com/", "title": "Link", "type": "link", "value": "{\"url\":\"https://airbyte.com/\",\"text\":\"Airbyte\",\"changed_at\":\"2022-11-21T14:40:42.184Z\"}"}, {"additional_info": "{\"label\":\"Label 3\",\"color\":\"#9D99B9\",\"changed_at\":\"2022-11-21T14:41:45.550Z\"}", "description": "", "id": "label", "text": "Label 3", "title": "Label", "type": "color", "value": "{\"index\":156,\"post_id\":null,\"changed_at\":\"2022-11-21T14:41:45.550Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "Test test test", "title": "Text", "type": "text", "value": "\"Test test test\""}], "created_at": "2022-11-21T14:40:34Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555433784", "name": "Test", "parent_item": {"id": "3555179351"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:42:01Z", "updates": [], "updated_at_int": 1669041721}, "emitted_at": 1689087818553} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179105"}, "column_values": [{"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2022-11-21T14:41:32.359Z\"}", "description": null, "id": "status", "text": "Working on it", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-11-21T14:41:32.359Z\"}"}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": "{\"label\":\"Label 1\",\"color\":\"#9AADBD\",\"changed_at\":\"2022-11-21T14:41:43.450Z\"}", "description": "", "id": "label", "text": "Label 1", "title": "Label", "type": "color", "value": "{\"index\":105,\"post_id\":null,\"changed_at\":\"2022-11-21T14:41:43.450Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "one two three #!!", "title": "Text", "type": "text", "value": "\"one two three #!!\""}], "created_at": "2022-11-21T14:41:12Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555437747", "name": "Test1", "parent_item": {"id": "3555179351"}, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2023-06-15T16:14:33Z", "updates": [{"id": "1825302913"}], "updated_at_int": 1686845673}, "emitted_at": 1689087818556} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": "{\"label\":\"Done!\",\"color\":\"#00c875\",\"changed_at\":\"2022-06-07T11:29:38.019Z\"}", "description": null, "id": "status_1", "text": "Done!", "title": "Status", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-06-07T11:29:38.019Z\"}"}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179259", "name": "Create a dev account", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": [], "updated_at_int": 1669039479}, "emitted_at": 1689087821001} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "Test, Test1", "title": "Subitems", "type": "subtasks", "value": "{\"linkedPulseIds\":[{\"linkedPulseId\":3555433784},{\"linkedPulseId\":3555437747}]}"}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2022-06-07T11:29:19.711Z\"}", "description": null, "id": "status_1", "text": "Working on it", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:29:19.711Z\"}"}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "29814928", "group": {"id": "topics"}, "id": "3555179351", "name": "Click to read this update \ud83e\udd29", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:41:13Z", "updates": [{"id": "1825206780"}], "updated_at_int": 1669041673}, "emitted_at": 1689087821004} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://www.youtube.com/watch?v=nUMK6d1JcCY", "title": "Link", "type": "link", "value": "{\"url\":\"https://www.youtube.com/watch?v=nUMK6d1JcCY\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:16:13.208Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "You can write you notes here", "title": "My notes", "type": "text", "value": "\"You can write you notes here\""}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Video\",\"color\":\"#e2445c\",\"changed_at\":\"2022-06-07T11:16:08.728Z\"}", "description": null, "id": "status_10", "text": "Video", "title": "Type", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2022-06-07T11:16:08.728Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "14293832", "group": {"id": "topics"}, "id": "3555179247", "name": "What is monday - 2 min video \ud83c\udfa5 (Very cool)", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": [], "updated_at_int": 1669039479}, "emitted_at": 1689087821007} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "Notes", "title": "My notes", "type": "text", "value": "\"Notes\""}, {"additional_info": "{\"label\":\"Working on it\",\"color\":\"#fdab3d\",\"changed_at\":\"2022-11-21T14:42:28.383Z\"}", "description": null, "id": "status_1", "text": "Working on it", "title": "Status", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-11-21T14:42:28.383Z\"}"}, {"additional_info": "{\"label\":\"Documentation\",\"color\":\"#175A63\",\"changed_at\":\"2022-11-21T14:42:31.122Z\"}", "description": null, "id": "status_10", "text": "Documentation", "title": "Type", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-11-21T14:42:31.122Z\"}"}], "created_at": "2022-11-21T14:42:29Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555446655", "name": "Item 1", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:42:42Z", "updates": [], "updated_at_int": 1669041762}, "emitted_at": 1689087821009} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "Note 2", "title": "My notes", "type": "text", "value": "\"Note 2\""}, {"additional_info": "{\"label\":\"Stuck\",\"color\":\"#e2445c\",\"changed_at\":\"2022-11-21T14:42:44.903Z\"}", "description": null, "id": "status_1", "text": "Stuck", "title": "Status", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2022-11-21T14:42:44.903Z\"}"}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-11-21T14:42:47.315Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-11-21T14:42:47.315Z\"}"}], "created_at": "2022-11-21T14:42:48Z", "creator_id": "36694549", "group": {"id": "topics"}, "id": "3555448801", "name": "Item 2", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:42:58Z", "updates": [], "updated_at_int": 1669041778}, "emitted_at": 1689087821012} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "LInk - https://support.monday.com/hc/en-us/articles/360001267945-The-board-views", "title": "Link", "type": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360001267945-The-board-views\",\"text\":\"LInk\",\"changed_at\":\"2022-06-07T11:18:26.141Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:17:57.718Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:17:57.718Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "new_group37570"}, "id": "3555179253", "name": "Board views", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": [], "updated_at_int": 1669039479}, "emitted_at": 1689087821014} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://support.monday.com/hc/en-us/articles/360017143959-The-Item-Card-", "title": "Link", "type": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360017143959-The-Item-Card-\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:57:42.870Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:22:29.156Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:22:29.156Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group37570"}, "id": "3555179292", "name": "Item views", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": [], "updated_at_int": 1669039479}, "emitted_at": 1689087821017} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://support.monday.com/hc/en-us/articles/360003445540-monday-com-Integrations", "title": "Link", "type": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360003445540-monday-com-Integrations\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:51:35.374Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:22:29.156Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:22:29.156Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group37570"}, "id": "3555179262", "name": "Integrations", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": [], "updated_at_int": 1669039479}, "emitted_at": 1689087821020} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://support.monday.com/hc/en-us/articles/360002187819-The-Dashboards", "title": "Link", "type": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360002187819-The-Dashboards\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:54:50.218Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:22:29.156Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:22:29.156Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group37570"}, "id": "3555179270", "name": "Dashboard widgets", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": [], "updated_at_int": 1669039479}, "emitted_at": 1689087821022} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://support.monday.com/hc/en-us/articles/360001362625-monday-com-board-templates", "title": "Link", "type": "link", "value": "{\"url\":\"https://support.monday.com/hc/en-us/articles/360001362625-monday-com-board-templates\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:56:20.627Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:56:23.316Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:56:23.316Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group37570"}, "id": "3555179288", "name": "Workspace template", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": [], "updated_at_int": 1669039479}, "emitted_at": 1689087821025} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Apps marketplace - https://monday.com/marketplace", "title": "Link", "type": "link", "value": "{\"url\":\"https://monday.com/marketplace\",\"text\":\"Apps marketplace\",\"changed_at\":\"2022-04-12T13:55:17.553Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:38Z", "creator_id": "14293832", "group": {"id": "group_title"}, "id": "3555179185", "name": "Check out our marketplace - The puzzle icon on the left pane", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:38Z", "updates": [], "updated_at_int": 1669039478}, "emitted_at": 1689087821028} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://apps.developer.monday.com/docs/monday-app-development-process", "title": "Link", "type": "link", "value": "{\"url\":\"https://apps.developer.monday.com/docs/monday-app-development-process\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:58:53.115Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T11:58:38.720Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T11:58:38.720Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "14293832", "group": {"id": "group_title"}, "id": "3555179305", "name": "Plan your app", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": [], "updated_at_int": 1669039479}, "emitted_at": 1689087821030} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://monday.com/developers/apps/intro", "title": "Link", "type": "link", "value": "{\"url\":\"https://monday.com/developers/apps/intro\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:59:07.145Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Documentation\",\"color\":\"#175A63\",\"changed_at\":\"2022-06-07T11:58:40.733Z\"}", "description": null, "id": "status_10", "text": "Documentation", "title": "Type", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-06-07T11:58:40.733Z\"}"}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555179310", "name": "Check out our monday apps documentation", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": [], "updated_at_int": 1669039480}, "emitted_at": 1689087821033} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://apps.developer.monday.com/docs/workspace-templates", "title": "Link", "type": "link", "value": "{\"url\":\"https://apps.developer.monday.com/docs/workspace-templates\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T11:59:30.527Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Documentation\",\"color\":\"#175A63\",\"changed_at\":\"2022-06-07T11:58:43.818Z\"}", "description": null, "id": "status_10", "text": "Documentation", "title": "Type", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-06-07T11:58:43.818Z\"}"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "36694549", "group": {"id": "group_title"}, "id": "3555179318", "name": "Bundling templates with your app", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": [], "updated_at_int": 1669039480}, "emitted_at": 1689087821036} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "API session, Build a view, Build an integration, Authentication, Build a Workspace template", "title": "Subitems", "type": "subtasks", "value": "{\"linkedPulseIds\":[{\"linkedPulseId\":3555179394},{\"linkedPulseId\":3555179405},{\"linkedPulseId\":3555179418},{\"linkedPulseId\":3555179422},{\"linkedPulseId\":3555179431}]}"}, {"additional_info": null, "description": null, "id": "link", "text": "", "title": "Link", "type": "link", "value": null}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Video\",\"color\":\"#e2445c\",\"changed_at\":\"2022-06-07T11:59:35.220Z\"}", "description": null, "id": "status_10", "text": "Video", "title": "Type", "type": "color", "value": "{\"index\":2,\"post_id\":null,\"changed_at\":\"2022-06-07T11:59:35.220Z\"}"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "29814928", "group": {"id": "group_title"}, "id": "3555179341", "name": "Sessions recordings - See the framework in action (Subitems)", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:42Z", "updates": [], "updated_at_int": 1669039482}, "emitted_at": 1689087821038} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://apps.developer.monday.com/docs/submit-your-app", "title": "Link", "type": "link", "value": "{\"url\":\"https://apps.developer.monday.com/docs/submit-your-app\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T12:06:37.152Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Article\",\"color\":\"#66CCFF\",\"changed_at\":\"2022-06-07T12:06:30.006Z\"}", "description": null, "id": "status_10", "text": "Article", "title": "Type", "type": "color", "value": "{\"index\":0,\"post_id\":null,\"changed_at\":\"2022-06-07T12:06:30.006Z\"}"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "36694549", "group": {"id": "new_group45036"}, "id": "3555179324", "name": "Prepare for marketplace review", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": [], "updated_at_int": 1669039480}, "emitted_at": 1689087821041} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link to board - https://view.monday.com/2586384041-f47a2dae812b0a295f0a974bfc39b42d?r=use1", "title": "Link", "type": "link", "value": "{\"url\":\"https://view.monday.com/2586384041-f47a2dae812b0a295f0a974bfc39b42d?r=use1\",\"text\":\"Link to board\",\"changed_at\":\"2022-04-25T09:16:11.585Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "29814928", "group": {"id": "new_group45036"}, "id": "3555179218", "name": "App review template board", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": [], "updated_at_int": 1669039479}, "emitted_at": 1689087821043} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Submission form - https://forms.monday.com/forms/c390831d51274ee8882bf4fc96a6fb17", "title": "Link", "type": "link", "value": "{\"url\":\"https://forms.monday.com/forms/c390831d51274ee8882bf4fc96a6fb17\",\"text\":\"Submission form\",\"changed_at\":\"2022-04-12T14:04:58.308Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "new_group45036"}, "id": "3555179230", "name": "Submit your app to review", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": [], "updated_at_int": 1669039479}, "emitted_at": 1689087821046} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://community.monday.com/c/developers/8", "title": "Link", "type": "link", "value": "{\"url\":\"https://community.monday.com/c/developers/8\",\"text\":\"Link \",\"changed_at\":\"2022-04-12T14:02:46.916Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:38Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555179200", "name": "Developers community \ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:38Z", "updates": [], "updated_at_int": 1669039478}, "emitted_at": 1689087821049} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://style.monday.com/?path=/docs/welcome--page", "title": "Link", "type": "link", "value": "{\"url\":\"https://style.monday.com/?path=/docs/welcome--page\",\"text\":\"Link\",\"changed_at\":\"2022-04-12T14:03:00.031Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555179207", "name": "Design kit \ud83d\udc69\ud83c\udffb\u200d\ud83c\udfa8", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": [], "updated_at_int": 1669039479}, "emitted_at": 1689087821051} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://apps.developer.monday.com/docs/monetization", "title": "Link", "type": "link", "value": "{\"url\":\"https://apps.developer.monday.com/docs/monetization\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T12:07:37.151Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": "{\"label\":\"Documentation\",\"color\":\"#175A63\",\"changed_at\":\"2022-06-07T12:07:24.046Z\"}", "description": null, "id": "status_10", "text": "Documentation", "title": "Type", "type": "color", "value": "{\"index\":1,\"post_id\":null,\"changed_at\":\"2022-06-07T12:07:24.046Z\"}"}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555179327", "name": "monday apps monetization \ud83d\udcb0", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": [], "updated_at_int": 1669039480}, "emitted_at": 1689087821054} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "appsupport@monday.com - mailto:appsupport@monday.com/", "title": "Link", "type": "link", "value": "{\"url\":\"mailto:appsupport@monday.com/\",\"text\":\"appsupport@monday.com\",\"changed_at\":\"2022-04-13T20:54:57.089Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:39Z", "creator_id": "36694549", "group": {"id": "new_group"}, "id": "3555179211", "name": "Technical support team \ud83e\udd70", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:39Z", "updates": [], "updated_at_int": 1669039479}, "emitted_at": 1689087821057} +{"stream": "items", "data": {"assets": [], "board": {"id": "3555179067"}, "column_values": [{"additional_info": null, "description": null, "id": "subitems", "text": "", "title": "Subitems", "type": "subtasks", "value": null}, {"additional_info": null, "description": null, "id": "link", "text": "Link - https://mondayclimatechallenge.devpost.com/", "title": "Link", "type": "link", "value": "{\"url\":\"https://mondayclimatechallenge.devpost.com/\",\"text\":\"Link\",\"changed_at\":\"2022-06-07T13:40:18.751Z\"}"}, {"additional_info": null, "description": null, "id": "text", "text": "", "title": "My notes", "type": "text", "value": null}, {"additional_info": null, "description": null, "id": "status_1", "text": "Need to review", "title": "Status", "type": "color", "value": null}, {"additional_info": null, "description": null, "id": "status_10", "text": "Other", "title": "Type", "type": "color", "value": null}], "created_at": "2022-11-21T14:04:40Z", "creator_id": "29814928", "group": {"id": "new_group"}, "id": "3555179334", "name": "Make sure you saw to see challenge post (awesome prizes included)", "parent_item": null, "state": "active", "subscribers": [{"id": 36694549}], "updated_at": "2022-11-21T14:04:40Z", "updates": [], "updated_at_int": 1669039480}, "emitted_at": 1689087821059} +{"stream": "activity_logs", "data": {"id": "81d07d4d-414d-458e-b44c-fef36e44c424", "event": "create_pulse", "data": "{\"board_id\":4635211873,\"group_id\":\"new_group\",\"group_name\":\"New Group unit board\",\"group_color\":\"#808080\",\"is_top_group\":false,\"pulse_id\":4672924165,\"pulse_name\":\"Item 7\",\"column_values_json\":\"{}\"}", "entity": "pulse", "created_at": "16872631837419768", "created_at_int": 1687263183, "pulse_id": 4672924165}, "emitted_at": 1689087829182} +{"stream": "activity_logs", "data": {"id": "c0aa4bab-d3a4-4f13-8942-934178c0238a", "event": "update_column_value", "data": "{\"board_id\":4635211873,\"group_id\":\"group_title\",\"is_top_group\":false,\"pulse_id\":4672922929,\"pulse_name\":\"Item 6\",\"column_id\":\"status\",\"column_type\":\"color\",\"column_title\":\"Status\",\"value\":{\"label\":{\"index\":1,\"text\":\"Done\",\"style\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"is_done\":true},\"post_id\":null},\"previous_value\":null,\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16872631743009674", "created_at_int": 1687263174, "pulse_id": 4672922929}, "emitted_at": 1689087829187} +{"stream": "activity_logs", "data": {"id": "4e8f926c-1b4e-43d8-a3de-09af876ccb9e", "event": "create_pulse", "data": "{\"board_id\":4635211873,\"group_id\":\"group_title\",\"group_name\":\"Group Title\",\"group_color\":\"#a25ddc\",\"is_top_group\":false,\"pulse_id\":4672922929,\"pulse_name\":\"Item 6\",\"column_values_json\":\"{}\"}", "entity": "pulse", "created_at": "16872631712788820", "created_at_int": 1687263171, "pulse_id": 4672922929}, "emitted_at": 1689087829189} +{"stream": "activity_logs", "data": {"id": "612cb507-12fe-4a03-8cd0-cce0b89a0b19", "event": "update_group_name", "data": "{\"board_id\":4635211873,\"group_id\":\"new_group\",\"value\":{\"name\":\"New Group unit board\"},\"previous_value\":{\"name\":\"New Group\"},\"group_color\":\"#808080\"}", "entity": "board", "created_at": "16872631660825340", "created_at_int": 1687263166, "board_id": 4635211873}, "emitted_at": 1689087829192} +{"stream": "activity_logs", "data": {"id": "1a205720-2df7-4347-9a66-63c08ca58c64", "event": "create_group", "data": "{\"board_id\":4635211873,\"group_id\":\"new_group\",\"group_title\":\"New Group\",\"group_color\":\"#808080\"}", "entity": "board", "created_at": "16872631576495010", "created_at_int": 1687263157, "board_id": 4635211873}, "emitted_at": 1689087829193} +{"stream": "activity_logs", "data": {"id": "5187ff30-948d-4007-a251-4727d362602d", "event": "update_column_value", "data": "{\"board_id\":4635211873,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":4635211964,\"pulse_name\":\"Item 2\",\"column_id\":\"tags\",\"column_type\":\"tag\",\"column_title\":\"Tags\",\"value\":{\"tags\":[{\"id\":19038091,\"name\":\"closed\",\"color\":\"#fdab3d\"}]},\"previous_value\":null,\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16866647770228472", "created_at_int": 1686664777, "pulse_id": 4635211964}, "emitted_at": 1689087829195} +{"stream": "activity_logs", "data": {"id": "f54070cd-c8f4-4bc4-931a-3a0899fd6621", "event": "update_column_value", "data": "{\"board_id\":4635211873,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":4635211945,\"pulse_name\":\"Item 1\",\"column_id\":\"tags\",\"column_type\":\"tag\",\"column_title\":\"Tags\",\"value\":{\"tags\":[{\"id\":19038090,\"name\":\"open\",\"color\":\"#00c875\"}]},\"previous_value\":null,\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16866647724549912", "created_at_int": 1686664772, "pulse_id": 4635211945}, "emitted_at": 1689087829197} +{"stream": "activity_logs", "data": {"id": "3d1ff099-0ec9-43fe-8718-bad0570ea85b", "event": "create_column", "data": "{\"board_id\":4635211873,\"column_id\":\"tags\",\"column_title\":\"Tags\",\"column_type\":\"tag\"}", "entity": "board", "created_at": "16866647322606218", "created_at_int": 1686664732, "board_id": 4635211873}, "emitted_at": 1689087829199} +{"stream": "activity_logs", "data": {"id": "beb26f37-ffcd-4dc5-8eb1-e65ec5a469bf", "event": "update_column_value", "data": "{\"board_id\":4635211873,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":4635211977,\"pulse_name\":\"Item 3\",\"column_id\":\"date4\",\"column_type\":\"date\",\"column_title\":\"Date\",\"value\":{\"date\":\"2023-06-13\",\"icon\":null,\"time\":null,\"changed_at\":\"2023-06-13T13:58:26.291Z\"},\"previous_value\":{\"date\":\"2019-09-25\",\"icon\":null,\"time\":null,\"changed_at\":\"2019-09-17T23:23:47.778Z\"},\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16866647064519740", "created_at_int": 1686664706, "pulse_id": 4635211977}, "emitted_at": 1689087829201} +{"stream": "activity_logs", "data": {"id": "ba0a2d19-09b7-4af2-9d8a-04b886128ef7", "event": "update_column_value", "data": "{\"board_id\":4635211873,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":4635211964,\"pulse_name\":\"Item 2\",\"column_id\":\"date4\",\"column_type\":\"date\",\"column_title\":\"Date\",\"value\":{\"date\":\"2023-06-11\",\"icon\":null,\"time\":null,\"changed_at\":\"2023-06-13T13:58:25.871Z\"},\"previous_value\":{\"date\":\"2019-09-20\",\"icon\":null,\"time\":null,\"changed_at\":\"2019-09-17T23:23:45.880Z\"},\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16866647062375920", "created_at_int": 1686664706, "pulse_id": 4635211964}, "emitted_at": 1689087829203} +{"stream": "activity_logs", "data": {"id": "599d7550-2c37-4b6e-9211-071ab7aebdc8", "event": "update_column_value", "data": "{\"board_id\":4635211873,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":4635211945,\"pulse_name\":\"Item 1\",\"column_id\":\"date4\",\"column_type\":\"date\",\"column_title\":\"Date\",\"value\":{\"date\":\"2023-06-11\",\"icon\":null,\"time\":null,\"changed_at\":\"2023-06-13T13:58:25.871Z\"},\"previous_value\":{\"date\":\"2019-09-17\",\"icon\":null,\"time\":null,\"changed_at\":\"2019-09-17T23:23:36.569Z\"},\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16866647060567080", "created_at_int": 1686664706, "pulse_id": 4635211945}, "emitted_at": 1689087829204} +{"stream": "activity_logs", "data": {"id": "2f056267-eae8-4aa4-9ca5-53ba4ae6f429", "event": "update_column_value", "data": "{\"board_id\":4635211873,\"group_id\":\"group_title\",\"is_top_group\":false,\"pulse_id\":4635212008,\"pulse_name\":\"Item 4\",\"column_id\":\"date4\",\"column_type\":\"date\",\"column_title\":\"Date\",\"value\":{\"date\":\"2023-06-13\",\"icon\":null,\"time\":null,\"changed_at\":\"2023-06-13T13:58:25.469Z\"},\"previous_value\":{\"date\":\"2019-09-06\",\"icon\":null,\"time\":null,\"changed_at\":\"2019-11-26T13:53:38.567Z\"},\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16866647058345316", "created_at_int": 1686664705, "pulse_id": 4635212008}, "emitted_at": 1689087829206} +{"stream": "activity_logs", "data": {"id": "12a0ff8d-2f08-487f-ab68-248fd5904e77", "event": "update_column_value", "data": "{\"board_id\":4635211873,\"group_id\":\"group_title\",\"is_top_group\":false,\"pulse_id\":4635211995,\"pulse_name\":\"Item 5\",\"column_id\":\"date4\",\"column_type\":\"date\",\"column_title\":\"Date\",\"value\":{\"date\":\"2023-06-13\",\"icon\":null,\"time\":null,\"changed_at\":\"2023-06-13T13:58:25.469Z\"},\"previous_value\":{\"date\":\"2019-09-28\",\"icon\":null,\"time\":null,\"changed_at\":\"2019-09-17T23:23:52.184Z\"},\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16866647056874976", "created_at_int": 1686664705, "pulse_id": 4635211995}, "emitted_at": 1689087829208} +{"stream": "activity_logs", "data": {"id": "629d6331-c871-488f-9865-cb64fb6a1ed3", "event": "create_column", "data": "{\"board_id\":4635211873,\"column_id\":\"date4\",\"column_title\":\"Date\",\"column_type\":\"date\"}", "entity": "board", "created_at": "16866647035824628", "created_at_int": 1686664703, "board_id": 4635211873}, "emitted_at": 1689087829210} +{"stream": "activity_logs", "data": {"id": "9fa88fc0-da97-4214-b81d-175ec76356e2", "event": "create_column", "data": "{\"board_id\":4635211873,\"column_id\":\"status\",\"column_title\":\"Status\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16866647035800504", "created_at_int": 1686664703, "board_id": 4635211873}, "emitted_at": 1689087829212} +{"stream": "activity_logs", "data": {"id": "5d3b0856-0b93-4aac-9c83-902f6b5877f8", "event": "create_column", "data": "{\"board_id\":4635211873,\"column_id\":\"person\",\"column_title\":\"Person\",\"column_type\":\"multiple-person\"}", "entity": "board", "created_at": "16866647035776758", "created_at_int": 1686664703, "board_id": 4635211873}, "emitted_at": 1689087829213} +{"stream": "activity_logs", "data": {"id": "bdba7f38-7772-4bca-bcb9-1145e19d8732", "event": "create_column", "data": "{\"board_id\":4635211873,\"column_id\":\"name\",\"column_title\":\"Name\",\"column_type\":\"name\"}", "entity": "board", "created_at": "16866647035749796", "created_at_int": 1686664703, "board_id": 4635211873}, "emitted_at": 1689087829215} +{"stream": "activity_logs", "data": {"id": "a5a2861e-5178-407b-a786-44e21222edbd", "event": "create_group", "data": "{\"board_id\":4635211873,\"group_id\":\"group_title\",\"group_title\":\"Group Title\",\"group_color\":\"#a25ddc\"}", "entity": "board", "created_at": "16866647035722008", "created_at_int": 1686664703, "board_id": 4635211873}, "emitted_at": 1689087829217} +{"stream": "activity_logs", "data": {"id": "e6460c88-63df-4f9e-b616-f96fbc62d05f", "event": "create_group", "data": "{\"board_id\":4635211873,\"group_id\":\"topics\",\"group_title\":\"Group Title\",\"group_color\":\"#579bfc\"}", "entity": "board", "created_at": "16866647035688830", "created_at_int": 1686664703, "board_id": 4635211873}, "emitted_at": 1689087829219} +{"stream": "activity_logs", "data": {"id": "b6a1453d-487a-467b-bc60-37fd8d8288d9", "event": "update_column_value", "data": "{\"board_id\":4634950289,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":4634950329,\"pulse_name\":\"Doc Comments\",\"column_id\":\"files\",\"column_type\":\"file\",\"column_title\":\"Files\",\"value\":{\"files\":[{\"fileType\":\"ASSET\",\"assetId\":916811099,\"name\":\"black_cat.jpg\",\"isImage\":\"true\",\"createdAt\":1686745812452,\"createdBy\":\"36694549\"}]},\"previous_value\":{},\"is_column_with_hide_permissions\":false,\"textual_value\":\"https://airbyte-unit.monday.com/protected_static/14202902/resources/916811099/black_cat.jpg\"}", "entity": "pulse", "created_at": "16867458146035478", "created_at_int": 1686745814, "pulse_id": 4634950329}, "emitted_at": 1689087829694} +{"stream": "activity_logs", "data": {"id": "165ffbd9-ad97-4815-9649-1fb3fbb0d992", "event": "create_column", "data": "{\"board_id\":4634950289,\"column_id\":\"files\",\"column_title\":\"Files\",\"column_type\":\"file\"}", "entity": "board", "created_at": "16866629117709884", "created_at_int": 1686662911, "board_id": 4634950289}, "emitted_at": 1689087829699} +{"stream": "activity_logs", "data": {"id": "a0c73590-7265-4059-9dc4-8286baa652e1", "event": "create_column", "data": "{\"board_id\":4634950289,\"column_id\":\"name\",\"column_title\":\"Name\",\"column_type\":\"name\"}", "entity": "board", "created_at": "16866629117684938", "created_at_int": 1686662911, "board_id": 4634950289}, "emitted_at": 1689087829702} +{"stream": "activity_logs", "data": {"id": "2cc50340-00eb-43b5-9e34-4463dd6351a4", "event": "create_group", "data": "{\"board_id\":4634950289,\"group_id\":\"topics\",\"group_title\":\"Group Title\",\"group_color\":\"#579bfc\"}", "entity": "board", "created_at": "16866629117655582", "created_at_int": 1686662911, "board_id": 4634950289}, "emitted_at": 1689087829704} +{"stream": "activity_logs", "data": {"id": "2c1c27fb-9f69-45b4-900e-f905195e1d6b", "event": "subscribe", "data": "{\"item_id\":3555407826,\"item_name\":\"Procurement process\",\"item_type\":\"Board\",\"subscribed_id\":36694549,\"board_id\":3555407826,\"pulse_id\":null}", "entity": "pulse", "created_at": "16690414110219214", "created_at_int": 1669041411}, "emitted_at": 1689087830098} +{"stream": "activity_logs", "data": {"id": "123caf16-c8db-406b-86e9-fecf21a5b2ac", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"last_updated\",\"column_title\":\"Last updated\",\"column_type\":\"pulse-updated\"}", "entity": "board", "created_at": "16690414105385840", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830100} +{"stream": "activity_logs", "data": {"id": "aab0bdd2-bc51-49a0-991f-49c9269a50e0", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"date\",\"column_title\":\"Renewal date\",\"column_type\":\"date\"}", "entity": "board", "created_at": "16690414105359240", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830101} +{"stream": "activity_logs", "data": {"id": "1b2d3865-3392-43f0-b8e0-c8d3fa93cacb", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"legal_approval\",\"column_title\":\"Security approval\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414105334172", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830103} +{"stream": "activity_logs", "data": {"id": "9c4236ed-24fa-4b5f-9a39-5630a7da7a1e", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"legal\",\"column_title\":\"Security\",\"column_type\":\"multiple-person\"}", "entity": "board", "created_at": "16690414105305260", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830105} +{"stream": "activity_logs", "data": {"id": "0bb8ed71-8b05-4dfa-901c-0a57285d760f", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"file\",\"column_title\":\"File\",\"column_type\":\"file\"}", "entity": "board", "created_at": "16690414105276092", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830107} +{"stream": "activity_logs", "data": {"id": "ba830562-5521-4ac9-82e9-67b764ae90e8", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"finance_approval\",\"column_title\":\"Legal approval\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414105244220", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830108} +{"stream": "activity_logs", "data": {"id": "28f309a4-6f48-429b-a917-6965ff5900e4", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"finance\",\"column_title\":\"Legal\",\"column_type\":\"multiple-person\"}", "entity": "board", "created_at": "16690414105215718", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830110} +{"stream": "activity_logs", "data": {"id": "be0bc557-3222-4546-9144-7a74008aae2e", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"procurement_approval\",\"column_title\":\"Finance approval\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414105186224", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830112} +{"stream": "activity_logs", "data": {"id": "b2bfb67f-a98a-432e-8dd7-a937a1b8850f", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"procurement_team\",\"column_title\":\"Finance\",\"column_type\":\"multiple-person\"}", "entity": "board", "created_at": "16690414105159560", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830114} +{"stream": "activity_logs", "data": {"id": "40f37533-5a6d-4012-8baa-4f55799ac629", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"budget_owner_approval\",\"column_title\":\"Procurement approval\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414105134878", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830115} +{"stream": "activity_logs", "data": {"id": "8317b861-011a-4637-9c69-4aab8eab77e9", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"people\",\"column_title\":\"Procurement team\",\"column_type\":\"multiple-person\"}", "entity": "board", "created_at": "16690414105109652", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830117} +{"stream": "activity_logs", "data": {"id": "639c0189-4843-4bfd-bc98-4f2cfc5ba056", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"status4\",\"column_title\":\"Budget owner approval\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414105081320", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830119} +{"stream": "activity_logs", "data": {"id": "1569436e-203f-4dad-a3a1-2c1cf7807301", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"manager\",\"column_title\":\"Budget owner\",\"column_type\":\"multiple-person\"}", "entity": "board", "created_at": "16690414105052870", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830121} +{"stream": "activity_logs", "data": {"id": "d192fa98-32c4-4979-b6d9-619e2ce30bb9", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"budget_owner_approval4\",\"column_title\":\"POC status\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414105022984", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830122} +{"stream": "activity_logs", "data": {"id": "33370270-2030-4728-8987-e617ffaa6147", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"budget_owner\",\"column_title\":\"POC owner\",\"column_type\":\"multiple-person\"}", "entity": "board", "created_at": "16690414104997594", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830124} +{"stream": "activity_logs", "data": {"id": "8b8cc677-9cdd-466a-8230-e3fb9b0424de", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"status\",\"column_title\":\"Manager approval\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414104974596", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830126} +{"stream": "activity_logs", "data": {"id": "60080db9-ea7b-4ebf-81ea-ba1cee0c8964", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"person\",\"column_title\":\"Manager\",\"column_type\":\"multiple-person\"}", "entity": "board", "created_at": "16690414104948524", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830128} +{"stream": "activity_logs", "data": {"id": "1a775d89-9e00-4096-84ab-680e89f72766", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"status1\",\"column_title\":\"Procurement status\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414104924526", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830129} +{"stream": "activity_logs", "data": {"id": "5e33e1c3-0b91-44d0-897c-2575e44cb65b", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"date4\",\"column_title\":\"Request date\",\"column_type\":\"date\"}", "entity": "board", "created_at": "16690414104900820", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830131} +{"stream": "activity_logs", "data": {"id": "3ac4a57b-fc0e-4a86-b59f-0e69ae9216ff", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"manager1\",\"column_title\":\"Owner\",\"column_type\":\"multiple-person\"}", "entity": "board", "created_at": "16690414104876470", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830133} +{"stream": "activity_logs", "data": {"id": "6025f51c-8eff-4079-bcc1-64b41781f413", "event": "create_column", "data": "{\"board_id\":3555407826,\"column_id\":\"name\",\"column_title\":\"Name\",\"column_type\":\"name\"}", "entity": "board", "created_at": "16690414104852936", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830135} +{"stream": "activity_logs", "data": {"id": "ce4eaf54-f714-4cf7-ba9c-d25a2082006e", "event": "create_group", "data": "{\"board_id\":3555407826,\"group_id\":\"new_group2816\",\"group_title\":\"Finance\",\"group_color\":\"#037f4c\"}", "entity": "board", "created_at": "16690414104829164", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830136} +{"stream": "activity_logs", "data": {"id": "8ecacf4c-c2e8-4c29-b1b7-52ea5aa1f8f0", "event": "create_group", "data": "{\"board_id\":3555407826,\"group_id\":\"new_group\",\"group_title\":\"Corporate IT\",\"group_color\":\"#FF642E\"}", "entity": "board", "created_at": "16690414104805548", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830138} +{"stream": "activity_logs", "data": {"id": "0c183cba-808a-4865-83e7-89a919387632", "event": "create_group", "data": "{\"board_id\":3555407826,\"group_id\":\"topics\",\"group_title\":\"Reviewing\",\"group_color\":\"#579bfc\"}", "entity": "board", "created_at": "16690414104777576", "created_at_int": 1669041410, "board_id": 3555407826}, "emitted_at": 1689087830140} +{"stream": "activity_logs", "data": {"id": "105abb96-a277-48d6-961b-46232f1ab0f2", "event": "create_pulse", "data": "{\"board_id\":3555407785,\"group_id\":\"topics\",\"group_name\":\"Laptops\",\"group_color\":\"#579bfc\",\"is_top_group\":false,\"pulse_id\":4672979272,\"pulse_name\":\"Macbook\",\"column_values_json\":\"{}\"}", "entity": "pulse", "created_at": "16872636879124876", "created_at_int": 1687263687, "pulse_id": 4672979272}, "emitted_at": 1689087830514} +{"stream": "activity_logs", "data": {"id": "b37e608e-1ad3-419d-ac43-c81563375c92", "event": "subscribe", "data": "{\"item_id\":3555407785,\"item_name\":\"Inventory management\",\"item_type\":\"Board\",\"subscribed_id\":36694549,\"board_id\":3555407785,\"pulse_id\":null}", "entity": "pulse", "created_at": "16690414102238280", "created_at_int": 1669041410}, "emitted_at": 1689087830519} +{"stream": "activity_logs", "data": {"id": "86c334bf-e205-429b-8672-96bd23285237", "event": "create_column", "data": "{\"board_id\":3555407785,\"column_id\":\"date_given_to_current_owner\",\"column_title\":\"Last checked\",\"column_type\":\"date\"}", "entity": "board", "created_at": "16690414098345902", "created_at_int": 1669041409, "board_id": 3555407785}, "emitted_at": 1689087830522} +{"stream": "activity_logs", "data": {"id": "1aee1747-0578-48d2-8399-6ca5d8e32588", "event": "create_column", "data": "{\"board_id\":3555407785,\"column_id\":\"text\",\"column_title\":\"Current owner\",\"column_type\":\"text\"}", "entity": "board", "created_at": "16690414098320604", "created_at_int": 1669041409, "board_id": 3555407785}, "emitted_at": 1689087830524} +{"stream": "activity_logs", "data": {"id": "a2143b7f-43bb-4f1f-aacd-23ece0907388", "event": "create_column", "data": "{\"board_id\":3555407785,\"column_id\":\"date4\",\"column_title\":\"Date given to current owner\",\"column_type\":\"date\"}", "entity": "board", "created_at": "16690414098297238", "created_at_int": 1669041409, "board_id": 3555407785}, "emitted_at": 1689087830525} +{"stream": "activity_logs", "data": {"id": "a3424deb-0b8f-467b-bb49-e0003a5eb4ec", "event": "create_column", "data": "{\"board_id\":3555407785,\"column_id\":\"status\",\"column_title\":\"Status\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414098273392", "created_at_int": 1669041409, "board_id": 3555407785}, "emitted_at": 1689087830527} +{"stream": "activity_logs", "data": {"id": "277359f1-1521-4a98-8e55-f8bff9092603", "event": "create_column", "data": "{\"board_id\":3555407785,\"column_id\":\"text4\",\"column_title\":\"SN\",\"column_type\":\"text\"}", "entity": "board", "created_at": "16690414098249162", "created_at_int": 1669041409, "board_id": 3555407785}, "emitted_at": 1689087830529} +{"stream": "activity_logs", "data": {"id": "06cd74dc-3a68-4bad-813d-8e2712035e34", "event": "create_column", "data": "{\"board_id\":3555407785,\"column_id\":\"name\",\"column_title\":\"Name\",\"column_type\":\"name\"}", "entity": "board", "created_at": "16690414098224872", "created_at_int": 1669041409, "board_id": 3555407785}, "emitted_at": 1689087830531} +{"stream": "activity_logs", "data": {"id": "08ad38f6-edeb-494d-86ff-3cf19ced2abd", "event": "create_group", "data": "{\"board_id\":3555407785,\"group_id\":\"new_group\",\"group_title\":\"TVs \\u0026 projectors\",\"group_color\":\"#037f4c\"}", "entity": "board", "created_at": "16690414098200262", "created_at_int": 1669041409, "board_id": 3555407785}, "emitted_at": 1689087830532} +{"stream": "activity_logs", "data": {"id": "f607c697-85da-4301-8013-7aa4894a9ecb", "event": "create_group", "data": "{\"board_id\":3555407785,\"group_id\":\"group_title\",\"group_title\":\"Monitors\",\"group_color\":\"#a25ddc\"}", "entity": "board", "created_at": "16690414098175690", "created_at_int": 1669041409, "board_id": 3555407785}, "emitted_at": 1689087830534} +{"stream": "activity_logs", "data": {"id": "39cc228d-9e4d-42e9-9928-8063f9e4b139", "event": "create_group", "data": "{\"board_id\":3555407785,\"group_id\":\"topics\",\"group_title\":\"Laptops\",\"group_color\":\"#579bfc\"}", "entity": "board", "created_at": "16690414098150552", "created_at_int": 1669041409, "board_id": 3555407785}, "emitted_at": 1689087830536} +{"stream": "activity_logs", "data": {"id": "1bfb9052-e49d-4268-bd02-5816627111a1", "event": "create_group", "data": "{\"board_id\":3555407785,\"group_id\":\"duplicate_of_tvs___projectors\",\"group_title\":\"Out of service\",\"group_color\":\"#BB3354\"}", "entity": "board", "created_at": "16690414098122328", "created_at_int": 1669041409, "board_id": 3555407785}, "emitted_at": 1689087830538} +{"stream": "activity_logs", "data": {"id": "cbafe665-dfda-4559-b26b-47cc9883685a", "event": "subscribe", "data": "{\"item_id\":3555407698,\"item_name\":\"IT Onboarding\",\"item_type\":\"Board\",\"subscribed_id\":36694549,\"board_id\":3555407698,\"pulse_id\":null}", "entity": "pulse", "created_at": "16690414095113132", "created_at_int": 1669041409}, "emitted_at": 1689087831026} +{"stream": "activity_logs", "data": {"id": "1f99a359-26f1-4592-b6af-cc0713719cd1", "event": "update_board_nickname", "data": "{\"board_id\":3555407698,\"board_name\":\"IT Onboarding\",\"value\":{\"preset_type\":\"employee\",\"singular\":\"board.pulse_nickname.dialog.presets.employee\",\"plural\":\"board.pulse_nickname.dialog.presets.employee_plural\"},\"previous_value\":null}", "entity": "board", "created_at": "16690414087437572", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831030} +{"stream": "activity_logs", "data": {"id": "24de98cf-da30-4f29-95b8-ab825d3da2d0", "event": "create_column", "data": "{\"board_id\":3555407698,\"column_id\":\"email\",\"column_title\":\"Email\",\"column_type\":\"email\"}", "entity": "board", "created_at": "16690414087407810", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831033} +{"stream": "activity_logs", "data": {"id": "c98ae5a8-32a7-4fef-9694-90be20051f6d", "event": "create_column", "data": "{\"board_id\":3555407698,\"column_id\":\"set_up_desk_monitor\",\"column_title\":\"Setup entrance tag\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414087380132", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831035} +{"stream": "activity_logs", "data": {"id": "27750b1e-e8f0-49ca-920d-e8cb869e7b59", "event": "create_column", "data": "{\"board_id\":3555407698,\"column_id\":\"365_account3\",\"column_title\":\"Setup desk monitor\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414087351162", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831037} +{"stream": "activity_logs", "data": {"id": "e722eeb6-04cd-40c8-bdf0-06b2c38c6cfd", "event": "create_column", "data": "{\"board_id\":3555407698,\"column_id\":\"zoom_account\",\"column_title\":\"365 account\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414087322888", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831038} +{"stream": "activity_logs", "data": {"id": "0acef444-cabe-494f-b70d-86418d06cbee", "event": "create_column", "data": "{\"board_id\":3555407698,\"column_id\":\"google_account\",\"column_title\":\"Zoom account\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414087293968", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831040} +{"stream": "activity_logs", "data": {"id": "11c70677-9a51-467c-b543-4e07922a1ecf", "event": "create_column", "data": "{\"board_id\":3555407698,\"column_id\":\"computer_setup\",\"column_title\":\"Google account\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414087262244", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831042} +{"stream": "activity_logs", "data": {"id": "6c27335b-4c65-45ec-9f21-a30bc51f4d0a", "event": "create_column", "data": "{\"board_id\":3555407698,\"column_id\":\"status2\",\"column_title\":\"Computer setup\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414087233188", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831044} +{"stream": "activity_logs", "data": {"id": "7aad4fe3-f18c-4de1-b11e-16de267c1548", "event": "create_column", "data": "{\"board_id\":3555407698,\"column_id\":\"status1\",\"column_title\":\"Computer type\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414087205434", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831046} +{"stream": "activity_logs", "data": {"id": "89628e50-7417-48f0-979d-044e1268c8dd", "event": "create_column", "data": "{\"board_id\":3555407698,\"column_id\":\"status8\",\"column_title\":\"Site\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414087175462", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831047} +{"stream": "activity_logs", "data": {"id": "54fd6a10-aa8f-4518-9df2-6e2e4458317c", "event": "create_column", "data": "{\"board_id\":3555407698,\"column_id\":\"status\",\"column_title\":\"Team\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690414087144112", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831049} +{"stream": "activity_logs", "data": {"id": "e0ae7c29-7d89-4abf-be2c-36f3936ea372", "event": "create_column", "data": "{\"board_id\":3555407698,\"column_id\":\"date4\",\"column_title\":\"Start date\",\"column_type\":\"date\"}", "entity": "board", "created_at": "16690414087116638", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831051} +{"stream": "activity_logs", "data": {"id": "de8f386d-db1c-4f63-8424-eb3e9f08ed3a", "event": "create_column", "data": "{\"board_id\":3555407698,\"column_id\":\"person\",\"column_title\":\"Responsible HR\",\"column_type\":\"multiple-person\"}", "entity": "board", "created_at": "16690414087088414", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831053} +{"stream": "activity_logs", "data": {"id": "f6184f83-c980-4d95-b582-e0cc4f065cb5", "event": "create_column", "data": "{\"board_id\":3555407698,\"column_id\":\"people\",\"column_title\":\"IT owner\",\"column_type\":\"multiple-person\"}", "entity": "board", "created_at": "16690414087061538", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831055} +{"stream": "activity_logs", "data": {"id": "1c709c22-36c3-4356-85ff-f37ab276967e", "event": "create_column", "data": "{\"board_id\":3555407698,\"column_id\":\"name\",\"column_title\":\"Name\",\"column_type\":\"name\"}", "entity": "board", "created_at": "16690414087035184", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831056} +{"stream": "activity_logs", "data": {"id": "9f1fa640-cb69-4f5e-bd68-19ad1d51ad5b", "event": "create_group", "data": "{\"board_id\":3555407698,\"group_id\":\"duplicate_of_new_hires___6_25_\",\"group_title\":\"New Hires - April\",\"group_color\":\"#037f4c\"}", "entity": "board", "created_at": "16690414087007542", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831058} +{"stream": "activity_logs", "data": {"id": "9f599a51-4e80-4573-8dac-070e20fb4d21", "event": "create_group", "data": "{\"board_id\":3555407698,\"group_id\":\"group_title\",\"group_title\":\"New Hires - May\",\"group_color\":\"#a25ddc\"}", "entity": "board", "created_at": "16690414086979086", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831060} +{"stream": "activity_logs", "data": {"id": "23891540-3325-4322-b8f8-d256343d32f3", "event": "create_group", "data": "{\"board_id\":3555407698,\"group_id\":\"topics\",\"group_title\":\"New Hires - June\",\"group_color\":\"#579bfc\"}", "entity": "board", "created_at": "16690414086948430", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831062} +{"stream": "activity_logs", "data": {"id": "a21a6dff-af5e-4028-ae3f-e990d2139a4c", "event": "create_group", "data": "{\"board_id\":3555407698,\"group_id\":\"new_group\",\"group_title\":\"More information about this template:\",\"group_color\":\"#FF642E\"}", "entity": "board", "created_at": "16690414086918896", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831064} +{"stream": "activity_logs", "data": {"id": "55985e18-5569-4873-a58b-b3c8f91b3fe7", "event": "create_group", "data": "{\"board_id\":3555407698,\"group_id\":\"airbyte_group\",\"group_title\":\"Airbyte group\",\"group_color\":\"#a25ddc\"}", "entity": "board", "created_at": "16690414086890028", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831065} +{"stream": "activity_logs", "data": {"id": "baa3167b-4165-4db0-ac8e-4178fbcaddbe", "event": "create_group", "data": "{\"board_id\":3555407698,\"group_id\":\"airbyte_group27398\",\"group_title\":\"Airbyte group\",\"group_color\":\"#037f4c\"}", "entity": "board", "created_at": "16690414086785652", "created_at_int": 1669041408, "board_id": 3555407698}, "emitted_at": 1689087831067} +{"stream": "activity_logs", "data": {"id": "c37fa137-938c-47b8-9d33-981c1f7df001", "event": "update_column_value", "data": "{\"board_id\":3555179105,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":3555437747,\"pulse_name\":\"Test1\",\"column_id\":\"text\",\"column_type\":\"text\",\"column_title\":\"Text\",\"value\":{\"value\":\"one two three #!!\"},\"previous_value\":null,\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16690417295453992", "created_at_int": 1669041729, "pulse_id": 3555437747}, "emitted_at": 1689087831454} +{"stream": "activity_logs", "data": {"id": "37ef0368-66e1-4bac-9b66-7753eb948371", "event": "update_column_value", "data": "{\"board_id\":3555179105,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":3555433784,\"pulse_name\":\"Test\",\"column_id\":\"text\",\"column_type\":\"text\",\"column_title\":\"Text\",\"value\":{\"value\":\"Test test test\"},\"previous_value\":null,\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16690417210472122", "created_at_int": 1669041721, "pulse_id": 3555433784}, "emitted_at": 1689087831459} +{"stream": "activity_logs", "data": {"id": "fe27419e-89ba-463a-b007-546f2b411b86", "event": "create_column", "data": "{\"board_id\":3555179105,\"column_id\":\"text\",\"column_title\":\"Text\",\"column_type\":\"text\"}", "entity": "board", "created_at": "16690417141438454", "created_at_int": 1669041714, "board_id": 3555179105}, "emitted_at": 1689087831462} +{"stream": "activity_logs", "data": {"id": "ce94188f-993c-4afd-aa94-55efd3ac8cad", "event": "update_column_value", "data": "{\"board_id\":3555179105,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":3555433784,\"pulse_name\":\"Test\",\"column_id\":\"label\",\"column_type\":\"color\",\"column_title\":\"Label\",\"value\":{\"label\":{\"index\":156,\"text\":\"Label 3\",\"style\":{\"color\":\"#9D99B9\",\"border\":\"#9D99B9\",\"var_name\":\"purple_gray\"},\"is_done\":false},\"post_id\":null},\"previous_value\":null,\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16690417121262068", "created_at_int": 1669041712, "pulse_id": 3555433784}, "emitted_at": 1689087831464} +{"stream": "activity_logs", "data": {"id": "28aa0dbf-70bc-47c1-8f68-eb7f9d89d19f", "event": "update_column_value", "data": "{\"board_id\":3555179105,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":3555437747,\"pulse_name\":\"Test1\",\"column_id\":\"label\",\"column_type\":\"color\",\"column_title\":\"Label\",\"value\":{\"label\":{\"index\":105,\"text\":\"Label 1\",\"style\":{\"color\":\"#9AADBD\",\"border\":\"#9AADBD\",\"var_name\":\"winter\"},\"is_done\":false},\"post_id\":null},\"previous_value\":null,\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16690417094137812", "created_at_int": 1669041709, "pulse_id": 3555437747}, "emitted_at": 1689087831466} +{"stream": "activity_logs", "data": {"id": "8cb1ab93-9e33-4c0f-992c-ded5ab382a83", "event": "create_column", "data": "{\"board_id\":3555179105,\"column_id\":\"label\",\"column_title\":\"Label\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690417055374810", "created_at_int": 1669041705, "board_id": 3555179105}, "emitted_at": 1689087831468} +{"stream": "activity_logs", "data": {"id": "d5c00cb7-9c73-425f-8bf7-09ffc59e03b4", "event": "update_column_value", "data": "{\"board_id\":3555179105,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":3555437747,\"pulse_name\":\"Test1\",\"column_id\":\"status\",\"column_type\":\"color\",\"column_title\":\"Status\",\"value\":{\"label\":{\"index\":0,\"text\":\"Working on it\",\"style\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"is_done\":false},\"post_id\":null},\"previous_value\":null,\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16690416981876072", "created_at_int": 1669041698, "pulse_id": 3555437747}, "emitted_at": 1689087831470} +{"stream": "activity_logs", "data": {"id": "8d2e61cb-be5f-42f5-b3f0-1962498c7a38", "event": "create_pulse", "data": "{\"board_id\":3555179105,\"group_id\":\"topics\",\"group_name\":\"Subitems\",\"group_color\":\"#579bfc\",\"is_top_group\":true,\"pulse_id\":3555437747,\"pulse_name\":\"Test1\",\"column_values_json\":\"{}\"}", "entity": "pulse", "created_at": "16690416734286556", "created_at_int": 1669041673, "pulse_id": 3555437747}, "emitted_at": 1689087831472} +{"stream": "activity_logs", "data": {"id": "c4549cd8-52cb-4482-8e39-c6f9a7e21f8f", "event": "update_column_value", "data": "{\"board_id\":3555179105,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":3555433784,\"pulse_name\":\"Test\",\"column_id\":\"status\",\"column_type\":\"color\",\"column_title\":\"Status\",\"value\":{\"label\":{\"index\":1,\"text\":\"Done\",\"style\":{\"color\":\"#00c875\",\"border\":\"#00B461\",\"var_name\":\"green-shadow\"},\"is_done\":true},\"post_id\":null},\"previous_value\":null,\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16690416644924402", "created_at_int": 1669041664, "pulse_id": 3555433784}, "emitted_at": 1689087831474} +{"stream": "activity_logs", "data": {"id": "77aa124b-b315-48dc-ae84-45e0441f488b", "event": "create_column", "data": "{\"board_id\":3555179105,\"column_id\":\"status\",\"column_title\":\"Status\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690416615994976", "created_at_int": 1669041661, "board_id": 3555179105}, "emitted_at": 1689087831475} +{"stream": "activity_logs", "data": {"id": "714f0ede-5a8f-40a1-9efc-8d2f64ca9d57", "event": "update_column_value", "data": "{\"board_id\":3555179105,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":3555433784,\"pulse_name\":\"Test\",\"column_id\":\"link\",\"column_type\":\"link\",\"column_title\":\"Link\",\"value\":{\"url\":\"https://airbyte.com/\",\"text\":\"Airbyte\",\"changed_at\":\"2022-11-21T14:40:42.184Z\",\"column_settings\":{}},\"previous_value\":{\"url\":\"https://airbyte.com\",\"text\":\"Airbyte\",\"changed_at\":\"2022-11-21T14:40:42.146Z\",\"column_settings\":{}},\"is_column_with_hide_permissions\":false,\"textual_value\":\"Airbyte - https://airbyte.com/\",\"previous_textual_value\":\"Airbyte - https://airbyte.com\"}", "entity": "pulse", "created_at": "16690416488048398", "created_at_int": 1669041648, "pulse_id": 3555433784}, "emitted_at": 1689087831477} +{"stream": "activity_logs", "data": {"id": "6f42329e-dd32-4be8-a986-7088b1e40286", "event": "update_column_value", "data": "{\"board_id\":3555179105,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":3555433784,\"pulse_name\":\"Test\",\"column_id\":\"link\",\"column_type\":\"link\",\"column_title\":\"Link\",\"value\":{\"url\":\"https://airbyte.com\",\"text\":\"Airbyte\",\"changed_at\":\"2022-11-21T14:40:42.146Z\",\"column_settings\":{}},\"previous_value\":{\"column_settings\":{}},\"is_column_with_hide_permissions\":false,\"textual_value\":\"Airbyte - https://airbyte.com\"}", "entity": "pulse", "created_at": "16690416480281686", "created_at_int": 1669041648, "pulse_id": 3555433784}, "emitted_at": 1689087831479} +{"stream": "activity_logs", "data": {"id": "fa142697-12d9-4c3f-b5c9-90f63a9c064b", "event": "create_pulse", "data": "{\"board_id\":3555179105,\"group_id\":\"topics\",\"group_name\":\"Subitems\",\"group_color\":\"#579bfc\",\"is_top_group\":true,\"pulse_id\":3555433784,\"pulse_name\":\"Test\",\"column_values_json\":\"{}\"}", "entity": "pulse", "created_at": "16690416349394782", "created_at_int": 1669041634, "pulse_id": 3555433784}, "emitted_at": 1689087831481} +{"stream": "activity_logs", "data": {"id": "bdb104e4-8c66-4ac4-a6bd-701b125b9118", "event": "create_column", "data": "{\"board_id\":3555179105,\"column_id\":\"link\",\"column_title\":\"Link\",\"column_type\":\"link\"}", "entity": "board", "created_at": "16690394779159986", "created_at_int": 1669039477, "board_id": 3555179105}, "emitted_at": 1689087831483} +{"stream": "activity_logs", "data": {"id": "2b32699e-6cea-45e5-b458-1b9725b2a1e1", "event": "create_column", "data": "{\"board_id\":3555179105,\"column_id\":\"name\",\"column_title\":\"Name\",\"column_type\":\"name\"}", "entity": "board", "created_at": "16690394779138288", "created_at_int": 1669039477, "board_id": 3555179105}, "emitted_at": 1689087831484} +{"stream": "activity_logs", "data": {"id": "809173b0-2840-4471-9ab9-393fd5eea948", "event": "create_group", "data": "{\"board_id\":3555179105,\"group_id\":\"topics\",\"group_title\":\"Subitems\",\"group_color\":\"#579bfc\"}", "entity": "board", "created_at": "16690394779114812", "created_at_int": 1669039477, "board_id": 3555179105}, "emitted_at": 1689087831486} +{"stream": "activity_logs", "data": {"id": "0d654f86-e1af-4fbc-9d4d-9fe47b82fdc5", "event": "update_column_value", "data": "{\"board_id\":3555179067,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":3555448801,\"pulse_name\":\"Item 2\",\"column_id\":\"text\",\"column_type\":\"text\",\"column_title\":\"My notes\",\"value\":{\"value\":\"Note 2\"},\"previous_value\":null,\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16690417789460866", "created_at_int": 1669041778, "pulse_id": 3555448801}, "emitted_at": 1689087831996} +{"stream": "activity_logs", "data": {"id": "9eeeb2b7-61ba-48ea-b9c6-ae969d7043ec", "event": "update_column_value", "data": "{\"board_id\":3555179067,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":3555448801,\"pulse_name\":\"Item 2\",\"column_id\":\"status_10\",\"column_type\":\"color\",\"column_title\":\"Type\",\"value\":{\"label\":{\"index\":0,\"text\":\"Article\",\"style\":{\"color\":\"#66CCFF\",\"border\":\"#5AB3E0\",\"var_name\":\"turquoise\"},\"is_done\":false},\"post_id\":null},\"previous_value\":null,\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16690417732029724", "created_at_int": 1669041773, "pulse_id": 3555448801}, "emitted_at": 1689087832000} +{"stream": "activity_logs", "data": {"id": "1488895a-7a73-4dc6-a30d-259eda2f87bd", "event": "update_column_value", "data": "{\"board_id\":3555179067,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":3555448801,\"pulse_name\":\"Item 2\",\"column_id\":\"status_1\",\"column_type\":\"color\",\"column_title\":\"Status\",\"value\":{\"label\":{\"index\":2,\"text\":\"Stuck\",\"style\":{\"color\":\"#e2445c\",\"border\":\"#CE3048\",\"var_name\":\"red-shadow\"},\"is_done\":false},\"post_id\":null},\"previous_value\":null,\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16690417710699428", "created_at_int": 1669041771, "pulse_id": 3555448801}, "emitted_at": 1689087832003} +{"stream": "activity_logs", "data": {"id": "26212ac8-4856-44b8-b309-397f111f0893", "event": "create_pulse", "data": "{\"board_id\":3555179067,\"group_id\":\"topics\",\"group_name\":\"Get to know monday.com\",\"group_color\":\"#579bfc\",\"is_top_group\":true,\"pulse_id\":3555448801,\"pulse_name\":\"Item 2\",\"column_values_json\":\"{}\"}", "entity": "pulse", "created_at": "16690417684086152", "created_at_int": 1669041768, "pulse_id": 3555448801}, "emitted_at": 1689087832005} +{"stream": "activity_logs", "data": {"id": "6b4ef75e-a4a5-4164-a3d6-7a2590e7c19d", "event": "update_column_value", "data": "{\"board_id\":3555179067,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":3555446655,\"pulse_name\":\"Item 1\",\"column_id\":\"text\",\"column_type\":\"text\",\"column_title\":\"My notes\",\"value\":{\"value\":\"Notes\"},\"previous_value\":null,\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16690417626227754", "created_at_int": 1669041762, "pulse_id": 3555446655}, "emitted_at": 1689087832007} +{"stream": "activity_logs", "data": {"id": "cc53a4e2-95be-44ed-acf8-bb62dad79319", "event": "update_column_value", "data": "{\"board_id\":3555179067,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":3555446655,\"pulse_name\":\"Item 1\",\"column_id\":\"status_10\",\"column_type\":\"color\",\"column_title\":\"Type\",\"value\":{\"label\":{\"index\":1,\"text\":\"Documentation\",\"style\":{\"color\":\"#175A63\",\"border\":\"#175A63\",\"var_name\":\"eden\"},\"is_done\":true},\"post_id\":null},\"previous_value\":null,\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16690417570437866", "created_at_int": 1669041757, "pulse_id": 3555446655}, "emitted_at": 1689087832009} +{"stream": "activity_logs", "data": {"id": "b3fae470-407c-4fba-8f7b-439b13e91a08", "event": "update_column_value", "data": "{\"board_id\":3555179067,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":3555446655,\"pulse_name\":\"Item 1\",\"column_id\":\"status_1\",\"column_type\":\"color\",\"column_title\":\"Status\",\"value\":{\"label\":{\"index\":0,\"text\":\"Working on it\",\"style\":{\"color\":\"#fdab3d\",\"border\":\"#E99729\",\"var_name\":\"orange\"},\"is_done\":false},\"post_id\":null},\"previous_value\":null,\"is_column_with_hide_permissions\":false}", "entity": "pulse", "created_at": "16690417549303576", "created_at_int": 1669041754, "pulse_id": 3555446655}, "emitted_at": 1689087832011} +{"stream": "activity_logs", "data": {"id": "7f1b497a-fc86-48e7-a5b7-06c573910116", "event": "create_pulse", "data": "{\"board_id\":3555179067,\"group_id\":\"topics\",\"group_name\":\"Get to know monday.com\",\"group_color\":\"#579bfc\",\"is_top_group\":true,\"pulse_id\":3555446655,\"pulse_name\":\"Item 1\",\"column_values_json\":\"{}\"}", "entity": "pulse", "created_at": "16690417499525056", "created_at_int": 1669041749, "pulse_id": 3555446655}, "emitted_at": 1689087832012} +{"stream": "activity_logs", "data": {"id": "9a2b1f31-ea18-4f04-b376-2ab004a9bea7", "event": "update_column_value", "data": "{\"board_id\":3555179067,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":3555179351,\"pulse_name\":\"Click to read this update \ud83e\udd29\",\"column_id\":\"subitems\",\"column_type\":\"subtasks\",\"column_title\":\"Subitems\",\"value\":{\"linkedPulseIds\":[{\"linkedPulseId\":3555433784},{\"linkedPulseId\":3555437747}],\"column_settings\":{\"displayType\":\"BOARD_INLINE\",\"itemTypeName\":\"column.subtasks.title\",\"allowMultipleItems\":true,\"boardIds\":[3555179105]}},\"previous_value\":{\"linkedPulseIds\":[{\"linkedPulseId\":3555433784}],\"column_settings\":{\"displayType\":\"BOARD_INLINE\",\"itemTypeName\":\"column.subtasks.title\",\"allowMultipleItems\":true,\"boardIds\":[3555179105]}},\"is_column_with_hide_permissions\":false,\"textual_value\":\"Test, Test1\",\"previous_textual_value\":\"Test\"}", "entity": "pulse", "created_at": "16690416732198970", "created_at_int": 1669041673, "pulse_id": 3555179351}, "emitted_at": 1689087832014} +{"stream": "activity_logs", "data": {"id": "5cdc92bf-20bb-4d05-9f67-f9f25beae0a9", "event": "update_column_value", "data": "{\"board_id\":3555179067,\"group_id\":\"topics\",\"is_top_group\":true,\"pulse_id\":3555179351,\"pulse_name\":\"Click to read this update \ud83e\udd29\",\"column_id\":\"subitems\",\"column_type\":\"subtasks\",\"column_title\":\"Subitems\",\"value\":{\"linkedPulseIds\":[{\"linkedPulseId\":3555433784}],\"column_settings\":{\"displayType\":\"BOARD_INLINE\",\"itemTypeName\":\"column.subtasks.title\",\"allowMultipleItems\":true,\"boardIds\":[3555179105]}},\"previous_value\":{\"column_settings\":{\"displayType\":\"BOARD_INLINE\",\"itemTypeName\":\"column.subtasks.title\",\"allowMultipleItems\":true,\"boardIds\":[3555179105]}},\"is_column_with_hide_permissions\":false,\"textual_value\":\"Test\"}", "entity": "pulse", "created_at": "16690416348402954", "created_at_int": 1669041634, "pulse_id": 3555179351}, "emitted_at": 1689087832016} +{"stream": "activity_logs", "data": {"id": "f1d67e7d-2c57-4b1c-ad44-441a61db9444", "event": "update_column_value", "data": "{\"board_id\":3555179067,\"group_id\":\"group_title\",\"is_top_group\":false,\"pulse_id\":3555179341,\"pulse_name\":\"Sessions recordings - See the framework in action (Subitems)\",\"column_id\":\"subitems\",\"column_type\":\"subtasks\",\"column_title\":\"Subitems\",\"value\":{\"linkedPulseIds\":[{\"linkedPulseId\":3555179394},{\"linkedPulseId\":3555179405},{\"linkedPulseId\":3555179418},{\"linkedPulseId\":3555179422},{\"linkedPulseId\":3555179431}],\"column_settings\":{\"displayType\":\"BOARD_INLINE\",\"itemTypeName\":\"column.subtasks.title\",\"allowMultipleItems\":true,\"boardIds\":[3555179105]}},\"previous_value\":{\"column_settings\":{\"displayType\":\"BOARD_INLINE\",\"itemTypeName\":\"column.subtasks.title\",\"allowMultipleItems\":true,\"boardIds\":[3555179105]}},\"is_column_with_hide_permissions\":false,\"textual_value\":\"API session, Build a view, Build an integration, Authentication, Build a Workspace template\"}", "entity": "pulse", "created_at": "16690394833961048", "created_at_int": 1669039483, "pulse_id": 3555179341}, "emitted_at": 1689087832018} +{"stream": "activity_logs", "data": {"id": "e7942b81-4c44-45d5-818d-60185c294706", "event": "create_column", "data": "{\"board_id\":3555179067,\"column_id\":\"status_10\",\"column_title\":\"Type\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690394773396428", "created_at_int": 1669039477, "board_id": 3555179067}, "emitted_at": 1689087832020} +{"stream": "activity_logs", "data": {"id": "cc4786a5-9e3c-4564-a68b-b74c5be5865e", "event": "create_column", "data": "{\"board_id\":3555179067,\"column_id\":\"status_1\",\"column_title\":\"Status\",\"column_type\":\"color\"}", "entity": "board", "created_at": "16690394773376320", "created_at_int": 1669039477, "board_id": 3555179067}, "emitted_at": 1689087832022} +{"stream": "activity_logs", "data": {"id": "2ecd3acc-3390-4d57-adcc-e0bdefcb1a74", "event": "create_column", "data": "{\"board_id\":3555179067,\"column_id\":\"text\",\"column_title\":\"My notes\",\"column_type\":\"text\"}", "entity": "board", "created_at": "16690394773357172", "created_at_int": 1669039477, "board_id": 3555179067}, "emitted_at": 1689087832023} +{"stream": "activity_logs", "data": {"id": "0f4e9af4-34eb-4fa8-9dc7-a9557f346a1b", "event": "create_column", "data": "{\"board_id\":3555179067,\"column_id\":\"link\",\"column_title\":\"Link\",\"column_type\":\"link\"}", "entity": "board", "created_at": "16690394773338136", "created_at_int": 1669039477, "board_id": 3555179067}, "emitted_at": 1689087832025} +{"stream": "activity_logs", "data": {"id": "570944f2-44ff-4b0a-8522-3a9f1127505f", "event": "create_column", "data": "{\"board_id\":3555179067,\"column_id\":\"subitems\",\"column_title\":\"Subitems\",\"column_type\":\"subtasks\"}", "entity": "board", "created_at": "16690394773318598", "created_at_int": 1669039477, "board_id": 3555179067}, "emitted_at": 1689087832027} +{"stream": "activity_logs", "data": {"id": "fb75e772-f5ef-4a41-8d09-29db09e939cc", "event": "create_column", "data": "{\"board_id\":3555179067,\"column_id\":\"name\",\"column_title\":\"Name\",\"column_type\":\"name\"}", "entity": "board", "created_at": "16690394773296104", "created_at_int": 1669039477, "board_id": 3555179067}, "emitted_at": 1689087832029} +{"stream": "activity_logs", "data": {"id": "2b6d0e92-f71d-4f26-a15c-53771c5d1636", "event": "create_group", "data": "{\"board_id\":3555179067,\"group_id\":\"new_group\",\"group_title\":\"Helpful resources\",\"group_color\":\"#0086c0\"}", "entity": "board", "created_at": "16690394773271470", "created_at_int": 1669039477, "board_id": 3555179067}, "emitted_at": 1689087832031} +{"stream": "activity_logs", "data": {"id": "0fb4fa76-2f7b-4f96-9b0e-15530ff668f3", "event": "create_group", "data": "{\"board_id\":3555179067,\"group_id\":\"new_group45036\",\"group_title\":\"Prepare for app submission\",\"group_color\":\"#fdab3d\"}", "entity": "board", "created_at": "16690394773248500", "created_at_int": 1669039477, "board_id": 3555179067}, "emitted_at": 1689087832032} +{"stream": "activity_logs", "data": {"id": "f4edd2cd-d1ed-42a5-9cd1-dfdf1a1b4c4d", "event": "create_group", "data": "{\"board_id\":3555179067,\"group_id\":\"group_title\",\"group_title\":\"Build your monday app\",\"group_color\":\"#a25ddc\"}", "entity": "board", "created_at": "16690394773225340", "created_at_int": 1669039477, "board_id": 3555179067}, "emitted_at": 1689087832034} +{"stream": "activity_logs", "data": {"id": "d38b875b-6001-46d7-bbc7-41be00edaaaf", "event": "create_group", "data": "{\"board_id\":3555179067,\"group_id\":\"new_group37570\",\"group_title\":\"What can be developed on monday.com\",\"group_color\":\"#FF158A\"}", "entity": "board", "created_at": "16690394773203176", "created_at_int": 1669039477, "board_id": 3555179067}, "emitted_at": 1689087832036} +{"stream": "activity_logs", "data": {"id": "10c84b88-768f-4168-8523-337a621269ab", "event": "create_group", "data": "{\"board_id\":3555179067,\"group_id\":\"topics\",\"group_title\":\"Get to know monday.com\",\"group_color\":\"#579bfc\"}", "entity": "board", "created_at": "16690394773090370", "created_at_int": 1669039477, "board_id": 3555179067}, "emitted_at": 1689087832037} +{"stream": "users", "data": {"birthday": null, "country_code": "UA", "created_at": "2022-11-21T14:03:00Z", "join_date": null, "email": "integration-test@airbyte.io", "enabled": true, "id": 36694549, "is_admin": true, "is_guest": false, "is_pending": false, "is_view_only": false, "is_verified": true, "location": null, "mobile_phone": null, "name": "Airbyte Team", "phone": "", "photo_original": "https://files.monday.com/use1/photos/36694549/original/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "photo_small": "https://files.monday.com/use1/photos/36694549/small/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "photo_thumb": "https://files.monday.com/use1/photos/36694549/thumb/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "photo_thumb_small": "https://files.monday.com/use1/photos/36694549/thumb_small/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "photo_tiny": "https://files.monday.com/use1/photos/36694549/tiny/36694549-user_photo_2022_11_21_14_10_42.png?1669039842", "time_zone_identifier": "Europe/Kiev", "title": "Airbyte Developer Account", "url": "https://airbyte-unit.monday.com/users/36694549", "utc_hours_diff": 3}, "emitted_at": 1689087827509} +{"stream": "users", "data": {"birthday": null, "country_code": "UA", "created_at": "2022-11-21T14:33:18Z", "join_date": null, "email": "iryna.grankova@airbyte.io", "enabled": true, "id": 36695702, "is_admin": false, "is_guest": false, "is_pending": false, "is_view_only": false, "is_verified": true, "location": null, "mobile_phone": null, "name": "Iryna Grankova", "phone": null, "photo_original": "https://files.monday.com/use1/photos/36695702/original/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "photo_small": "https://files.monday.com/use1/photos/36695702/small/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "photo_thumb": "https://files.monday.com/use1/photos/36695702/thumb/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "photo_thumb_small": "https://files.monday.com/use1/photos/36695702/thumb_small/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "photo_tiny": "https://files.monday.com/use1/photos/36695702/tiny/36695702-user_photo_initials_2022_11_21_14_34_12.png?1669041252", "time_zone_identifier": "Europe/Athens", "title": null, "url": "https://airbyte-unit.monday.com/users/36695702", "utc_hours_diff": 3}, "emitted_at": 1689087827510} diff --git a/airbyte-integrations/connectors/source-monday/integration_tests/incremental_catalog.json b/airbyte-integrations/connectors/source-monday/integration_tests/incremental_catalog.json new file mode 100644 index 000000000000..dbe78bcc0d69 --- /dev/null +++ b/airbyte-integrations/connectors/source-monday/integration_tests/incremental_catalog.json @@ -0,0 +1,46 @@ +{ + "streams": [ + { + "stream": { + "name": "activity_logs", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["created_at_int"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["created_at_int"], + "destination_sync_mode": "overwrite", + "primary_key": [["id"]] + }, + { + "stream": { + "name": "items", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated_at_int"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["updated_at_int"], + "destination_sync_mode": "overwrite", + "primary_key": [["id"]] + }, + { + "stream": { + "name": "boards", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated_at_int"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["updated_at_int"], + "destination_sync_mode": "overwrite", + "primary_key": [["id"]] + } + ] +} diff --git a/airbyte-integrations/connectors/source-monday/integration_tests/sample_state.json b/airbyte-integrations/connectors/source-monday/integration_tests/sample_state.json index 3587e579822d..82269c101ad8 100644 --- a/airbyte-integrations/connectors/source-monday/integration_tests/sample_state.json +++ b/airbyte-integrations/connectors/source-monday/integration_tests/sample_state.json @@ -1,5 +1,41 @@ -{ - "todo-stream-name": { - "todo-field-name": "value" +[ + { + "type" : "STREAM", + "stream" : { + "stream_descriptor" : { + "name" : "items" + }, + "stream_state" : { + "updated_at_int" : 1677263687, + "activity_logs" : { + "created_at_int" : 1677263687 + } + } + } + }, + { + "type" : "STREAM", + "stream" : { + "stream_descriptor" : { + "name" : "boards" + }, + "stream_state" : { + "updated_at_int" : 1677263687, + "activity_logs" : { + "created_at_int" : 1677263687 + } + } + } + }, + { + "type" : "STREAM", + "stream" : { + "stream_descriptor" : { + "name" : "activity_logs" + }, + "stream_state" : { + "created_at_int" : 1677263687 + } + } } -} +] diff --git a/airbyte-integrations/connectors/source-monday/metadata.yaml b/airbyte-integrations/connectors/source-monday/metadata.yaml index 1ec5b8c5b059..3ef85d77a343 100644 --- a/airbyte-integrations/connectors/source-monday/metadata.yaml +++ b/airbyte-integrations/connectors/source-monday/metadata.yaml @@ -5,7 +5,7 @@ data: connectorSubtype: api connectorType: source definitionId: 80a54ea2-9959-4040-aac1-eee42423ec9b - dockerImageTag: 1.0.0 + dockerImageTag: 1.1.0 dockerRepository: airbyte/source-monday githubIssueLabel: source-monday icon: monday.svg diff --git a/airbyte-integrations/connectors/source-monday/setup.py b/airbyte-integrations/connectors/source-monday/setup.py index 4d2beea9a22c..ceb655af425c 100644 --- a/airbyte-integrations/connectors/source-monday/setup.py +++ b/airbyte-integrations/connectors/source-monday/setup.py @@ -6,7 +6,7 @@ from setuptools import find_packages, setup MAIN_REQUIREMENTS = [ - "airbyte-cdk", + "airbyte-cdk>=0.44.1", ] TEST_REQUIREMENTS = [ diff --git a/airbyte-integrations/connectors/source-monday/source_monday/components.py b/airbyte-integrations/connectors/source-monday/source_monday/components.py new file mode 100644 index 000000000000..fde4f2f3b958 --- /dev/null +++ b/airbyte-integrations/connectors/source-monday/source_monday/components.py @@ -0,0 +1,217 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +from dataclasses import InitVar, dataclass, field +from typing import Any, Iterable, List, Mapping, Optional, Union + +import dpath.util +from airbyte_cdk.models import AirbyteMessage, SyncMode, Type +from airbyte_cdk.sources.declarative.incremental import Cursor +from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString +from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig +from airbyte_cdk.sources.declarative.requesters.request_option import RequestOptionType +from airbyte_cdk.sources.declarative.types import Config, Record, StreamSlice, StreamState +from airbyte_cdk.sources.streams.core import Stream + +RequestInput = Union[str, Mapping[str, str]] + + +@dataclass +class IncrementalSingleSlice(Cursor): + cursor_field: Union[InterpolatedString, str] + config: Config + parameters: InitVar[Mapping[str, Any]] + + def __post_init__(self, parameters: Mapping[str, Any]): + self._state = {} + self.cursor_field = InterpolatedString.create(self.cursor_field, parameters=parameters) + + def get_request_params( + self, + stream_state: Optional[StreamState] = None, + stream_slice: Optional[StreamSlice] = None, + next_page_token: Optional[Mapping[str, Any]] = None, + ) -> Mapping[str, Any]: + # Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response + return self._get_request_option(RequestOptionType.request_parameter, stream_slice) + + def get_request_headers( + self, + stream_state: Optional[StreamState] = None, + stream_slice: Optional[StreamSlice] = None, + next_page_token: Optional[Mapping[str, Any]] = None, + ) -> Mapping[str, Any]: + # Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response + return self._get_request_option(RequestOptionType.header, stream_slice) + + def get_request_body_data( + self, + stream_state: Optional[StreamState] = None, + stream_slice: Optional[StreamSlice] = None, + next_page_token: Optional[Mapping[str, Any]] = None, + ) -> Mapping[str, Any]: + # Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response + return self._get_request_option(RequestOptionType.body_data, stream_slice) + + def get_request_body_json( + self, + stream_state: Optional[StreamState] = None, + stream_slice: Optional[StreamSlice] = None, + next_page_token: Optional[Mapping[str, Any]] = None, + ) -> Optional[Mapping]: + # Pass the stream_slice from the argument, not the cursor because the cursor is updated after processing the response + return self._get_request_option(RequestOptionType.body_json, stream_slice) + + def _get_request_option(self, option_type: RequestOptionType, stream_slice: StreamSlice): + return {} + + def get_stream_state(self) -> StreamState: + return self._state + + def set_initial_state(self, stream_state: StreamState): + cursor_value = stream_state.get(self.cursor_field.eval(self.config)) + if cursor_value: + self._state[self.cursor_field.eval(self.config)] = cursor_value + + def close_slice(self, stream_slice: StreamSlice, most_recent_record: Optional[Record]) -> None: + latest_record = self._state if self.is_greater_than_or_equal(self._state, most_recent_record) else most_recent_record + + if not latest_record: + return + self._state[self.cursor_field.eval(self.config)] = latest_record[self.cursor_field.eval(self.config)] + + def stream_slices(self) -> Iterable[Mapping[str, Any]]: + yield {} + + def should_be_synced(self, record: Record) -> bool: + """ + As of 2023-06-28, the expectation is that this method will only be used for semi-incremental and data feed and therefore the + implementation is irrelevant for greenhouse + """ + return True + + def is_greater_than_or_equal(self, first: Record, second: Record) -> bool: + """ + Evaluating which record is greater in terms of cursor. This is used to avoid having to capture all the records to close a slice + """ + first_cursor_value = first.get(self.cursor_field.eval(self.config)) if first else None + second_cursor_value = second.get(self.cursor_field.eval(self.config)) if second else None + if first_cursor_value and second_cursor_value: + return first_cursor_value > second_cursor_value + elif first_cursor_value: + return True + else: + return False + + +@dataclass +class IncrementalSubstreamSlicer(IncrementalSingleSlice): + """ + Like SubstreamSlicer, but works incrementaly with both parent and substream. + + Input Arguments: + + :: cursor_field: srt - substream cursor_field value + :: parent_complete_fetch: bool - If `True`, all slices is fetched into a list first, then yield. + If `False`, substream emits records on each parernt slice yield. + :: parent_stream_configs: ParentStreamConfig - Describes how to create a stream slice from a parent stream. + + """ + + config: Config + parameters: InitVar[Mapping[str, Any]] + cursor_field: Union[InterpolatedString, str] + parent_stream_configs: List[ParentStreamConfig] + nested_items_per_page: int + parent_complete_fetch: bool = field(default=False) + + def __post_init__(self, parameters: Mapping[str, Any]): + super().__post_init__(parameters) + if not self.parent_stream_configs: + raise ValueError("IncrementalSubstreamSlicer needs at least 1 parent stream") + self.cursor_field = InterpolatedString.create(self.cursor_field, parameters=parameters) + # parent stream parts + self.parent_config: ParentStreamConfig = self.parent_stream_configs[0] + self.parent_stream: Stream = self.parent_config.stream + self.parent_stream_name: str = self.parent_stream.name + self.parent_cursor_field: str = self.parent_stream.cursor_field + self.parent_sync_mode: SyncMode = SyncMode.incremental if self.parent_stream.supports_incremental is True else SyncMode.full_refresh + self.substream_slice_field: str = self.parent_stream_configs[0].partition_field.eval(self.config) + self.parent_field: str = self.parent_stream_configs[0].parent_key.eval(self.config) + + def set_initial_state(self, stream_state: StreamState): + cursor_value = stream_state.get(self.cursor_field.eval(self.config)) + if cursor_value: + self._state[self.cursor_field.eval(self.config)] = cursor_value + if self.parent_stream_name in stream_state and stream_state.get(self.parent_stream_name, {}).get(self.parent_cursor_field): + self._state[self.parent_stream_name] = { + self.parent_cursor_field: stream_state[self.parent_stream_name][self.parent_cursor_field] + } + + def close_slice(self, stream_slice: StreamSlice, most_recent_record: Optional[Record]) -> None: + latest_record = self._state if self.is_greater_than_or_equal(self._state, most_recent_record) else most_recent_record + + if not latest_record: + return + + max_state = latest_record[self.cursor_field.eval(self.config)] + self._state[self.cursor_field.eval(self.config)] = max_state + + if self.parent_stream: + parent_state = self.parent_stream.state or {self.parent_cursor_field: max_state} + self._state[self.parent_stream_name] = parent_state + + def read_parent_stream( + self, sync_mode: SyncMode, cursor_field: Optional[str], stream_state: Mapping[str, Any] + ) -> Iterable[Mapping[str, Any]]: + self.parent_stream.state = stream_state + + # check if state is empty -> + if not stream_state.get(self.parent_cursor_field): + # yield empty slice for complete fetch of items stream + yield {} + return + + all_ids = set() + slice_ids = list() + empty_parent_slice = True + + for parent_slice in self.parent_stream.stream_slices(sync_mode=sync_mode, cursor_field=cursor_field, stream_state=stream_state): + for parent_record in self.parent_stream.read_records( + sync_mode=sync_mode, cursor_field=cursor_field, stream_slice=parent_slice, stream_state=stream_state + ): + # Skip non-records (eg AirbyteLogMessage) + if isinstance(parent_record, AirbyteMessage): + if parent_record.type == Type.RECORD: + parent_record = parent_record.record.data + + try: + substream_slice = dpath.util.get(parent_record, self.parent_field) + except KeyError: + pass + else: + empty_parent_slice = False + + # check if record with this id was already processed + if substream_slice not in all_ids: + all_ids.add(substream_slice) + slice_ids.append(substream_slice) + + # yield slice with desired number of ids + if self.nested_items_per_page == len(slice_ids): + yield {self.substream_slice_field: slice_ids} + slice_ids = list() + # yield leftover ids if any left + if slice_ids: + yield {self.substream_slice_field: slice_ids} + + # If the parent slice contains no records + if empty_parent_slice: + yield from [] + + def stream_slices(self) -> Iterable[Mapping[str, Any]]: + parent_state = (self._state or {}).get(self.parent_stream_name, {}) + + slices_generator = self.read_parent_stream(self.parent_sync_mode, self.parent_cursor_field, parent_state) + yield from [slice for slice in slices_generator] if self.parent_complete_fetch else slices_generator diff --git a/airbyte-integrations/connectors/source-monday/source_monday/extractor.py b/airbyte-integrations/connectors/source-monday/source_monday/extractor.py new file mode 100644 index 000000000000..4a9a10633da5 --- /dev/null +++ b/airbyte-integrations/connectors/source-monday/source_monday/extractor.py @@ -0,0 +1,105 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import json +from dataclasses import InitVar, dataclass, field +from datetime import datetime +from typing import Any, List, Mapping, Union + +import dpath.util +import requests +from airbyte_cdk.sources.declarative.decoders.decoder import Decoder +from airbyte_cdk.sources.declarative.decoders.json_decoder import JsonDecoder +from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor +from airbyte_cdk.sources.declarative.interpolation.interpolated_string import InterpolatedString +from airbyte_cdk.sources.declarative.types import Config, Record + + +@dataclass +class MondayActivityExtractor(RecordExtractor): + """ + Record extractor that extracts record of the form from activity logs stream: + + { "list": { "ID_1": record_1, "ID_2": record_2, ... } } + + Attributes: + parameters (Mapping[str, Any]): Additional runtime parameters to be used for string interpolation + decoder (Decoder): The decoder responsible to transfom the response in a Mapping + """ + + parameters: InitVar[Mapping[str, Any]] + decoder: Decoder = JsonDecoder(parameters={}) + + def extract_records(self, response: requests.Response) -> List[Record]: + response_body = self.decoder.decode(response) + result = [] + if not response_body["data"]["boards"]: + return result + + for board_data in response_body["data"]["boards"]: + if not isinstance(board_data, dict): + continue + + for record in board_data.get("activity_logs", []): + json_data = json.loads(record["data"]) + new_record = record + if record.get("created_at"): + new_record.update({"created_at_int": int(record.get("created_at", 0)) // 10_000_000}) + else: + continue + + if record.get("entity") == "pulse" and json_data.get("pulse_id"): + new_record.update({"pulse_id": json_data.get("pulse_id")}) + + if record.get("entity") == "board" and json_data.get("board_id"): + new_record.update({"board_id": json_data.get("board_id")}) + + result.append(new_record) + + return result + + +@dataclass +class MondayIncrementalItemsExtractor(RecordExtractor): + """ + Record extractor that searches a decoded response over a path defined as an array of fields. + """ + + field_path: List[Union[InterpolatedString, str]] + config: Config + parameters: InitVar[Mapping[str, Any]] + additional_field_path: List[Union[InterpolatedString, str]] = field(default_factory=list) + decoder: Decoder = JsonDecoder(parameters={}) + + def __post_init__(self, parameters: Mapping[str, Any]): + for field_list in (self.field_path, self.additional_field_path): + for path_index in range(len(field_list)): + if isinstance(field_list[path_index], str): + field_list[path_index] = InterpolatedString.create(field_list[path_index], parameters=parameters) + + def try_extract_records(self, response: requests.Response, field_path: List[Union[InterpolatedString, str]]) -> List[Record]: + response_body = self.decoder.decode(response) + + path = [path.eval(self.config) for path in field_path] + extracted = dpath.util.values(response_body, path) if path else response_body + + pattern_path = "*" in path + if not pattern_path: + extracted = dpath.util.get(response_body, path, default=[]) + + if extracted: + return extracted if isinstance(extracted, list) else [extracted] + return [] + + def extract_records(self, response: requests.Response) -> List[Record]: + result = self.try_extract_records(response, field_path=self.field_path) + if not result and self.additional_field_path: + result = self.try_extract_records(response, self.additional_field_path) + + for item_index in range(len(result)): + if "updated_at" in result[item_index]: + result[item_index]["updated_at_int"] = int( + datetime.strptime(result[item_index]["updated_at"], "%Y-%m-%dT%H:%M:%S%z").timestamp() + ) + return result diff --git a/airbyte-integrations/connectors/source-monday/source_monday/graphql_requester.py b/airbyte-integrations/connectors/source-monday/source_monday/graphql_requester.py index c15eb5a31701..0e5fd049583c 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/graphql_requester.py +++ b/airbyte-integrations/connectors/source-monday/source_monday/graphql_requester.py @@ -3,6 +3,7 @@ # from dataclasses import dataclass +from datetime import datetime from functools import partial from typing import Any, Mapping, MutableMapping, Optional, Type, Union @@ -15,14 +16,15 @@ @dataclass class MondayGraphqlRequester(HttpRequester): NEXT_PAGE_TOKEN_FIELD_NAME = "next_page_token" - NESTED_OBJECTS_LIMIT_MAX_VALUE = 100 limit: Union[InterpolatedString, str, int] = None + nested_limit: Union[InterpolatedString, str, int] = None def __post_init__(self, parameters: Mapping[str, Any]): super(MondayGraphqlRequester, self).__post_init__(parameters) self.limit = InterpolatedString.create(self.limit, parameters=parameters) + self.nested_limit = InterpolatedString.create(self.nested_limit, parameters=parameters) self.name = parameters.get("name", "").lower() def _ensure_type(self, t: Type, o: Any): @@ -34,11 +36,26 @@ def _ensure_type(self, t: Type, o: Any): def _get_schema_root_properties(self): schema_loader = JsonFileSchemaLoader(config=self.config, parameters={"name": self.name}) - schema = schema_loader.get_json_schema() - return schema["properties"] + schema = schema_loader.get_json_schema()["properties"] + + # delete fields that will be created by extractor + delete_fields = ["updated_at_int", "created_at_int", "pulse_id"] + if self.name == "activity_logs": + delete_fields.append("board_id") + for field in delete_fields: + if field in schema: + schema.pop(field) + + return schema def _get_object_arguments(self, **object_arguments) -> str: - return ",".join([f"{argument}:{value}" for argument, value in object_arguments.items() if value is not None]) + return ",".join( + [ + f"{argument}:{value}" if argument != "fromt" else f'from:"{value}"' + for argument, value in object_arguments.items() + if value is not None + ] + ) def _build_query(self, object_name: str, field_schema: dict, **object_arguments) -> str: """ @@ -69,10 +86,23 @@ def _build_items_query(self, object_name: str, field_schema: dict, sub_page: Opt Special optimization needed for items stream. Starting October 3rd, 2022 items can only be reached through boards. See https://developer.monday.com/api-reference/docs/items-queries#items-queries """ - query = self._build_query(object_name, field_schema, limit=self.NESTED_OBJECTS_LIMIT_MAX_VALUE, page=sub_page) + nested_limit = self.nested_limit.eval(self.config) + + query = self._build_query("items", field_schema, limit=nested_limit, page=sub_page) arguments = self._get_object_arguments(**object_arguments) return f"boards({arguments}){{{query}}}" + def _build_items_incremental_query(self, object_name: str, field_schema: dict, stream_slice: dict, **object_arguments) -> str: + """ + Special optimization needed for items stream. Starting October 3rd, 2022 items can only be reached through boards. + See https://developer.monday.com/api-reference/docs/items-queries#items-queries + """ + nested_limit = self.nested_limit.eval(self.config) + + object_arguments["limit"] = nested_limit + object_arguments["ids"] = stream_slice["ids"] + return self._build_query("items", field_schema, **object_arguments) + def _build_teams_query(self, object_name: str, field_schema: dict, **object_arguments) -> str: """ Special optimization needed for tests to pass successfully because of rate limits. @@ -86,6 +116,23 @@ def _build_teams_query(self, object_name: str, field_schema: dict, **object_argu return f"{object_name}({arguments}){query}" return self._build_query(object_name=object_name, field_schema=field_schema, **object_arguments) + def _build_activity_query(self, object_name: str, field_schema: dict, sub_page: Optional[int], **object_arguments) -> str: + """ + Special optimization needed for items stream. Starting October 3rd, 2022 items can only be reached through boards. + See https://developer.monday.com/api-reference/docs/items-queries#items-queries + """ + nested_limit = self.nested_limit.eval(self.config) + + created_at = (object_arguments.get("stream_state", dict()) or dict()).get("created_at_int") + object_arguments.pop("stream_state") + + if created_at: + created_at = datetime.fromtimestamp(created_at).strftime("%Y-%m-%dT%H:%M:%SZ") + + query = self._build_query(object_name, field_schema, limit=nested_limit, page=sub_page, fromt=created_at) + arguments = self._get_object_arguments(**object_arguments) + return f"boards({arguments}){{{query}}}" + def get_request_params( self, *, @@ -97,13 +144,22 @@ def get_request_params( Combines queries to a single GraphQL query. """ limit = self.limit.eval(self.config) + page = next_page_token and next_page_token[self.NEXT_PAGE_TOKEN_FIELD_NAME] - if self.name == "items": + if self.name == "boards" and stream_slice: + query_builder = partial(self._build_query, **stream_slice) + elif self.name == "items": # `items` stream use a separate pagination strategy where first level pages are across `boards` and sub-pages are across `items` page, sub_page = page if page else (None, None) - query_builder = partial(self._build_items_query, sub_page=sub_page) + if not stream_slice: + query_builder = partial(self._build_items_query, sub_page=sub_page) + else: + query_builder = partial(self._build_items_incremental_query, stream_slice=stream_slice) elif self.name == "teams": query_builder = self._build_teams_query + elif self.name == "activity_logs": + page, sub_page = page if page else (None, None) + query_builder = partial(self._build_activity_query, sub_page=sub_page, stream_state=stream_state) else: query_builder = self._build_query query = query_builder( diff --git a/airbyte-integrations/connectors/source-monday/source_monday/item_pagination_strategy.py b/airbyte-integrations/connectors/source-monday/source_monday/item_pagination_strategy.py index a46ab8a18e09..5b18cb4b37b7 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/item_pagination_strategy.py +++ b/airbyte-integrations/connectors/source-monday/source_monday/item_pagination_strategy.py @@ -39,7 +39,7 @@ def next_page_token(self, response, last_records: List[Mapping[str, Any]]) -> Op self._sub_page += 1 else: self._sub_page = self.start_from_page - if len(response.json()["data"]["boards"]): + if response.json()["data"].get("boards"): self._page += 1 else: return None diff --git a/airbyte-integrations/connectors/source-monday/source_monday/manifest.yaml b/airbyte-integrations/connectors/source-monday/source_monday/manifest.yaml index feabb83b8d3a..599e60d17b09 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/manifest.yaml +++ b/airbyte-integrations/connectors/source-monday/source_monday/manifest.yaml @@ -20,6 +20,7 @@ definitions: type: BearerAuthenticator api_token: "{{ config.get('credentials', {}).get('api_token') if config.get('credentials', {}).get('auth_type') == 'api_token' else config.get('credentials', {}).get('access_token') if config.get('credentials', {}).get('auth_type') == 'oauth2.0' else config.get('api_token', '') }}" limit: "{{ parameters['items_per_page'] }}" + nested_limit: "{{ parameters.get('nested_items_per_page', 1) }}" error_handler: type: CompositeErrorHandler error_handlers: @@ -72,30 +73,6 @@ definitions: $ref: "#/definitions/retriever" paginator: type: NoPagination - items_stream: - $ref: "#/definitions/base_stream" - retriever: - $ref: "#/definitions/retriever" - record_selector: - type: RecordSelector - extractor: - field_path: ["data", "boards", "*", "items", "*"] - paginator: - $ref: "#/definitions/default_paginator" - pagination_strategy: - class_name: "source_monday.item_pagination_strategy.ItemPaginationStrategy" - type: "CustomPaginationStrategy" - page_size: 100 - $parameters: - name: "items" - path: "" - items_per_page: 1 - boards_stream: - $ref: "#/definitions/base_stream" - $parameters: - name: "boards" - path: "" - items_per_page: 100 tags_stream: $ref: "#/definitions/base_nopagination_stream" $parameters: @@ -122,6 +99,92 @@ definitions: name: "workspaces" path: "" + double_paginator: + $ref: "#/definitions/default_paginator" + pagination_strategy: + class_name: "source_monday.item_pagination_strategy.ItemPaginationStrategy" + type: "CustomPaginationStrategy" + + activity_logs_stream: + description: "https://developers.intercom.com/intercom-api-reference/reference/scroll-over-all-companies" + incremental_sync: + type: CustomIncrementalSync + class_name: source_monday.components.IncrementalSingleSlice + cursor_field: "created_at_int" + retriever: + $ref: "#/definitions/base_stream/retriever" + record_selector: + $ref: "#/definitions/selector" + extractor: + class_name: "source_monday.extractor.MondayActivityExtractor" + paginator: + $ref: "#/definitions/double_paginator" + $parameters: + name: "activity_logs" + primary_key: "id" + path: "" + items_per_page: 1 + page_size: 50 + nested_items_per_page: 50 + + # semi-incremental substreams + substream_semi_incremental: + $ref: "#/definitions/base_stream" + incremental_sync: + type: CustomIncrementalSync + class_name: source_monday.components.IncrementalSubstreamSlicer + cursor_field: "updated_at_int" + parent_complete_fetch: true + parent_stream_configs: + - type: ParentStreamConfig + stream: "#/definitions/activity_logs_stream" + partition_field: "ids" + incremental_extractor: + class_name: "source_monday.extractor.MondayIncrementalItemsExtractor" + + boards_stream: + $ref: "#/definitions/substream_semi_incremental" + $parameters: + name: "boards" + path: "" + parent_key: "board_id" + items_per_page: 10 + nested_items_per_page: 10 + field_path: [ "data", "boards", "*" ] + retriever: + $ref: "#/definitions/base_stream/retriever" + paginator: + type: "DefaultPaginator" + pagination_strategy: + type: "PageIncrement" + start_from_page: 1 + page_size: 10 + record_selector: + $ref: "#/definitions/selector" + extractor: + $ref: "#/definitions/incremental_extractor" + + items_stream: + $ref: "#/definitions/substream_semi_incremental" + $parameters: + name: "items" + path: "" + items_per_page: 1 + page_size: 20 + nested_items_per_page: 20 + parent_key: "pulse_id" + field_path: [ "data", "items", "*" ] + additional_field_path: [ "data", "boards", "*", "items", "*" ] + retriever: + $ref: "#/definitions/base_stream/retriever" + paginator: + $ref: "#/definitions/double_paginator" + record_selector: + $ref: "#/definitions/selector" + extractor: + $ref: "#/definitions/incremental_extractor" + + streams: - "#/definitions/items_stream" - "#/definitions/boards_stream" @@ -130,7 +193,8 @@ streams: - "#/definitions/updates_stream" - "#/definitions/users_stream" - "#/definitions/workspaces_stream" + - "#/definitions/activity_logs_stream" check: stream_names: - - "users" \ No newline at end of file + - "users" diff --git a/airbyte-integrations/connectors/source-monday/source_monday/schemas/activity_logs.json b/airbyte-integrations/connectors/source-monday/source_monday/schemas/activity_logs.json new file mode 100644 index 000000000000..117fb27d3f65 --- /dev/null +++ b/airbyte-integrations/connectors/source-monday/source_monday/schemas/activity_logs.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "id": { "type": ["null", "string"] }, + "event": { "type": ["null", "string"] }, + "data": { "type": ["null", "string"] }, + "entity": { "type": ["null", "string"] }, + "created_at": { "type": ["null", "string"] }, + "created_at_int": { "type": ["null", "integer"] }, + "pulse_id": { "type": ["null", "integer"] }, + "board_id": { "type": ["null", "integer"] } + } +} \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-monday/source_monday/schemas/boards.json b/airbyte-integrations/connectors/source-monday/source_monday/schemas/boards.json index 9829d82e38d7..f89903bf90aa 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/schemas/boards.json +++ b/airbyte-integrations/connectors/source-monday/source_monday/schemas/boards.json @@ -84,6 +84,7 @@ } }, "updated_at": { "type": ["null", "string"], "format": "date-time" }, + "updated_at_int": { "type": ["null", "integer"]}, "updates": { "type": ["null", "array"], "items": { diff --git a/airbyte-integrations/connectors/source-monday/source_monday/schemas/items.json b/airbyte-integrations/connectors/source-monday/source_monday/schemas/items.json index 61090df1d431..27f02d52354f 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/schemas/items.json +++ b/airbyte-integrations/connectors/source-monday/source_monday/schemas/items.json @@ -76,6 +76,7 @@ } }, "updated_at": { "type": ["null", "string"], "format": "date-time" }, + "updated_at_int": { "type": ["null", "integer"] }, "updates": { "type": ["null", "array"], "items": { diff --git a/airbyte-integrations/connectors/source-monday/source_monday/schemas/tags.json b/airbyte-integrations/connectors/source-monday/source_monday/schemas/tags.json index 08deffe7b8c1..c96a58d1d42a 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/schemas/tags.json +++ b/airbyte-integrations/connectors/source-monday/source_monday/schemas/tags.json @@ -6,4 +6,4 @@ "id": { "type": ["null", "integer"] }, "name": { "type": ["null", "string"] } } -} \ No newline at end of file +} diff --git a/airbyte-integrations/connectors/source-monday/source_monday/schemas/workspaces.json b/airbyte-integrations/connectors/source-monday/source_monday/schemas/workspaces.json index 891800eb2cbf..af7bf79b2d97 100644 --- a/airbyte-integrations/connectors/source-monday/source_monday/schemas/workspaces.json +++ b/airbyte-integrations/connectors/source-monday/source_monday/schemas/workspaces.json @@ -70,4 +70,4 @@ } } } -} \ No newline at end of file +} diff --git a/airbyte-integrations/connectors/source-monday/unit_tests/test_components.py b/airbyte-integrations/connectors/source-monday/unit_tests/test_components.py new file mode 100644 index 000000000000..1b7b3fb00c01 --- /dev/null +++ b/airbyte-integrations/connectors/source-monday/unit_tests/test_components.py @@ -0,0 +1,55 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +from unittest.mock import MagicMock, Mock + +import pytest +from airbyte_cdk.sources.declarative.partition_routers.substream_partition_router import ParentStreamConfig +from airbyte_cdk.sources.streams import Stream +from source_monday.components import IncrementalSingleSlice, IncrementalSubstreamSlicer + + +def test_slicer(): + date_time_dict = {"updated_at": 1662459010} + slicer = IncrementalSingleSlice(config={}, parameters={}, cursor_field="updated_at") + slicer.close_slice(date_time_dict, date_time_dict) + assert slicer.get_stream_state() == date_time_dict + assert slicer.get_request_headers() == {} + assert slicer.get_request_body_data() == {} + assert slicer.get_request_body_json() == {} + + +@pytest.mark.parametrize( + "last_record, expected, records", + [ + ( + {"first_stream_cursor": 1662459010}, + {'parent_stream_name': {'parent_cursor_field': 1662459010}, 'first_stream_cursor': 1662459010}, + [{"first_stream_cursor": 1662459010}], + ), + (None, {}, []), + ], +) +def test_sub_slicer(last_record, expected, records): + parent_stream = Mock(spec=Stream) + parent_stream.name = "parent_stream_name" + parent_stream.cursor_field = "parent_cursor_field" + parent_stream.stream_slices.return_value = [{"a slice": "value"}] + parent_stream.read_records = MagicMock(return_value=records) + + parent_config = ParentStreamConfig( + stream=parent_stream, + parent_key="id", + partition_field="first_stream_id", + parameters={}, + config={}, + ) + + slicer = IncrementalSubstreamSlicer( + config={}, parameters={}, cursor_field="first_stream_cursor", parent_stream_configs=[parent_config], nested_items_per_page=10 + ) + stream_slice = next(slicer.stream_slices()) if records else {} + slicer.close_slice(stream_slice, last_record) + assert slicer.get_stream_state() == expected diff --git a/airbyte-integrations/connectors/source-monday/unit_tests/test_graphql_requester.py b/airbyte-integrations/connectors/source-monday/unit_tests/test_graphql_requester.py index 19c94851f706..ed79a1bce6bb 100644 --- a/airbyte-integrations/connectors/source-monday/unit_tests/test_graphql_requester.py +++ b/airbyte-integrations/connectors/source-monday/unit_tests/test_graphql_requester.py @@ -98,7 +98,8 @@ def test_get_request_params(mocker, input_schema, graphql_query, stream_name, co authenticator=MagicMock(), error_handler=MagicMock(), limit="{{ parameters['items_per_page'] }}", - parameters={"name": stream_name, "items_per_page": 100}, + nested_limit="{{ parameters.get('nested_items_per_page', 1) }}", + parameters={"name": stream_name, "items_per_page": 100, "nested_items_per_page": 100}, config=config ) assert requester.get_request_params( diff --git a/docs/integrations/sources/monday.md b/docs/integrations/sources/monday.md index 3e4652e7b8a0..76801a290544 100644 --- a/docs/integrations/sources/monday.md +++ b/docs/integrations/sources/monday.md @@ -31,7 +31,7 @@ The Monday supports full refresh syncs | Feature | Supported? | |:------------------|:-----------| | Full Refresh Sync | Yes | -| Incremental Sync | No | +| Incremental Sync | Yes | | SSL connection | No | | Namespaces | No | @@ -39,6 +39,7 @@ The Monday supports full refresh syncs Several output streams are available from this source: +* [Activity logs](https://developer.monday.com/api-reference/docs/activity-logs) * [Items](https://developer.monday.com/api-reference/docs/items-queries) * [Boards](https://developer.monday.com/api-reference/docs/groups-queries#groups-queries) * [Teams](https://developer.monday.com/api-reference/docs/teams-queries) @@ -53,10 +54,13 @@ The typical name of the table depends on the `destination` you use like `boards. * `Column Values` are available from the `Items` stream. By syncing the `Items` stream you will get the `Column Values` for each `Item` (row) of the board. The typical name of the table depends on the `destination` you use like `items.column_values`, for instance. - - If there are more endpoints you'd like Airbyte to support, please [create an issue.](https://github.com/airbytehq/airbyte/issues/new/choose) +* Incremental sync for `Items` and `Boards` streams is done using the `Activity logs` stream. +Ids of boards and items are extracted from activity logs events and used to selectively sync boards and items. +Some data may be lost if the time between incremental syncs is longer than the activity logs retention time for your plan. +Check your Monday plan at https://monday.com/pricing. + ## Performance considerations @@ -65,18 +69,19 @@ The Monday connector should not run into Monday API limitations under normal usa ## Changelog -| Version | Date | Pull Request | Subject | -|:--------|:-----------|:---------------------------------------------------------|:------------------------------------------------------------------------| -| 1.0.0 | 2023-06-20 | [27410](https://github.com/airbytehq/airbyte/pull/27410) | Add new streams: Tags, Workspaces. Add new fields for existing streams. | -| 0.2.6 | 2023-06-12 | [27244](https://github.com/airbytehq/airbyte/pull/27244) | Added http error handling for `403` and `500` HTTP errors | +| Version | Date | Pull Request | Subject | +|:--------|:-----------|:----------------------------------------------------------|:------------------------------------------------------------------------| +| 1.1.0 | 2023-07-05 | [27944](https://github.com/airbytehq/airbyte/pull/27944) | Add incremental sync for Items and Boards streams | +| 1.0.0 | 2023-06-20 | [27410](https://github.com/airbytehq/airbyte/pull/27410) | Add new streams: Tags, Workspaces. Add new fields for existing streams. | +| 0.2.6 | 2023-06-12 | [27244](https://github.com/airbytehq/airbyte/pull/27244) | Added http error handling for `403` and `500` HTTP errors | | 0.2.5 | 2023-05-22 | [225881](https://github.com/airbytehq/airbyte/pull/25881) | Fix pagination for the items stream | -| 0.2.4 | 2023-04-26 | [25277](https://github.com/airbytehq/airbyte/pull/25277) | Increase row limit to 100 | -| 0.2.3 | 2023-03-06 | [23231](https://github.com/airbytehq/airbyte/pull/23231) | Publish using low-code CDK Beta version | -| 0.2.2 | 2023-01-04 | [20996](https://github.com/airbytehq/airbyte/pull/20996) | Fix json schema loader | -| 0.2.1 | 2022-12-15 | [20533](https://github.com/airbytehq/airbyte/pull/20533) | Bump CDK version | -| 0.2.0 | 2022-12-13 | [19586](https://github.com/airbytehq/airbyte/pull/19586) | Migrate to low-code | -| 0.1.4 | 2022-06-06 | [14443](https://github.com/airbytehq/airbyte/pull/14443) | Increase retry_factor for Items stream | -| 0.1.3 | 2021-12-23 | [8172](https://github.com/airbytehq/airbyte/pull/8172) | Add oauth2.0 support | -| 0.1.2 | 2021-12-07 | [8429](https://github.com/airbytehq/airbyte/pull/8429) | Update titles and descriptions | -| 0.1.1 | 2021-11-18 | [8016](https://github.com/airbytehq/airbyte/pull/8016) | 🐛 Source Monday: fix pagination and schema bug | -| 0.1.0 | 2021-11-07 | [7168](https://github.com/airbytehq/airbyte/pull/7168) | 🎉 New Source: Monday | +| 0.2.4 | 2023-04-26 | [25277](https://github.com/airbytehq/airbyte/pull/25277) | Increase row limit to 100 | +| 0.2.3 | 2023-03-06 | [23231](https://github.com/airbytehq/airbyte/pull/23231) | Publish using low-code CDK Beta version | +| 0.2.2 | 2023-01-04 | [20996](https://github.com/airbytehq/airbyte/pull/20996) | Fix json schema loader | +| 0.2.1 | 2022-12-15 | [20533](https://github.com/airbytehq/airbyte/pull/20533) | Bump CDK version | +| 0.2.0 | 2022-12-13 | [19586](https://github.com/airbytehq/airbyte/pull/19586) | Migrate to low-code | +| 0.1.4 | 2022-06-06 | [14443](https://github.com/airbytehq/airbyte/pull/14443) | Increase retry_factor for Items stream | +| 0.1.3 | 2021-12-23 | [8172](https://github.com/airbytehq/airbyte/pull/8172) | Add oauth2.0 support | +| 0.1.2 | 2021-12-07 | [8429](https://github.com/airbytehq/airbyte/pull/8429) | Update titles and descriptions | +| 0.1.1 | 2021-11-18 | [8016](https://github.com/airbytehq/airbyte/pull/8016) | 🐛 Source Monday: fix pagination and schema bug | +| 0.1.0 | 2021-11-07 | [7168](https://github.com/airbytehq/airbyte/pull/7168) | 🎉 New Source: Monday | From a0e152aa55d36248389d952662f12802ad9a5146 Mon Sep 17 00:00:00 2001 From: Artem Inzhyyants <36314070+artem1205@users.noreply.github.com> Date: Thu, 13 Jul 2023 11:23:47 +0200 Subject: [PATCH 52/63] =?UTF-8?q?=F0=9F=9A=A8=F0=9F=9A=A8=20Source=20PayPa?= =?UTF-8?q?l=20Transactions:=20Rename=20field=20in=20`Balances`=20schema?= =?UTF-8?q?=20(#27916)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Source PayPal Transactions: update spec * Source PayPal Transactions: update docs * Source PayPal Transactions: update test config * Source PayPal Transactions: update test config * Source PayPal Transactions: update test config * Source PayPal Transactions: update balances schema * Source PayPal Transactions: update test config * Source PayPal: bump version --------- Co-authored-by: Augustin --- .../source-paypal-transaction/Dockerfile | 2 +- .../acceptance-test-config.yml | 31 +++++-- .../integration_tests/expected_records.jsonl | 42 +--------- .../expected_records_sandbox.jsonl | 2 + .../source-paypal-transaction/metadata.yaml | 2 +- .../schemas/balances.json | 80 ++++++++++--------- .../sources/paypal-transaction.md | 1 + 7 files changed, 73 insertions(+), 87 deletions(-) create mode 100644 airbyte-integrations/connectors/source-paypal-transaction/integration_tests/expected_records_sandbox.jsonl diff --git a/airbyte-integrations/connectors/source-paypal-transaction/Dockerfile b/airbyte-integrations/connectors/source-paypal-transaction/Dockerfile index 8a719603df2b..282bb021a007 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/Dockerfile +++ b/airbyte-integrations/connectors/source-paypal-transaction/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=1.0.0 +LABEL io.airbyte.version=2.0.0 LABEL io.airbyte.name=airbyte/source-paypal-transaction diff --git a/airbyte-integrations/connectors/source-paypal-transaction/acceptance-test-config.yml b/airbyte-integrations/connectors/source-paypal-transaction/acceptance-test-config.yml index 7737a11d89ba..38e6b7be325e 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-paypal-transaction/acceptance-test-config.yml @@ -9,27 +9,46 @@ acceptance_tests: disable_for_version: "0.1.13" connection: tests: - - config_path: integration_tests/invalid_config.json - status: failed - config_path: secrets/config_oauth.json status: succeed + - config_path: secrets/config_oauth_sandbox.json + status: succeed + - config_path: integration_tests/invalid_config.json + status: failed - config_path: integration_tests/invalid_config_oauth.json status: failed discovery: tests: - config_path: secrets/config_oauth.json + backward_compatibility_tests_config: + disable_for_version: "1.0.0" # Balances schema changed basic_read: tests: - config_path: secrets/config_oauth.json + ignored_fields: + balances: + - name: last_refresh_time + bypass_reason: "field changes during every read" empty_streams: - - name: balances - bypass_reason: "value of 'last_refresh_time' field changes during every read" + - name: transactions + bypass_reason: "can not populate" timeout_seconds: 1200 expect_records: path: "integration_tests/expected_records.jsonl" extra_fields: no exact_order: no extra_records: yes + - config_path: secrets/config_oauth_sandbox.json + ignored_fields: + balances: + - name: last_refresh_time + bypass_reason: "field changes during every read" + timeout_seconds: 1200 + expect_records: + path: "integration_tests/expected_records_sandbox.jsonl" + extra_fields: no + exact_order: no + extra_records: yes incremental: tests: - config_path: secrets/config_oauth.json @@ -37,8 +56,8 @@ acceptance_tests: future_state: future_state_path: integration_tests/abnormal_state.json cursor_paths: - transactions: ["date"] - balances: ["date"] + transactions: [ "date" ] + balances: [ "date" ] full_refresh: tests: - config_path: secrets/config_oauth.json diff --git a/airbyte-integrations/connectors/source-paypal-transaction/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-paypal-transaction/integration_tests/expected_records.jsonl index 5be7b634a755..7841d256e49d 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-paypal-transaction/integration_tests/expected_records.jsonl @@ -1,41 +1 @@ -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "23N61105X92314351", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-04T17:13:23+0000", "transaction_updated_date": "2021-07-04T17:13:23+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "202.58"}, "available_balance": {"currency_code": "USD", "value": "202.58"}, "invoice_id": "48787580055", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "48787580055"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "48787580055"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-04T17:13:23+0000", "transaction_id": "23N61105X92314351"}, "emitted_at": 1673959656444} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "1FN09943JY662130R", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T22:56:54+0000", "transaction_updated_date": "2021-07-05T22:56:54+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "231.52"}, "available_balance": {"currency_code": "USD", "value": "231.52"}, "invoice_id": "65095789448", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "65095789448"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "65095789448"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T22:56:54+0000", "transaction_id": "1FN09943JY662130R"}, "emitted_at": 1673959656446} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "0M443597T0019954R", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:01:13+0000", "transaction_updated_date": "2021-07-05T23:01:13+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "260.46"}, "available_balance": {"currency_code": "USD", "value": "260.46"}, "invoice_id": "41468340464", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "41468340464"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "41468340464"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:01:13+0000", "transaction_id": "0M443597T0019954R"}, "emitted_at": 1673959656448} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "19C257131E850262B", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:02:46+0000", "transaction_updated_date": "2021-07-05T23:02:46+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "289.40"}, "available_balance": {"currency_code": "USD", "value": "289.40"}, "invoice_id": "23749371955", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "23749371955"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "23749371955"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:02:46+0000", "transaction_id": "19C257131E850262B"}, "emitted_at": 1673959656450} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "6S892278N6406494Y", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:06:12+0000", "transaction_updated_date": "2021-07-05T23:06:12+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "318.34"}, "available_balance": {"currency_code": "USD", "value": "318.34"}, "invoice_id": "62173333941", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "62173333941"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "62173333941"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:06:12+0000", "transaction_id": "6S892278N6406494Y"}, "emitted_at": 1673959656453} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "0T320567TS5587836", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:09:04+0000", "transaction_updated_date": "2021-07-05T23:09:04+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "347.28"}, "available_balance": {"currency_code": "USD", "value": "347.28"}, "invoice_id": "56028534885", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "56028534885"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "56028534885"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:09:04+0000", "transaction_id": "0T320567TS5587836"}, "emitted_at": 1673959656455} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "3DF69605L9958744R", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:12:40+0000", "transaction_updated_date": "2021-07-05T23:12:40+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "376.22"}, "available_balance": {"currency_code": "USD", "value": "376.22"}, "invoice_id": "31766547902", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "31766547902"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "31766547902"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:12:40+0000", "transaction_id": "3DF69605L9958744R"}, "emitted_at": 1673959656457} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "2F535603PS249601F", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:12:57+0000", "transaction_updated_date": "2021-07-05T23:12:57+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "405.16"}, "available_balance": {"currency_code": "USD", "value": "405.16"}, "invoice_id": "32577611997", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "32577611997"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "32577611997"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:12:57+0000", "transaction_id": "2F535603PS249601F"}, "emitted_at": 1673959656459} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "243514451L952570P", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:14:02+0000", "transaction_updated_date": "2021-07-05T23:14:02+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "434.10"}, "available_balance": {"currency_code": "USD", "value": "434.10"}, "invoice_id": "23612058730", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "23612058730"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "23612058730"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:14:02+0000", "transaction_id": "243514451L952570P"}, "emitted_at": 1673959656460} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "27881589Y9461861H", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:14:19+0000", "transaction_updated_date": "2021-07-05T23:14:19+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "463.04"}, "available_balance": {"currency_code": "USD", "value": "463.04"}, "invoice_id": "53296156982", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "53296156982"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "53296156982"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:14:19+0000", "transaction_id": "27881589Y9461861H"}, "emitted_at": 1673959656462} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "3MG39755337297727", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:14:36+0000", "transaction_updated_date": "2021-07-05T23:14:36+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "491.98"}, "available_balance": {"currency_code": "USD", "value": "491.98"}, "invoice_id": "53235397043", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "53235397043"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "53235397043"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:14:36+0000", "transaction_id": "3MG39755337297727"}, "emitted_at": 1673959656463} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "32J59182JY5989507", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:14:52+0000", "transaction_updated_date": "2021-07-05T23:14:52+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "520.92"}, "available_balance": {"currency_code": "USD", "value": "520.92"}, "invoice_id": "18208641465", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "18208641465"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "18208641465"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:14:52+0000", "transaction_id": "32J59182JY5989507"}, "emitted_at": 1673959656464} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "52795774C7828234R", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:15:09+0000", "transaction_updated_date": "2021-07-05T23:15:09+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "549.86"}, "available_balance": {"currency_code": "USD", "value": "549.86"}, "invoice_id": "32274344746", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "32274344746"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "32274344746"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:15:09+0000", "transaction_id": "52795774C7828234R"}, "emitted_at": 1673959656465} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "19B82038T92822940", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:15:26+0000", "transaction_updated_date": "2021-07-05T23:15:26+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "578.80"}, "available_balance": {"currency_code": "USD", "value": "578.80"}, "invoice_id": "36419288277", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "36419288277"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "36419288277"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:15:26+0000", "transaction_id": "19B82038T92822940"}, "emitted_at": 1673959656467} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "61G749036D552760G", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:15:42+0000", "transaction_updated_date": "2021-07-05T23:15:42+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "607.74"}, "available_balance": {"currency_code": "USD", "value": "607.74"}, "invoice_id": "88092228645", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "88092228645"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "88092228645"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:15:42+0000", "transaction_id": "61G749036D552760G"}, "emitted_at": 1673959656468} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "5EL311302L108363J", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:15:58+0000", "transaction_updated_date": "2021-07-05T23:15:58+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "636.68"}, "available_balance": {"currency_code": "USD", "value": "636.68"}, "invoice_id": "25494061224", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "25494061224"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "25494061224"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:15:58+0000", "transaction_id": "5EL311302L108363J"}, "emitted_at": 1673959656470} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "3VP82838NP358133N", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:16:15+0000", "transaction_updated_date": "2021-07-05T23:16:15+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "665.62"}, "available_balance": {"currency_code": "USD", "value": "665.62"}, "invoice_id": "82173600275", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "82173600275"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "82173600275"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:16:15+0000", "transaction_id": "3VP82838NP358133N"}, "emitted_at": 1673959656471} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "2N796839EY2539153", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:16:32+0000", "transaction_updated_date": "2021-07-05T23:16:32+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "694.56"}, "available_balance": {"currency_code": "USD", "value": "694.56"}, "invoice_id": "10442581967", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "10442581967"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "10442581967"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:16:32+0000", "transaction_id": "2N796839EY2539153"}, "emitted_at": 1673959656472} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "5WX252723D093564T", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:23:29+0000", "transaction_updated_date": "2021-07-05T23:23:29+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "723.50"}, "available_balance": {"currency_code": "USD", "value": "723.50"}, "invoice_id": "71987080514", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "71987080514"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "71987080514"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:23:29+0000", "transaction_id": "5WX252723D093564T"}, "emitted_at": 1673959656473} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "4PW76195NN227720S", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:23:40+0000", "transaction_updated_date": "2021-07-05T23:23:40+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "752.44"}, "available_balance": {"currency_code": "USD", "value": "752.44"}, "invoice_id": "93025400757", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "93025400757"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "93025400757"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:23:40+0000", "transaction_id": "4PW76195NN227720S"}, "emitted_at": 1673959656474} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "0VE851712U5895412", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:23:51+0000", "transaction_updated_date": "2021-07-05T23:23:51+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "781.38"}, "available_balance": {"currency_code": "USD", "value": "781.38"}, "invoice_id": "46225965444", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "46225965444"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "46225965444"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:23:51+0000", "transaction_id": "0VE851712U5895412"}, "emitted_at": 1673959656475} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "63U003588S1135607", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:29:26+0000", "transaction_updated_date": "2021-07-05T23:29:26+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "810.32"}, "available_balance": {"currency_code": "USD", "value": "810.32"}, "invoice_id": "34635559567", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "34635559567"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "34635559567"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:29:26+0000", "transaction_id": "63U003588S1135607"}, "emitted_at": 1673959656476} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "2AJ081444T051123A", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:29:37+0000", "transaction_updated_date": "2021-07-05T23:29:37+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "839.26"}, "available_balance": {"currency_code": "USD", "value": "839.26"}, "invoice_id": "92544485996", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "92544485996"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "92544485996"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:29:37+0000", "transaction_id": "2AJ081444T051123A"}, "emitted_at": 1673959656477} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "2KU13114TJ604181E", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:29:48+0000", "transaction_updated_date": "2021-07-05T23:29:48+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "868.20"}, "available_balance": {"currency_code": "USD", "value": "868.20"}, "invoice_id": "10184574713", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "10184574713"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "10184574713"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:29:48+0000", "transaction_id": "2KU13114TJ604181E"}, "emitted_at": 1673959656478} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "1ST090036H2235215", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:31:35+0000", "transaction_updated_date": "2021-07-05T23:31:35+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "897.14"}, "available_balance": {"currency_code": "USD", "value": "897.14"}, "invoice_id": "50350860865", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "50350860865"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "50350860865"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:31:35+0000", "transaction_id": "1ST090036H2235215"}, "emitted_at": 1673959656479} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "5BJ418934Y425901G", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:31:46+0000", "transaction_updated_date": "2021-07-05T23:31:46+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "926.08"}, "available_balance": {"currency_code": "USD", "value": "926.08"}, "invoice_id": "12278283055", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "12278283055"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "12278283055"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:31:46+0000", "transaction_id": "5BJ418934Y425901G"}, "emitted_at": 1673959656480} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "0SD21997LN026020M", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:31:56+0000", "transaction_updated_date": "2021-07-05T23:31:56+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "955.02"}, "available_balance": {"currency_code": "USD", "value": "955.02"}, "invoice_id": "52396214250", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "52396214250"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "52396214250"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:31:56+0000", "transaction_id": "0SD21997LN026020M"}, "emitted_at": 1673959656481} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "3BH630398E562901G", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:42:41+0000", "transaction_updated_date": "2021-07-05T23:42:41+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "983.96"}, "available_balance": {"currency_code": "USD", "value": "983.96"}, "invoice_id": "18793521512", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "18793521512"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "18793521512"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:42:41+0000", "transaction_id": "3BH630398E562901G"}, "emitted_at": 1673959656482} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "03D88325GF8461705", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:42:52+0000", "transaction_updated_date": "2021-07-05T23:42:52+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "1012.90"}, "available_balance": {"currency_code": "USD", "value": "1012.90"}, "invoice_id": "71793513892", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "71793513892"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "71793513892"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:42:52+0000", "transaction_id": "03D88325GF8461705"}, "emitted_at": 1673959656484} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "51852852PL0100404", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:43:03+0000", "transaction_updated_date": "2021-07-05T23:43:03+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "1041.84"}, "available_balance": {"currency_code": "USD", "value": "1041.84"}, "invoice_id": "98653187889", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "98653187889"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "98653187889"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:43:03+0000", "transaction_id": "51852852PL0100404"}, "emitted_at": 1673959656485} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "8MF4324694292993B", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:44:21+0000", "transaction_updated_date": "2021-07-05T23:44:21+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "1070.78"}, "available_balance": {"currency_code": "USD", "value": "1070.78"}, "invoice_id": "12489150471", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "12489150471"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "12489150471"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:44:21+0000", "transaction_id": "8MF4324694292993B"}, "emitted_at": 1673959656486} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "87S73342AS6001233", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:44:32+0000", "transaction_updated_date": "2021-07-05T23:44:32+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "1099.72"}, "available_balance": {"currency_code": "USD", "value": "1099.72"}, "invoice_id": "99595079917", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "99595079917"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "99595079917"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:44:32+0000", "transaction_id": "87S73342AS6001233"}, "emitted_at": 1673959656487} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "112146346A741221U", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:44:44+0000", "transaction_updated_date": "2021-07-05T23:44:44+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "1128.66"}, "available_balance": {"currency_code": "USD", "value": "1128.66"}, "invoice_id": "93286331651", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "93286331651"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "93286331651"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:44:44+0000", "transaction_id": "112146346A741221U"}, "emitted_at": 1673959656488} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "0N2242037Y9449344", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:44:54+0000", "transaction_updated_date": "2021-07-05T23:44:54+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "1157.60"}, "available_balance": {"currency_code": "USD", "value": "1157.60"}, "invoice_id": "71349988314", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "71349988314"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "71349988314"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:44:54+0000", "transaction_id": "0N2242037Y9449344"}, "emitted_at": 1673959656489} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "9NH78349H0388780F", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:45:05+0000", "transaction_updated_date": "2021-07-05T23:45:05+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "1186.54"}, "available_balance": {"currency_code": "USD", "value": "1186.54"}, "invoice_id": "83951023481", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "83951023481"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "83951023481"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:45:05+0000", "transaction_id": "9NH78349H0388780F"}, "emitted_at": 1673959656490} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "10S137566E4828249", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:45:16+0000", "transaction_updated_date": "2021-07-05T23:45:16+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "1215.48"}, "available_balance": {"currency_code": "USD", "value": "1215.48"}, "invoice_id": "88168198250", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "88168198250"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "88168198250"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:45:16+0000", "transaction_id": "10S137566E4828249"}, "emitted_at": 1673959656491} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "7N749695W59419057", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:45:27+0000", "transaction_updated_date": "2021-07-05T23:45:27+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "1244.42"}, "available_balance": {"currency_code": "USD", "value": "1244.42"}, "invoice_id": "38296993497", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "38296993497"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "38296993497"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:45:27+0000", "transaction_id": "7N749695W59419057"}, "emitted_at": 1673959656492} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "43X058357A257931N", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:45:39+0000", "transaction_updated_date": "2021-07-05T23:45:39+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "1273.36"}, "available_balance": {"currency_code": "USD", "value": "1273.36"}, "invoice_id": "33391419042", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "33391419042"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "33391419042"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:45:39+0000", "transaction_id": "43X058357A257931N"}, "emitted_at": 1673959656493} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "5WL82051VY277550S", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:45:50+0000", "transaction_updated_date": "2021-07-05T23:45:50+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "1302.30"}, "available_balance": {"currency_code": "USD", "value": "1302.30"}, "invoice_id": "69341308548", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "69341308548"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "69341308548"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:45:50+0000", "transaction_id": "5WL82051VY277550S"}, "emitted_at": 1673959656494} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "9CG36572NK0728016", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:46:01+0000", "transaction_updated_date": "2021-07-05T23:46:01+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "1331.24"}, "available_balance": {"currency_code": "USD", "value": "1331.24"}, "invoice_id": "70491310163", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "70491310163"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "70491310163"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:46:01+0000", "transaction_id": "9CG36572NK0728016"}, "emitted_at": 1673959656495} -{"stream": "transactions", "data": {"transaction_info": {"paypal_account_id": "ZE5533HZPGMC6", "transaction_id": "9K759703FU663194K", "transaction_event_code": "T0006", "transaction_initiation_date": "2021-07-05T23:46:43+0000", "transaction_updated_date": "2021-07-05T23:46:43+0000", "transaction_amount": {"currency_code": "USD", "value": "30.11"}, "fee_amount": {"currency_code": "USD", "value": "-1.17"}, "insurance_amount": {"currency_code": "USD", "value": "0.01"}, "shipping_amount": {"currency_code": "USD", "value": "1.03"}, "shipping_discount_amount": {"currency_code": "USD", "value": "1.00"}, "transaction_status": "S", "transaction_subject": "This is the payment transaction description.", "ending_balance": {"currency_code": "USD", "value": "1360.18"}, "available_balance": {"currency_code": "USD", "value": "1360.18"}, "invoice_id": "44794712899", "custom_field": "EBAY_EMS_90048630020055", "protection_eligibility": "01"}, "payer_info": {"account_id": "ZE5533HZPGMC6", "email_address": "integration-test-buyer@airbyte.io", "address_status": "Y", "payer_status": "Y", "payer_name": {"given_name": "test", "surname": "buyer", "alternate_full_name": "test buyer"}, "country_code": "US"}, "shipping_info": {"name": "Hello World", "address": {"line1": "4thFloor", "line2": "unit#34", "city": "SAn Jose", "state": "CA", "country_code": "US", "postal_code": "95131"}}, "cart_info": {"item_details": [{"item_code": "1", "item_name": "hat", "item_description": "Brown color hat", "item_quantity": "5", "item_unit_price": {"currency_code": "USD", "value": "3.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.05"}}], "total_item_amount": {"currency_code": "USD", "value": "15.05"}, "invoice_number": "44794712899"}, {"item_code": "product34", "item_name": "handbag", "item_description": "Black color hand bag", "item_quantity": "1", "item_unit_price": {"currency_code": "USD", "value": "15.00"}, "item_amount": {"currency_code": "USD", "value": "15.00"}, "tax_amounts": [{"tax_amount": {"currency_code": "USD", "value": "0.02"}}], "total_item_amount": {"currency_code": "USD", "value": "15.02"}, "invoice_number": "44794712899"}]}, "store_info": {}, "auction_info": {}, "incentive_info": {}, "transaction_initiation_date": "2021-07-05T23:46:43+0000", "transaction_id": "9K759703FU663194K"}, "emitted_at": 1673959656495} \ No newline at end of file +{"stream":"balances","data":{"balances":[{"currency":"USD","primary":true,"total_balance":{"currency_code":"USD","value":"0.00"},"available_balance":{"currency_code":"USD","value":"0.00"},"withheld_balance":{"currency_code":"USD","value":"0.00"}}],"account_id":"QJQSC8WXYCA2L","as_of_time":"2021-07-03T00:00:00+00:00","last_refresh_time":"2023-07-04T07:29:59Z"},"emitted_at":1688463837632} \ No newline at end of file diff --git a/airbyte-integrations/connectors/source-paypal-transaction/integration_tests/expected_records_sandbox.jsonl b/airbyte-integrations/connectors/source-paypal-transaction/integration_tests/expected_records_sandbox.jsonl new file mode 100644 index 000000000000..3d60f02eb69d --- /dev/null +++ b/airbyte-integrations/connectors/source-paypal-transaction/integration_tests/expected_records_sandbox.jsonl @@ -0,0 +1,2 @@ +{"stream":"transactions","data":{"transaction_info":{"paypal_account_id":"ZE5533HZPGMC6","transaction_id":"23N61105X92314351","transaction_event_code":"T0006","transaction_initiation_date":"2021-07-04T17:13:23+0000","transaction_updated_date":"2021-07-04T17:13:23+0000","transaction_amount":{"currency_code":"USD","value":"30.11"},"fee_amount":{"currency_code":"USD","value":"-1.17"},"insurance_amount":{"currency_code":"USD","value":"0.01"},"shipping_amount":{"currency_code":"USD","value":"1.03"},"shipping_discount_amount":{"currency_code":"USD","value":"1.00"},"transaction_status":"S","transaction_subject":"This is the payment transaction description.","ending_balance":{"currency_code":"USD","value":"202.58"},"available_balance":{"currency_code":"USD","value":"202.58"},"invoice_id":"48787580055","custom_field":"EBAY_EMS_90048630020055","protection_eligibility":"01"},"payer_info":{"account_id":"ZE5533HZPGMC6","email_address":"integration-test-buyer@airbyte.io","address_status":"Y","payer_status":"Y","payer_name":{"given_name":"test","surname":"buyer","alternate_full_name":"test buyer"},"country_code":"US"},"shipping_info":{"name":"Hello World","address":{"line1":"4thFloor","line2":"unit#34","city":"SAn Jose","state":"CA","country_code":"US","postal_code":"95131"}},"cart_info":{"item_details":[{"item_code":"1","item_name":"hat","item_description":"Brown color hat","item_quantity":"5","item_unit_price":{"currency_code":"USD","value":"3.00"},"item_amount":{"currency_code":"USD","value":"15.00"},"tax_amounts":[{"tax_amount":{"currency_code":"USD","value":"0.05"}}],"total_item_amount":{"currency_code":"USD","value":"15.05"},"invoice_number":"48787580055"},{"item_code":"product34","item_name":"handbag","item_description":"Black color hand bag","item_quantity":"1","item_unit_price":{"currency_code":"USD","value":"15.00"},"item_amount":{"currency_code":"USD","value":"15.00"},"tax_amounts":[{"tax_amount":{"currency_code":"USD","value":"0.02"}}],"total_item_amount":{"currency_code":"USD","value":"15.02"},"invoice_number":"48787580055"}]},"store_info":{},"auction_info":{},"incentive_info":{},"transaction_initiation_date":"2021-07-04T17:13:23+0000","transaction_id":"23N61105X92314351"},"emitted_at":1688463620839} +{"stream":"balances","data":{"balances":[{"currency":"USD","primary":true,"total_balance":{"currency_code":"USD","value":"173.64"},"available_balance":{"currency_code":"USD","value":"173.64"},"withheld_balance":{"currency_code":"USD","value":"0.00"}}],"account_id":"MDXWPD67GEP5W","as_of_time":"2021-07-03T00:00:00+00:00","last_refresh_time":"2023-07-04T04:59:59Z"},"emitted_at":1688463625694} diff --git a/airbyte-integrations/connectors/source-paypal-transaction/metadata.yaml b/airbyte-integrations/connectors/source-paypal-transaction/metadata.yaml index bdaa28d428ce..c4e0674cfa88 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/metadata.yaml +++ b/airbyte-integrations/connectors/source-paypal-transaction/metadata.yaml @@ -6,7 +6,7 @@ data: connectorSubtype: api connectorType: source definitionId: d913b0f2-cc51-4e55-a44c-8ba1697b9239 - dockerImageTag: 1.0.0 + dockerImageTag: 2.0.0 dockerRepository: airbyte/source-paypal-transaction githubIssueLabel: source-paypal-transaction icon: paypal.svg diff --git a/airbyte-integrations/connectors/source-paypal-transaction/source_paypal_transaction/schemas/balances.json b/airbyte-integrations/connectors/source-paypal-transaction/source_paypal_transaction/schemas/balances.json index cfed43f13e47..7fa6cf28d5ae 100644 --- a/airbyte-integrations/connectors/source-paypal-transaction/source_paypal_transaction/schemas/balances.json +++ b/airbyte-integrations/connectors/source-paypal-transaction/source_paypal_transaction/schemas/balances.json @@ -1,49 +1,53 @@ { - "$schema": "http://json-schema.org/draft-07/schema#", + "$schema": "https://json-schema.org/draft-07/schema#", "type": ["null", "object"], "properties": { - "balance": { - "type": ["null", "object"], - "properties": { - "currency": { - "type": ["null", "string"] - }, - "primary": { - "type": ["null", "boolean"] - }, - "total_balance": { - "type": ["null", "object"], - "properties": { - "currency_code": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] + "balances": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "properties": { + "currency": { + "type": ["null", "string"] + }, + "primary": { + "type": ["null", "boolean"] + }, + "total_balance": { + "type": ["null", "object"], + "properties": { + "currency_code": { + "type": ["null", "string"] + }, + "value": { + "type": ["null", "string"] + } } - } - }, - "available_balance": { - "type": ["null", "object"], - "properties": { - "currency_code": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] + }, + "available_balance": { + "type": ["null", "object"], + "properties": { + "currency_code": { + "type": ["null", "string"] + }, + "value": { + "type": ["null", "string"] + } } - } - }, - "withheld_balance": { - "type": ["null", "object"], - "properties": { - "currency_code": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] + }, + "withheld_balance": { + "type": ["null", "object"], + "properties": { + "currency_code": { + "type": ["null", "string"] + }, + "value": { + "type": ["null", "string"] + } } } } + } }, "account_id": { diff --git a/docs/integrations/sources/paypal-transaction.md b/docs/integrations/sources/paypal-transaction.md index 4d2f8c5bd264..85277858c465 100644 --- a/docs/integrations/sources/paypal-transaction.md +++ b/docs/integrations/sources/paypal-transaction.md @@ -87,6 +87,7 @@ Transactions sync is performed with default `stream_slice_period` = 1 day, it me | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------| +| 2.0.0 | 2023-07-05 | [27916](https://github.com/airbytehq/airbyte/pull/27916) | Update `Balances` schema | | 1.0.0 | 2023-07-03 | [27968](https://github.com/airbytehq/airbyte/pull/27968) | mark `Client ID` and `Client Secret` as required fields | | 0.1.13 | 2023-02-20 | [22916](https://github.com/airbytehq/airbyte/pull/22916) | Specified date formatting in specification | | 0.1.12 | 2023-02-18 | [23211](https://github.com/airbytehq/airbyte/pull/23211) | Fix error handler | From aea5a9ec8e745a5dba2da5d302ca66d844afc7fa Mon Sep 17 00:00:00 2001 From: "Roman Yermilov [GL]" <86300758+roman-yermilov-gl@users.noreply.github.com> Date: Thu, 13 Jul 2023 15:10:41 +0400 Subject: [PATCH 53/63] Source Amazon Ads: fix Nonetype error when recordId is missing (#28155) * Source Amazon Ads: fix Nonetype error when recordId is missing * Source Amazon Ads: bump version and update changelog * Source Amazon Ads: unittest for recordId generation --- .../connectors/source-amazon-ads/Dockerfile | 2 +- .../source-amazon-ads/metadata.yaml | 2 +- .../streams/report_streams/report_streams.py | 5 ++++- .../unit_tests/test_report_streams.py | 22 +++++++++++++++++++ docs/integrations/sources/amazon-ads.md | 3 ++- 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/airbyte-integrations/connectors/source-amazon-ads/Dockerfile b/airbyte-integrations/connectors/source-amazon-ads/Dockerfile index e30c2e80141c..9ea3330ad325 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/Dockerfile +++ b/airbyte-integrations/connectors/source-amazon-ads/Dockerfile @@ -13,5 +13,5 @@ ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=2.3.0 +LABEL io.airbyte.version=2.3.1 LABEL io.airbyte.name=airbyte/source-amazon-ads diff --git a/airbyte-integrations/connectors/source-amazon-ads/metadata.yaml b/airbyte-integrations/connectors/source-amazon-ads/metadata.yaml index 39f131fd7326..492e109a6957 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/metadata.yaml +++ b/airbyte-integrations/connectors/source-amazon-ads/metadata.yaml @@ -8,7 +8,7 @@ data: connectorSubtype: api connectorType: source definitionId: c6b0a29e-1da9-4512-9002-7bfd0cba2246 - dockerImageTag: 2.3.0 + dockerImageTag: 2.3.1 dockerRepository: airbyte/source-amazon-ads githubIssueLabel: source-amazon-ads icon: amazonads.svg diff --git a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/report_streams.py b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/report_streams.py index 047a8a75e497..dd836c11e136 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/report_streams.py +++ b/airbyte-integrations/connectors/source-amazon-ads/source_amazon_ads/streams/report_streams/report_streams.py @@ -171,10 +171,13 @@ def read_records( profileId=report_info.profile_id, recordType=report_info.record_type, reportDate=report_date, - recordId=metric_object.get(self.metrics_type_to_id_map[report_info.record_type], str(uuid.uuid4())), + recordId=self.get_record_id(metric_object, report_info.record_type), metric=metric_object, ).dict() + def get_record_id(self, metric_object: dict, record_type: str) -> str: + return metric_object.get(self.metrics_type_to_id_map[record_type]) or str(uuid.uuid4()) + def backoff_max_time(func): def wrapped(self, *args, **kwargs): return backoff.on_exception(backoff.constant, RetryableException, max_time=self.report_wait_timeout * 60, interval=10)(func)( diff --git a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_report_streams.py b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_report_streams.py index 3d53cc91d051..c2b7c74e3f77 100644 --- a/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_report_streams.py +++ b/airbyte-integrations/connectors/source-amazon-ads/unit_tests/test_report_streams.py @@ -898,3 +898,25 @@ def test_brands_video_report_with_custom_record_types(config_gen, custom_record_ if record['recordType'] not in expected_record_types: if flag_match_error: assert False + + +@pytest.mark.parametrize( + "metric_object, record_type", + [ + ({"campaignId": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"}, "campaigns"), + ({"campaignId": ""}, "campaigns"), + ({"campaignId": None}, "campaigns") + ] +) +def test_get_record_id_by_report_type(config, metric_object, record_type): + """ + Test if a `recordId` is allways non-empty for any given `metric_object`. + `recordId` is not a contant key for every report. + We define suitable key for every report by its type and normally it should not be empty. + It may be `campaignId` or `adGroupId` or any other key depending on report type (See METRICS_TYPE_TO_ID_MAP). + In case when it is not defined or empty (sometimes we get one record with missing data while others are populated) + we must return `recordId` anyway so we generate it manually. + """ + profiles = make_profiles(profile_type="vendor") + stream = SponsoredProductsReportStream(config, profiles, authenticator=mock.MagicMock()) + assert stream.get_record_id(metric_object, record_type), "recordId must be non-empty value" diff --git a/docs/integrations/sources/amazon-ads.md b/docs/integrations/sources/amazon-ads.md index 594c17cf06c1..1a77119107e2 100644 --- a/docs/integrations/sources/amazon-ads.md +++ b/docs/integrations/sources/amazon-ads.md @@ -99,7 +99,8 @@ Information about expected report generation waiting time you may find [here](ht | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------| -| 2.3.0 | 2023-07-06 | [28002](https://github.com/airbytehq/airbyte/pull/28002) | Add sponsored_product_ad_group_suggested_keywords, sponsored_product_ad_group_bid_recommendations streams | +| 2.3.1 | 2023-07-11 | [28155](https://github.com/airbytehq/airbyte/pull/28155) | Bugfix: validation error when record values are missing | +| 2.3.0 | 2023-07-06 | [28002](https://github.com/airbytehq/airbyte/pull/28002) | Add sponsored_product_ad_group_suggested_keywords, sponsored_product_ad_group_bid_recommendations streams | | 2.2.0 | 2023-07-05 | [27607](https://github.com/airbytehq/airbyte/pull/27607) | Add stream for sponsored brands v3 purchased product reports | | 2.1.0 | 2023-06-19 | [25412](https://github.com/airbytehq/airbyte/pull/25412) | Add sponsored_product_campaign_negative_keywords, sponsored_display_budget_rules streams | | 2.0.0 | 2023-05-31 | [25874](https://github.com/airbytehq/airbyte/pull/25874) | Type `portfolioId` as integer | From 94fd3f5c29b94cab443ca275368e1b2eca018097 Mon Sep 17 00:00:00 2001 From: Arsen Losenko <20901439+arsenlosenko@users.noreply.github.com> Date: Thu, 13 Jul 2023 15:13:44 +0300 Subject: [PATCH 54/63] Source Sentry: update expected records (#28271) --- .../source-sentry/integration_tests/expected_records.jsonl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/airbyte-integrations/connectors/source-sentry/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-sentry/integration_tests/expected_records.jsonl index 97fac2e4d8fe..935e3ecaee19 100644 --- a/airbyte-integrations/connectors/source-sentry/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-sentry/integration_tests/expected_records.jsonl @@ -1,4 +1,4 @@ -{"stream": "project_detail", "data": {"id": "5942472", "slug": "airbyte-09", "name": "airbyte-09", "platform": "python", "dateCreated": "2021-09-02T07:42:22.421223Z", "isBookmarked": false, "isMember": true, "features": ["alert-filters", "minidump", "race-free-group-creation", "similarity-indexing", "similarity-view", "releases"], "firstEvent": null, "firstTransactionEvent": false, "access": ["event:read", "event:admin", "event:write", "project:write", "org:integrations", "alerts:read", "project:admin", "team:admin", "team:read", "member:read", "org:read", "project:read", "alerts:write", "team:write", "project:releases"], "hasAccess": true, "hasMinifiedStackTrace": false, "hasMonitors": false, "hasProfiles": false, "hasReplays": false, "hasSessions": false, "isInternal": false, "isPublic": false, "avatar": {"avatarType": "letter_avatar", "avatarUuid": null}, "color": "#803fbf", "status": "active", "team": {"id": "1170523", "slug": "airbyte", "name": "Airbyte"}, "teams": [{"id": "1170523", "slug": "airbyte", "name": "Airbyte"}], "latestRelease": {"version": "checkout-app@3.2"}, "options": {"quotas:spike-protection-disabled": false, "sentry:token": "5006ad000bc111ec95cd8e5fccda0a6a", "sentry:option-epoch": 7, "sentry:csp_ignored_sources_defaults": true, "sentry:csp_ignored_sources": "", "sentry:reprocessing_active": false, "filters:blacklisted_ips": "", "filters:react-hydration-errors": true, "filters:releases": "", "filters:error_messages": "", "feedback:branding": true}, "digestsMinDelay": 300, "digestsMaxDelay": 1800, "subjectPrefix": "", "allowedDomains": ["*"], "resolveAge": 0, "dataScrubber": true, "dataScrubberDefaults": true, "safeFields": [], "recapServerUrl": null, "storeCrashReports": null, "sensitiveFields": [], "subjectTemplate": "$shortID - $title", "securityToken": "5006ad000bc111ec95cd8e5fccda0a6a", "securityTokenHeader": null, "verifySSL": false, "scrubIPAddresses": false, "scrapeJavaScript": true, "groupingConfig": "newstyle:2023-01-11", "groupingEnhancements": "", "groupingEnhancementsBase": null, "secondaryGroupingExpiry": 0, "secondaryGroupingConfig": null, "groupingAutoUpdate": true, "fingerprintingRules": "", "organization": {"id": "985996", "slug": "airbyte-09", "status": {"id": "active", "name": "active"}, "name": "Airbyte", "dateCreated": "2021-09-02T07:41:55.899035Z", "isEarlyAdopter": false, "require2FA": false, "requireEmailVerification": false, "avatar": {"avatarType": "letter_avatar", "avatarUuid": null}, "features": ["device-classification", "profile-image-decode-main-thread-visible", "monitors", "performance-n-plus-one-api-calls-visible", "shared-issues", "promotion-be-adoption-enabled", "performance-m-n-plus-one-db-queries-visible", "performance-issues-render-blocking-assets-detector", "profile-image-decode-main-thread-post-process-group", "performance-new-widget-designs", "ds-sliding-window-org", "profile-json-decode-main-thread-post-process-group", "release-health-drop-sessions", "customer-domains", "symbol-sources", "performance-large-http-payload-ingest", "performance-issues-m-n-plus-one-db-detector", "transaction-metrics-extraction", "performance-m-n-plus-one-db-queries-ingest", "open-ai-suggestion", "performance-issues-all-events-tab", "performance-consecutive-db-queries-ingest", "mep-rollout-flag", "profiling-ga", "profile-file-io-main-thread-post-process-group", "advanced-search", "minute-resolution-sessions", "performance-uncompressed-assets-post-process-group", "performance-consecutive-http-visible", "auto-enable-codecov", "onboarding", "profiling-billing", "business-to-team-promotion", "transaction-name-mark-scrubbed-as-sanitized", "performance-file-io-main-thread-detector", "bundle-plan-checkout", "performance-consecutive-http-ingest", "dashboards-rh-widget", "performance-metrics-backed-transaction-summary", "performance-n-plus-one-api-calls-post-process-group", "performance-span-histogram-view", "sourcemaps-bundle-indexing", "session-replay", "performance-n-plus-one-db-queries-visible", "performance-landing-page-stats-period", "performance-db-main-thread-post-process-group", "performance-transaction-name-only-search-indexed", "integrations-deployment", "performance-mep-bannerless-ui", "performance-n-plus-one-db-queries-ingest", "performance-consecutive-http-detector", "mobile-cpu-memory-in-transactions", "performance-n-plus-one-api-calls-detector", "performance-n-plus-one-db-queries-post-process-group", "performance-issues-compressed-assets-detector", "open-membership", "performance-render-blocking-asset-span-visible", "performance-consecutive-http-post-process-group", "performance-render-blocking-asset-span-ingest", "performance-slow-db-query-post-process-group", "org-subdomains", "invite-members-rate-limits", "issue-platform", "performance-consecutive-db-queries-visible", "india-promotion", "performance-large-http-payload-post-process-group", "session-replay-ui", "performance-issues-search", "performance-large-http-payload-detector", "onboarding-project-deletion-on-back-click", "performance-file-io-main-thread-post-process-group", "performance-slow-db-issue", "performance-m-n-plus-one-db-queries-post-process-group", "track-button-click-events", "streamline-targeting-context", "session-replay-recording-scrubbing", "profile-file-io-main-thread-visible", "derive-code-mappings", "am2-billing", "transaction-name-normalize-legacy", "session-replay-index-subquery", "crons-issue-platform", "crons-timeline-listing-page", "performance-consecutive-db-queries-post-process-group", "ondemand-budgets", "metric-alert-chartcuterie", "discover-events-rate-limit", "alert-crash-free-metrics", "profile-json-decode-main-thread-ingest", "event-attachments", "anr-rate", "sql-format", "performance-n-plus-one-api-calls-ingest", "profile-file-io-main-thread-ingest", "performance-file-io-main-thread-visible", "profile-image-decode-main-thread-ingest", "performance-large-http-payload-visible", "new-spike-protection", "slack-overage-notifications", "getting-started-doc-with-product-selection", "transaction-name-normalize", "performance-db-main-thread-ingest", "session-replay-errors-tab", "metrics-extraction", "performance-slow-db-query-ingest", "paid-to-free-promotion", "project-stats", "performance-uncompressed-assets-visible", "issue-alert-fallback-targeting", "profiling", "device-class-synthesis", "promotion-mobperf-discount20", "performance-onboarding-checklist", "performance-slow-db-query-visible", "profile-json-decode-main-thread-visible", "performance-db-main-thread-visible", "issue-list-prefetch-issue-on-hover", "onboarding-sdk-selection", "integrations-stacktrace-link", "performance-render-blocking-asset-span-post-process-group", "promotion-mobperf-gift50kerr", "dynamic-sampling", "performance-db-main-thread-detector", "performance-view", "performance-file-io-main-thread-ingest", "performance-consecutive-db-issue", "performance-uncompressed-assets-ingest", "team-project-creation-all"], "links": {"organizationUrl": "https://airbyte-09.sentry.io", "regionUrl": "https://us.sentry.io"}, "hasAuthProvider": false}, "plugins": [], "platforms": ["python"], "processingIssues": 0, "defaultEnvironment": null, "relayPiiConfig": null, "builtinSymbolSources": ["ios", "microsoft", "android"], "dynamicSamplingBiases": [{"id": "boostEnvironments", "active": true}, {"id": "boostLatestRelease", "active": true}, {"id": "ignoreHealthChecks", "active": true}, {"id": "boostKeyTransactions", "active": true}, {"id": "boostLowVolumeTransactions", "active": true}, {"id": "boostReplayId", "active": true}, {"id": "recalibrationRule", "active": true}], "eventProcessing": {"symbolicationDegraded": false}, "symbolSources": "[]"}, "emitted_at": 1688656993283} +{"stream": "project_detail", "data": {"id": "5942472", "slug": "airbyte-09", "name": "airbyte-09", "platform": "python", "dateCreated": "2021-09-02T07:42:22.421223Z", "isBookmarked": false, "isMember": true, "features": ["alert-filters", "minidump", "race-free-group-creation", "similarity-indexing", "similarity-view", "releases"], "firstEvent": null, "firstTransactionEvent": false, "access": ["member:read", "org:read", "team:admin", "event:admin", "org:integrations", "team:read", "event:read", "project:write", "project:releases", "alerts:read", "project:read", "event:write", "team:write", "alerts:write", "project:admin"], "hasAccess": true, "hasMinifiedStackTrace": false, "hasMonitors": false, "hasProfiles": false, "hasReplays": false, "hasSessions": false, "isInternal": false, "isPublic": false, "avatar": {"avatarType": "letter_avatar", "avatarUuid": null}, "color": "#803fbf", "status": "active", "team": {"id": "1170523", "slug": "airbyte", "name": "Airbyte"}, "teams": [{"id": "1170523", "slug": "airbyte", "name": "Airbyte"}], "latestRelease": {"version": "checkout-app@3.2"}, "options": {"quotas:spike-protection-disabled": false, "sentry:token": "5006ad000bc111ec95cd8e5fccda0a6a", "sentry:option-epoch": 7, "sentry:csp_ignored_sources_defaults": true, "sentry:csp_ignored_sources": "", "sentry:reprocessing_active": false, "filters:blacklisted_ips": "", "filters:react-hydration-errors": true, "filters:releases": "", "filters:error_messages": "", "feedback:branding": true}, "digestsMinDelay": 300, "digestsMaxDelay": 1800, "subjectPrefix": "", "allowedDomains": ["*"], "resolveAge": 0, "dataScrubber": true, "dataScrubberDefaults": true, "safeFields": [], "recapServerUrl": null, "storeCrashReports": null, "sensitiveFields": [], "subjectTemplate": "$shortID - $title", "securityToken": "5006ad000bc111ec95cd8e5fccda0a6a", "securityTokenHeader": null, "verifySSL": false, "scrubIPAddresses": false, "scrapeJavaScript": true, "groupingConfig": "newstyle:2023-01-11", "groupingEnhancements": "", "groupingEnhancementsBase": null, "secondaryGroupingExpiry": 0, "secondaryGroupingConfig": null, "groupingAutoUpdate": true, "fingerprintingRules": "", "organization": {"id": "985996", "slug": "airbyte-09", "status": {"id": "active", "name": "active"}, "name": "Airbyte", "dateCreated": "2021-09-02T07:41:55.899035Z", "isEarlyAdopter": false, "require2FA": false, "requireEmailVerification": false, "avatar": {"avatarType": "letter_avatar", "avatarUuid": null}, "features": ["anr-rate", "paid-to-free-promotion", "performance-m-n-plus-one-db-queries-visible", "performance-file-io-main-thread-visible", "customer-domains", "performance-landing-page-stats-period", "performance-uncompressed-assets-visible", "profile-image-decode-main-thread-ingest", "integrations-deployment", "performance-consecutive-db-queries-visible", "streamline-targeting-context", "performance-large-http-payload-visible", "assign-to-me", "issue-platform", "performance-render-blocking-asset-span-ingest", "sourcemaps-bundle-indexing", "bundle-plan-checkout", "symbol-sources", "release-health-drop-sessions", "profile-image-decode-main-thread-visible", "performance-db-main-thread-post-process-group", "profile-image-decode-main-thread-post-process-group", "performance-issues-all-events-tab", "performance-consecutive-http-ingest", "performance-n-plus-one-db-queries-post-process-group", "ondemand-budgets", "performance-slow-db-query-ingest", "performance-consecutive-http-post-process-group", "performance-db-main-thread-ingest", "performance-issues-compressed-assets-detector", "crons-timeline-listing-page", "team-project-creation-all", "dynamic-sampling", "promotion-be-adoption-enabled", "onboarding", "performance-onboarding-checklist", "performance-span-histogram-view", "performance-m-n-plus-one-db-queries-ingest", "performance-issues-m-n-plus-one-db-detector", "alert-crash-free-metrics", "performance-large-http-payload-ingest", "invite-members-rate-limits", "integrations-stacktrace-link", "promotion-mobperf-gift50kerr", "performance-render-blocking-asset-span-post-process-group", "transaction-name-normalize", "transaction-metrics-extraction", "business-to-team-promotion", "performance-n-plus-one-api-calls-detector", "dashboards-rh-widget", "transaction-name-mark-scrubbed-as-sanitized", "performance-consecutive-db-queries-ingest", "performance-slow-db-issue", "session-replay", "profile-json-decode-main-thread-visible", "metrics-extraction", "profile-file-io-main-thread-ingest", "performance-m-n-plus-one-db-queries-post-process-group", "performance-uncompressed-assets-post-process-group", "monitors", "onboarding-sdk-selection", "performance-n-plus-one-db-queries-visible", "performance-n-plus-one-api-calls-visible", "performance-n-plus-one-api-calls-post-process-group", "performance-consecutive-db-issue", "performance-mep-bannerless-ui", "performance-consecutive-db-queries-post-process-group", "profile-file-io-main-thread-post-process-group", "mobile-cpu-memory-in-transactions", "performance-slow-db-query-post-process-group", "device-classification", "issue-alert-fallback-targeting", "performance-uncompressed-assets-ingest", "performance-slow-db-query-visible", "profile-file-io-main-thread-visible", "performance-issues-search", "performance-consecutive-http-visible", "promotion-mobperf-discount20", "minute-resolution-sessions", "onboarding-project-deletion-on-back-click", "profiling", "metric-alert-chartcuterie", "mute-metric-alerts", "device-class-synthesis", "performance-new-widget-designs", "getting-started-doc-with-product-selection", "profiling-billing", "profiling-ga", "open-ai-suggestion", "org-subdomains", "performance-view", "session-replay-ui", "performance-n-plus-one-db-queries-ingest", "profile-json-decode-main-thread-post-process-group", "performance-render-blocking-asset-span-visible", "performance-metrics-backed-transaction-summary", "derive-code-mappings", "performance-file-io-main-thread-post-process-group", "performance-db-main-thread-detector", "track-button-click-events", "event-attachments", "performance-file-io-main-thread-ingest", "performance-large-http-payload-post-process-group", "open-membership", "issue-list-better-priority-sort", "shared-issues", "performance-transaction-name-only-search-indexed", "project-stats", "mep-rollout-flag", "ds-sliding-window-org", "am2-billing", "performance-issues-render-blocking-assets-detector", "slack-overage-notifications", "india-promotion", "session-replay-recording-scrubbing", "slack-use-new-lookup", "crons-issue-platform", "performance-file-io-main-thread-detector", "auto-enable-codecov", "discover-events-rate-limit", "performance-db-main-thread-visible", "performance-consecutive-http-detector", "performance-large-http-payload-detector", "profile-json-decode-main-thread-ingest", "advanced-search", "performance-n-plus-one-api-calls-ingest"], "links": {"organizationUrl": "https://airbyte-09.sentry.io", "regionUrl": "https://us.sentry.io"}, "hasAuthProvider": false}, "plugins": [], "platforms": [], "processingIssues": 0, "defaultEnvironment": null, "relayPiiConfig": null, "builtinSymbolSources": ["ios", "microsoft", "android"], "dynamicSamplingBiases": [{"id": "boostEnvironments", "active": true}, {"id": "boostLatestRelease", "active": true}, {"id": "ignoreHealthChecks", "active": true}, {"id": "boostKeyTransactions", "active": true}, {"id": "boostLowVolumeTransactions", "active": true}, {"id": "boostReplayId", "active": true}, {"id": "recalibrationRule", "active": true}], "eventProcessing": {"symbolicationDegraded": false}, "symbolSources": "[]"}, "emitted_at": 1689246410694} {"stream":"projects","data":{"id":"6712547","slug":"demo-integration","name":"demo-integration","platform":"javascript-react","dateCreated":"2022-09-02T15:01:28.946777Z","isBookmarked":false,"isMember":true,"features":["alert-filters","minidump","race-free-group-creation","similarity-indexing","similarity-view"],"firstEvent":"2022-09-02T15:36:50.870000Z","firstTransactionEvent":false,"access":["org:integrations","team:read","alerts:write","alerts:read","project:read","member:read","project:write","project:admin","event:admin","team:write","event:write","project:releases","team:admin","event:read","org:read"],"hasAccess":true,"hasMinifiedStackTrace":false,"hasMonitors":false,"hasProfiles":false,"hasReplays":false,"hasSessions":false,"isInternal":false,"isPublic":false,"avatar":{"avatarType":"letter_avatar","avatarUuid":null},"color":"#bf833f","status":"active","organization":{"id":"985996","slug":"airbyte-09","status":{"id":"active","name":"active"},"name":"Airbyte","dateCreated":"2021-09-02T07:41:55.899035Z","isEarlyAdopter":false,"require2FA":false,"requireEmailVerification":false,"avatar":{"avatarType":"letter_avatar","avatarUuid":null},"features":["metrics-extraction","new-spike-protection","promotion-mobperf-discount20","session-replay-recording-scrubbing","performance-m-n-plus-one-db-queries-ingest","performance-consecutive-db-queries-ingest","sql-format","slack-overage-notifications","ondemand-budgets","issue-list-prefetch-issue-on-hover","profiling","performance-render-blocking-asset-span-ingest","getting-started-doc-with-product-selection","performance-consecutive-http-post-process-group","performance-view","integrations-stacktrace-link","dashboards-rh-widget","bundle-plan-checkout","invite-members-rate-limits","advanced-search","performance-db-main-thread-detector","integrations-deployment","profile-json-decode-main-thread-post-process-group","transaction-name-mark-scrubbed-as-sanitized","performance-db-main-thread-ingest","india-promotion","performance-consecutive-db-issue","performance-mep-bannerless-ui","performance-consecutive-http-detector","device-class-synthesis","auto-enable-codecov","performance-n-plus-one-api-calls-post-process-group","performance-render-blocking-asset-span-post-process-group","metric-alert-chartcuterie","session-replay","performance-landing-page-stats-period","transaction-name-normalize","symbol-sources","performance-issues-search","profile-json-decode-main-thread-ingest","sentry-pride-logo-footer","performance-uncompressed-assets-visible","profile-file-io-main-thread-visible","project-stats","performance-n-plus-one-api-calls-visible","performance-file-io-main-thread-ingest","profile-image-decode-main-thread-post-process-group","release-health-drop-sessions","minute-resolution-sessions","onboarding","performance-span-histogram-view","profile-image-decode-main-thread-ingest","profile-json-decode-main-thread-visible","paid-to-free-promotion","performance-file-io-main-thread-post-process-group","source-maps-debug-ids","performance-large-http-payload-post-process-group","performance-m-n-plus-one-db-queries-visible","profile-image-decode-main-thread-visible","ds-sliding-window-org","performance-issues-all-events-tab","performance-consecutive-db-queries-visible","streamline-targeting-context","onboarding-sdk-selection","session-replay-click-search-banner-rollout","performance-onboarding-checklist","discover-events-rate-limit","performance-m-n-plus-one-db-queries-post-process-group","shared-issues","performance-issues-m-n-plus-one-db-detector","profiling-billing","open-ai-suggestion","anr-rate","performance-n-plus-one-db-queries-visible","business-to-team-promotion","monitors","performance-slow-db-issue","team-project-creation-all","session-replay-index-subquery","performance-file-io-main-thread-visible","crons-issue-platform","performance-issues-compressed-assets-detector","performance-db-main-thread-post-process-group","performance-transaction-name-only-search-indexed","alert-crash-free-metrics","performance-slow-db-query-visible","dynamic-sampling-transaction-name-priority","performance-n-plus-one-db-queries-post-process-group","performance-render-blocking-asset-span-visible","onboarding-project-deletion-on-back-click","session-replay-ga","performance-file-io-main-thread-detector","profile-file-io-main-thread-post-process-group","promotion-mobperf-gift50kerr","performance-db-main-thread-visible","performance-n-plus-one-api-calls-ingest","performance-n-plus-one-db-queries-ingest","am2-billing","performance-uncompressed-assets-post-process-group","performance-metrics-backed-transaction-summary","performance-n-plus-one-api-calls-detector","performance-slow-db-query-post-process-group","performance-large-http-payload-ingest","ds-boost-new-projects","customer-domains","mobile-cpu-memory-in-transactions","session-replay-network-details","performance-slow-db-query-ingest","issue-alert-fallback-targeting","performance-consecutive-http-visible","performance-uncompressed-assets-ingest","session-replay-ui","performance-consecutive-db-queries-post-process-group","profiling-ga","open-membership","performance-new-widget-designs","crons-timeline-listing-page","event-attachments","mep-rollout-flag","device-classification","derive-code-mappings","profile-file-io-main-thread-ingest","issue-platform","track-button-click-events","performance-issues-render-blocking-assets-detector","dynamic-sampling","performance-large-http-payload-visible","transaction-metrics-extraction","performance-large-http-payload-detector","performance-consecutive-http-ingest","promotion-be-adoption-enabled","org-subdomains"],"links":{"organizationUrl":"https://airbyte-09.sentry.io","regionUrl":"https://us.sentry.io"},"hasAuthProvider":false}},"emitted_at":1687535328146} {"stream":"projects","data":{"id":"5942472","slug":"airbyte-09","name":"airbyte-09","platform":"python","dateCreated":"2021-09-02T07:42:22.421223Z","isBookmarked":false,"isMember":true,"features":["alert-filters","minidump","race-free-group-creation","similarity-indexing","similarity-view","releases"],"firstEvent":null,"firstTransactionEvent":false,"access":["org:integrations","team:read","alerts:write","alerts:read","project:read","member:read","project:write","project:admin","event:admin","team:write","event:write","project:releases","team:admin","event:read","org:read"],"hasAccess":true,"hasMinifiedStackTrace":false,"hasMonitors":false,"hasProfiles":false,"hasReplays":false,"hasSessions":false,"isInternal":false,"isPublic":false,"avatar":{"avatarType":"letter_avatar","avatarUuid":null},"color":"#803fbf","status":"active","organization":{"id":"985996","slug":"airbyte-09","status":{"id":"active","name":"active"},"name":"Airbyte","dateCreated":"2021-09-02T07:41:55.899035Z","isEarlyAdopter":false,"require2FA":false,"requireEmailVerification":false,"avatar":{"avatarType":"letter_avatar","avatarUuid":null},"features":["metrics-extraction","new-spike-protection","promotion-mobperf-discount20","session-replay-recording-scrubbing","performance-m-n-plus-one-db-queries-ingest","performance-consecutive-db-queries-ingest","sql-format","slack-overage-notifications","ondemand-budgets","issue-list-prefetch-issue-on-hover","profiling","performance-render-blocking-asset-span-ingest","getting-started-doc-with-product-selection","performance-consecutive-http-post-process-group","performance-view","integrations-stacktrace-link","dashboards-rh-widget","bundle-plan-checkout","invite-members-rate-limits","advanced-search","performance-db-main-thread-detector","integrations-deployment","profile-json-decode-main-thread-post-process-group","transaction-name-mark-scrubbed-as-sanitized","performance-db-main-thread-ingest","india-promotion","performance-consecutive-db-issue","performance-mep-bannerless-ui","performance-consecutive-http-detector","device-class-synthesis","auto-enable-codecov","performance-n-plus-one-api-calls-post-process-group","performance-render-blocking-asset-span-post-process-group","metric-alert-chartcuterie","session-replay","performance-landing-page-stats-period","transaction-name-normalize","symbol-sources","performance-issues-search","profile-json-decode-main-thread-ingest","sentry-pride-logo-footer","performance-uncompressed-assets-visible","profile-file-io-main-thread-visible","project-stats","performance-n-plus-one-api-calls-visible","performance-file-io-main-thread-ingest","profile-image-decode-main-thread-post-process-group","release-health-drop-sessions","minute-resolution-sessions","onboarding","performance-span-histogram-view","profile-image-decode-main-thread-ingest","profile-json-decode-main-thread-visible","paid-to-free-promotion","performance-file-io-main-thread-post-process-group","source-maps-debug-ids","performance-large-http-payload-post-process-group","performance-m-n-plus-one-db-queries-visible","profile-image-decode-main-thread-visible","ds-sliding-window-org","performance-issues-all-events-tab","performance-consecutive-db-queries-visible","streamline-targeting-context","onboarding-sdk-selection","session-replay-click-search-banner-rollout","performance-onboarding-checklist","discover-events-rate-limit","performance-m-n-plus-one-db-queries-post-process-group","shared-issues","performance-issues-m-n-plus-one-db-detector","profiling-billing","open-ai-suggestion","anr-rate","performance-n-plus-one-db-queries-visible","business-to-team-promotion","monitors","performance-slow-db-issue","team-project-creation-all","session-replay-index-subquery","performance-file-io-main-thread-visible","crons-issue-platform","performance-issues-compressed-assets-detector","performance-db-main-thread-post-process-group","performance-transaction-name-only-search-indexed","alert-crash-free-metrics","performance-slow-db-query-visible","dynamic-sampling-transaction-name-priority","performance-n-plus-one-db-queries-post-process-group","performance-render-blocking-asset-span-visible","onboarding-project-deletion-on-back-click","session-replay-ga","performance-file-io-main-thread-detector","profile-file-io-main-thread-post-process-group","promotion-mobperf-gift50kerr","performance-db-main-thread-visible","performance-n-plus-one-api-calls-ingest","performance-n-plus-one-db-queries-ingest","am2-billing","performance-uncompressed-assets-post-process-group","performance-metrics-backed-transaction-summary","performance-n-plus-one-api-calls-detector","performance-slow-db-query-post-process-group","performance-large-http-payload-ingest","ds-boost-new-projects","customer-domains","mobile-cpu-memory-in-transactions","session-replay-network-details","performance-slow-db-query-ingest","issue-alert-fallback-targeting","performance-consecutive-http-visible","performance-uncompressed-assets-ingest","session-replay-ui","performance-consecutive-db-queries-post-process-group","profiling-ga","open-membership","performance-new-widget-designs","crons-timeline-listing-page","event-attachments","mep-rollout-flag","device-classification","derive-code-mappings","profile-file-io-main-thread-ingest","issue-platform","track-button-click-events","performance-issues-render-blocking-assets-detector","dynamic-sampling","performance-large-http-payload-visible","transaction-metrics-extraction","performance-large-http-payload-detector","performance-consecutive-http-ingest","promotion-be-adoption-enabled","org-subdomains"],"links":{"organizationUrl":"https://airbyte-09.sentry.io","regionUrl":"https://us.sentry.io"},"hasAuthProvider":false}},"emitted_at":1687535328148} -{"stream":"releases","data":{"id":289364918,"version":"checkout-app@3.2","status":"open","shortVersion":"checkout-app@3.2","versionInfo":{"package":"checkout-app","version":{"raw":"3.2","major":3,"minor":2,"patch":0,"pre":null,"buildCode":null,"components":2},"description":"3.2","buildHash":null},"ref":null,"url":null,"dateReleased":null,"dateCreated":"2021-09-02T08:10:12.826000Z","data":{},"newGroups":0,"owner":null,"commitCount":0,"lastCommit":null,"deployCount":0,"lastDeploy":null,"authors":[],"projects":[{"id":5942472,"slug":"airbyte-09","name":"airbyte-09","newGroups":0,"platform":"python","platforms":["python"],"hasHealthData":false}],"firstEvent":null,"lastEvent":null,"currentProjectMeta":{},"userAgent":null},"emitted_at":1687535329104} +{"stream": "releases", "data": {"id": 289364918, "version": "checkout-app@3.2", "status": "open", "shortVersion": "checkout-app@3.2", "versionInfo": {"package": "checkout-app", "version": {"raw": "3.2", "major": 3, "minor": 2, "patch": 0, "pre": null, "buildCode": null, "components": 2}, "description": "3.2", "buildHash": null}, "ref": null, "url": null, "dateReleased": null, "dateCreated": "2021-09-02T08:10:12.826000Z", "data": {}, "newGroups": 0, "owner": null, "commitCount": 0, "lastCommit": null, "deployCount": 0, "lastDeploy": null, "authors": [], "projects": [{"id": 5942472, "slug": "airbyte-09", "name": "airbyte-09", "newGroups": 0, "platform": "python", "platforms": [], "hasHealthData": false}], "firstEvent": null, "lastEvent": null, "currentProjectMeta": {}, "userAgent": null}, "emitted_at": 1689246658349} From 3f8c87d5e085564c86611b6b33d739fe0af59810 Mon Sep 17 00:00:00 2001 From: Arsen Losenko <20901439+arsenlosenko@users.noreply.github.com> Date: Thu, 13 Jul 2023 15:14:21 +0300 Subject: [PATCH 55/63] =?UTF-8?q?=F0=9F=90=9B=20Source=20Hubspot:=20update?= =?UTF-8?q?=20expected=20records=20(#28040)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Source Hubstpo: update expected records * Update contacts, email_events, goals expected records * Update CAT config * Update goals expected records --- .../source-hubspot/acceptance-test-config.yml | 2 ++ .../integration_tests/expected_records.jsonl | 32 ++++++++----------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/airbyte-integrations/connectors/source-hubspot/acceptance-test-config.yml b/airbyte-integrations/connectors/source-hubspot/acceptance-test-config.yml index c1ed7d4424b7..c5d58431fac0 100644 --- a/airbyte-integrations/connectors/source-hubspot/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-hubspot/acceptance-test-config.yml @@ -39,6 +39,8 @@ acceptance_tests: bypass_reason: Unable to populate - name: quotes bypass_reason: Unable to populate + - name: deals_archived + bypass_reason: Unable to populate ignored_fields: contact_lists: - name: ilsFilterBranch diff --git a/airbyte-integrations/connectors/source-hubspot/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-hubspot/integration_tests/expected_records.jsonl index 9069a222206a..bc0d3805f203 100644 --- a/airbyte-integrations/connectors/source-hubspot/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-hubspot/integration_tests/expected_records.jsonl @@ -1,18 +1,16 @@ -{"stream":"campaigns","data":{"id":243851494,"lastUpdatedTime":1675121674226,"appId":113,"appName":"Batch","contentId":100523515217,"subject":"test","name":"test","counters":{"dropped":1},"lastProcessingFinishedAt":1675121674000,"lastProcessingStartedAt":1675121671000,"lastProcessingStateChangeAt":1675121674000,"numIncluded":1,"processingState":"DONE","type":"BATCH_EMAIL"},"emitted_at":1688056093971} -{"stream":"campaigns","data":{"id":115429485,"lastUpdatedTime":1615506409286,"appId":113,"appName":"Batch","contentId":42931043849,"subject":"Test subj","name":"Test subj","counters":{"processed":1,"deferred":1,"mta_dropped":1,"dropped":3,"sent":0},"lastProcessingFinishedAt":1615504712000,"lastProcessingStartedAt":1615504687000,"lastProcessingStateChangeAt":1615504712000,"numIncluded":3,"processingState":"DONE","type":"BATCH_EMAIL"},"emitted_at":1688056094127} +{"stream": "campaigns", "data": {"id": 243851494, "lastUpdatedTime": 1675121674226, "appId": 113, "appName": "Batch", "contentId": 100523515217, "subject": "test", "name": "test", "counters": {"dropped": 1}, "lastProcessingFinishedAt": 1675121674000, "lastProcessingStartedAt": 1675121671000, "lastProcessingStateChangeAt": 1675121674000, "numIncluded": 1, "processingState": "DONE", "type": "BATCH_EMAIL"}, "emitted_at": 1688723569670} {"stream":"companies","data":{"id":"4992593519","properties":{"about_us":null,"address":null,"address2":null,"annualrevenue":null,"city":"San Francisco","closedate":null,"closedate_timestamp_earliest_value_a2a17e6e":null,"country":"United States","createdate":"2020-12-10T07:58:09.554000+00:00","custom_company_property":null,"days_to_close":null,"description":"Airbyte is an open-source data integration platform to build ELT pipelines. Consolidate your data in your data warehouses, lakes and databases.","domain":"airbyte.io","engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"facebook_company_page":null,"facebookfans":null,"first_contact_createdate":null,"first_contact_createdate_timestamp_earliest_value_78b50eea":null,"first_conversion_date":null,"first_conversion_date_timestamp_earliest_value_61f58f2c":null,"first_conversion_event_name":null,"first_conversion_event_name_timestamp_earliest_value_68ddae0a":null,"first_deal_created_date":"2021-05-21T10:17:06.028000+00:00","founded_year":"2020","googleplus_page":null,"hs_additional_domains":null,"hs_all_accessible_team_ids":null,"hs_all_owner_ids":"52550153","hs_all_team_ids":null,"hs_analytics_first_timestamp":null,"hs_analytics_first_timestamp_timestamp_earliest_value_11e3a63a":null,"hs_analytics_first_touch_converting_campaign":null,"hs_analytics_first_touch_converting_campaign_timestamp_earliest_value_4757fe10":null,"hs_analytics_first_visit_timestamp":null,"hs_analytics_first_visit_timestamp_timestamp_earliest_value_accc17ae":null,"hs_analytics_last_timestamp":null,"hs_analytics_last_timestamp_timestamp_latest_value_4e16365a":null,"hs_analytics_last_touch_converting_campaign":null,"hs_analytics_last_touch_converting_campaign_timestamp_latest_value_81a64e30":null,"hs_analytics_last_visit_timestamp":null,"hs_analytics_last_visit_timestamp_timestamp_latest_value_999a0fce":null,"hs_analytics_latest_source":null,"hs_analytics_latest_source_data_1":null,"hs_analytics_latest_source_data_2":null,"hs_analytics_latest_source_timestamp":null,"hs_analytics_num_page_views":null,"hs_analytics_num_page_views_cardinality_sum_e46e85b0":null,"hs_analytics_num_visits":null,"hs_analytics_num_visits_cardinality_sum_53d952a6":null,"hs_analytics_source":null,"hs_analytics_source_data_1":null,"hs_analytics_source_data_1_timestamp_earliest_value_9b2f1fa1":null,"hs_analytics_source_data_2":null,"hs_analytics_source_data_2_timestamp_earliest_value_9b2f9400":null,"hs_analytics_source_timestamp_earliest_value_25a3a52c":null,"hs_annual_revenue_currency_code":"USD","hs_avatar_filemanager_key":null,"hs_created_by_user_id":12282590,"hs_createdate":null,"hs_date_entered_customer":null,"hs_date_entered_evangelist":null,"hs_date_entered_lead":null,"hs_date_entered_marketingqualifiedlead":null,"hs_date_entered_opportunity":"2021-05-21T10:17:28.964000+00:00","hs_date_entered_other":null,"hs_date_entered_salesqualifiedlead":null,"hs_date_entered_subscriber":null,"hs_date_exited_customer":null,"hs_date_exited_evangelist":null,"hs_date_exited_lead":null,"hs_date_exited_marketingqualifiedlead":null,"hs_date_exited_opportunity":null,"hs_date_exited_other":null,"hs_date_exited_salesqualifiedlead":null,"hs_date_exited_subscriber":null,"hs_ideal_customer_profile":null,"hs_is_target_account":null,"hs_last_booked_meeting_date":null,"hs_last_logged_call_date":null,"hs_last_open_task_date":null,"hs_last_sales_activity_date":null,"hs_last_sales_activity_timestamp":null,"hs_last_sales_activity_type":null,"hs_lastmodifieddate":"2023-01-26T11:45:49.817000+00:00","hs_latest_createdate_of_active_subscriptions":null,"hs_latest_meeting_activity":null,"hs_lead_status":null,"hs_merged_object_ids":null,"hs_num_blockers":null,"hs_num_child_companies":0,"hs_num_contacts_with_buying_roles":null,"hs_num_decision_makers":null,"hs_num_open_deals":1,"hs_object_id":4992593519,"hs_parent_company_id":null,"hs_pinned_engagement_id":null,"hs_pipeline":null,"hs_predictivecontactscore_v2":null,"hs_predictivecontactscore_v2_next_max_max_d4e58c1e":null,"hs_read_only":null,"hs_sales_email_last_replied":null,"hs_target_account":null,"hs_target_account_probability":0.5476861596107483,"hs_target_account_recommendation_snooze_time":null,"hs_target_account_recommendation_state":null,"hs_time_in_customer":null,"hs_time_in_evangelist":null,"hs_time_in_lead":null,"hs_time_in_marketingqualifiedlead":null,"hs_time_in_opportunity":66464803798,"hs_time_in_other":null,"hs_time_in_salesqualifiedlead":null,"hs_time_in_subscriber":null,"hs_total_deal_value":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"12282590","hs_was_imported":null,"hubspot_owner_assigneddate":"2020-12-10T07:58:09.554000+00:00","hubspot_owner_id":"52550153","hubspot_team_id":null,"hubspotscore":null,"industry":null,"is_public":false,"lifecyclestage":"opportunity","linkedin_company_page":"https://www.linkedin.com/company/airbytehq","linkedinbio":"Airbyte is an open-source data integration platform to build ELT pipelines. Consolidate your data in your data warehouses, lakes and databases.","name":"Airbyte test1","notes_last_contacted":null,"notes_last_updated":null,"notes_next_activity_date":null,"num_associated_contacts":0,"num_associated_deals":1,"num_contacted_notes":null,"num_conversion_events":null,"num_conversion_events_cardinality_sum_d095f14b":null,"num_notes":null,"numberofemployees":200,"phone":"+1 415-307-4864","recent_conversion_date":null,"recent_conversion_date_timestamp_latest_value_72856da1":null,"recent_conversion_event_name":null,"recent_conversion_event_name_timestamp_latest_value_66c820bf":null,"recent_deal_amount":null,"recent_deal_close_date":null,"state":"CA","timezone":"America/Los_Angeles","total_money_raised":null,"total_revenue":null,"twitterbio":null,"twitterfollowers":null,"twitterhandle":"AirbyteHQ","type":null,"web_technologies":"slack;segment;google_tag_manager;greenhouse;google_analytics;intercom;piwik;google_apps;hubspot;facebook_advertiser","website":"airbyte.io","zip":"94114"},"createdAt":"2020-12-10T07:58:09.554Z","updatedAt":"2023-01-26T11:45:49.817Z","archived":false},"emitted_at":1688057053048} {"stream":"companies","data":{"id":"5000526215","properties":{"about_us":null,"address":null,"address2":null,"annualrevenue":null,"city":"San Francisco","closedate":"2023-04-04T15:00:58.081000+00:00","closedate_timestamp_earliest_value_a2a17e6e":null,"country":"United States","createdate":"2020-12-11T01:27:40.002000+00:00","custom_company_property":null,"days_to_close":844,"description":"Airbyte is an open-source data integration platform to build ELT pipelines. Consolidate your data in your data warehouses, lakes and databases.","domain":"dataline.io","engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"facebook_company_page":null,"facebookfans":null,"first_contact_createdate":"2020-12-11T01:29:50.116000+00:00","first_contact_createdate_timestamp_earliest_value_78b50eea":null,"first_conversion_date":null,"first_conversion_date_timestamp_earliest_value_61f58f2c":null,"first_conversion_event_name":null,"first_conversion_event_name_timestamp_earliest_value_68ddae0a":null,"first_deal_created_date":"2021-01-13T10:30:42.221000+00:00","founded_year":"2020","googleplus_page":null,"hs_additional_domains":null,"hs_all_accessible_team_ids":null,"hs_all_owner_ids":"52550153","hs_all_team_ids":null,"hs_analytics_first_timestamp":"2020-12-11T01:29:50.116000+00:00","hs_analytics_first_timestamp_timestamp_earliest_value_11e3a63a":null,"hs_analytics_first_touch_converting_campaign":null,"hs_analytics_first_touch_converting_campaign_timestamp_earliest_value_4757fe10":null,"hs_analytics_first_visit_timestamp":null,"hs_analytics_first_visit_timestamp_timestamp_earliest_value_accc17ae":null,"hs_analytics_last_timestamp":null,"hs_analytics_last_timestamp_timestamp_latest_value_4e16365a":null,"hs_analytics_last_touch_converting_campaign":null,"hs_analytics_last_touch_converting_campaign_timestamp_latest_value_81a64e30":null,"hs_analytics_last_visit_timestamp":null,"hs_analytics_last_visit_timestamp_timestamp_latest_value_999a0fce":null,"hs_analytics_latest_source":"OFFLINE","hs_analytics_latest_source_data_1":"CONTACTS","hs_analytics_latest_source_data_2":"CRM_UI","hs_analytics_latest_source_timestamp":"2020-12-11T01:29:50.153000+00:00","hs_analytics_num_page_views":0,"hs_analytics_num_page_views_cardinality_sum_e46e85b0":null,"hs_analytics_num_visits":0,"hs_analytics_num_visits_cardinality_sum_53d952a6":null,"hs_analytics_source":"OFFLINE","hs_analytics_source_data_1":"CONTACTS","hs_analytics_source_data_1_timestamp_earliest_value_9b2f1fa1":null,"hs_analytics_source_data_2":"CRM_UI","hs_analytics_source_data_2_timestamp_earliest_value_9b2f9400":null,"hs_analytics_source_timestamp_earliest_value_25a3a52c":null,"hs_annual_revenue_currency_code":"USD","hs_avatar_filemanager_key":null,"hs_created_by_user_id":12282590,"hs_createdate":null,"hs_date_entered_customer":"2023-04-04T15:00:58.081000+00:00","hs_date_entered_evangelist":null,"hs_date_entered_lead":null,"hs_date_entered_marketingqualifiedlead":null,"hs_date_entered_opportunity":"2021-02-23T20:21:06.027000+00:00","hs_date_entered_other":null,"hs_date_entered_salesqualifiedlead":null,"hs_date_entered_subscriber":null,"hs_date_exited_customer":null,"hs_date_exited_evangelist":null,"hs_date_exited_lead":null,"hs_date_exited_marketingqualifiedlead":null,"hs_date_exited_opportunity":"2023-04-04T15:00:58.081000+00:00","hs_date_exited_other":null,"hs_date_exited_salesqualifiedlead":null,"hs_date_exited_subscriber":null,"hs_ideal_customer_profile":null,"hs_is_target_account":null,"hs_last_booked_meeting_date":null,"hs_last_logged_call_date":null,"hs_last_open_task_date":null,"hs_last_sales_activity_date":null,"hs_last_sales_activity_timestamp":null,"hs_last_sales_activity_type":null,"hs_lastmodifieddate":"2023-04-04T15:12:52.778000+00:00","hs_latest_createdate_of_active_subscriptions":null,"hs_latest_meeting_activity":null,"hs_lead_status":null,"hs_merged_object_ids":"5183403213","hs_num_blockers":0,"hs_num_child_companies":0,"hs_num_contacts_with_buying_roles":0,"hs_num_decision_makers":0,"hs_num_open_deals":2,"hs_object_id":5000526215,"hs_parent_company_id":null,"hs_pinned_engagement_id":null,"hs_pipeline":"companies-lifecycle-pipeline","hs_predictivecontactscore_v2":0.29,"hs_predictivecontactscore_v2_next_max_max_d4e58c1e":null,"hs_read_only":null,"hs_sales_email_last_replied":null,"hs_target_account":null,"hs_target_account_probability":0.46257445216178894,"hs_target_account_recommendation_snooze_time":null,"hs_target_account_recommendation_state":null,"hs_time_in_customer":7436594684,"hs_time_in_evangelist":null,"hs_time_in_lead":null,"hs_time_in_marketingqualifiedlead":null,"hs_time_in_opportunity":66508792054,"hs_time_in_other":null,"hs_time_in_salesqualifiedlead":null,"hs_time_in_subscriber":null,"hs_total_deal_value":60010,"hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"12282590","hs_was_imported":null,"hubspot_owner_assigneddate":"2020-12-11T01:27:40.002000+00:00","hubspot_owner_id":"52550153","hubspot_team_id":null,"hubspotscore":null,"industry":null,"is_public":false,"lifecyclestage":"customer","linkedin_company_page":"https://www.linkedin.com/company/airbytehq","linkedinbio":"Airbyte is an open-source data integration platform to build ELT pipelines. Consolidate your data in your data warehouses, lakes and databases.","name":"Dataline","notes_last_contacted":null,"notes_last_updated":null,"notes_next_activity_date":null,"num_associated_contacts":1,"num_associated_deals":3,"num_contacted_notes":null,"num_conversion_events":null,"num_conversion_events_cardinality_sum_d095f14b":null,"num_notes":null,"numberofemployees":25,"phone":"","recent_conversion_date":null,"recent_conversion_date_timestamp_latest_value_72856da1":null,"recent_conversion_event_name":null,"recent_conversion_event_name_timestamp_latest_value_66c820bf":null,"recent_deal_amount":60000,"recent_deal_close_date":"2023-04-04T14:59:45.103000+00:00","state":"CA","timezone":"America/Los_Angeles","total_money_raised":null,"total_revenue":60000,"twitterbio":null,"twitterfollowers":null,"twitterhandle":"AirbyteHQ","type":null,"web_technologies":"slack;segment;google_tag_manager;cloud_flare;google_analytics;intercom;lever;google_apps","website":"dataline.io","zip":""},"createdAt":"2020-12-11T01:27:40.002Z","updatedAt":"2023-04-04T15:12:52.778Z","archived":false,"contacts":["151","151"]},"emitted_at":1688057053049} {"stream":"companies","data":{"id":"5000787595","properties":{"about_us":null,"address":"2261 Market Street","address2":null,"annualrevenue":null,"city":"San Francisco","closedate":null,"closedate_timestamp_earliest_value_a2a17e6e":null,"country":"United States","createdate":"2020-12-11T01:28:27.673000+00:00","custom_company_property":null,"days_to_close":null,"description":"Airbyte is an open-source data integration platform to build ELT pipelines. Consolidate your data in your data warehouses, lakes and databases.","domain":"Daxtarity.com","engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"facebook_company_page":null,"facebookfans":null,"first_contact_createdate":null,"first_contact_createdate_timestamp_earliest_value_78b50eea":null,"first_conversion_date":null,"first_conversion_date_timestamp_earliest_value_61f58f2c":null,"first_conversion_event_name":null,"first_conversion_event_name_timestamp_earliest_value_68ddae0a":null,"first_deal_created_date":null,"founded_year":"2020","googleplus_page":null,"hs_additional_domains":null,"hs_all_accessible_team_ids":null,"hs_all_owner_ids":"52550153","hs_all_team_ids":null,"hs_analytics_first_timestamp":null,"hs_analytics_first_timestamp_timestamp_earliest_value_11e3a63a":null,"hs_analytics_first_touch_converting_campaign":null,"hs_analytics_first_touch_converting_campaign_timestamp_earliest_value_4757fe10":null,"hs_analytics_first_visit_timestamp":null,"hs_analytics_first_visit_timestamp_timestamp_earliest_value_accc17ae":null,"hs_analytics_last_timestamp":null,"hs_analytics_last_timestamp_timestamp_latest_value_4e16365a":null,"hs_analytics_last_touch_converting_campaign":null,"hs_analytics_last_touch_converting_campaign_timestamp_latest_value_81a64e30":null,"hs_analytics_last_visit_timestamp":null,"hs_analytics_last_visit_timestamp_timestamp_latest_value_999a0fce":null,"hs_analytics_latest_source":"","hs_analytics_latest_source_data_1":"","hs_analytics_latest_source_data_2":"","hs_analytics_latest_source_timestamp":null,"hs_analytics_num_page_views":null,"hs_analytics_num_page_views_cardinality_sum_e46e85b0":null,"hs_analytics_num_visits":null,"hs_analytics_num_visits_cardinality_sum_53d952a6":null,"hs_analytics_source":"","hs_analytics_source_data_1":"","hs_analytics_source_data_1_timestamp_earliest_value_9b2f1fa1":null,"hs_analytics_source_data_2":"","hs_analytics_source_data_2_timestamp_earliest_value_9b2f9400":null,"hs_analytics_source_timestamp_earliest_value_25a3a52c":null,"hs_annual_revenue_currency_code":"USD","hs_avatar_filemanager_key":null,"hs_created_by_user_id":12282590,"hs_createdate":null,"hs_date_entered_customer":null,"hs_date_entered_evangelist":null,"hs_date_entered_lead":null,"hs_date_entered_marketingqualifiedlead":null,"hs_date_entered_opportunity":null,"hs_date_entered_other":null,"hs_date_entered_salesqualifiedlead":null,"hs_date_entered_subscriber":null,"hs_date_exited_customer":null,"hs_date_exited_evangelist":null,"hs_date_exited_lead":null,"hs_date_exited_marketingqualifiedlead":null,"hs_date_exited_opportunity":null,"hs_date_exited_other":null,"hs_date_exited_salesqualifiedlead":null,"hs_date_exited_subscriber":null,"hs_ideal_customer_profile":null,"hs_is_target_account":null,"hs_last_booked_meeting_date":null,"hs_last_logged_call_date":null,"hs_last_open_task_date":null,"hs_last_sales_activity_date":null,"hs_last_sales_activity_timestamp":null,"hs_last_sales_activity_type":null,"hs_lastmodifieddate":"2023-01-23T15:41:56.644000+00:00","hs_latest_createdate_of_active_subscriptions":null,"hs_latest_meeting_activity":null,"hs_lead_status":null,"hs_merged_object_ids":null,"hs_num_blockers":0,"hs_num_child_companies":0,"hs_num_contacts_with_buying_roles":0,"hs_num_decision_makers":0,"hs_num_open_deals":0,"hs_object_id":5000787595,"hs_parent_company_id":null,"hs_pinned_engagement_id":null,"hs_pipeline":null,"hs_predictivecontactscore_v2":null,"hs_predictivecontactscore_v2_next_max_max_d4e58c1e":null,"hs_read_only":null,"hs_sales_email_last_replied":null,"hs_target_account":null,"hs_target_account_probability":0.4076234698295593,"hs_target_account_recommendation_snooze_time":null,"hs_target_account_recommendation_state":null,"hs_time_in_customer":null,"hs_time_in_evangelist":null,"hs_time_in_lead":null,"hs_time_in_marketingqualifiedlead":null,"hs_time_in_opportunity":null,"hs_time_in_other":null,"hs_time_in_salesqualifiedlead":null,"hs_time_in_subscriber":null,"hs_total_deal_value":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"12282590","hs_was_imported":null,"hubspot_owner_assigneddate":"2020-12-11T01:28:27.673000+00:00","hubspot_owner_id":"52550153","hubspot_team_id":null,"hubspotscore":null,"industry":null,"is_public":false,"lifecyclestage":null,"linkedin_company_page":"https://www.linkedin.com/company/airbytehq","linkedinbio":"Airbyte is an open-source data integration platform to build ELT pipelines. Consolidate your data in your data warehouses, lakes and databases.","name":"Daxtarity","notes_last_contacted":null,"notes_last_updated":null,"notes_next_activity_date":null,"num_associated_contacts":0,"num_associated_deals":null,"num_contacted_notes":null,"num_conversion_events":null,"num_conversion_events_cardinality_sum_d095f14b":null,"num_notes":null,"numberofemployees":50,"phone":"+1 415-307-4864","recent_conversion_date":null,"recent_conversion_date_timestamp_latest_value_72856da1":null,"recent_conversion_event_name":null,"recent_conversion_event_name_timestamp_latest_value_66c820bf":null,"recent_deal_amount":null,"recent_deal_close_date":null,"state":"CA","timezone":"America/Los_Angeles","total_money_raised":null,"total_revenue":null,"twitterbio":null,"twitterfollowers":null,"twitterhandle":"AirbyteHQ","type":null,"web_technologies":"slack;google_tag_manager;greenhouse;google_analytics;intercom;piwik;google_apps;hubspot;facebook_advertiser","website":"Daxtarity.com","zip":"94114"},"createdAt":"2020-12-11T01:28:27.673Z","updatedAt":"2023-01-23T15:41:56.644Z","archived":false},"emitted_at":1688057053050} {"stream": "contact_lists", "data": {"portalId": 8727216, "listId": 166, "createdAt": 1675120756833, "updatedAt": 1675120852460, "name": "Test", "listType": "DYNAMIC", "authorId": 12282590, "filters": [], "metaData": {"size": 3, "lastSizeChangeAt": 1675257270514, "processing": "DONE", "lastProcessingStateChangeAt": 1675120853286, "error": "", "listReferencesCount": null, "parentFolderId": null}, "archived": false, "teamIds": [], "ilsFilterBranch": "{\"filterBranchOperator\":\"OR\",\"filters\":[],\"filterBranches\":[{\"filterBranchOperator\":\"AND\",\"filters\":[{\"filterType\":\"PROPERTY\",\"property\":\"createdate\",\"operation\":{\"propertyType\":\"datetime\",\"operator\":\"IS_AFTER\",\"timestamp\":1669957199999,\"defaultValue\":null,\"includeObjectsWithNoValueSet\":false,\"requiresTimeZoneConversion\":true,\"operationType\":\"datetime\",\"operatorName\":\"IS_AFTER\"},\"frameworkFilterId\":null}],\"filterBranches\":[],\"filterBranchType\":\"AND\"}],\"filterBranchType\":\"OR\"}", "readOnly": false, "internal": false, "limitExempt": false, "dynamic": true}, "emitted_at": 1685387174847} -{"stream":"contacts","data":{"id":"151","properties":{"address":null,"annualrevenue":null,"associatedcompanyid":5000526215,"associatedcompanylastupdated":null,"city":null,"closedate":null,"company":null,"company_size":null,"country":null,"createdate":"2020-12-11T01:29:50.116000+00:00","currentlyinworkflow":null,"date_of_birth":null,"days_to_close":null,"degree":null,"email":"shef@dne.io","engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"fax":null,"field_of_study":null,"first_conversion_date":null,"first_conversion_event_name":null,"first_deal_created_date":null,"firstname":"sh","gender":null,"graduation_date":null,"hs_additional_emails":null,"hs_all_accessible_team_ids":null,"hs_all_contact_vids":"151","hs_all_owner_ids":"52550153","hs_all_team_ids":null,"hs_analytics_average_page_views":0,"hs_analytics_first_referrer":null,"hs_analytics_first_timestamp":"2020-12-11T01:29:50.116000+00:00","hs_analytics_first_touch_converting_campaign":null,"hs_analytics_first_url":null,"hs_analytics_first_visit_timestamp":null,"hs_analytics_last_referrer":null,"hs_analytics_last_timestamp":null,"hs_analytics_last_touch_converting_campaign":null,"hs_analytics_last_url":null,"hs_analytics_last_visit_timestamp":null,"hs_analytics_num_event_completions":0,"hs_analytics_num_page_views":0,"hs_analytics_num_visits":0,"hs_analytics_revenue":0,"hs_analytics_source":"OFFLINE","hs_analytics_source_data_1":"CONTACTS","hs_analytics_source_data_2":"CRM_UI","hs_avatar_filemanager_key":null,"hs_buying_role":null,"hs_calculated_form_submissions":null,"hs_calculated_merged_vids":null,"hs_calculated_mobile_number":null,"hs_calculated_phone_number":null,"hs_calculated_phone_number_area_code":null,"hs_calculated_phone_number_country_code":null,"hs_calculated_phone_number_region_code":null,"hs_clicked_linkedin_ad":null,"hs_content_membership_email":null,"hs_content_membership_email_confirmed":null,"hs_content_membership_notes":null,"hs_content_membership_registered_at":null,"hs_content_membership_registration_domain_sent_to":null,"hs_content_membership_registration_email_sent_at":null,"hs_content_membership_status":null,"hs_conversations_visitor_email":null,"hs_count_is_unworked":1,"hs_count_is_worked":0,"hs_created_by_conversations":null,"hs_created_by_user_id":null,"hs_createdate":null,"hs_date_entered_customer":null,"hs_date_entered_evangelist":null,"hs_date_entered_lead":null,"hs_date_entered_marketingqualifiedlead":null,"hs_date_entered_opportunity":null,"hs_date_entered_other":null,"hs_date_entered_salesqualifiedlead":null,"hs_date_entered_subscriber":"2020-12-11T01:29:50.116000+00:00","hs_date_exited_customer":null,"hs_date_exited_evangelist":null,"hs_date_exited_lead":null,"hs_date_exited_marketingqualifiedlead":null,"hs_date_exited_opportunity":null,"hs_date_exited_other":null,"hs_date_exited_salesqualifiedlead":null,"hs_date_exited_subscriber":null,"hs_document_last_revisited":null,"hs_email_bad_address":null,"hs_email_bounce":null,"hs_email_click":null,"hs_email_customer_quarantined_reason":null,"hs_email_delivered":null,"hs_email_domain":"dne.io","hs_email_first_click_date":null,"hs_email_first_open_date":null,"hs_email_first_reply_date":null,"hs_email_first_send_date":null,"hs_email_hard_bounce_reason":null,"hs_email_hard_bounce_reason_enum":null,"hs_email_is_ineligible":null,"hs_email_last_click_date":null,"hs_email_last_email_name":null,"hs_email_last_open_date":null,"hs_email_last_reply_date":null,"hs_email_last_send_date":null,"hs_email_open":null,"hs_email_optout":null,"hs_email_optout_10798197":null,"hs_email_optout_11890603":null,"hs_email_optout_11890831":null,"hs_email_optout_23704464":null,"hs_email_optout_94692364":null,"hs_email_quarantined":null,"hs_email_quarantined_reason":null,"hs_email_recipient_fatigue_recovery_time":null,"hs_email_replied":null,"hs_email_sends_since_last_engagement":null,"hs_emailconfirmationstatus":null,"hs_facebook_ad_clicked":null,"hs_facebook_click_id":null,"hs_feedback_last_nps_follow_up":null,"hs_feedback_last_nps_rating":null,"hs_feedback_last_survey_date":null,"hs_feedback_show_nps_web_survey":null,"hs_first_engagement_object_id":null,"hs_first_outreach_date":null,"hs_first_subscription_create_date":null,"hs_google_click_id":null,"hs_has_active_subscription":null,"hs_ip_timezone":null,"hs_is_contact":true,"hs_is_unworked":true,"hs_language":null,"hs_last_sales_activity_date":null,"hs_last_sales_activity_timestamp":null,"hs_last_sales_activity_type":null,"hs_lastmodifieddate":null,"hs_latest_meeting_activity":null,"hs_latest_sequence_ended_date":null,"hs_latest_sequence_enrolled":null,"hs_latest_sequence_enrolled_date":null,"hs_latest_sequence_finished_date":null,"hs_latest_sequence_unenrolled_date":null,"hs_latest_source":"OFFLINE","hs_latest_source_data_1":"CONTACTS","hs_latest_source_data_2":"CRM_UI","hs_latest_source_timestamp":"2020-12-11T01:29:50.153000+00:00","hs_latest_subscription_create_date":null,"hs_lead_status":null,"hs_legal_basis":null,"hs_lifecyclestage_customer_date":null,"hs_lifecyclestage_evangelist_date":null,"hs_lifecyclestage_lead_date":null,"hs_lifecyclestage_marketingqualifiedlead_date":null,"hs_lifecyclestage_opportunity_date":null,"hs_lifecyclestage_other_date":null,"hs_lifecyclestage_salesqualifiedlead_date":null,"hs_lifecyclestage_subscriber_date":"2020-12-11T01:29:50.116000+00:00","hs_linkedin_ad_clicked":null,"hs_marketable_reason_id":null,"hs_marketable_reason_type":null,"hs_marketable_status":"false","hs_marketable_until_renewal":"false","hs_merged_object_ids":null,"hs_object_id":151,"hs_persona":null,"hs_pinned_engagement_id":null,"hs_pipeline":"contacts-lifecycle-pipeline","hs_predictivecontactscore":null,"hs_predictivecontactscore_v2":0.29,"hs_predictivecontactscorebucket":null,"hs_predictivescoringtier":"tier_4","hs_read_only":null,"hs_sa_first_engagement_date":null,"hs_sa_first_engagement_descr":null,"hs_sa_first_engagement_object_type":null,"hs_sales_email_last_clicked":null,"hs_sales_email_last_opened":null,"hs_sales_email_last_replied":null,"hs_searchable_calculated_international_mobile_number":null,"hs_searchable_calculated_international_phone_number":null,"hs_searchable_calculated_mobile_number":null,"hs_searchable_calculated_phone_number":null,"hs_sequences_actively_enrolled_count":null,"hs_sequences_enrolled_count":null,"hs_sequences_is_enrolled":null,"hs_testpurge":null,"hs_testrollback":null,"hs_time_between_contact_creation_and_deal_close":null,"hs_time_between_contact_creation_and_deal_creation":null,"hs_time_in_customer":null,"hs_time_in_evangelist":null,"hs_time_in_lead":null,"hs_time_in_marketingqualifiedlead":null,"hs_time_in_opportunity":null,"hs_time_in_other":null,"hs_time_in_salesqualifiedlead":null,"hs_time_in_subscriber":80408501697,"hs_time_to_first_engagement":null,"hs_time_to_move_from_lead_to_customer":null,"hs_time_to_move_from_marketingqualifiedlead_to_customer":null,"hs_time_to_move_from_opportunity_to_customer":null,"hs_time_to_move_from_salesqualifiedlead_to_customer":null,"hs_time_to_move_from_subscriber_to_customer":null,"hs_timezone":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"12282590","hs_was_imported":null,"hs_whatsapp_phone_number":null,"hubspot_owner_assigneddate":"2020-12-11T01:29:50.093000+00:00","hubspot_owner_id":"52550153","hubspot_team_id":null,"hubspotscore":null,"industry":null,"ip_city":null,"ip_country":null,"ip_country_code":null,"ip_latlon":null,"ip_state":null,"ip_state_code":null,"ip_zipcode":null,"job_function":null,"jobtitle":null,"lastmodifieddate":"2023-03-21T19:28:17.125000+00:00","lastname":"na","lifecyclestage":"subscriber","marital_status":null,"message":null,"military_status":null,"mobilephone":null,"my_custom_test_property":null,"notes_last_contacted":null,"notes_last_updated":null,"notes_next_activity_date":null,"num_associated_deals":null,"num_contacted_notes":null,"num_conversion_events":0,"num_notes":null,"num_unique_conversion_events":0,"numemployees":null,"phone":null,"recent_conversion_date":null,"recent_conversion_event_name":null,"recent_deal_amount":null,"recent_deal_close_date":null,"relationship_status":null,"salutation":null,"school":null,"seniority":null,"start_date":null,"state":null,"surveymonkeyeventlastupdated":null,"test":null,"total_revenue":null,"twitterhandle":null,"webinareventlastupdated":null,"website":null,"work_email":null,"zip":null},"createdAt":"2020-12-11T01:29:50.116Z","updatedAt":"2023-03-21T19:28:17.125Z","archived":false,"companies":["5000526215","5000526215"]},"emitted_at":1688058691914} -{"stream":"contacts","data":{"id":"201","properties":{"address":"25 First Street","annualrevenue":null,"associatedcompanyid":5170561229,"associatedcompanylastupdated":null,"city":"Cambridge","closedate":null,"company":"HubSpot","company_size":null,"country":null,"createdate":"2021-01-14T14:26:17.014000+00:00","currentlyinworkflow":null,"date_of_birth":null,"days_to_close":null,"degree":null,"email":"testingapis@hubspot.com","engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"fax":null,"field_of_study":null,"first_conversion_date":null,"first_conversion_event_name":null,"first_deal_created_date":null,"firstname":"test","gender":null,"graduation_date":null,"hs_additional_emails":null,"hs_all_accessible_team_ids":null,"hs_all_contact_vids":"201","hs_all_owner_ids":null,"hs_all_team_ids":null,"hs_analytics_average_page_views":0,"hs_analytics_first_referrer":null,"hs_analytics_first_timestamp":"2021-01-14T14:26:17.014000+00:00","hs_analytics_first_touch_converting_campaign":null,"hs_analytics_first_url":null,"hs_analytics_first_visit_timestamp":null,"hs_analytics_last_referrer":null,"hs_analytics_last_timestamp":null,"hs_analytics_last_touch_converting_campaign":null,"hs_analytics_last_url":null,"hs_analytics_last_visit_timestamp":null,"hs_analytics_num_event_completions":0,"hs_analytics_num_page_views":0,"hs_analytics_num_visits":0,"hs_analytics_revenue":0,"hs_analytics_source":"OFFLINE","hs_analytics_source_data_1":"API","hs_analytics_source_data_2":null,"hs_avatar_filemanager_key":null,"hs_buying_role":null,"hs_calculated_form_submissions":null,"hs_calculated_merged_vids":null,"hs_calculated_mobile_number":null,"hs_calculated_phone_number":null,"hs_calculated_phone_number_area_code":null,"hs_calculated_phone_number_country_code":null,"hs_calculated_phone_number_region_code":null,"hs_clicked_linkedin_ad":null,"hs_content_membership_email":null,"hs_content_membership_email_confirmed":null,"hs_content_membership_notes":null,"hs_content_membership_registered_at":null,"hs_content_membership_registration_domain_sent_to":null,"hs_content_membership_registration_email_sent_at":null,"hs_content_membership_status":null,"hs_conversations_visitor_email":null,"hs_count_is_unworked":null,"hs_count_is_worked":null,"hs_created_by_conversations":null,"hs_created_by_user_id":null,"hs_createdate":null,"hs_date_entered_customer":null,"hs_date_entered_evangelist":null,"hs_date_entered_lead":null,"hs_date_entered_marketingqualifiedlead":null,"hs_date_entered_opportunity":null,"hs_date_entered_other":null,"hs_date_entered_salesqualifiedlead":null,"hs_date_entered_subscriber":"2021-01-14T14:26:17.014000+00:00","hs_date_exited_customer":null,"hs_date_exited_evangelist":null,"hs_date_exited_lead":null,"hs_date_exited_marketingqualifiedlead":null,"hs_date_exited_opportunity":null,"hs_date_exited_other":null,"hs_date_exited_salesqualifiedlead":null,"hs_date_exited_subscriber":null,"hs_document_last_revisited":null,"hs_email_bad_address":null,"hs_email_bounce":null,"hs_email_click":null,"hs_email_customer_quarantined_reason":null,"hs_email_delivered":null,"hs_email_domain":"hubspot.com","hs_email_first_click_date":null,"hs_email_first_open_date":null,"hs_email_first_reply_date":null,"hs_email_first_send_date":null,"hs_email_hard_bounce_reason":null,"hs_email_hard_bounce_reason_enum":"OTHER","hs_email_is_ineligible":null,"hs_email_last_click_date":null,"hs_email_last_email_name":null,"hs_email_last_open_date":null,"hs_email_last_reply_date":null,"hs_email_last_send_date":null,"hs_email_open":null,"hs_email_optout":null,"hs_email_optout_10798197":null,"hs_email_optout_11890603":null,"hs_email_optout_11890831":null,"hs_email_optout_23704464":null,"hs_email_optout_94692364":null,"hs_email_quarantined":null,"hs_email_quarantined_reason":null,"hs_email_recipient_fatigue_recovery_time":null,"hs_email_replied":null,"hs_email_sends_since_last_engagement":null,"hs_emailconfirmationstatus":null,"hs_facebook_ad_clicked":null,"hs_facebook_click_id":null,"hs_feedback_last_nps_follow_up":null,"hs_feedback_last_nps_rating":null,"hs_feedback_last_survey_date":null,"hs_feedback_show_nps_web_survey":null,"hs_first_engagement_object_id":null,"hs_first_outreach_date":null,"hs_first_subscription_create_date":null,"hs_google_click_id":null,"hs_has_active_subscription":null,"hs_ip_timezone":null,"hs_is_contact":true,"hs_is_unworked":true,"hs_language":null,"hs_last_sales_activity_date":null,"hs_last_sales_activity_timestamp":null,"hs_last_sales_activity_type":null,"hs_lastmodifieddate":null,"hs_latest_meeting_activity":null,"hs_latest_sequence_ended_date":null,"hs_latest_sequence_enrolled":null,"hs_latest_sequence_enrolled_date":null,"hs_latest_sequence_finished_date":null,"hs_latest_sequence_unenrolled_date":null,"hs_latest_source":"OFFLINE","hs_latest_source_data_1":"API","hs_latest_source_data_2":null,"hs_latest_source_timestamp":"2021-01-14T14:26:17.081000+00:00","hs_latest_subscription_create_date":null,"hs_lead_status":null,"hs_legal_basis":null,"hs_lifecyclestage_customer_date":null,"hs_lifecyclestage_evangelist_date":null,"hs_lifecyclestage_lead_date":null,"hs_lifecyclestage_marketingqualifiedlead_date":null,"hs_lifecyclestage_opportunity_date":null,"hs_lifecyclestage_other_date":null,"hs_lifecyclestage_salesqualifiedlead_date":null,"hs_lifecyclestage_subscriber_date":"2021-01-14T14:26:17.014000+00:00","hs_linkedin_ad_clicked":null,"hs_marketable_reason_id":null,"hs_marketable_reason_type":null,"hs_marketable_status":"false","hs_marketable_until_renewal":"false","hs_merged_object_ids":null,"hs_object_id":201,"hs_persona":null,"hs_pinned_engagement_id":null,"hs_pipeline":"contacts-lifecycle-pipeline","hs_predictivecontactscore":null,"hs_predictivecontactscore_v2":0.3,"hs_predictivecontactscorebucket":null,"hs_predictivescoringtier":"tier_3","hs_read_only":null,"hs_sa_first_engagement_date":null,"hs_sa_first_engagement_descr":null,"hs_sa_first_engagement_object_type":null,"hs_sales_email_last_clicked":null,"hs_sales_email_last_opened":null,"hs_sales_email_last_replied":null,"hs_searchable_calculated_international_mobile_number":null,"hs_searchable_calculated_international_phone_number":null,"hs_searchable_calculated_mobile_number":null,"hs_searchable_calculated_phone_number":"5551222323","hs_sequences_actively_enrolled_count":null,"hs_sequences_enrolled_count":null,"hs_sequences_is_enrolled":null,"hs_testpurge":null,"hs_testrollback":null,"hs_time_between_contact_creation_and_deal_close":null,"hs_time_between_contact_creation_and_deal_creation":null,"hs_time_in_customer":null,"hs_time_in_evangelist":null,"hs_time_in_lead":null,"hs_time_in_marketingqualifiedlead":null,"hs_time_in_opportunity":null,"hs_time_in_other":null,"hs_time_in_salesqualifiedlead":null,"hs_time_in_subscriber":77424314799,"hs_time_to_first_engagement":null,"hs_time_to_move_from_lead_to_customer":null,"hs_time_to_move_from_marketingqualifiedlead_to_customer":null,"hs_time_to_move_from_opportunity_to_customer":null,"hs_time_to_move_from_salesqualifiedlead_to_customer":null,"hs_time_to_move_from_subscriber_to_customer":null,"hs_timezone":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":null,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":null,"hs_was_imported":null,"hs_whatsapp_phone_number":null,"hubspot_owner_assigneddate":null,"hubspot_owner_id":null,"hubspot_team_id":null,"hubspotscore":null,"industry":null,"ip_city":null,"ip_country":null,"ip_country_code":null,"ip_latlon":null,"ip_state":null,"ip_state_code":null,"ip_zipcode":null,"job_function":null,"jobtitle":null,"lastmodifieddate":"2023-04-03T20:30:56.518000+00:00","lastname":"testerson","lifecyclestage":"subscriber","marital_status":null,"message":null,"military_status":null,"mobilephone":null,"my_custom_test_property":null,"notes_last_contacted":null,"notes_last_updated":null,"notes_next_activity_date":null,"num_associated_deals":null,"num_contacted_notes":null,"num_conversion_events":0,"num_notes":null,"num_unique_conversion_events":0,"numemployees":null,"phone":"555-122-2323","recent_conversion_date":null,"recent_conversion_event_name":null,"recent_deal_amount":null,"recent_deal_close_date":null,"relationship_status":null,"salutation":null,"school":null,"seniority":null,"start_date":null,"state":"MA","surveymonkeyeventlastupdated":null,"test":null,"total_revenue":null,"twitterhandle":null,"webinareventlastupdated":null,"website":"http://hubspot.com","work_email":null,"zip":"02139"},"createdAt":"2021-01-14T14:26:17.014Z","updatedAt":"2023-04-03T20:30:56.518Z","archived":false,"companies":["5170561229","5170561229"]},"emitted_at":1688058691915} -{"stream":"contacts","data":{"id":"251","properties":{"address":"25000000 First Street","annualrevenue":null,"associatedcompanyid":5170561229,"associatedcompanylastupdated":null,"city":"Cambridge","closedate":null,"company":"HubSpot","company_size":null,"country":"USA","createdate":"2021-02-22T14:05:09.944000+00:00","currentlyinworkflow":null,"date_of_birth":null,"days_to_close":null,"degree":null,"email":"testingdsapis@hubspot.com","engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"fax":null,"field_of_study":null,"first_conversion_date":null,"first_conversion_event_name":null,"first_deal_created_date":null,"firstname":"Test User 5001","gender":null,"graduation_date":null,"hs_additional_emails":null,"hs_all_accessible_team_ids":null,"hs_all_contact_vids":"251","hs_all_owner_ids":null,"hs_all_team_ids":null,"hs_analytics_average_page_views":0,"hs_analytics_first_referrer":null,"hs_analytics_first_timestamp":"2021-02-22T14:05:09.944000+00:00","hs_analytics_first_touch_converting_campaign":null,"hs_analytics_first_url":null,"hs_analytics_first_visit_timestamp":null,"hs_analytics_last_referrer":null,"hs_analytics_last_timestamp":null,"hs_analytics_last_touch_converting_campaign":null,"hs_analytics_last_url":null,"hs_analytics_last_visit_timestamp":null,"hs_analytics_num_event_completions":0,"hs_analytics_num_page_views":0,"hs_analytics_num_visits":0,"hs_analytics_revenue":0,"hs_analytics_source":"OFFLINE","hs_analytics_source_data_1":"API","hs_analytics_source_data_2":null,"hs_avatar_filemanager_key":null,"hs_buying_role":null,"hs_calculated_form_submissions":null,"hs_calculated_merged_vids":null,"hs_calculated_mobile_number":null,"hs_calculated_phone_number":null,"hs_calculated_phone_number_area_code":null,"hs_calculated_phone_number_country_code":null,"hs_calculated_phone_number_region_code":null,"hs_clicked_linkedin_ad":null,"hs_content_membership_email":null,"hs_content_membership_email_confirmed":null,"hs_content_membership_notes":null,"hs_content_membership_registered_at":null,"hs_content_membership_registration_domain_sent_to":null,"hs_content_membership_registration_email_sent_at":null,"hs_content_membership_status":null,"hs_conversations_visitor_email":null,"hs_count_is_unworked":null,"hs_count_is_worked":null,"hs_created_by_conversations":null,"hs_created_by_user_id":null,"hs_createdate":null,"hs_date_entered_customer":null,"hs_date_entered_evangelist":null,"hs_date_entered_lead":null,"hs_date_entered_marketingqualifiedlead":null,"hs_date_entered_opportunity":null,"hs_date_entered_other":null,"hs_date_entered_salesqualifiedlead":null,"hs_date_entered_subscriber":"2021-02-22T14:05:09.944000+00:00","hs_date_exited_customer":null,"hs_date_exited_evangelist":null,"hs_date_exited_lead":null,"hs_date_exited_marketingqualifiedlead":null,"hs_date_exited_opportunity":null,"hs_date_exited_other":null,"hs_date_exited_salesqualifiedlead":null,"hs_date_exited_subscriber":null,"hs_document_last_revisited":null,"hs_email_bad_address":null,"hs_email_bounce":null,"hs_email_click":null,"hs_email_customer_quarantined_reason":null,"hs_email_delivered":null,"hs_email_domain":"hubspot.com","hs_email_first_click_date":null,"hs_email_first_open_date":null,"hs_email_first_reply_date":null,"hs_email_first_send_date":null,"hs_email_hard_bounce_reason":null,"hs_email_hard_bounce_reason_enum":null,"hs_email_is_ineligible":null,"hs_email_last_click_date":null,"hs_email_last_email_name":null,"hs_email_last_open_date":null,"hs_email_last_reply_date":null,"hs_email_last_send_date":null,"hs_email_open":null,"hs_email_optout":null,"hs_email_optout_10798197":null,"hs_email_optout_11890603":null,"hs_email_optout_11890831":null,"hs_email_optout_23704464":null,"hs_email_optout_94692364":null,"hs_email_quarantined":null,"hs_email_quarantined_reason":null,"hs_email_recipient_fatigue_recovery_time":null,"hs_email_replied":null,"hs_email_sends_since_last_engagement":null,"hs_emailconfirmationstatus":null,"hs_facebook_ad_clicked":null,"hs_facebook_click_id":null,"hs_feedback_last_nps_follow_up":null,"hs_feedback_last_nps_rating":null,"hs_feedback_last_survey_date":null,"hs_feedback_show_nps_web_survey":null,"hs_first_engagement_object_id":null,"hs_first_outreach_date":null,"hs_first_subscription_create_date":null,"hs_google_click_id":null,"hs_has_active_subscription":null,"hs_ip_timezone":null,"hs_is_contact":true,"hs_is_unworked":true,"hs_language":null,"hs_last_sales_activity_date":null,"hs_last_sales_activity_timestamp":null,"hs_last_sales_activity_type":null,"hs_lastmodifieddate":null,"hs_latest_meeting_activity":null,"hs_latest_sequence_ended_date":null,"hs_latest_sequence_enrolled":null,"hs_latest_sequence_enrolled_date":null,"hs_latest_sequence_finished_date":null,"hs_latest_sequence_unenrolled_date":null,"hs_latest_source":"OFFLINE","hs_latest_source_data_1":"API","hs_latest_source_data_2":null,"hs_latest_source_timestamp":"2021-02-22T14:05:10.036000+00:00","hs_latest_subscription_create_date":null,"hs_lead_status":null,"hs_legal_basis":null,"hs_lifecyclestage_customer_date":null,"hs_lifecyclestage_evangelist_date":null,"hs_lifecyclestage_lead_date":null,"hs_lifecyclestage_marketingqualifiedlead_date":null,"hs_lifecyclestage_opportunity_date":null,"hs_lifecyclestage_other_date":null,"hs_lifecyclestage_salesqualifiedlead_date":null,"hs_lifecyclestage_subscriber_date":"2021-02-22T14:05:09.944000+00:00","hs_linkedin_ad_clicked":null,"hs_marketable_reason_id":null,"hs_marketable_reason_type":null,"hs_marketable_status":"false","hs_marketable_until_renewal":"false","hs_merged_object_ids":null,"hs_object_id":251,"hs_persona":null,"hs_pinned_engagement_id":null,"hs_pipeline":"contacts-lifecycle-pipeline","hs_predictivecontactscore":null,"hs_predictivecontactscore_v2":0.29,"hs_predictivecontactscorebucket":null,"hs_predictivescoringtier":"tier_4","hs_read_only":null,"hs_sa_first_engagement_date":null,"hs_sa_first_engagement_descr":null,"hs_sa_first_engagement_object_type":null,"hs_sales_email_last_clicked":null,"hs_sales_email_last_opened":null,"hs_sales_email_last_replied":null,"hs_searchable_calculated_international_mobile_number":null,"hs_searchable_calculated_international_phone_number":null,"hs_searchable_calculated_mobile_number":null,"hs_searchable_calculated_phone_number":"5551222323","hs_sequences_actively_enrolled_count":null,"hs_sequences_enrolled_count":null,"hs_sequences_is_enrolled":null,"hs_testpurge":null,"hs_testrollback":null,"hs_time_between_contact_creation_and_deal_close":null,"hs_time_between_contact_creation_and_deal_creation":null,"hs_time_in_customer":null,"hs_time_in_evangelist":null,"hs_time_in_lead":null,"hs_time_in_marketingqualifiedlead":null,"hs_time_in_opportunity":null,"hs_time_in_other":null,"hs_time_in_salesqualifiedlead":null,"hs_time_in_subscriber":74055981870,"hs_time_to_first_engagement":null,"hs_time_to_move_from_lead_to_customer":null,"hs_time_to_move_from_marketingqualifiedlead_to_customer":null,"hs_time_to_move_from_opportunity_to_customer":null,"hs_time_to_move_from_salesqualifiedlead_to_customer":null,"hs_time_to_move_from_subscriber_to_customer":null,"hs_timezone":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":null,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":null,"hs_was_imported":null,"hs_whatsapp_phone_number":null,"hubspot_owner_assigneddate":null,"hubspot_owner_id":null,"hubspot_team_id":null,"hubspotscore":null,"industry":null,"ip_city":null,"ip_country":null,"ip_country_code":null,"ip_latlon":null,"ip_state":null,"ip_state_code":null,"ip_zipcode":null,"job_function":null,"jobtitle":null,"lastmodifieddate":"2023-03-21T19:29:13.036000+00:00","lastname":"Test Lastname 5001","lifecyclestage":"subscriber","marital_status":null,"message":null,"military_status":null,"mobilephone":null,"my_custom_test_property":null,"notes_last_contacted":null,"notes_last_updated":null,"notes_next_activity_date":null,"num_associated_deals":null,"num_contacted_notes":null,"num_conversion_events":0,"num_notes":null,"num_unique_conversion_events":0,"numemployees":null,"phone":"555-122-2323","recent_conversion_date":null,"recent_conversion_event_name":null,"recent_deal_amount":null,"recent_deal_close_date":null,"relationship_status":null,"salutation":null,"school":null,"seniority":null,"start_date":null,"state":"MA","surveymonkeyeventlastupdated":null,"test":null,"total_revenue":null,"twitterhandle":null,"webinareventlastupdated":null,"website":"http://hubspot.com","work_email":null,"zip":"02139"},"createdAt":"2021-02-22T14:05:09.944Z","updatedAt":"2023-03-21T19:29:13.036Z","archived":false,"companies":["5170561229","5170561229"]},"emitted_at":1688058691916} -{"stream":"contacts","data":{"id":"401","properties":{"address":"25 First Street","annualrevenue":null,"associatedcompanyid":null,"associatedcompanylastupdated":null,"city":"Cambridge","closedate":null,"company":null,"company_size":null,"country":null,"createdate":"2021-02-23T20:10:36.191000+00:00","currentlyinworkflow":null,"date_of_birth":null,"days_to_close":null,"degree":null,"email":"macmitch@hubspot.com","engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"fax":null,"field_of_study":null,"first_conversion_date":null,"first_conversion_event_name":null,"first_deal_created_date":null,"firstname":"Mac","gender":null,"graduation_date":null,"hs_additional_emails":null,"hs_all_accessible_team_ids":null,"hs_all_contact_vids":"401","hs_all_owner_ids":"52550153","hs_all_team_ids":null,"hs_analytics_average_page_views":0,"hs_analytics_first_referrer":null,"hs_analytics_first_timestamp":"2021-02-23T20:10:36.181000+00:00","hs_analytics_first_touch_converting_campaign":null,"hs_analytics_first_url":null,"hs_analytics_first_visit_timestamp":null,"hs_analytics_last_referrer":null,"hs_analytics_last_timestamp":null,"hs_analytics_last_touch_converting_campaign":null,"hs_analytics_last_url":null,"hs_analytics_last_visit_timestamp":null,"hs_analytics_num_event_completions":0,"hs_analytics_num_page_views":0,"hs_analytics_num_visits":0,"hs_analytics_revenue":0,"hs_analytics_source":"OFFLINE","hs_analytics_source_data_1":"IMPORT","hs_analytics_source_data_2":"13256565","hs_avatar_filemanager_key":null,"hs_buying_role":null,"hs_calculated_form_submissions":null,"hs_calculated_merged_vids":null,"hs_calculated_mobile_number":null,"hs_calculated_phone_number":"+18884827768","hs_calculated_phone_number_area_code":null,"hs_calculated_phone_number_country_code":"US","hs_calculated_phone_number_region_code":null,"hs_clicked_linkedin_ad":null,"hs_content_membership_email":null,"hs_content_membership_email_confirmed":null,"hs_content_membership_notes":null,"hs_content_membership_registered_at":null,"hs_content_membership_registration_domain_sent_to":null,"hs_content_membership_registration_email_sent_at":null,"hs_content_membership_status":null,"hs_conversations_visitor_email":null,"hs_count_is_unworked":1,"hs_count_is_worked":0,"hs_created_by_conversations":null,"hs_created_by_user_id":null,"hs_createdate":null,"hs_date_entered_customer":null,"hs_date_entered_evangelist":null,"hs_date_entered_lead":"2021-02-23T20:10:36.181000+00:00","hs_date_entered_marketingqualifiedlead":null,"hs_date_entered_opportunity":null,"hs_date_entered_other":null,"hs_date_entered_salesqualifiedlead":null,"hs_date_entered_subscriber":null,"hs_date_exited_customer":null,"hs_date_exited_evangelist":null,"hs_date_exited_lead":null,"hs_date_exited_marketingqualifiedlead":null,"hs_date_exited_opportunity":null,"hs_date_exited_other":null,"hs_date_exited_salesqualifiedlead":null,"hs_date_exited_subscriber":null,"hs_document_last_revisited":null,"hs_email_bad_address":null,"hs_email_bounce":null,"hs_email_click":null,"hs_email_customer_quarantined_reason":null,"hs_email_delivered":null,"hs_email_domain":"hubspot.com","hs_email_first_click_date":null,"hs_email_first_open_date":null,"hs_email_first_reply_date":null,"hs_email_first_send_date":null,"hs_email_hard_bounce_reason":null,"hs_email_hard_bounce_reason_enum":"OTHER","hs_email_is_ineligible":null,"hs_email_last_click_date":null,"hs_email_last_email_name":null,"hs_email_last_open_date":null,"hs_email_last_reply_date":null,"hs_email_last_send_date":null,"hs_email_open":null,"hs_email_optout":null,"hs_email_optout_10798197":null,"hs_email_optout_11890603":null,"hs_email_optout_11890831":null,"hs_email_optout_23704464":null,"hs_email_optout_94692364":null,"hs_email_quarantined":null,"hs_email_quarantined_reason":null,"hs_email_recipient_fatigue_recovery_time":null,"hs_email_replied":null,"hs_email_sends_since_last_engagement":null,"hs_emailconfirmationstatus":null,"hs_facebook_ad_clicked":null,"hs_facebook_click_id":null,"hs_feedback_last_nps_follow_up":null,"hs_feedback_last_nps_rating":null,"hs_feedback_last_survey_date":null,"hs_feedback_show_nps_web_survey":null,"hs_first_engagement_object_id":null,"hs_first_outreach_date":null,"hs_first_subscription_create_date":null,"hs_google_click_id":null,"hs_has_active_subscription":null,"hs_ip_timezone":null,"hs_is_contact":true,"hs_is_unworked":true,"hs_language":null,"hs_last_sales_activity_date":null,"hs_last_sales_activity_timestamp":null,"hs_last_sales_activity_type":null,"hs_lastmodifieddate":null,"hs_latest_meeting_activity":null,"hs_latest_sequence_ended_date":null,"hs_latest_sequence_enrolled":null,"hs_latest_sequence_enrolled_date":null,"hs_latest_sequence_finished_date":null,"hs_latest_sequence_unenrolled_date":null,"hs_latest_source":"OFFLINE","hs_latest_source_data_1":"IMPORT","hs_latest_source_data_2":"13256565","hs_latest_source_timestamp":"2021-02-23T20:10:36.210000+00:00","hs_latest_subscription_create_date":null,"hs_lead_status":null,"hs_legal_basis":null,"hs_lifecyclestage_customer_date":null,"hs_lifecyclestage_evangelist_date":null,"hs_lifecyclestage_lead_date":"2021-02-23T20:10:36.181000+00:00","hs_lifecyclestage_marketingqualifiedlead_date":null,"hs_lifecyclestage_opportunity_date":null,"hs_lifecyclestage_other_date":null,"hs_lifecyclestage_salesqualifiedlead_date":null,"hs_lifecyclestage_subscriber_date":null,"hs_linkedin_ad_clicked":null,"hs_marketable_reason_id":null,"hs_marketable_reason_type":null,"hs_marketable_status":"false","hs_marketable_until_renewal":"false","hs_merged_object_ids":null,"hs_object_id":401,"hs_persona":null,"hs_pinned_engagement_id":null,"hs_pipeline":"contacts-lifecycle-pipeline","hs_predictivecontactscore":null,"hs_predictivecontactscore_v2":0.29,"hs_predictivecontactscorebucket":null,"hs_predictivescoringtier":"tier_4","hs_read_only":null,"hs_sa_first_engagement_date":null,"hs_sa_first_engagement_descr":null,"hs_sa_first_engagement_object_type":null,"hs_sales_email_last_clicked":null,"hs_sales_email_last_opened":null,"hs_sales_email_last_replied":null,"hs_searchable_calculated_international_mobile_number":null,"hs_searchable_calculated_international_phone_number":null,"hs_searchable_calculated_mobile_number":null,"hs_searchable_calculated_phone_number":"8884827768","hs_sequences_actively_enrolled_count":null,"hs_sequences_enrolled_count":null,"hs_sequences_is_enrolled":null,"hs_testpurge":null,"hs_testrollback":null,"hs_time_between_contact_creation_and_deal_close":null,"hs_time_between_contact_creation_and_deal_creation":null,"hs_time_in_customer":null,"hs_time_in_evangelist":null,"hs_time_in_lead":73947655632,"hs_time_in_marketingqualifiedlead":null,"hs_time_in_opportunity":null,"hs_time_in_other":null,"hs_time_in_salesqualifiedlead":null,"hs_time_in_subscriber":null,"hs_time_to_first_engagement":null,"hs_time_to_move_from_lead_to_customer":null,"hs_time_to_move_from_marketingqualifiedlead_to_customer":null,"hs_time_to_move_from_opportunity_to_customer":null,"hs_time_to_move_from_salesqualifiedlead_to_customer":null,"hs_time_to_move_from_subscriber_to_customer":null,"hs_timezone":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":null,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"12282590","hs_was_imported":null,"hs_whatsapp_phone_number":null,"hubspot_owner_assigneddate":"2021-05-21T10:20:30.963000+00:00","hubspot_owner_id":"52550153","hubspot_team_id":null,"hubspotscore":null,"industry":null,"ip_city":null,"ip_country":null,"ip_country_code":null,"ip_latlon":null,"ip_state":null,"ip_state_code":null,"ip_zipcode":null,"job_function":null,"jobtitle":null,"lastmodifieddate":"2023-03-21T19:31:00.563000+00:00","lastname":"Mitchell","lifecyclestage":"lead","marital_status":null,"message":null,"military_status":null,"mobilephone":null,"my_custom_test_property":null,"notes_last_contacted":null,"notes_last_updated":null,"notes_next_activity_date":null,"num_associated_deals":null,"num_contacted_notes":null,"num_conversion_events":0,"num_notes":null,"num_unique_conversion_events":0,"numemployees":null,"phone":"1(888) 482-7768","recent_conversion_date":null,"recent_conversion_event_name":null,"recent_deal_amount":null,"recent_deal_close_date":null,"relationship_status":null,"salutation":null,"school":null,"seniority":null,"start_date":null,"state":"MA","surveymonkeyeventlastupdated":null,"test":null,"total_revenue":null,"twitterhandle":null,"webinareventlastupdated":null,"website":null,"work_email":null,"zip":"21430"},"createdAt":"2021-02-23T20:10:36.191Z","updatedAt":"2023-03-21T19:31:00.563Z","archived":false},"emitted_at":1688058691916} -{"stream":"contacts","data":{"id":"601","properties":{"address":"0 First Street","annualrevenue":null,"associatedcompanyid":null,"associatedcompanylastupdated":null,"city":"Cambridge","closedate":null,"company":"HubSpot Test","company_size":null,"country":null,"createdate":"2021-10-12T13:22:50.930000+00:00","currentlyinworkflow":null,"date_of_birth":null,"days_to_close":null,"degree":null,"email":"testingapicontact_0@hubspot.com","engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"fax":null,"field_of_study":null,"first_conversion_date":null,"first_conversion_event_name":null,"first_deal_created_date":null,"firstname":"test contact 0","gender":null,"graduation_date":null,"hs_additional_emails":null,"hs_all_accessible_team_ids":null,"hs_all_contact_vids":"601","hs_all_owner_ids":null,"hs_all_team_ids":null,"hs_analytics_average_page_views":0,"hs_analytics_first_referrer":null,"hs_analytics_first_timestamp":"2021-10-12T13:22:50.930000+00:00","hs_analytics_first_touch_converting_campaign":null,"hs_analytics_first_url":null,"hs_analytics_first_visit_timestamp":null,"hs_analytics_last_referrer":null,"hs_analytics_last_timestamp":null,"hs_analytics_last_touch_converting_campaign":null,"hs_analytics_last_url":null,"hs_analytics_last_visit_timestamp":null,"hs_analytics_num_event_completions":0,"hs_analytics_num_page_views":0,"hs_analytics_num_visits":0,"hs_analytics_revenue":0,"hs_analytics_source":"OFFLINE","hs_analytics_source_data_1":"API","hs_analytics_source_data_2":null,"hs_avatar_filemanager_key":null,"hs_buying_role":null,"hs_calculated_form_submissions":null,"hs_calculated_merged_vids":null,"hs_calculated_mobile_number":null,"hs_calculated_phone_number":null,"hs_calculated_phone_number_area_code":null,"hs_calculated_phone_number_country_code":null,"hs_calculated_phone_number_region_code":null,"hs_clicked_linkedin_ad":null,"hs_content_membership_email":null,"hs_content_membership_email_confirmed":null,"hs_content_membership_notes":null,"hs_content_membership_registered_at":null,"hs_content_membership_registration_domain_sent_to":null,"hs_content_membership_registration_email_sent_at":null,"hs_content_membership_status":null,"hs_conversations_visitor_email":null,"hs_count_is_unworked":null,"hs_count_is_worked":null,"hs_created_by_conversations":null,"hs_created_by_user_id":null,"hs_createdate":null,"hs_date_entered_customer":null,"hs_date_entered_evangelist":null,"hs_date_entered_lead":null,"hs_date_entered_marketingqualifiedlead":null,"hs_date_entered_opportunity":null,"hs_date_entered_other":null,"hs_date_entered_salesqualifiedlead":null,"hs_date_entered_subscriber":"2021-10-12T13:22:50.930000+00:00","hs_date_exited_customer":null,"hs_date_exited_evangelist":null,"hs_date_exited_lead":null,"hs_date_exited_marketingqualifiedlead":null,"hs_date_exited_opportunity":null,"hs_date_exited_other":null,"hs_date_exited_salesqualifiedlead":null,"hs_date_exited_subscriber":null,"hs_document_last_revisited":null,"hs_email_bad_address":null,"hs_email_bounce":null,"hs_email_click":null,"hs_email_customer_quarantined_reason":null,"hs_email_delivered":null,"hs_email_domain":"hubspot.com","hs_email_first_click_date":null,"hs_email_first_open_date":null,"hs_email_first_reply_date":null,"hs_email_first_send_date":null,"hs_email_hard_bounce_reason":null,"hs_email_hard_bounce_reason_enum":null,"hs_email_is_ineligible":null,"hs_email_last_click_date":null,"hs_email_last_email_name":null,"hs_email_last_open_date":null,"hs_email_last_reply_date":null,"hs_email_last_send_date":null,"hs_email_open":null,"hs_email_optout":null,"hs_email_optout_10798197":null,"hs_email_optout_11890603":null,"hs_email_optout_11890831":null,"hs_email_optout_23704464":null,"hs_email_optout_94692364":null,"hs_email_quarantined":null,"hs_email_quarantined_reason":null,"hs_email_recipient_fatigue_recovery_time":null,"hs_email_replied":null,"hs_email_sends_since_last_engagement":null,"hs_emailconfirmationstatus":null,"hs_facebook_ad_clicked":null,"hs_facebook_click_id":null,"hs_feedback_last_nps_follow_up":null,"hs_feedback_last_nps_rating":null,"hs_feedback_last_survey_date":null,"hs_feedback_show_nps_web_survey":null,"hs_first_engagement_object_id":null,"hs_first_outreach_date":null,"hs_first_subscription_create_date":null,"hs_google_click_id":null,"hs_has_active_subscription":null,"hs_ip_timezone":null,"hs_is_contact":true,"hs_is_unworked":true,"hs_language":null,"hs_last_sales_activity_date":null,"hs_last_sales_activity_timestamp":null,"hs_last_sales_activity_type":null,"hs_lastmodifieddate":null,"hs_latest_meeting_activity":null,"hs_latest_sequence_ended_date":null,"hs_latest_sequence_enrolled":null,"hs_latest_sequence_enrolled_date":null,"hs_latest_sequence_finished_date":null,"hs_latest_sequence_unenrolled_date":null,"hs_latest_source":"OFFLINE","hs_latest_source_data_1":"API","hs_latest_source_data_2":null,"hs_latest_source_timestamp":"2021-10-12T13:22:51.107000+00:00","hs_latest_subscription_create_date":null,"hs_lead_status":null,"hs_legal_basis":null,"hs_lifecyclestage_customer_date":null,"hs_lifecyclestage_evangelist_date":null,"hs_lifecyclestage_lead_date":null,"hs_lifecyclestage_marketingqualifiedlead_date":null,"hs_lifecyclestage_opportunity_date":null,"hs_lifecyclestage_other_date":null,"hs_lifecyclestage_salesqualifiedlead_date":null,"hs_lifecyclestage_subscriber_date":"2021-10-12T13:22:50.930000+00:00","hs_linkedin_ad_clicked":null,"hs_marketable_reason_id":null,"hs_marketable_reason_type":null,"hs_marketable_status":"false","hs_marketable_until_renewal":"false","hs_merged_object_ids":null,"hs_object_id":601,"hs_persona":null,"hs_pinned_engagement_id":null,"hs_pipeline":"contacts-lifecycle-pipeline","hs_predictivecontactscore":null,"hs_predictivecontactscore_v2":0.31,"hs_predictivecontactscorebucket":null,"hs_predictivescoringtier":"tier_2","hs_read_only":null,"hs_sa_first_engagement_date":null,"hs_sa_first_engagement_descr":null,"hs_sa_first_engagement_object_type":null,"hs_sales_email_last_clicked":null,"hs_sales_email_last_opened":null,"hs_sales_email_last_replied":null,"hs_searchable_calculated_international_mobile_number":null,"hs_searchable_calculated_international_phone_number":null,"hs_searchable_calculated_mobile_number":null,"hs_searchable_calculated_phone_number":"5551222323","hs_sequences_actively_enrolled_count":0,"hs_sequences_enrolled_count":null,"hs_sequences_is_enrolled":null,"hs_testpurge":null,"hs_testrollback":null,"hs_time_between_contact_creation_and_deal_close":null,"hs_time_between_contact_creation_and_deal_creation":null,"hs_time_in_customer":null,"hs_time_in_evangelist":null,"hs_time_in_lead":null,"hs_time_in_marketingqualifiedlead":null,"hs_time_in_opportunity":null,"hs_time_in_other":null,"hs_time_in_salesqualifiedlead":null,"hs_time_in_subscriber":54013720883,"hs_time_to_first_engagement":null,"hs_time_to_move_from_lead_to_customer":null,"hs_time_to_move_from_marketingqualifiedlead_to_customer":null,"hs_time_to_move_from_opportunity_to_customer":null,"hs_time_to_move_from_salesqualifiedlead_to_customer":null,"hs_time_to_move_from_subscriber_to_customer":null,"hs_timezone":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":null,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":null,"hs_was_imported":null,"hs_whatsapp_phone_number":null,"hubspot_owner_assigneddate":null,"hubspot_owner_id":null,"hubspot_team_id":null,"hubspotscore":null,"industry":null,"ip_city":null,"ip_country":null,"ip_country_code":null,"ip_latlon":null,"ip_state":null,"ip_state_code":null,"ip_zipcode":null,"job_function":null,"jobtitle":null,"lastmodifieddate":"2023-04-03T20:29:57.224000+00:00","lastname":"testerson number 0","lifecyclestage":"subscriber","marital_status":null,"message":null,"military_status":null,"mobilephone":null,"my_custom_test_property":null,"notes_last_contacted":null,"notes_last_updated":null,"notes_next_activity_date":null,"num_associated_deals":null,"num_contacted_notes":null,"num_conversion_events":0,"num_notes":null,"num_unique_conversion_events":0,"numemployees":null,"phone":"555-122-2323","recent_conversion_date":null,"recent_conversion_event_name":null,"recent_deal_amount":null,"recent_deal_close_date":null,"relationship_status":null,"salutation":null,"school":null,"seniority":null,"start_date":null,"state":"MA","surveymonkeyeventlastupdated":null,"test":null,"total_revenue":null,"twitterhandle":null,"webinareventlastupdated":null,"website":"http://hubspot.com","work_email":null,"zip":"02139"},"createdAt":"2021-10-12T13:22:50.930Z","updatedAt":"2023-04-03T20:29:57.224Z","archived":false},"emitted_at":1688058691917} -{"stream":"contacts","data":{"id":"651","properties":{"address":"1 First Street","annualrevenue":null,"associatedcompanyid":null,"associatedcompanylastupdated":null,"city":"Cambridge","closedate":null,"company":"HubSpot Test","company_size":null,"country":null,"createdate":"2021-10-12T13:23:01.830000+00:00","currentlyinworkflow":null,"date_of_birth":null,"days_to_close":null,"degree":null,"email":"testingapicontact_1@hubspot.com","engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"fax":null,"field_of_study":null,"first_conversion_date":null,"first_conversion_event_name":null,"first_deal_created_date":null,"firstname":"test contact 1-1","gender":null,"graduation_date":null,"hs_additional_emails":null,"hs_all_accessible_team_ids":null,"hs_all_contact_vids":"651","hs_all_owner_ids":null,"hs_all_team_ids":null,"hs_analytics_average_page_views":0,"hs_analytics_first_referrer":null,"hs_analytics_first_timestamp":"2021-10-12T13:23:01.830000+00:00","hs_analytics_first_touch_converting_campaign":null,"hs_analytics_first_url":null,"hs_analytics_first_visit_timestamp":null,"hs_analytics_last_referrer":null,"hs_analytics_last_timestamp":null,"hs_analytics_last_touch_converting_campaign":null,"hs_analytics_last_url":null,"hs_analytics_last_visit_timestamp":null,"hs_analytics_num_event_completions":0,"hs_analytics_num_page_views":0,"hs_analytics_num_visits":0,"hs_analytics_revenue":0,"hs_analytics_source":"OFFLINE","hs_analytics_source_data_1":"API","hs_analytics_source_data_2":null,"hs_avatar_filemanager_key":null,"hs_buying_role":null,"hs_calculated_form_submissions":null,"hs_calculated_merged_vids":null,"hs_calculated_mobile_number":null,"hs_calculated_phone_number":null,"hs_calculated_phone_number_area_code":null,"hs_calculated_phone_number_country_code":null,"hs_calculated_phone_number_region_code":null,"hs_clicked_linkedin_ad":null,"hs_content_membership_email":null,"hs_content_membership_email_confirmed":null,"hs_content_membership_notes":null,"hs_content_membership_registered_at":null,"hs_content_membership_registration_domain_sent_to":null,"hs_content_membership_registration_email_sent_at":null,"hs_content_membership_status":null,"hs_conversations_visitor_email":null,"hs_count_is_unworked":null,"hs_count_is_worked":null,"hs_created_by_conversations":null,"hs_created_by_user_id":null,"hs_createdate":null,"hs_date_entered_customer":null,"hs_date_entered_evangelist":null,"hs_date_entered_lead":null,"hs_date_entered_marketingqualifiedlead":null,"hs_date_entered_opportunity":null,"hs_date_entered_other":null,"hs_date_entered_salesqualifiedlead":null,"hs_date_entered_subscriber":"2021-10-12T13:23:01.830000+00:00","hs_date_exited_customer":null,"hs_date_exited_evangelist":null,"hs_date_exited_lead":null,"hs_date_exited_marketingqualifiedlead":null,"hs_date_exited_opportunity":null,"hs_date_exited_other":null,"hs_date_exited_salesqualifiedlead":null,"hs_date_exited_subscriber":null,"hs_document_last_revisited":null,"hs_email_bad_address":null,"hs_email_bounce":null,"hs_email_click":null,"hs_email_customer_quarantined_reason":null,"hs_email_delivered":null,"hs_email_domain":"hubspot.com","hs_email_first_click_date":null,"hs_email_first_open_date":null,"hs_email_first_reply_date":null,"hs_email_first_send_date":null,"hs_email_hard_bounce_reason":null,"hs_email_hard_bounce_reason_enum":null,"hs_email_is_ineligible":null,"hs_email_last_click_date":null,"hs_email_last_email_name":null,"hs_email_last_open_date":null,"hs_email_last_reply_date":null,"hs_email_last_send_date":null,"hs_email_open":null,"hs_email_optout":null,"hs_email_optout_10798197":null,"hs_email_optout_11890603":null,"hs_email_optout_11890831":null,"hs_email_optout_23704464":null,"hs_email_optout_94692364":null,"hs_email_quarantined":null,"hs_email_quarantined_reason":null,"hs_email_recipient_fatigue_recovery_time":null,"hs_email_replied":null,"hs_email_sends_since_last_engagement":null,"hs_emailconfirmationstatus":null,"hs_facebook_ad_clicked":null,"hs_facebook_click_id":null,"hs_feedback_last_nps_follow_up":null,"hs_feedback_last_nps_rating":null,"hs_feedback_last_survey_date":null,"hs_feedback_show_nps_web_survey":null,"hs_first_engagement_object_id":null,"hs_first_outreach_date":null,"hs_first_subscription_create_date":null,"hs_google_click_id":null,"hs_has_active_subscription":null,"hs_ip_timezone":null,"hs_is_contact":true,"hs_is_unworked":true,"hs_language":null,"hs_last_sales_activity_date":null,"hs_last_sales_activity_timestamp":null,"hs_last_sales_activity_type":null,"hs_lastmodifieddate":null,"hs_latest_meeting_activity":null,"hs_latest_sequence_ended_date":null,"hs_latest_sequence_enrolled":null,"hs_latest_sequence_enrolled_date":null,"hs_latest_sequence_finished_date":null,"hs_latest_sequence_unenrolled_date":null,"hs_latest_source":"OFFLINE","hs_latest_source_data_1":"API","hs_latest_source_data_2":null,"hs_latest_source_timestamp":"2021-10-12T13:23:01.857000+00:00","hs_latest_subscription_create_date":null,"hs_lead_status":null,"hs_legal_basis":null,"hs_lifecyclestage_customer_date":null,"hs_lifecyclestage_evangelist_date":null,"hs_lifecyclestage_lead_date":null,"hs_lifecyclestage_marketingqualifiedlead_date":null,"hs_lifecyclestage_opportunity_date":null,"hs_lifecyclestage_other_date":null,"hs_lifecyclestage_salesqualifiedlead_date":null,"hs_lifecyclestage_subscriber_date":"2021-10-12T13:23:01.830000+00:00","hs_linkedin_ad_clicked":null,"hs_marketable_reason_id":null,"hs_marketable_reason_type":null,"hs_marketable_status":"false","hs_marketable_until_renewal":"false","hs_merged_object_ids":null,"hs_object_id":651,"hs_persona":null,"hs_pinned_engagement_id":null,"hs_pipeline":"contacts-lifecycle-pipeline","hs_predictivecontactscore":null,"hs_predictivecontactscore_v2":0.31,"hs_predictivecontactscorebucket":null,"hs_predictivescoringtier":"tier_2","hs_read_only":null,"hs_sa_first_engagement_date":null,"hs_sa_first_engagement_descr":null,"hs_sa_first_engagement_object_type":null,"hs_sales_email_last_clicked":null,"hs_sales_email_last_opened":null,"hs_sales_email_last_replied":null,"hs_searchable_calculated_international_mobile_number":null,"hs_searchable_calculated_international_phone_number":null,"hs_searchable_calculated_mobile_number":null,"hs_searchable_calculated_phone_number":"5551222323","hs_sequences_actively_enrolled_count":0,"hs_sequences_enrolled_count":null,"hs_sequences_is_enrolled":null,"hs_testpurge":null,"hs_testrollback":null,"hs_time_between_contact_creation_and_deal_close":null,"hs_time_between_contact_creation_and_deal_creation":null,"hs_time_in_customer":null,"hs_time_in_evangelist":null,"hs_time_in_lead":null,"hs_time_in_marketingqualifiedlead":null,"hs_time_in_opportunity":null,"hs_time_in_other":null,"hs_time_in_salesqualifiedlead":null,"hs_time_in_subscriber":54013709983,"hs_time_to_first_engagement":null,"hs_time_to_move_from_lead_to_customer":null,"hs_time_to_move_from_marketingqualifiedlead_to_customer":null,"hs_time_to_move_from_opportunity_to_customer":null,"hs_time_to_move_from_salesqualifiedlead_to_customer":null,"hs_time_to_move_from_subscriber_to_customer":null,"hs_timezone":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":null,"hs_was_imported":null,"hs_whatsapp_phone_number":null,"hubspot_owner_assigneddate":null,"hubspot_owner_id":null,"hubspot_team_id":null,"hubspotscore":null,"industry":null,"ip_city":null,"ip_country":null,"ip_country_code":null,"ip_latlon":null,"ip_state":null,"ip_state_code":null,"ip_zipcode":null,"job_function":null,"jobtitle":null,"lastmodifieddate":"2023-04-03T20:28:44.429000+00:00","lastname":"testerson number 1","lifecyclestage":"subscriber","marital_status":null,"message":null,"military_status":null,"mobilephone":null,"my_custom_test_property":null,"notes_last_contacted":null,"notes_last_updated":null,"notes_next_activity_date":null,"num_associated_deals":null,"num_contacted_notes":null,"num_conversion_events":0,"num_notes":null,"num_unique_conversion_events":0,"numemployees":null,"phone":"555-122-2323","recent_conversion_date":null,"recent_conversion_event_name":null,"recent_deal_amount":null,"recent_deal_close_date":null,"relationship_status":null,"salutation":null,"school":null,"seniority":null,"start_date":null,"state":"MA","surveymonkeyeventlastupdated":null,"test":null,"total_revenue":null,"twitterhandle":null,"webinareventlastupdated":null,"website":"http://hubspot.com","work_email":null,"zip":"02139"},"createdAt":"2021-10-12T13:23:01.830Z","updatedAt":"2023-04-03T20:28:44.429Z","archived":false},"emitted_at":1688058691918} -{"stream":"contacts","data":{"id":"2501","properties":{"address":null,"annualrevenue":null,"associatedcompanyid":null,"associatedcompanylastupdated":null,"city":null,"closedate":null,"company":null,"company_size":null,"country":null,"createdate":"2023-01-30T23:17:09.904000+00:00","currentlyinworkflow":null,"date_of_birth":null,"days_to_close":null,"degree":null,"email":"test@test.com","engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"fax":null,"field_of_study":null,"first_conversion_date":null,"first_conversion_event_name":null,"first_deal_created_date":null,"firstname":"test","gender":null,"graduation_date":null,"hs_additional_emails":null,"hs_all_accessible_team_ids":null,"hs_all_contact_vids":"2501","hs_all_owner_ids":"","hs_all_team_ids":null,"hs_analytics_average_page_views":0,"hs_analytics_first_referrer":null,"hs_analytics_first_timestamp":"2023-01-30T23:17:09.904000+00:00","hs_analytics_first_touch_converting_campaign":null,"hs_analytics_first_url":null,"hs_analytics_first_visit_timestamp":null,"hs_analytics_last_referrer":null,"hs_analytics_last_timestamp":null,"hs_analytics_last_touch_converting_campaign":null,"hs_analytics_last_url":null,"hs_analytics_last_visit_timestamp":null,"hs_analytics_num_event_completions":0,"hs_analytics_num_page_views":0,"hs_analytics_num_visits":0,"hs_analytics_revenue":0,"hs_analytics_source":"OFFLINE","hs_analytics_source_data_1":"CRM_UI","hs_analytics_source_data_2":"userId:12282590","hs_avatar_filemanager_key":null,"hs_buying_role":null,"hs_calculated_form_submissions":null,"hs_calculated_merged_vids":null,"hs_calculated_mobile_number":null,"hs_calculated_phone_number":"+555555555555","hs_calculated_phone_number_area_code":null,"hs_calculated_phone_number_country_code":"BR","hs_calculated_phone_number_region_code":null,"hs_clicked_linkedin_ad":null,"hs_content_membership_email":null,"hs_content_membership_email_confirmed":null,"hs_content_membership_notes":null,"hs_content_membership_registered_at":null,"hs_content_membership_registration_domain_sent_to":null,"hs_content_membership_registration_email_sent_at":null,"hs_content_membership_status":null,"hs_conversations_visitor_email":null,"hs_count_is_unworked":null,"hs_count_is_worked":null,"hs_created_by_conversations":null,"hs_created_by_user_id":12282590,"hs_createdate":null,"hs_date_entered_customer":null,"hs_date_entered_evangelist":null,"hs_date_entered_lead":"2023-01-30T23:17:09.904000+00:00","hs_date_entered_marketingqualifiedlead":null,"hs_date_entered_opportunity":"2023-01-31T00:31:07.832000+00:00","hs_date_entered_other":null,"hs_date_entered_salesqualifiedlead":null,"hs_date_entered_subscriber":null,"hs_date_exited_customer":null,"hs_date_exited_evangelist":null,"hs_date_exited_lead":"2023-01-31T00:31:07.832000+00:00","hs_date_exited_marketingqualifiedlead":null,"hs_date_exited_opportunity":null,"hs_date_exited_other":null,"hs_date_exited_salesqualifiedlead":null,"hs_date_exited_subscriber":null,"hs_document_last_revisited":null,"hs_email_bad_address":null,"hs_email_bounce":null,"hs_email_click":null,"hs_email_customer_quarantined_reason":null,"hs_email_delivered":null,"hs_email_domain":"test.com","hs_email_first_click_date":null,"hs_email_first_open_date":null,"hs_email_first_reply_date":null,"hs_email_first_send_date":null,"hs_email_hard_bounce_reason":null,"hs_email_hard_bounce_reason_enum":null,"hs_email_is_ineligible":null,"hs_email_last_click_date":null,"hs_email_last_email_name":null,"hs_email_last_open_date":null,"hs_email_last_reply_date":null,"hs_email_last_send_date":null,"hs_email_open":null,"hs_email_optout":null,"hs_email_optout_10798197":null,"hs_email_optout_11890603":null,"hs_email_optout_11890831":null,"hs_email_optout_23704464":null,"hs_email_optout_94692364":null,"hs_email_quarantined":null,"hs_email_quarantined_reason":null,"hs_email_recipient_fatigue_recovery_time":null,"hs_email_replied":null,"hs_email_sends_since_last_engagement":null,"hs_emailconfirmationstatus":null,"hs_facebook_ad_clicked":null,"hs_facebook_click_id":null,"hs_feedback_last_nps_follow_up":null,"hs_feedback_last_nps_rating":null,"hs_feedback_last_survey_date":null,"hs_feedback_show_nps_web_survey":null,"hs_first_engagement_object_id":null,"hs_first_outreach_date":null,"hs_first_subscription_create_date":null,"hs_google_click_id":null,"hs_has_active_subscription":null,"hs_ip_timezone":null,"hs_is_contact":true,"hs_is_unworked":true,"hs_language":null,"hs_last_sales_activity_date":null,"hs_last_sales_activity_timestamp":null,"hs_last_sales_activity_type":null,"hs_lastmodifieddate":null,"hs_latest_meeting_activity":null,"hs_latest_sequence_ended_date":null,"hs_latest_sequence_enrolled":null,"hs_latest_sequence_enrolled_date":null,"hs_latest_sequence_finished_date":null,"hs_latest_sequence_unenrolled_date":null,"hs_latest_source":"OFFLINE","hs_latest_source_data_1":"CRM_UI","hs_latest_source_data_2":"userId:12282590","hs_latest_source_timestamp":"2023-01-30T23:17:10.053000+00:00","hs_latest_subscription_create_date":null,"hs_lead_status":null,"hs_legal_basis":"Legitimate interest – prospect/lead","hs_lifecyclestage_customer_date":null,"hs_lifecyclestage_evangelist_date":null,"hs_lifecyclestage_lead_date":"2023-01-30T23:17:09.904000+00:00","hs_lifecyclestage_marketingqualifiedlead_date":null,"hs_lifecyclestage_opportunity_date":"2023-01-31T00:31:07.832000+00:00","hs_lifecyclestage_other_date":null,"hs_lifecyclestage_salesqualifiedlead_date":null,"hs_lifecyclestage_subscriber_date":null,"hs_linkedin_ad_clicked":null,"hs_marketable_reason_id":null,"hs_marketable_reason_type":null,"hs_marketable_status":"false","hs_marketable_until_renewal":"false","hs_merged_object_ids":null,"hs_object_id":2501,"hs_persona":null,"hs_pinned_engagement_id":null,"hs_pipeline":"contacts-lifecycle-pipeline","hs_predictivecontactscore":null,"hs_predictivecontactscore_v2":2.93,"hs_predictivecontactscorebucket":null,"hs_predictivescoringtier":"tier_1","hs_read_only":null,"hs_sa_first_engagement_date":null,"hs_sa_first_engagement_descr":null,"hs_sa_first_engagement_object_type":null,"hs_sales_email_last_clicked":null,"hs_sales_email_last_opened":null,"hs_sales_email_last_replied":null,"hs_searchable_calculated_international_mobile_number":null,"hs_searchable_calculated_international_phone_number":null,"hs_searchable_calculated_mobile_number":null,"hs_searchable_calculated_phone_number":"5555555555","hs_sequences_actively_enrolled_count":0,"hs_sequences_enrolled_count":null,"hs_sequences_is_enrolled":null,"hs_testpurge":null,"hs_testrollback":null,"hs_time_between_contact_creation_and_deal_close":null,"hs_time_between_contact_creation_and_deal_creation":null,"hs_time_in_customer":null,"hs_time_in_evangelist":null,"hs_time_in_lead":4437928,"hs_time_in_marketingqualifiedlead":null,"hs_time_in_opportunity":12933623981,"hs_time_in_other":null,"hs_time_in_salesqualifiedlead":null,"hs_time_in_subscriber":null,"hs_time_to_first_engagement":null,"hs_time_to_move_from_lead_to_customer":null,"hs_time_to_move_from_marketingqualifiedlead_to_customer":null,"hs_time_to_move_from_opportunity_to_customer":null,"hs_time_to_move_from_salesqualifiedlead_to_customer":null,"hs_time_to_move_from_subscriber_to_customer":null,"hs_timezone":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"","hs_was_imported":null,"hs_whatsapp_phone_number":null,"hubspot_owner_assigneddate":null,"hubspot_owner_id":"","hubspot_team_id":null,"hubspotscore":null,"industry":null,"ip_city":null,"ip_country":null,"ip_country_code":null,"ip_latlon":null,"ip_state":null,"ip_state_code":null,"ip_zipcode":null,"job_function":null,"jobtitle":null,"lastmodifieddate":"2023-04-04T15:11:47.143000+00:00","lastname":"test","lifecyclestage":"opportunity","marital_status":null,"message":null,"military_status":null,"mobilephone":null,"my_custom_test_property":null,"notes_last_contacted":null,"notes_last_updated":null,"notes_next_activity_date":null,"num_associated_deals":null,"num_contacted_notes":null,"num_conversion_events":0,"num_notes":null,"num_unique_conversion_events":0,"numemployees":null,"phone":"+555555555555","recent_conversion_date":null,"recent_conversion_event_name":null,"recent_deal_amount":null,"recent_deal_close_date":null,"relationship_status":null,"salutation":null,"school":null,"seniority":null,"start_date":null,"state":null,"surveymonkeyeventlastupdated":null,"test":null,"total_revenue":null,"twitterhandle":null,"webinareventlastupdated":null,"website":null,"work_email":null,"zip":null},"createdAt":"2023-01-30T23:17:09.904Z","updatedAt":"2023-04-04T15:11:47.143Z","archived":false},"emitted_at":1688058691919} -{"stream":"contacts","data":{"id":"2551","properties":{"address":null,"annualrevenue":null,"associatedcompanyid":null,"associatedcompanylastupdated":null,"city":null,"closedate":null,"company":null,"company_size":null,"country":null,"createdate":"2023-01-31T00:11:58.499000+00:00","currentlyinworkflow":null,"date_of_birth":null,"days_to_close":null,"degree":null,"email":"test-integration-test-user-4@testmail.com","engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"fax":null,"field_of_study":null,"first_conversion_date":null,"first_conversion_event_name":null,"first_deal_created_date":null,"firstname":null,"gender":null,"graduation_date":null,"hs_additional_emails":null,"hs_all_accessible_team_ids":null,"hs_all_contact_vids":"2551","hs_all_owner_ids":"52550153","hs_all_team_ids":null,"hs_analytics_average_page_views":0,"hs_analytics_first_referrer":null,"hs_analytics_first_timestamp":"2023-01-31T00:11:58.499000+00:00","hs_analytics_first_touch_converting_campaign":null,"hs_analytics_first_url":null,"hs_analytics_first_visit_timestamp":null,"hs_analytics_last_referrer":null,"hs_analytics_last_timestamp":null,"hs_analytics_last_touch_converting_campaign":null,"hs_analytics_last_url":null,"hs_analytics_last_visit_timestamp":null,"hs_analytics_num_event_completions":0,"hs_analytics_num_page_views":0,"hs_analytics_num_visits":0,"hs_analytics_revenue":0,"hs_analytics_source":"OFFLINE","hs_analytics_source_data_1":"CRM_UI","hs_analytics_source_data_2":"userId:12282590","hs_avatar_filemanager_key":null,"hs_buying_role":null,"hs_calculated_form_submissions":null,"hs_calculated_merged_vids":null,"hs_calculated_mobile_number":null,"hs_calculated_phone_number":null,"hs_calculated_phone_number_area_code":null,"hs_calculated_phone_number_country_code":null,"hs_calculated_phone_number_region_code":null,"hs_clicked_linkedin_ad":null,"hs_content_membership_email":null,"hs_content_membership_email_confirmed":null,"hs_content_membership_notes":null,"hs_content_membership_registered_at":null,"hs_content_membership_registration_domain_sent_to":null,"hs_content_membership_registration_email_sent_at":null,"hs_content_membership_status":null,"hs_conversations_visitor_email":null,"hs_count_is_unworked":1,"hs_count_is_worked":0,"hs_created_by_conversations":null,"hs_created_by_user_id":12282590,"hs_createdate":null,"hs_date_entered_customer":null,"hs_date_entered_evangelist":null,"hs_date_entered_lead":"2023-01-31T00:11:58.499000+00:00","hs_date_entered_marketingqualifiedlead":null,"hs_date_entered_opportunity":null,"hs_date_entered_other":null,"hs_date_entered_salesqualifiedlead":null,"hs_date_entered_subscriber":null,"hs_date_exited_customer":null,"hs_date_exited_evangelist":null,"hs_date_exited_lead":null,"hs_date_exited_marketingqualifiedlead":null,"hs_date_exited_opportunity":null,"hs_date_exited_other":null,"hs_date_exited_salesqualifiedlead":null,"hs_date_exited_subscriber":null,"hs_document_last_revisited":null,"hs_email_bad_address":null,"hs_email_bounce":null,"hs_email_click":null,"hs_email_customer_quarantined_reason":null,"hs_email_delivered":null,"hs_email_domain":"testmail.com","hs_email_first_click_date":null,"hs_email_first_open_date":null,"hs_email_first_reply_date":null,"hs_email_first_send_date":null,"hs_email_hard_bounce_reason":null,"hs_email_hard_bounce_reason_enum":null,"hs_email_is_ineligible":null,"hs_email_last_click_date":null,"hs_email_last_email_name":null,"hs_email_last_open_date":null,"hs_email_last_reply_date":null,"hs_email_last_send_date":null,"hs_email_open":null,"hs_email_optout":null,"hs_email_optout_10798197":null,"hs_email_optout_11890603":null,"hs_email_optout_11890831":null,"hs_email_optout_23704464":null,"hs_email_optout_94692364":null,"hs_email_quarantined":null,"hs_email_quarantined_reason":null,"hs_email_recipient_fatigue_recovery_time":null,"hs_email_replied":null,"hs_email_sends_since_last_engagement":null,"hs_emailconfirmationstatus":null,"hs_facebook_ad_clicked":null,"hs_facebook_click_id":null,"hs_feedback_last_nps_follow_up":null,"hs_feedback_last_nps_rating":null,"hs_feedback_last_survey_date":null,"hs_feedback_show_nps_web_survey":null,"hs_first_engagement_object_id":null,"hs_first_outreach_date":null,"hs_first_subscription_create_date":null,"hs_google_click_id":null,"hs_has_active_subscription":null,"hs_ip_timezone":null,"hs_is_contact":true,"hs_is_unworked":true,"hs_language":null,"hs_last_sales_activity_date":null,"hs_last_sales_activity_timestamp":null,"hs_last_sales_activity_type":null,"hs_lastmodifieddate":null,"hs_latest_meeting_activity":null,"hs_latest_sequence_ended_date":null,"hs_latest_sequence_enrolled":null,"hs_latest_sequence_enrolled_date":null,"hs_latest_sequence_finished_date":null,"hs_latest_sequence_unenrolled_date":null,"hs_latest_source":"OFFLINE","hs_latest_source_data_1":"CRM_UI","hs_latest_source_data_2":"userId:12282590","hs_latest_source_timestamp":"2023-01-31T00:11:58.582000+00:00","hs_latest_subscription_create_date":null,"hs_lead_status":null,"hs_legal_basis":"Legitimate interest – prospect/lead","hs_lifecyclestage_customer_date":null,"hs_lifecyclestage_evangelist_date":null,"hs_lifecyclestage_lead_date":"2023-01-31T00:11:58.499000+00:00","hs_lifecyclestage_marketingqualifiedlead_date":null,"hs_lifecyclestage_opportunity_date":null,"hs_lifecyclestage_other_date":null,"hs_lifecyclestage_salesqualifiedlead_date":null,"hs_lifecyclestage_subscriber_date":null,"hs_linkedin_ad_clicked":null,"hs_marketable_reason_id":null,"hs_marketable_reason_type":null,"hs_marketable_status":"false","hs_marketable_until_renewal":"false","hs_merged_object_ids":null,"hs_object_id":2551,"hs_persona":null,"hs_pinned_engagement_id":null,"hs_pipeline":"contacts-lifecycle-pipeline","hs_predictivecontactscore":null,"hs_predictivecontactscore_v2":2.93,"hs_predictivecontactscorebucket":null,"hs_predictivescoringtier":"tier_1","hs_read_only":null,"hs_sa_first_engagement_date":null,"hs_sa_first_engagement_descr":null,"hs_sa_first_engagement_object_type":null,"hs_sales_email_last_clicked":null,"hs_sales_email_last_opened":null,"hs_sales_email_last_replied":null,"hs_searchable_calculated_international_mobile_number":null,"hs_searchable_calculated_international_phone_number":null,"hs_searchable_calculated_mobile_number":null,"hs_searchable_calculated_phone_number":null,"hs_sequences_actively_enrolled_count":0,"hs_sequences_enrolled_count":null,"hs_sequences_is_enrolled":null,"hs_testpurge":null,"hs_testrollback":null,"hs_time_between_contact_creation_and_deal_close":null,"hs_time_between_contact_creation_and_deal_creation":null,"hs_time_in_customer":null,"hs_time_in_evangelist":null,"hs_time_in_lead":12934773314,"hs_time_in_marketingqualifiedlead":null,"hs_time_in_opportunity":null,"hs_time_in_other":null,"hs_time_in_salesqualifiedlead":null,"hs_time_in_subscriber":null,"hs_time_to_first_engagement":null,"hs_time_to_move_from_lead_to_customer":null,"hs_time_to_move_from_marketingqualifiedlead_to_customer":null,"hs_time_to_move_from_opportunity_to_customer":null,"hs_time_to_move_from_salesqualifiedlead_to_customer":null,"hs_time_to_move_from_subscriber_to_customer":null,"hs_timezone":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"12282590","hs_was_imported":null,"hs_whatsapp_phone_number":null,"hubspot_owner_assigneddate":"2023-01-31T00:20:40.680000+00:00","hubspot_owner_id":"52550153","hubspot_team_id":null,"hubspotscore":null,"industry":null,"ip_city":null,"ip_country":null,"ip_country_code":null,"ip_latlon":null,"ip_state":null,"ip_state_code":null,"ip_zipcode":null,"job_function":null,"jobtitle":null,"lastmodifieddate":"2023-04-03T20:29:54.560000+00:00","lastname":null,"lifecyclestage":"lead","marital_status":null,"message":null,"military_status":null,"mobilephone":null,"my_custom_test_property":null,"notes_last_contacted":null,"notes_last_updated":null,"notes_next_activity_date":null,"num_associated_deals":null,"num_contacted_notes":null,"num_conversion_events":0,"num_notes":null,"num_unique_conversion_events":0,"numemployees":null,"phone":null,"recent_conversion_date":null,"recent_conversion_event_name":null,"recent_deal_amount":null,"recent_deal_close_date":null,"relationship_status":null,"salutation":null,"school":null,"seniority":null,"start_date":null,"state":null,"surveymonkeyeventlastupdated":null,"test":null,"total_revenue":null,"twitterhandle":null,"webinareventlastupdated":null,"website":null,"work_email":null,"zip":null},"createdAt":"2023-01-31T00:11:58.499Z","updatedAt":"2023-04-03T20:29:54.560Z","archived":false},"emitted_at":1688058691920} -{"stream":"contacts","data":{"id":"2601","properties":{"address":null,"annualrevenue":null,"associatedcompanyid":null,"associatedcompanylastupdated":null,"city":null,"closedate":null,"company":null,"company_size":null,"country":null,"createdate":"2023-02-01T13:08:49.766000+00:00","currentlyinworkflow":null,"date_of_birth":null,"days_to_close":null,"degree":null,"email":"test.person@airbyte.com","engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"fax":null,"field_of_study":null,"first_conversion_date":null,"first_conversion_event_name":null,"first_deal_created_date":null,"firstname":"TEST","gender":null,"graduation_date":null,"hs_additional_emails":null,"hs_all_accessible_team_ids":null,"hs_all_contact_vids":"2601","hs_all_owner_ids":"52550153","hs_all_team_ids":null,"hs_analytics_average_page_views":0,"hs_analytics_first_referrer":null,"hs_analytics_first_timestamp":"2023-02-01T13:08:49.735000+00:00","hs_analytics_first_touch_converting_campaign":null,"hs_analytics_first_url":null,"hs_analytics_first_visit_timestamp":null,"hs_analytics_last_referrer":null,"hs_analytics_last_timestamp":null,"hs_analytics_last_touch_converting_campaign":null,"hs_analytics_last_url":null,"hs_analytics_last_visit_timestamp":null,"hs_analytics_num_event_completions":0,"hs_analytics_num_page_views":0,"hs_analytics_num_visits":0,"hs_analytics_revenue":0,"hs_analytics_source":"OFFLINE","hs_analytics_source_data_1":"CRM_UI","hs_analytics_source_data_2":"userId:12282590","hs_avatar_filemanager_key":null,"hs_buying_role":null,"hs_calculated_form_submissions":null,"hs_calculated_merged_vids":null,"hs_calculated_mobile_number":null,"hs_calculated_phone_number":null,"hs_calculated_phone_number_area_code":null,"hs_calculated_phone_number_country_code":null,"hs_calculated_phone_number_region_code":null,"hs_clicked_linkedin_ad":null,"hs_content_membership_email":null,"hs_content_membership_email_confirmed":null,"hs_content_membership_notes":null,"hs_content_membership_registered_at":null,"hs_content_membership_registration_domain_sent_to":null,"hs_content_membership_registration_email_sent_at":null,"hs_content_membership_status":null,"hs_conversations_visitor_email":null,"hs_count_is_unworked":1,"hs_count_is_worked":0,"hs_created_by_conversations":null,"hs_created_by_user_id":12282590,"hs_createdate":null,"hs_date_entered_customer":null,"hs_date_entered_evangelist":null,"hs_date_entered_lead":"2023-02-01T13:08:49.735000+00:00","hs_date_entered_marketingqualifiedlead":null,"hs_date_entered_opportunity":null,"hs_date_entered_other":null,"hs_date_entered_salesqualifiedlead":null,"hs_date_entered_subscriber":null,"hs_date_exited_customer":null,"hs_date_exited_evangelist":null,"hs_date_exited_lead":null,"hs_date_exited_marketingqualifiedlead":null,"hs_date_exited_opportunity":null,"hs_date_exited_other":null,"hs_date_exited_salesqualifiedlead":null,"hs_date_exited_subscriber":null,"hs_document_last_revisited":null,"hs_email_bad_address":null,"hs_email_bounce":null,"hs_email_click":null,"hs_email_customer_quarantined_reason":null,"hs_email_delivered":null,"hs_email_domain":"airbyte.com","hs_email_first_click_date":null,"hs_email_first_open_date":null,"hs_email_first_reply_date":null,"hs_email_first_send_date":null,"hs_email_hard_bounce_reason":null,"hs_email_hard_bounce_reason_enum":null,"hs_email_is_ineligible":null,"hs_email_last_click_date":null,"hs_email_last_email_name":null,"hs_email_last_open_date":null,"hs_email_last_reply_date":null,"hs_email_last_send_date":null,"hs_email_open":null,"hs_email_optout":null,"hs_email_optout_10798197":null,"hs_email_optout_11890603":null,"hs_email_optout_11890831":null,"hs_email_optout_23704464":null,"hs_email_optout_94692364":null,"hs_email_quarantined":null,"hs_email_quarantined_reason":null,"hs_email_recipient_fatigue_recovery_time":null,"hs_email_replied":null,"hs_email_sends_since_last_engagement":null,"hs_emailconfirmationstatus":null,"hs_facebook_ad_clicked":null,"hs_facebook_click_id":null,"hs_feedback_last_nps_follow_up":null,"hs_feedback_last_nps_rating":null,"hs_feedback_last_survey_date":null,"hs_feedback_show_nps_web_survey":null,"hs_first_engagement_object_id":null,"hs_first_outreach_date":null,"hs_first_subscription_create_date":null,"hs_google_click_id":null,"hs_has_active_subscription":null,"hs_ip_timezone":null,"hs_is_contact":true,"hs_is_unworked":true,"hs_language":null,"hs_last_sales_activity_date":null,"hs_last_sales_activity_timestamp":null,"hs_last_sales_activity_type":null,"hs_lastmodifieddate":null,"hs_latest_meeting_activity":null,"hs_latest_sequence_ended_date":null,"hs_latest_sequence_enrolled":null,"hs_latest_sequence_enrolled_date":null,"hs_latest_sequence_finished_date":null,"hs_latest_sequence_unenrolled_date":null,"hs_latest_source":"OFFLINE","hs_latest_source_data_1":"CRM_UI","hs_latest_source_data_2":"userId:12282590","hs_latest_source_timestamp":"2023-02-01T13:08:49.863000+00:00","hs_latest_subscription_create_date":null,"hs_lead_status":null,"hs_legal_basis":"Performance of a contract","hs_lifecyclestage_customer_date":null,"hs_lifecyclestage_evangelist_date":null,"hs_lifecyclestage_lead_date":"2023-02-01T13:08:49.735000+00:00","hs_lifecyclestage_marketingqualifiedlead_date":null,"hs_lifecyclestage_opportunity_date":null,"hs_lifecyclestage_other_date":null,"hs_lifecyclestage_salesqualifiedlead_date":null,"hs_lifecyclestage_subscriber_date":null,"hs_linkedin_ad_clicked":null,"hs_marketable_reason_id":"12282590","hs_marketable_reason_type":"USER_SET","hs_marketable_status":"true","hs_marketable_until_renewal":"false","hs_merged_object_ids":null,"hs_object_id":2601,"hs_persona":null,"hs_pinned_engagement_id":null,"hs_pipeline":"contacts-lifecycle-pipeline","hs_predictivecontactscore":null,"hs_predictivecontactscore_v2":3.15,"hs_predictivecontactscorebucket":null,"hs_predictivescoringtier":"tier_1","hs_read_only":null,"hs_sa_first_engagement_date":null,"hs_sa_first_engagement_descr":null,"hs_sa_first_engagement_object_type":null,"hs_sales_email_last_clicked":null,"hs_sales_email_last_opened":null,"hs_sales_email_last_replied":null,"hs_searchable_calculated_international_mobile_number":null,"hs_searchable_calculated_international_phone_number":null,"hs_searchable_calculated_mobile_number":null,"hs_searchable_calculated_phone_number":null,"hs_sequences_actively_enrolled_count":0,"hs_sequences_enrolled_count":null,"hs_sequences_is_enrolled":null,"hs_testpurge":null,"hs_testrollback":null,"hs_time_between_contact_creation_and_deal_close":null,"hs_time_between_contact_creation_and_deal_creation":null,"hs_time_in_customer":null,"hs_time_in_evangelist":null,"hs_time_in_lead":12801762079,"hs_time_in_marketingqualifiedlead":null,"hs_time_in_opportunity":null,"hs_time_in_other":null,"hs_time_in_salesqualifiedlead":null,"hs_time_in_subscriber":null,"hs_time_to_first_engagement":null,"hs_time_to_move_from_lead_to_customer":null,"hs_time_to_move_from_marketingqualifiedlead_to_customer":null,"hs_time_to_move_from_opportunity_to_customer":null,"hs_time_to_move_from_salesqualifiedlead_to_customer":null,"hs_time_to_move_from_subscriber_to_customer":null,"hs_timezone":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"12282590","hs_was_imported":null,"hs_whatsapp_phone_number":null,"hubspot_owner_assigneddate":"2023-02-01T13:08:49.735000+00:00","hubspot_owner_id":"52550153","hubspot_team_id":null,"hubspotscore":null,"industry":null,"ip_city":null,"ip_country":null,"ip_country_code":null,"ip_latlon":null,"ip_state":null,"ip_state_code":null,"ip_zipcode":null,"job_function":null,"jobtitle":null,"lastmodifieddate":"2023-04-03T20:29:58.691000+00:00","lastname":"TEST","lifecyclestage":"lead","marital_status":null,"message":null,"military_status":null,"mobilephone":null,"my_custom_test_property":null,"notes_last_contacted":null,"notes_last_updated":null,"notes_next_activity_date":null,"num_associated_deals":null,"num_contacted_notes":null,"num_conversion_events":0,"num_notes":null,"num_unique_conversion_events":0,"numemployees":null,"phone":null,"recent_conversion_date":null,"recent_conversion_event_name":null,"recent_deal_amount":null,"recent_deal_close_date":null,"relationship_status":null,"salutation":null,"school":null,"seniority":null,"start_date":null,"state":null,"surveymonkeyeventlastupdated":null,"test":null,"total_revenue":null,"twitterhandle":null,"webinareventlastupdated":null,"website":null,"work_email":null,"zip":null},"createdAt":"2023-02-01T13:08:49.766Z","updatedAt":"2023-04-03T20:29:58.691Z","archived":false},"emitted_at":1688058691921} +{"stream": "contacts", "data": {"id": "151", "properties": {"address": null, "annualrevenue": null, "associatedcompanyid": 5000526215, "associatedcompanylastupdated": null, "city": null, "closedate": null, "company": null, "company_size": null, "country": null, "createdate": "2020-12-11T01:29:50.116000+00:00", "currentlyinworkflow": null, "date_of_birth": null, "days_to_close": null, "degree": null, "email": "shef@dne.io", "engagements_last_meeting_booked": null, "engagements_last_meeting_booked_campaign": null, "engagements_last_meeting_booked_medium": null, "engagements_last_meeting_booked_source": null, "fax": null, "field_of_study": null, "first_conversion_date": null, "first_conversion_event_name": null, "first_deal_created_date": null, "firstname": "sh", "gender": null, "graduation_date": null, "hs_additional_emails": null, "hs_all_accessible_team_ids": null, "hs_all_contact_vids": "151", "hs_all_owner_ids": "52550153", "hs_all_team_ids": null, "hs_analytics_average_page_views": 0, "hs_analytics_first_referrer": null, "hs_analytics_first_timestamp": "2020-12-11T01:29:50.116000+00:00", "hs_analytics_first_touch_converting_campaign": null, "hs_analytics_first_url": null, "hs_analytics_first_visit_timestamp": null, "hs_analytics_last_referrer": null, "hs_analytics_last_timestamp": null, "hs_analytics_last_touch_converting_campaign": null, "hs_analytics_last_url": null, "hs_analytics_last_visit_timestamp": null, "hs_analytics_num_event_completions": 0, "hs_analytics_num_page_views": 0, "hs_analytics_num_visits": 0, "hs_analytics_revenue": 0.0, "hs_analytics_source": "OFFLINE", "hs_analytics_source_data_1": "CONTACTS", "hs_analytics_source_data_2": "CRM_UI", "hs_avatar_filemanager_key": null, "hs_buying_role": null, "hs_calculated_form_submissions": null, "hs_calculated_merged_vids": null, "hs_calculated_mobile_number": null, "hs_calculated_phone_number": null, "hs_calculated_phone_number_area_code": null, "hs_calculated_phone_number_country_code": null, "hs_calculated_phone_number_region_code": null, "hs_clicked_linkedin_ad": null, "hs_content_membership_email": null, "hs_content_membership_email_confirmed": null, "hs_content_membership_notes": null, "hs_content_membership_registered_at": null, "hs_content_membership_registration_domain_sent_to": null, "hs_content_membership_registration_email_sent_at": null, "hs_content_membership_status": null, "hs_conversations_visitor_email": null, "hs_count_is_unworked": 1, "hs_count_is_worked": 0, "hs_created_by_conversations": null, "hs_created_by_user_id": null, "hs_createdate": null, "hs_date_entered_customer": null, "hs_date_entered_evangelist": null, "hs_date_entered_lead": null, "hs_date_entered_marketingqualifiedlead": null, "hs_date_entered_opportunity": null, "hs_date_entered_other": null, "hs_date_entered_salesqualifiedlead": null, "hs_date_entered_subscriber": "2020-12-11T01:29:50.116000+00:00", "hs_date_exited_customer": null, "hs_date_exited_evangelist": null, "hs_date_exited_lead": null, "hs_date_exited_marketingqualifiedlead": null, "hs_date_exited_opportunity": null, "hs_date_exited_other": null, "hs_date_exited_salesqualifiedlead": null, "hs_date_exited_subscriber": null, "hs_document_last_revisited": null, "hs_email_bad_address": null, "hs_email_bounce": null, "hs_email_click": null, "hs_email_customer_quarantined_reason": null, "hs_email_delivered": null, "hs_email_domain": "dne.io", "hs_email_first_click_date": null, "hs_email_first_open_date": null, "hs_email_first_reply_date": null, "hs_email_first_send_date": null, "hs_email_hard_bounce_reason": null, "hs_email_hard_bounce_reason_enum": null, "hs_email_is_ineligible": null, "hs_email_last_click_date": null, "hs_email_last_email_name": null, "hs_email_last_open_date": null, "hs_email_last_reply_date": null, "hs_email_last_send_date": null, "hs_email_open": null, "hs_email_optout": null, "hs_email_optout_10798197": null, "hs_email_optout_11890603": null, "hs_email_optout_11890831": null, "hs_email_optout_23704464": null, "hs_email_optout_94692364": null, "hs_email_quarantined": null, "hs_email_quarantined_reason": null, "hs_email_recipient_fatigue_recovery_time": null, "hs_email_replied": null, "hs_email_sends_since_last_engagement": null, "hs_emailconfirmationstatus": null, "hs_facebook_ad_clicked": null, "hs_facebook_click_id": null, "hs_feedback_last_nps_follow_up": null, "hs_feedback_last_nps_rating": null, "hs_feedback_last_survey_date": null, "hs_feedback_show_nps_web_survey": null, "hs_first_engagement_object_id": null, "hs_first_outreach_date": null, "hs_first_subscription_create_date": null, "hs_google_click_id": null, "hs_has_active_subscription": null, "hs_ip_timezone": null, "hs_is_contact": true, "hs_is_unworked": true, "hs_language": null, "hs_last_sales_activity_date": null, "hs_last_sales_activity_timestamp": null, "hs_last_sales_activity_type": null, "hs_lastmodifieddate": null, "hs_latest_meeting_activity": null, "hs_latest_sequence_ended_date": null, "hs_latest_sequence_enrolled": null, "hs_latest_sequence_enrolled_date": null, "hs_latest_sequence_finished_date": null, "hs_latest_sequence_unenrolled_date": null, "hs_latest_source": "OFFLINE", "hs_latest_source_data_1": "CONTACTS", "hs_latest_source_data_2": "CRM_UI", "hs_latest_source_timestamp": "2020-12-11T01:29:50.153000+00:00", "hs_latest_subscription_create_date": null, "hs_lead_status": null, "hs_legal_basis": null, "hs_lifecyclestage_customer_date": null, "hs_lifecyclestage_evangelist_date": null, "hs_lifecyclestage_lead_date": null, "hs_lifecyclestage_marketingqualifiedlead_date": null, "hs_lifecyclestage_opportunity_date": null, "hs_lifecyclestage_other_date": null, "hs_lifecyclestage_salesqualifiedlead_date": null, "hs_lifecyclestage_subscriber_date": "2020-12-11T01:29:50.116000+00:00", "hs_linkedin_ad_clicked": null, "hs_marketable_reason_id": null, "hs_marketable_reason_type": null, "hs_marketable_status": "false", "hs_marketable_until_renewal": "false", "hs_merged_object_ids": null, "hs_object_id": 151, "hs_persona": null, "hs_pinned_engagement_id": null, "hs_pipeline": "contacts-lifecycle-pipeline", "hs_predictivecontactscore": null, "hs_predictivecontactscore_v2": 0.29, "hs_predictivecontactscorebucket": null, "hs_predictivescoringtier": "tier_4", "hs_read_only": null, "hs_sa_first_engagement_date": null, "hs_sa_first_engagement_descr": null, "hs_sa_first_engagement_object_type": null, "hs_sales_email_last_clicked": null, "hs_sales_email_last_opened": null, "hs_sales_email_last_replied": null, "hs_searchable_calculated_international_mobile_number": null, "hs_searchable_calculated_international_phone_number": null, "hs_searchable_calculated_mobile_number": null, "hs_searchable_calculated_phone_number": null, "hs_sequences_actively_enrolled_count": null, "hs_sequences_enrolled_count": null, "hs_sequences_is_enrolled": null, "hs_testpurge": null, "hs_testrollback": null, "hs_time_between_contact_creation_and_deal_close": null, "hs_time_between_contact_creation_and_deal_creation": null, "hs_time_in_customer": null, "hs_time_in_evangelist": null, "hs_time_in_lead": null, "hs_time_in_marketingqualifiedlead": null, "hs_time_in_opportunity": null, "hs_time_in_other": null, "hs_time_in_salesqualifiedlead": null, "hs_time_in_subscriber": 81326932669, "hs_time_to_first_engagement": null, "hs_time_to_move_from_lead_to_customer": null, "hs_time_to_move_from_marketingqualifiedlead_to_customer": null, "hs_time_to_move_from_opportunity_to_customer": null, "hs_time_to_move_from_salesqualifiedlead_to_customer": null, "hs_time_to_move_from_subscriber_to_customer": null, "hs_timezone": null, "hs_unique_creation_key": null, "hs_updated_by_user_id": 12282590, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": "12282590", "hs_was_imported": null, "hs_whatsapp_phone_number": null, "hubspot_owner_assigneddate": "2020-12-11T01:29:50.093000+00:00", "hubspot_owner_id": "52550153", "hubspot_team_id": null, "hubspotscore": null, "industry": null, "ip_city": null, "ip_country": null, "ip_country_code": null, "ip_latlon": null, "ip_state": null, "ip_state_code": null, "ip_zipcode": null, "job_function": null, "jobtitle": null, "lastmodifieddate": "2023-03-21T19:28:17.125000+00:00", "lastname": "na", "lifecyclestage": "subscriber", "marital_status": null, "message": null, "military_status": null, "mobilephone": null, "my_custom_test_property": null, "notes_last_contacted": null, "notes_last_updated": null, "notes_next_activity_date": null, "num_associated_deals": null, "num_contacted_notes": null, "num_conversion_events": 0, "num_notes": null, "num_unique_conversion_events": 0, "numemployees": null, "phone": null, "recent_conversion_date": null, "recent_conversion_event_name": null, "recent_deal_amount": null, "recent_deal_close_date": null, "relationship_status": null, "salutation": null, "school": null, "seniority": null, "start_date": null, "state": null, "surveymonkeyeventlastupdated": null, "test": null, "total_revenue": null, "twitterhandle": null, "webinareventlastupdated": null, "website": null, "work_email": null, "zip": null}, "createdAt": "2020-12-11T01:29:50.116Z", "updatedAt": "2023-03-21T19:28:17.125Z", "archived": false, "companies": ["5000526215", "5000526215"]}, "emitted_at": 1688977122794} +{"stream": "contacts", "data": {"id": "251", "properties": {"address": "25000000 First Street", "annualrevenue": null, "associatedcompanyid": 5170561229, "associatedcompanylastupdated": null, "city": "Cambridge", "closedate": null, "company": "HubSpot", "company_size": null, "country": "USA", "createdate": "2021-02-22T14:05:09.944000+00:00", "currentlyinworkflow": null, "date_of_birth": null, "days_to_close": null, "degree": null, "email": "testingdsapis@hubspot.com", "engagements_last_meeting_booked": null, "engagements_last_meeting_booked_campaign": null, "engagements_last_meeting_booked_medium": null, "engagements_last_meeting_booked_source": null, "fax": null, "field_of_study": null, "first_conversion_date": null, "first_conversion_event_name": null, "first_deal_created_date": null, "firstname": "Test User 5001", "gender": null, "graduation_date": null, "hs_additional_emails": null, "hs_all_accessible_team_ids": null, "hs_all_contact_vids": "251", "hs_all_owner_ids": null, "hs_all_team_ids": null, "hs_analytics_average_page_views": 0, "hs_analytics_first_referrer": null, "hs_analytics_first_timestamp": "2021-02-22T14:05:09.944000+00:00", "hs_analytics_first_touch_converting_campaign": null, "hs_analytics_first_url": null, "hs_analytics_first_visit_timestamp": null, "hs_analytics_last_referrer": null, "hs_analytics_last_timestamp": null, "hs_analytics_last_touch_converting_campaign": null, "hs_analytics_last_url": null, "hs_analytics_last_visit_timestamp": null, "hs_analytics_num_event_completions": 0, "hs_analytics_num_page_views": 0, "hs_analytics_num_visits": 0, "hs_analytics_revenue": 0.0, "hs_analytics_source": "OFFLINE", "hs_analytics_source_data_1": "API", "hs_analytics_source_data_2": null, "hs_avatar_filemanager_key": null, "hs_buying_role": null, "hs_calculated_form_submissions": null, "hs_calculated_merged_vids": null, "hs_calculated_mobile_number": null, "hs_calculated_phone_number": null, "hs_calculated_phone_number_area_code": null, "hs_calculated_phone_number_country_code": null, "hs_calculated_phone_number_region_code": null, "hs_clicked_linkedin_ad": null, "hs_content_membership_email": null, "hs_content_membership_email_confirmed": null, "hs_content_membership_notes": null, "hs_content_membership_registered_at": null, "hs_content_membership_registration_domain_sent_to": null, "hs_content_membership_registration_email_sent_at": null, "hs_content_membership_status": null, "hs_conversations_visitor_email": null, "hs_count_is_unworked": null, "hs_count_is_worked": null, "hs_created_by_conversations": null, "hs_created_by_user_id": null, "hs_createdate": null, "hs_date_entered_customer": null, "hs_date_entered_evangelist": null, "hs_date_entered_lead": null, "hs_date_entered_marketingqualifiedlead": null, "hs_date_entered_opportunity": null, "hs_date_entered_other": null, "hs_date_entered_salesqualifiedlead": null, "hs_date_entered_subscriber": "2021-02-22T14:05:09.944000+00:00", "hs_date_exited_customer": null, "hs_date_exited_evangelist": null, "hs_date_exited_lead": null, "hs_date_exited_marketingqualifiedlead": null, "hs_date_exited_opportunity": null, "hs_date_exited_other": null, "hs_date_exited_salesqualifiedlead": null, "hs_date_exited_subscriber": null, "hs_document_last_revisited": null, "hs_email_bad_address": null, "hs_email_bounce": null, "hs_email_click": null, "hs_email_customer_quarantined_reason": null, "hs_email_delivered": null, "hs_email_domain": "hubspot.com", "hs_email_first_click_date": null, "hs_email_first_open_date": null, "hs_email_first_reply_date": null, "hs_email_first_send_date": null, "hs_email_hard_bounce_reason": null, "hs_email_hard_bounce_reason_enum": null, "hs_email_is_ineligible": null, "hs_email_last_click_date": null, "hs_email_last_email_name": null, "hs_email_last_open_date": null, "hs_email_last_reply_date": null, "hs_email_last_send_date": null, "hs_email_open": null, "hs_email_optout": null, "hs_email_optout_10798197": null, "hs_email_optout_11890603": null, "hs_email_optout_11890831": null, "hs_email_optout_23704464": null, "hs_email_optout_94692364": null, "hs_email_quarantined": null, "hs_email_quarantined_reason": null, "hs_email_recipient_fatigue_recovery_time": null, "hs_email_replied": null, "hs_email_sends_since_last_engagement": null, "hs_emailconfirmationstatus": null, "hs_facebook_ad_clicked": null, "hs_facebook_click_id": null, "hs_feedback_last_nps_follow_up": null, "hs_feedback_last_nps_rating": null, "hs_feedback_last_survey_date": null, "hs_feedback_show_nps_web_survey": null, "hs_first_engagement_object_id": null, "hs_first_outreach_date": null, "hs_first_subscription_create_date": null, "hs_google_click_id": null, "hs_has_active_subscription": null, "hs_ip_timezone": null, "hs_is_contact": true, "hs_is_unworked": true, "hs_language": null, "hs_last_sales_activity_date": null, "hs_last_sales_activity_timestamp": null, "hs_last_sales_activity_type": null, "hs_lastmodifieddate": null, "hs_latest_meeting_activity": null, "hs_latest_sequence_ended_date": null, "hs_latest_sequence_enrolled": null, "hs_latest_sequence_enrolled_date": null, "hs_latest_sequence_finished_date": null, "hs_latest_sequence_unenrolled_date": null, "hs_latest_source": "OFFLINE", "hs_latest_source_data_1": "API", "hs_latest_source_data_2": null, "hs_latest_source_timestamp": "2021-02-22T14:05:10.036000+00:00", "hs_latest_subscription_create_date": null, "hs_lead_status": null, "hs_legal_basis": null, "hs_lifecyclestage_customer_date": null, "hs_lifecyclestage_evangelist_date": null, "hs_lifecyclestage_lead_date": null, "hs_lifecyclestage_marketingqualifiedlead_date": null, "hs_lifecyclestage_opportunity_date": null, "hs_lifecyclestage_other_date": null, "hs_lifecyclestage_salesqualifiedlead_date": null, "hs_lifecyclestage_subscriber_date": "2021-02-22T14:05:09.944000+00:00", "hs_linkedin_ad_clicked": null, "hs_marketable_reason_id": null, "hs_marketable_reason_type": null, "hs_marketable_status": "false", "hs_marketable_until_renewal": "false", "hs_merged_object_ids": null, "hs_object_id": 251, "hs_persona": null, "hs_pinned_engagement_id": null, "hs_pipeline": "contacts-lifecycle-pipeline", "hs_predictivecontactscore": null, "hs_predictivecontactscore_v2": 0.29, "hs_predictivecontactscorebucket": null, "hs_predictivescoringtier": "tier_4", "hs_read_only": null, "hs_sa_first_engagement_date": null, "hs_sa_first_engagement_descr": null, "hs_sa_first_engagement_object_type": null, "hs_sales_email_last_clicked": null, "hs_sales_email_last_opened": null, "hs_sales_email_last_replied": null, "hs_searchable_calculated_international_mobile_number": null, "hs_searchable_calculated_international_phone_number": null, "hs_searchable_calculated_mobile_number": null, "hs_searchable_calculated_phone_number": "5551222323", "hs_sequences_actively_enrolled_count": null, "hs_sequences_enrolled_count": null, "hs_sequences_is_enrolled": null, "hs_testpurge": null, "hs_testrollback": null, "hs_time_between_contact_creation_and_deal_close": null, "hs_time_between_contact_creation_and_deal_creation": null, "hs_time_in_customer": null, "hs_time_in_evangelist": null, "hs_time_in_lead": null, "hs_time_in_marketingqualifiedlead": null, "hs_time_in_opportunity": null, "hs_time_in_other": null, "hs_time_in_salesqualifiedlead": null, "hs_time_in_subscriber": 74974412842, "hs_time_to_first_engagement": null, "hs_time_to_move_from_lead_to_customer": null, "hs_time_to_move_from_marketingqualifiedlead_to_customer": null, "hs_time_to_move_from_opportunity_to_customer": null, "hs_time_to_move_from_salesqualifiedlead_to_customer": null, "hs_time_to_move_from_subscriber_to_customer": null, "hs_timezone": null, "hs_unique_creation_key": null, "hs_updated_by_user_id": null, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": null, "hs_was_imported": null, "hs_whatsapp_phone_number": null, "hubspot_owner_assigneddate": null, "hubspot_owner_id": null, "hubspot_team_id": null, "hubspotscore": null, "industry": null, "ip_city": null, "ip_country": null, "ip_country_code": null, "ip_latlon": null, "ip_state": null, "ip_state_code": null, "ip_zipcode": null, "job_function": null, "jobtitle": null, "lastmodifieddate": "2023-03-21T19:29:13.036000+00:00", "lastname": "Test Lastname 5001", "lifecyclestage": "subscriber", "marital_status": null, "message": null, "military_status": null, "mobilephone": null, "my_custom_test_property": null, "notes_last_contacted": null, "notes_last_updated": null, "notes_next_activity_date": null, "num_associated_deals": null, "num_contacted_notes": null, "num_conversion_events": 0, "num_notes": null, "num_unique_conversion_events": 0, "numemployees": null, "phone": "555-122-2323", "recent_conversion_date": null, "recent_conversion_event_name": null, "recent_deal_amount": null, "recent_deal_close_date": null, "relationship_status": null, "salutation": null, "school": null, "seniority": null, "start_date": null, "state": "MA", "surveymonkeyeventlastupdated": null, "test": null, "total_revenue": null, "twitterhandle": null, "webinareventlastupdated": null, "website": "http://hubspot.com", "work_email": null, "zip": "02139"}, "createdAt": "2021-02-22T14:05:09.944Z", "updatedAt": "2023-03-21T19:29:13.036Z", "archived": false, "companies": ["5170561229", "5170561229"]}, "emitted_at": 1688977122795} +{"stream": "contacts", "data": {"id": "401", "properties": {"address": "25 First Street", "annualrevenue": null, "associatedcompanyid": null, "associatedcompanylastupdated": null, "city": "Cambridge", "closedate": null, "company": null, "company_size": null, "country": null, "createdate": "2021-02-23T20:10:36.191000+00:00", "currentlyinworkflow": null, "date_of_birth": null, "days_to_close": null, "degree": null, "email": "macmitch@hubspot.com", "engagements_last_meeting_booked": null, "engagements_last_meeting_booked_campaign": null, "engagements_last_meeting_booked_medium": null, "engagements_last_meeting_booked_source": null, "fax": null, "field_of_study": null, "first_conversion_date": null, "first_conversion_event_name": null, "first_deal_created_date": null, "firstname": "Mac", "gender": null, "graduation_date": null, "hs_additional_emails": null, "hs_all_accessible_team_ids": null, "hs_all_contact_vids": "401", "hs_all_owner_ids": "52550153", "hs_all_team_ids": null, "hs_analytics_average_page_views": 0, "hs_analytics_first_referrer": null, "hs_analytics_first_timestamp": "2021-02-23T20:10:36.181000+00:00", "hs_analytics_first_touch_converting_campaign": null, "hs_analytics_first_url": null, "hs_analytics_first_visit_timestamp": null, "hs_analytics_last_referrer": null, "hs_analytics_last_timestamp": null, "hs_analytics_last_touch_converting_campaign": null, "hs_analytics_last_url": null, "hs_analytics_last_visit_timestamp": null, "hs_analytics_num_event_completions": 0, "hs_analytics_num_page_views": 0, "hs_analytics_num_visits": 0, "hs_analytics_revenue": 0.0, "hs_analytics_source": "OFFLINE", "hs_analytics_source_data_1": "IMPORT", "hs_analytics_source_data_2": "13256565", "hs_avatar_filemanager_key": null, "hs_buying_role": null, "hs_calculated_form_submissions": null, "hs_calculated_merged_vids": null, "hs_calculated_mobile_number": null, "hs_calculated_phone_number": "+18884827768", "hs_calculated_phone_number_area_code": null, "hs_calculated_phone_number_country_code": "US", "hs_calculated_phone_number_region_code": null, "hs_clicked_linkedin_ad": null, "hs_content_membership_email": null, "hs_content_membership_email_confirmed": null, "hs_content_membership_notes": null, "hs_content_membership_registered_at": null, "hs_content_membership_registration_domain_sent_to": null, "hs_content_membership_registration_email_sent_at": null, "hs_content_membership_status": null, "hs_conversations_visitor_email": null, "hs_count_is_unworked": 1, "hs_count_is_worked": 0, "hs_created_by_conversations": null, "hs_created_by_user_id": null, "hs_createdate": null, "hs_date_entered_customer": null, "hs_date_entered_evangelist": null, "hs_date_entered_lead": "2021-02-23T20:10:36.181000+00:00", "hs_date_entered_marketingqualifiedlead": null, "hs_date_entered_opportunity": null, "hs_date_entered_other": null, "hs_date_entered_salesqualifiedlead": null, "hs_date_entered_subscriber": null, "hs_date_exited_customer": null, "hs_date_exited_evangelist": null, "hs_date_exited_lead": null, "hs_date_exited_marketingqualifiedlead": null, "hs_date_exited_opportunity": null, "hs_date_exited_other": null, "hs_date_exited_salesqualifiedlead": null, "hs_date_exited_subscriber": null, "hs_document_last_revisited": null, "hs_email_bad_address": null, "hs_email_bounce": null, "hs_email_click": null, "hs_email_customer_quarantined_reason": null, "hs_email_delivered": null, "hs_email_domain": "hubspot.com", "hs_email_first_click_date": null, "hs_email_first_open_date": null, "hs_email_first_reply_date": null, "hs_email_first_send_date": null, "hs_email_hard_bounce_reason": null, "hs_email_hard_bounce_reason_enum": "OTHER", "hs_email_is_ineligible": null, "hs_email_last_click_date": null, "hs_email_last_email_name": null, "hs_email_last_open_date": null, "hs_email_last_reply_date": null, "hs_email_last_send_date": null, "hs_email_open": null, "hs_email_optout": null, "hs_email_optout_10798197": null, "hs_email_optout_11890603": null, "hs_email_optout_11890831": null, "hs_email_optout_23704464": null, "hs_email_optout_94692364": null, "hs_email_quarantined": null, "hs_email_quarantined_reason": null, "hs_email_recipient_fatigue_recovery_time": null, "hs_email_replied": null, "hs_email_sends_since_last_engagement": null, "hs_emailconfirmationstatus": null, "hs_facebook_ad_clicked": null, "hs_facebook_click_id": null, "hs_feedback_last_nps_follow_up": null, "hs_feedback_last_nps_rating": null, "hs_feedback_last_survey_date": null, "hs_feedback_show_nps_web_survey": null, "hs_first_engagement_object_id": null, "hs_first_outreach_date": null, "hs_first_subscription_create_date": null, "hs_google_click_id": null, "hs_has_active_subscription": null, "hs_ip_timezone": null, "hs_is_contact": true, "hs_is_unworked": true, "hs_language": null, "hs_last_sales_activity_date": null, "hs_last_sales_activity_timestamp": null, "hs_last_sales_activity_type": null, "hs_lastmodifieddate": null, "hs_latest_meeting_activity": null, "hs_latest_sequence_ended_date": null, "hs_latest_sequence_enrolled": null, "hs_latest_sequence_enrolled_date": null, "hs_latest_sequence_finished_date": null, "hs_latest_sequence_unenrolled_date": null, "hs_latest_source": "OFFLINE", "hs_latest_source_data_1": "IMPORT", "hs_latest_source_data_2": "13256565", "hs_latest_source_timestamp": "2021-02-23T20:10:36.210000+00:00", "hs_latest_subscription_create_date": null, "hs_lead_status": null, "hs_legal_basis": null, "hs_lifecyclestage_customer_date": null, "hs_lifecyclestage_evangelist_date": null, "hs_lifecyclestage_lead_date": "2021-02-23T20:10:36.181000+00:00", "hs_lifecyclestage_marketingqualifiedlead_date": null, "hs_lifecyclestage_opportunity_date": null, "hs_lifecyclestage_other_date": null, "hs_lifecyclestage_salesqualifiedlead_date": null, "hs_lifecyclestage_subscriber_date": null, "hs_linkedin_ad_clicked": null, "hs_marketable_reason_id": null, "hs_marketable_reason_type": null, "hs_marketable_status": "false", "hs_marketable_until_renewal": "false", "hs_merged_object_ids": null, "hs_object_id": 401, "hs_persona": null, "hs_pinned_engagement_id": null, "hs_pipeline": "contacts-lifecycle-pipeline", "hs_predictivecontactscore": null, "hs_predictivecontactscore_v2": 0.29, "hs_predictivecontactscorebucket": null, "hs_predictivescoringtier": "tier_4", "hs_read_only": null, "hs_sa_first_engagement_date": null, "hs_sa_first_engagement_descr": null, "hs_sa_first_engagement_object_type": null, "hs_sales_email_last_clicked": null, "hs_sales_email_last_opened": null, "hs_sales_email_last_replied": null, "hs_searchable_calculated_international_mobile_number": null, "hs_searchable_calculated_international_phone_number": null, "hs_searchable_calculated_mobile_number": null, "hs_searchable_calculated_phone_number": "8884827768", "hs_sequences_actively_enrolled_count": null, "hs_sequences_enrolled_count": null, "hs_sequences_is_enrolled": null, "hs_testpurge": null, "hs_testrollback": null, "hs_time_between_contact_creation_and_deal_close": null, "hs_time_between_contact_creation_and_deal_creation": null, "hs_time_in_customer": null, "hs_time_in_evangelist": null, "hs_time_in_lead": 74866086605, "hs_time_in_marketingqualifiedlead": null, "hs_time_in_opportunity": null, "hs_time_in_other": null, "hs_time_in_salesqualifiedlead": null, "hs_time_in_subscriber": null, "hs_time_to_first_engagement": null, "hs_time_to_move_from_lead_to_customer": null, "hs_time_to_move_from_marketingqualifiedlead_to_customer": null, "hs_time_to_move_from_opportunity_to_customer": null, "hs_time_to_move_from_salesqualifiedlead_to_customer": null, "hs_time_to_move_from_subscriber_to_customer": null, "hs_timezone": null, "hs_unique_creation_key": null, "hs_updated_by_user_id": null, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": "12282590", "hs_was_imported": null, "hs_whatsapp_phone_number": null, "hubspot_owner_assigneddate": "2021-05-21T10:20:30.963000+00:00", "hubspot_owner_id": "52550153", "hubspot_team_id": null, "hubspotscore": null, "industry": null, "ip_city": null, "ip_country": null, "ip_country_code": null, "ip_latlon": null, "ip_state": null, "ip_state_code": null, "ip_zipcode": null, "job_function": null, "jobtitle": null, "lastmodifieddate": "2023-03-21T19:31:00.563000+00:00", "lastname": "Mitchell", "lifecyclestage": "lead", "marital_status": null, "message": null, "military_status": null, "mobilephone": null, "my_custom_test_property": null, "notes_last_contacted": null, "notes_last_updated": null, "notes_next_activity_date": null, "num_associated_deals": null, "num_contacted_notes": null, "num_conversion_events": 0, "num_notes": null, "num_unique_conversion_events": 0, "numemployees": null, "phone": "1(888) 482-7768", "recent_conversion_date": null, "recent_conversion_event_name": null, "recent_deal_amount": null, "recent_deal_close_date": null, "relationship_status": null, "salutation": null, "school": null, "seniority": null, "start_date": null, "state": "MA", "surveymonkeyeventlastupdated": null, "test": null, "total_revenue": null, "twitterhandle": null, "webinareventlastupdated": null, "website": null, "work_email": null, "zip": "21430"}, "createdAt": "2021-02-23T20:10:36.191Z", "updatedAt": "2023-03-21T19:31:00.563Z", "archived": false}, "emitted_at": 1688977122796} +{"stream": "contacts", "data": {"id": "601", "properties": {"address": "0 First Street", "annualrevenue": null, "associatedcompanyid": null, "associatedcompanylastupdated": null, "city": "Cambridge", "closedate": null, "company": "HubSpot Test", "company_size": null, "country": null, "createdate": "2021-10-12T13:22:50.930000+00:00", "currentlyinworkflow": null, "date_of_birth": null, "days_to_close": null, "degree": null, "email": "testingapicontact_0@hubspot.com", "engagements_last_meeting_booked": null, "engagements_last_meeting_booked_campaign": null, "engagements_last_meeting_booked_medium": null, "engagements_last_meeting_booked_source": null, "fax": null, "field_of_study": null, "first_conversion_date": null, "first_conversion_event_name": null, "first_deal_created_date": null, "firstname": "test contact 0", "gender": null, "graduation_date": null, "hs_additional_emails": null, "hs_all_accessible_team_ids": null, "hs_all_contact_vids": "601", "hs_all_owner_ids": null, "hs_all_team_ids": null, "hs_analytics_average_page_views": 0, "hs_analytics_first_referrer": null, "hs_analytics_first_timestamp": "2021-10-12T13:22:50.930000+00:00", "hs_analytics_first_touch_converting_campaign": null, "hs_analytics_first_url": null, "hs_analytics_first_visit_timestamp": null, "hs_analytics_last_referrer": null, "hs_analytics_last_timestamp": null, "hs_analytics_last_touch_converting_campaign": null, "hs_analytics_last_url": null, "hs_analytics_last_visit_timestamp": null, "hs_analytics_num_event_completions": 0, "hs_analytics_num_page_views": 0, "hs_analytics_num_visits": 0, "hs_analytics_revenue": 0.0, "hs_analytics_source": "OFFLINE", "hs_analytics_source_data_1": "API", "hs_analytics_source_data_2": null, "hs_avatar_filemanager_key": null, "hs_buying_role": null, "hs_calculated_form_submissions": null, "hs_calculated_merged_vids": null, "hs_calculated_mobile_number": null, "hs_calculated_phone_number": null, "hs_calculated_phone_number_area_code": null, "hs_calculated_phone_number_country_code": null, "hs_calculated_phone_number_region_code": null, "hs_clicked_linkedin_ad": null, "hs_content_membership_email": null, "hs_content_membership_email_confirmed": null, "hs_content_membership_notes": null, "hs_content_membership_registered_at": null, "hs_content_membership_registration_domain_sent_to": null, "hs_content_membership_registration_email_sent_at": null, "hs_content_membership_status": null, "hs_conversations_visitor_email": null, "hs_count_is_unworked": null, "hs_count_is_worked": null, "hs_created_by_conversations": null, "hs_created_by_user_id": null, "hs_createdate": null, "hs_date_entered_customer": null, "hs_date_entered_evangelist": null, "hs_date_entered_lead": null, "hs_date_entered_marketingqualifiedlead": null, "hs_date_entered_opportunity": null, "hs_date_entered_other": null, "hs_date_entered_salesqualifiedlead": null, "hs_date_entered_subscriber": "2021-10-12T13:22:50.930000+00:00", "hs_date_exited_customer": null, "hs_date_exited_evangelist": null, "hs_date_exited_lead": null, "hs_date_exited_marketingqualifiedlead": null, "hs_date_exited_opportunity": null, "hs_date_exited_other": null, "hs_date_exited_salesqualifiedlead": null, "hs_date_exited_subscriber": null, "hs_document_last_revisited": null, "hs_email_bad_address": null, "hs_email_bounce": null, "hs_email_click": null, "hs_email_customer_quarantined_reason": null, "hs_email_delivered": null, "hs_email_domain": "hubspot.com", "hs_email_first_click_date": null, "hs_email_first_open_date": null, "hs_email_first_reply_date": null, "hs_email_first_send_date": null, "hs_email_hard_bounce_reason": null, "hs_email_hard_bounce_reason_enum": null, "hs_email_is_ineligible": null, "hs_email_last_click_date": null, "hs_email_last_email_name": null, "hs_email_last_open_date": null, "hs_email_last_reply_date": null, "hs_email_last_send_date": null, "hs_email_open": null, "hs_email_optout": null, "hs_email_optout_10798197": null, "hs_email_optout_11890603": null, "hs_email_optout_11890831": null, "hs_email_optout_23704464": null, "hs_email_optout_94692364": null, "hs_email_quarantined": null, "hs_email_quarantined_reason": null, "hs_email_recipient_fatigue_recovery_time": null, "hs_email_replied": null, "hs_email_sends_since_last_engagement": null, "hs_emailconfirmationstatus": null, "hs_facebook_ad_clicked": null, "hs_facebook_click_id": null, "hs_feedback_last_nps_follow_up": null, "hs_feedback_last_nps_rating": null, "hs_feedback_last_survey_date": null, "hs_feedback_show_nps_web_survey": null, "hs_first_engagement_object_id": null, "hs_first_outreach_date": null, "hs_first_subscription_create_date": null, "hs_google_click_id": null, "hs_has_active_subscription": null, "hs_ip_timezone": null, "hs_is_contact": true, "hs_is_unworked": true, "hs_language": null, "hs_last_sales_activity_date": null, "hs_last_sales_activity_timestamp": null, "hs_last_sales_activity_type": null, "hs_lastmodifieddate": null, "hs_latest_meeting_activity": null, "hs_latest_sequence_ended_date": null, "hs_latest_sequence_enrolled": null, "hs_latest_sequence_enrolled_date": null, "hs_latest_sequence_finished_date": null, "hs_latest_sequence_unenrolled_date": null, "hs_latest_source": "OFFLINE", "hs_latest_source_data_1": "API", "hs_latest_source_data_2": null, "hs_latest_source_timestamp": "2021-10-12T13:22:51.107000+00:00", "hs_latest_subscription_create_date": null, "hs_lead_status": null, "hs_legal_basis": null, "hs_lifecyclestage_customer_date": null, "hs_lifecyclestage_evangelist_date": null, "hs_lifecyclestage_lead_date": null, "hs_lifecyclestage_marketingqualifiedlead_date": null, "hs_lifecyclestage_opportunity_date": null, "hs_lifecyclestage_other_date": null, "hs_lifecyclestage_salesqualifiedlead_date": null, "hs_lifecyclestage_subscriber_date": "2021-10-12T13:22:50.930000+00:00", "hs_linkedin_ad_clicked": null, "hs_marketable_reason_id": null, "hs_marketable_reason_type": null, "hs_marketable_status": "false", "hs_marketable_until_renewal": "false", "hs_merged_object_ids": null, "hs_object_id": 601, "hs_persona": null, "hs_pinned_engagement_id": null, "hs_pipeline": "contacts-lifecycle-pipeline", "hs_predictivecontactscore": null, "hs_predictivecontactscore_v2": 0.31, "hs_predictivecontactscorebucket": null, "hs_predictivescoringtier": "tier_2", "hs_read_only": null, "hs_sa_first_engagement_date": null, "hs_sa_first_engagement_descr": null, "hs_sa_first_engagement_object_type": null, "hs_sales_email_last_clicked": null, "hs_sales_email_last_opened": null, "hs_sales_email_last_replied": null, "hs_searchable_calculated_international_mobile_number": null, "hs_searchable_calculated_international_phone_number": null, "hs_searchable_calculated_mobile_number": null, "hs_searchable_calculated_phone_number": "5551222323", "hs_sequences_actively_enrolled_count": 0, "hs_sequences_enrolled_count": null, "hs_sequences_is_enrolled": null, "hs_testpurge": null, "hs_testrollback": null, "hs_time_between_contact_creation_and_deal_close": null, "hs_time_between_contact_creation_and_deal_creation": null, "hs_time_in_customer": null, "hs_time_in_evangelist": null, "hs_time_in_lead": null, "hs_time_in_marketingqualifiedlead": null, "hs_time_in_opportunity": null, "hs_time_in_other": null, "hs_time_in_salesqualifiedlead": null, "hs_time_in_subscriber": 54932151855, "hs_time_to_first_engagement": null, "hs_time_to_move_from_lead_to_customer": null, "hs_time_to_move_from_marketingqualifiedlead_to_customer": null, "hs_time_to_move_from_opportunity_to_customer": null, "hs_time_to_move_from_salesqualifiedlead_to_customer": null, "hs_time_to_move_from_subscriber_to_customer": null, "hs_timezone": null, "hs_unique_creation_key": null, "hs_updated_by_user_id": null, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": null, "hs_was_imported": null, "hs_whatsapp_phone_number": null, "hubspot_owner_assigneddate": null, "hubspot_owner_id": null, "hubspot_team_id": null, "hubspotscore": null, "industry": null, "ip_city": null, "ip_country": null, "ip_country_code": null, "ip_latlon": null, "ip_state": null, "ip_state_code": null, "ip_zipcode": null, "job_function": null, "jobtitle": null, "lastmodifieddate": "2023-04-03T20:29:57.224000+00:00", "lastname": "testerson number 0", "lifecyclestage": "subscriber", "marital_status": null, "message": null, "military_status": null, "mobilephone": null, "my_custom_test_property": null, "notes_last_contacted": null, "notes_last_updated": null, "notes_next_activity_date": null, "num_associated_deals": null, "num_contacted_notes": null, "num_conversion_events": 0, "num_notes": null, "num_unique_conversion_events": 0, "numemployees": null, "phone": "555-122-2323", "recent_conversion_date": null, "recent_conversion_event_name": null, "recent_deal_amount": null, "recent_deal_close_date": null, "relationship_status": null, "salutation": null, "school": null, "seniority": null, "start_date": null, "state": "MA", "surveymonkeyeventlastupdated": null, "test": null, "total_revenue": null, "twitterhandle": null, "webinareventlastupdated": null, "website": "http://hubspot.com", "work_email": null, "zip": "02139"}, "createdAt": "2021-10-12T13:22:50.930Z", "updatedAt": "2023-04-03T20:29:57.224Z", "archived": false}, "emitted_at": 1688977122796} +{"stream": "contacts", "data": {"id": "651", "properties": {"address": "1 First Street", "annualrevenue": null, "associatedcompanyid": 5170561229, "associatedcompanylastupdated": null, "city": "Cambridge", "closedate": null, "company": "HubSpot Test", "company_size": null, "country": null, "createdate": "2021-01-14T14:26:17.014000+00:00", "currentlyinworkflow": null, "date_of_birth": null, "days_to_close": null, "degree": null, "email": "testingapicontact_1@hubspot.com", "engagements_last_meeting_booked": null, "engagements_last_meeting_booked_campaign": null, "engagements_last_meeting_booked_medium": null, "engagements_last_meeting_booked_source": null, "fax": null, "field_of_study": null, "first_conversion_date": null, "first_conversion_event_name": null, "first_deal_created_date": null, "firstname": "test contact 1-1", "gender": null, "graduation_date": null, "hs_additional_emails": "testingapis@hubspot.com", "hs_all_accessible_team_ids": null, "hs_all_contact_vids": "201;651", "hs_all_owner_ids": null, "hs_all_team_ids": null, "hs_analytics_average_page_views": 0, "hs_analytics_first_referrer": null, "hs_analytics_first_timestamp": "2021-01-14T14:26:17.014000+00:00", "hs_analytics_first_touch_converting_campaign": null, "hs_analytics_first_url": null, "hs_analytics_first_visit_timestamp": null, "hs_analytics_last_referrer": null, "hs_analytics_last_timestamp": null, "hs_analytics_last_touch_converting_campaign": null, "hs_analytics_last_url": null, "hs_analytics_last_visit_timestamp": null, "hs_analytics_num_event_completions": 0, "hs_analytics_num_page_views": 0, "hs_analytics_num_visits": 0, "hs_analytics_revenue": 0.0, "hs_analytics_source": "OFFLINE", "hs_analytics_source_data_1": "API", "hs_analytics_source_data_2": null, "hs_avatar_filemanager_key": null, "hs_buying_role": null, "hs_calculated_form_submissions": null, "hs_calculated_merged_vids": "201:1688758327178", "hs_calculated_mobile_number": null, "hs_calculated_phone_number": null, "hs_calculated_phone_number_area_code": null, "hs_calculated_phone_number_country_code": null, "hs_calculated_phone_number_region_code": null, "hs_clicked_linkedin_ad": null, "hs_content_membership_email": null, "hs_content_membership_email_confirmed": null, "hs_content_membership_notes": null, "hs_content_membership_registered_at": null, "hs_content_membership_registration_domain_sent_to": null, "hs_content_membership_registration_email_sent_at": null, "hs_content_membership_status": null, "hs_conversations_visitor_email": null, "hs_count_is_unworked": null, "hs_count_is_worked": null, "hs_created_by_conversations": null, "hs_created_by_user_id": null, "hs_createdate": null, "hs_date_entered_customer": null, "hs_date_entered_evangelist": null, "hs_date_entered_lead": null, "hs_date_entered_marketingqualifiedlead": null, "hs_date_entered_opportunity": null, "hs_date_entered_other": null, "hs_date_entered_salesqualifiedlead": null, "hs_date_entered_subscriber": "2021-10-12T13:23:01.830000+00:00", "hs_date_exited_customer": null, "hs_date_exited_evangelist": null, "hs_date_exited_lead": null, "hs_date_exited_marketingqualifiedlead": null, "hs_date_exited_opportunity": null, "hs_date_exited_other": null, "hs_date_exited_salesqualifiedlead": null, "hs_date_exited_subscriber": null, "hs_document_last_revisited": null, "hs_email_bad_address": null, "hs_email_bounce": null, "hs_email_click": null, "hs_email_customer_quarantined_reason": null, "hs_email_delivered": null, "hs_email_domain": "hubspot.com", "hs_email_first_click_date": null, "hs_email_first_open_date": null, "hs_email_first_reply_date": null, "hs_email_first_send_date": null, "hs_email_hard_bounce_reason": null, "hs_email_hard_bounce_reason_enum": "", "hs_email_is_ineligible": null, "hs_email_last_click_date": null, "hs_email_last_email_name": null, "hs_email_last_open_date": null, "hs_email_last_reply_date": null, "hs_email_last_send_date": null, "hs_email_open": null, "hs_email_optout": null, "hs_email_optout_10798197": null, "hs_email_optout_11890603": null, "hs_email_optout_11890831": null, "hs_email_optout_23704464": null, "hs_email_optout_94692364": null, "hs_email_quarantined": null, "hs_email_quarantined_reason": null, "hs_email_recipient_fatigue_recovery_time": null, "hs_email_replied": null, "hs_email_sends_since_last_engagement": null, "hs_emailconfirmationstatus": null, "hs_facebook_ad_clicked": null, "hs_facebook_click_id": null, "hs_feedback_last_nps_follow_up": null, "hs_feedback_last_nps_rating": null, "hs_feedback_last_survey_date": null, "hs_feedback_show_nps_web_survey": null, "hs_first_engagement_object_id": null, "hs_first_outreach_date": null, "hs_first_subscription_create_date": null, "hs_google_click_id": null, "hs_has_active_subscription": null, "hs_ip_timezone": null, "hs_is_contact": true, "hs_is_unworked": true, "hs_language": null, "hs_last_sales_activity_date": null, "hs_last_sales_activity_timestamp": null, "hs_last_sales_activity_type": null, "hs_lastmodifieddate": null, "hs_latest_meeting_activity": null, "hs_latest_sequence_ended_date": null, "hs_latest_sequence_enrolled": null, "hs_latest_sequence_enrolled_date": null, "hs_latest_sequence_finished_date": null, "hs_latest_sequence_unenrolled_date": null, "hs_latest_source": "OFFLINE", "hs_latest_source_data_1": "API", "hs_latest_source_data_2": null, "hs_latest_source_timestamp": "2021-01-14T14:26:17.081000+00:00", "hs_latest_subscription_create_date": null, "hs_lead_status": null, "hs_legal_basis": null, "hs_lifecyclestage_customer_date": null, "hs_lifecyclestage_evangelist_date": null, "hs_lifecyclestage_lead_date": null, "hs_lifecyclestage_marketingqualifiedlead_date": null, "hs_lifecyclestage_opportunity_date": null, "hs_lifecyclestage_other_date": null, "hs_lifecyclestage_salesqualifiedlead_date": null, "hs_lifecyclestage_subscriber_date": "2021-10-12T13:23:01.830000+00:00", "hs_linkedin_ad_clicked": null, "hs_marketable_reason_id": null, "hs_marketable_reason_type": null, "hs_marketable_status": "false", "hs_marketable_until_renewal": "false", "hs_merged_object_ids": "201", "hs_object_id": 651, "hs_persona": null, "hs_pinned_engagement_id": null, "hs_pipeline": "contacts-lifecycle-pipeline", "hs_predictivecontactscore": null, "hs_predictivecontactscore_v2": 0.39, "hs_predictivecontactscorebucket": null, "hs_predictivescoringtier": "tier_2", "hs_read_only": null, "hs_sa_first_engagement_date": null, "hs_sa_first_engagement_descr": null, "hs_sa_first_engagement_object_type": null, "hs_sales_email_last_clicked": null, "hs_sales_email_last_opened": null, "hs_sales_email_last_replied": null, "hs_searchable_calculated_international_mobile_number": null, "hs_searchable_calculated_international_phone_number": null, "hs_searchable_calculated_mobile_number": null, "hs_searchable_calculated_phone_number": "5551222323", "hs_sequences_actively_enrolled_count": 0, "hs_sequences_enrolled_count": null, "hs_sequences_is_enrolled": null, "hs_testpurge": null, "hs_testrollback": null, "hs_time_between_contact_creation_and_deal_close": null, "hs_time_between_contact_creation_and_deal_creation": null, "hs_time_in_customer": null, "hs_time_in_evangelist": null, "hs_time_in_lead": null, "hs_time_in_marketingqualifiedlead": null, "hs_time_in_opportunity": null, "hs_time_in_other": null, "hs_time_in_salesqualifiedlead": null, "hs_time_in_subscriber": 54932140956, "hs_time_to_first_engagement": null, "hs_time_to_move_from_lead_to_customer": null, "hs_time_to_move_from_marketingqualifiedlead_to_customer": null, "hs_time_to_move_from_opportunity_to_customer": null, "hs_time_to_move_from_salesqualifiedlead_to_customer": null, "hs_time_to_move_from_subscriber_to_customer": null, "hs_timezone": null, "hs_unique_creation_key": null, "hs_updated_by_user_id": 12282590, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": null, "hs_was_imported": null, "hs_whatsapp_phone_number": null, "hubspot_owner_assigneddate": null, "hubspot_owner_id": null, "hubspot_team_id": null, "hubspotscore": null, "industry": null, "ip_city": null, "ip_country": null, "ip_country_code": null, "ip_latlon": null, "ip_state": null, "ip_state_code": null, "ip_zipcode": null, "job_function": null, "jobtitle": null, "lastmodifieddate": "2023-07-07T19:33:25.177000+00:00", "lastname": "testerson number 1", "lifecyclestage": "subscriber", "marital_status": null, "message": null, "military_status": null, "mobilephone": null, "my_custom_test_property": null, "notes_last_contacted": null, "notes_last_updated": null, "notes_next_activity_date": null, "num_associated_deals": null, "num_contacted_notes": null, "num_conversion_events": 0, "num_notes": null, "num_unique_conversion_events": 0, "numemployees": null, "phone": "555-122-2323", "recent_conversion_date": null, "recent_conversion_event_name": null, "recent_deal_amount": null, "recent_deal_close_date": null, "relationship_status": null, "salutation": null, "school": null, "seniority": null, "start_date": null, "state": "MA", "surveymonkeyeventlastupdated": null, "test": null, "total_revenue": null, "twitterhandle": null, "webinareventlastupdated": null, "website": "http://hubspot.com", "work_email": null, "zip": "02139"}, "createdAt": "2021-01-14T14:26:17.014Z", "updatedAt": "2023-07-07T19:33:25.177Z", "archived": false, "companies": ["5170561229", "5170561229"]}, "emitted_at": 1688977122797} +{"stream": "contacts", "data": {"id": "2501", "properties": {"address": null, "annualrevenue": null, "associatedcompanyid": null, "associatedcompanylastupdated": null, "city": null, "closedate": null, "company": null, "company_size": null, "country": null, "createdate": "2023-01-30T23:17:09.904000+00:00", "currentlyinworkflow": null, "date_of_birth": null, "days_to_close": null, "degree": null, "email": "test@test.com", "engagements_last_meeting_booked": null, "engagements_last_meeting_booked_campaign": null, "engagements_last_meeting_booked_medium": null, "engagements_last_meeting_booked_source": null, "fax": null, "field_of_study": null, "first_conversion_date": null, "first_conversion_event_name": null, "first_deal_created_date": null, "firstname": "test", "gender": null, "graduation_date": null, "hs_additional_emails": null, "hs_all_accessible_team_ids": null, "hs_all_contact_vids": "2501", "hs_all_owner_ids": "", "hs_all_team_ids": null, "hs_analytics_average_page_views": 0, "hs_analytics_first_referrer": null, "hs_analytics_first_timestamp": "2023-01-30T23:17:09.904000+00:00", "hs_analytics_first_touch_converting_campaign": null, "hs_analytics_first_url": null, "hs_analytics_first_visit_timestamp": null, "hs_analytics_last_referrer": null, "hs_analytics_last_timestamp": null, "hs_analytics_last_touch_converting_campaign": null, "hs_analytics_last_url": null, "hs_analytics_last_visit_timestamp": null, "hs_analytics_num_event_completions": 0, "hs_analytics_num_page_views": 0, "hs_analytics_num_visits": 0, "hs_analytics_revenue": 0.0, "hs_analytics_source": "OFFLINE", "hs_analytics_source_data_1": "CRM_UI", "hs_analytics_source_data_2": "userId:12282590", "hs_avatar_filemanager_key": null, "hs_buying_role": null, "hs_calculated_form_submissions": null, "hs_calculated_merged_vids": null, "hs_calculated_mobile_number": null, "hs_calculated_phone_number": "+555555555555", "hs_calculated_phone_number_area_code": null, "hs_calculated_phone_number_country_code": "BR", "hs_calculated_phone_number_region_code": null, "hs_clicked_linkedin_ad": null, "hs_content_membership_email": null, "hs_content_membership_email_confirmed": null, "hs_content_membership_notes": null, "hs_content_membership_registered_at": null, "hs_content_membership_registration_domain_sent_to": null, "hs_content_membership_registration_email_sent_at": null, "hs_content_membership_status": null, "hs_conversations_visitor_email": null, "hs_count_is_unworked": null, "hs_count_is_worked": null, "hs_created_by_conversations": null, "hs_created_by_user_id": 12282590, "hs_createdate": null, "hs_date_entered_customer": null, "hs_date_entered_evangelist": null, "hs_date_entered_lead": "2023-01-30T23:17:09.904000+00:00", "hs_date_entered_marketingqualifiedlead": null, "hs_date_entered_opportunity": "2023-01-31T00:31:07.832000+00:00", "hs_date_entered_other": null, "hs_date_entered_salesqualifiedlead": null, "hs_date_entered_subscriber": null, "hs_date_exited_customer": null, "hs_date_exited_evangelist": null, "hs_date_exited_lead": "2023-01-31T00:31:07.832000+00:00", "hs_date_exited_marketingqualifiedlead": null, "hs_date_exited_opportunity": null, "hs_date_exited_other": null, "hs_date_exited_salesqualifiedlead": null, "hs_date_exited_subscriber": null, "hs_document_last_revisited": null, "hs_email_bad_address": null, "hs_email_bounce": null, "hs_email_click": null, "hs_email_customer_quarantined_reason": null, "hs_email_delivered": null, "hs_email_domain": "test.com", "hs_email_first_click_date": null, "hs_email_first_open_date": null, "hs_email_first_reply_date": null, "hs_email_first_send_date": null, "hs_email_hard_bounce_reason": null, "hs_email_hard_bounce_reason_enum": null, "hs_email_is_ineligible": null, "hs_email_last_click_date": null, "hs_email_last_email_name": null, "hs_email_last_open_date": null, "hs_email_last_reply_date": null, "hs_email_last_send_date": null, "hs_email_open": null, "hs_email_optout": null, "hs_email_optout_10798197": null, "hs_email_optout_11890603": null, "hs_email_optout_11890831": null, "hs_email_optout_23704464": null, "hs_email_optout_94692364": null, "hs_email_quarantined": null, "hs_email_quarantined_reason": null, "hs_email_recipient_fatigue_recovery_time": null, "hs_email_replied": null, "hs_email_sends_since_last_engagement": null, "hs_emailconfirmationstatus": null, "hs_facebook_ad_clicked": null, "hs_facebook_click_id": null, "hs_feedback_last_nps_follow_up": null, "hs_feedback_last_nps_rating": null, "hs_feedback_last_survey_date": null, "hs_feedback_show_nps_web_survey": null, "hs_first_engagement_object_id": null, "hs_first_outreach_date": null, "hs_first_subscription_create_date": null, "hs_google_click_id": null, "hs_has_active_subscription": null, "hs_ip_timezone": null, "hs_is_contact": true, "hs_is_unworked": true, "hs_language": null, "hs_last_sales_activity_date": null, "hs_last_sales_activity_timestamp": null, "hs_last_sales_activity_type": null, "hs_lastmodifieddate": null, "hs_latest_meeting_activity": null, "hs_latest_sequence_ended_date": null, "hs_latest_sequence_enrolled": null, "hs_latest_sequence_enrolled_date": null, "hs_latest_sequence_finished_date": null, "hs_latest_sequence_unenrolled_date": null, "hs_latest_source": "OFFLINE", "hs_latest_source_data_1": "CRM_UI", "hs_latest_source_data_2": "userId:12282590", "hs_latest_source_timestamp": "2023-01-30T23:17:10.053000+00:00", "hs_latest_subscription_create_date": null, "hs_lead_status": null, "hs_legal_basis": "Legitimate interest \u2013 prospect/lead", "hs_lifecyclestage_customer_date": null, "hs_lifecyclestage_evangelist_date": null, "hs_lifecyclestage_lead_date": "2023-01-30T23:17:09.904000+00:00", "hs_lifecyclestage_marketingqualifiedlead_date": null, "hs_lifecyclestage_opportunity_date": "2023-01-31T00:31:07.832000+00:00", "hs_lifecyclestage_other_date": null, "hs_lifecyclestage_salesqualifiedlead_date": null, "hs_lifecyclestage_subscriber_date": null, "hs_linkedin_ad_clicked": null, "hs_marketable_reason_id": null, "hs_marketable_reason_type": null, "hs_marketable_status": "false", "hs_marketable_until_renewal": "false", "hs_merged_object_ids": null, "hs_object_id": 2501, "hs_persona": null, "hs_pinned_engagement_id": null, "hs_pipeline": "contacts-lifecycle-pipeline", "hs_predictivecontactscore": null, "hs_predictivecontactscore_v2": 2.93, "hs_predictivecontactscorebucket": null, "hs_predictivescoringtier": "tier_1", "hs_read_only": null, "hs_sa_first_engagement_date": null, "hs_sa_first_engagement_descr": null, "hs_sa_first_engagement_object_type": null, "hs_sales_email_last_clicked": null, "hs_sales_email_last_opened": null, "hs_sales_email_last_replied": null, "hs_searchable_calculated_international_mobile_number": null, "hs_searchable_calculated_international_phone_number": null, "hs_searchable_calculated_mobile_number": null, "hs_searchable_calculated_phone_number": "5555555555", "hs_sequences_actively_enrolled_count": 0, "hs_sequences_enrolled_count": null, "hs_sequences_is_enrolled": null, "hs_testpurge": null, "hs_testrollback": null, "hs_time_between_contact_creation_and_deal_close": null, "hs_time_between_contact_creation_and_deal_creation": null, "hs_time_in_customer": null, "hs_time_in_evangelist": null, "hs_time_in_lead": 4437928, "hs_time_in_marketingqualifiedlead": null, "hs_time_in_opportunity": 13852054954, "hs_time_in_other": null, "hs_time_in_salesqualifiedlead": null, "hs_time_in_subscriber": null, "hs_time_to_first_engagement": null, "hs_time_to_move_from_lead_to_customer": null, "hs_time_to_move_from_marketingqualifiedlead_to_customer": null, "hs_time_to_move_from_opportunity_to_customer": null, "hs_time_to_move_from_salesqualifiedlead_to_customer": null, "hs_time_to_move_from_subscriber_to_customer": null, "hs_timezone": null, "hs_unique_creation_key": null, "hs_updated_by_user_id": 12282590, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": "", "hs_was_imported": null, "hs_whatsapp_phone_number": null, "hubspot_owner_assigneddate": null, "hubspot_owner_id": "", "hubspot_team_id": null, "hubspotscore": null, "industry": null, "ip_city": null, "ip_country": null, "ip_country_code": null, "ip_latlon": null, "ip_state": null, "ip_state_code": null, "ip_zipcode": null, "job_function": null, "jobtitle": null, "lastmodifieddate": "2023-04-04T15:11:47.143000+00:00", "lastname": "test", "lifecyclestage": "opportunity", "marital_status": null, "message": null, "military_status": null, "mobilephone": null, "my_custom_test_property": null, "notes_last_contacted": null, "notes_last_updated": null, "notes_next_activity_date": null, "num_associated_deals": null, "num_contacted_notes": null, "num_conversion_events": 0, "num_notes": null, "num_unique_conversion_events": 0, "numemployees": null, "phone": "+555555555555", "recent_conversion_date": null, "recent_conversion_event_name": null, "recent_deal_amount": null, "recent_deal_close_date": null, "relationship_status": null, "salutation": null, "school": null, "seniority": null, "start_date": null, "state": null, "surveymonkeyeventlastupdated": null, "test": null, "total_revenue": null, "twitterhandle": null, "webinareventlastupdated": null, "website": null, "work_email": null, "zip": null}, "createdAt": "2023-01-30T23:17:09.904Z", "updatedAt": "2023-04-04T15:11:47.143Z", "archived": false}, "emitted_at": 1688977122798} +{"stream": "contacts", "data": {"id": "2551", "properties": {"address": null, "annualrevenue": null, "associatedcompanyid": null, "associatedcompanylastupdated": null, "city": null, "closedate": null, "company": null, "company_size": null, "country": null, "createdate": "2023-01-31T00:11:58.499000+00:00", "currentlyinworkflow": null, "date_of_birth": null, "days_to_close": null, "degree": null, "email": "test-integration-test-user-4@testmail.com", "engagements_last_meeting_booked": null, "engagements_last_meeting_booked_campaign": null, "engagements_last_meeting_booked_medium": null, "engagements_last_meeting_booked_source": null, "fax": null, "field_of_study": null, "first_conversion_date": null, "first_conversion_event_name": null, "first_deal_created_date": null, "firstname": null, "gender": null, "graduation_date": null, "hs_additional_emails": null, "hs_all_accessible_team_ids": null, "hs_all_contact_vids": "2551", "hs_all_owner_ids": "52550153", "hs_all_team_ids": null, "hs_analytics_average_page_views": 0, "hs_analytics_first_referrer": null, "hs_analytics_first_timestamp": "2023-01-31T00:11:58.499000+00:00", "hs_analytics_first_touch_converting_campaign": null, "hs_analytics_first_url": null, "hs_analytics_first_visit_timestamp": null, "hs_analytics_last_referrer": null, "hs_analytics_last_timestamp": null, "hs_analytics_last_touch_converting_campaign": null, "hs_analytics_last_url": null, "hs_analytics_last_visit_timestamp": null, "hs_analytics_num_event_completions": 0, "hs_analytics_num_page_views": 0, "hs_analytics_num_visits": 0, "hs_analytics_revenue": 0.0, "hs_analytics_source": "OFFLINE", "hs_analytics_source_data_1": "CRM_UI", "hs_analytics_source_data_2": "userId:12282590", "hs_avatar_filemanager_key": null, "hs_buying_role": null, "hs_calculated_form_submissions": null, "hs_calculated_merged_vids": null, "hs_calculated_mobile_number": null, "hs_calculated_phone_number": null, "hs_calculated_phone_number_area_code": null, "hs_calculated_phone_number_country_code": null, "hs_calculated_phone_number_region_code": null, "hs_clicked_linkedin_ad": null, "hs_content_membership_email": null, "hs_content_membership_email_confirmed": null, "hs_content_membership_notes": null, "hs_content_membership_registered_at": null, "hs_content_membership_registration_domain_sent_to": null, "hs_content_membership_registration_email_sent_at": null, "hs_content_membership_status": null, "hs_conversations_visitor_email": null, "hs_count_is_unworked": 1, "hs_count_is_worked": 0, "hs_created_by_conversations": null, "hs_created_by_user_id": 12282590, "hs_createdate": null, "hs_date_entered_customer": null, "hs_date_entered_evangelist": null, "hs_date_entered_lead": "2023-01-31T00:11:58.499000+00:00", "hs_date_entered_marketingqualifiedlead": null, "hs_date_entered_opportunity": null, "hs_date_entered_other": null, "hs_date_entered_salesqualifiedlead": null, "hs_date_entered_subscriber": null, "hs_date_exited_customer": null, "hs_date_exited_evangelist": null, "hs_date_exited_lead": null, "hs_date_exited_marketingqualifiedlead": null, "hs_date_exited_opportunity": null, "hs_date_exited_other": null, "hs_date_exited_salesqualifiedlead": null, "hs_date_exited_subscriber": null, "hs_document_last_revisited": null, "hs_email_bad_address": null, "hs_email_bounce": null, "hs_email_click": null, "hs_email_customer_quarantined_reason": null, "hs_email_delivered": null, "hs_email_domain": "testmail.com", "hs_email_first_click_date": null, "hs_email_first_open_date": null, "hs_email_first_reply_date": null, "hs_email_first_send_date": null, "hs_email_hard_bounce_reason": null, "hs_email_hard_bounce_reason_enum": null, "hs_email_is_ineligible": null, "hs_email_last_click_date": null, "hs_email_last_email_name": null, "hs_email_last_open_date": null, "hs_email_last_reply_date": null, "hs_email_last_send_date": null, "hs_email_open": null, "hs_email_optout": null, "hs_email_optout_10798197": null, "hs_email_optout_11890603": null, "hs_email_optout_11890831": null, "hs_email_optout_23704464": null, "hs_email_optout_94692364": null, "hs_email_quarantined": null, "hs_email_quarantined_reason": null, "hs_email_recipient_fatigue_recovery_time": null, "hs_email_replied": null, "hs_email_sends_since_last_engagement": null, "hs_emailconfirmationstatus": null, "hs_facebook_ad_clicked": null, "hs_facebook_click_id": null, "hs_feedback_last_nps_follow_up": null, "hs_feedback_last_nps_rating": null, "hs_feedback_last_survey_date": null, "hs_feedback_show_nps_web_survey": null, "hs_first_engagement_object_id": null, "hs_first_outreach_date": null, "hs_first_subscription_create_date": null, "hs_google_click_id": null, "hs_has_active_subscription": null, "hs_ip_timezone": null, "hs_is_contact": true, "hs_is_unworked": true, "hs_language": null, "hs_last_sales_activity_date": null, "hs_last_sales_activity_timestamp": null, "hs_last_sales_activity_type": null, "hs_lastmodifieddate": null, "hs_latest_meeting_activity": null, "hs_latest_sequence_ended_date": null, "hs_latest_sequence_enrolled": null, "hs_latest_sequence_enrolled_date": null, "hs_latest_sequence_finished_date": null, "hs_latest_sequence_unenrolled_date": null, "hs_latest_source": "OFFLINE", "hs_latest_source_data_1": "CRM_UI", "hs_latest_source_data_2": "userId:12282590", "hs_latest_source_timestamp": "2023-01-31T00:11:58.582000+00:00", "hs_latest_subscription_create_date": null, "hs_lead_status": null, "hs_legal_basis": "Legitimate interest \u2013 prospect/lead", "hs_lifecyclestage_customer_date": null, "hs_lifecyclestage_evangelist_date": null, "hs_lifecyclestage_lead_date": "2023-01-31T00:11:58.499000+00:00", "hs_lifecyclestage_marketingqualifiedlead_date": null, "hs_lifecyclestage_opportunity_date": null, "hs_lifecyclestage_other_date": null, "hs_lifecyclestage_salesqualifiedlead_date": null, "hs_lifecyclestage_subscriber_date": null, "hs_linkedin_ad_clicked": null, "hs_marketable_reason_id": null, "hs_marketable_reason_type": null, "hs_marketable_status": "false", "hs_marketable_until_renewal": "false", "hs_merged_object_ids": null, "hs_object_id": 2551, "hs_persona": null, "hs_pinned_engagement_id": null, "hs_pipeline": "contacts-lifecycle-pipeline", "hs_predictivecontactscore": null, "hs_predictivecontactscore_v2": 2.93, "hs_predictivecontactscorebucket": null, "hs_predictivescoringtier": "tier_1", "hs_read_only": null, "hs_sa_first_engagement_date": null, "hs_sa_first_engagement_descr": null, "hs_sa_first_engagement_object_type": null, "hs_sales_email_last_clicked": null, "hs_sales_email_last_opened": null, "hs_sales_email_last_replied": null, "hs_searchable_calculated_international_mobile_number": null, "hs_searchable_calculated_international_phone_number": null, "hs_searchable_calculated_mobile_number": null, "hs_searchable_calculated_phone_number": null, "hs_sequences_actively_enrolled_count": 0, "hs_sequences_enrolled_count": null, "hs_sequences_is_enrolled": null, "hs_testpurge": null, "hs_testrollback": null, "hs_time_between_contact_creation_and_deal_close": null, "hs_time_between_contact_creation_and_deal_creation": null, "hs_time_in_customer": null, "hs_time_in_evangelist": null, "hs_time_in_lead": 13853204287, "hs_time_in_marketingqualifiedlead": null, "hs_time_in_opportunity": null, "hs_time_in_other": null, "hs_time_in_salesqualifiedlead": null, "hs_time_in_subscriber": null, "hs_time_to_first_engagement": null, "hs_time_to_move_from_lead_to_customer": null, "hs_time_to_move_from_marketingqualifiedlead_to_customer": null, "hs_time_to_move_from_opportunity_to_customer": null, "hs_time_to_move_from_salesqualifiedlead_to_customer": null, "hs_time_to_move_from_subscriber_to_customer": null, "hs_timezone": null, "hs_unique_creation_key": null, "hs_updated_by_user_id": 12282590, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": "12282590", "hs_was_imported": null, "hs_whatsapp_phone_number": null, "hubspot_owner_assigneddate": "2023-01-31T00:20:40.680000+00:00", "hubspot_owner_id": "52550153", "hubspot_team_id": null, "hubspotscore": null, "industry": null, "ip_city": null, "ip_country": null, "ip_country_code": null, "ip_latlon": null, "ip_state": null, "ip_state_code": null, "ip_zipcode": null, "job_function": null, "jobtitle": null, "lastmodifieddate": "2023-04-03T20:29:54.560000+00:00", "lastname": null, "lifecyclestage": "lead", "marital_status": null, "message": null, "military_status": null, "mobilephone": null, "my_custom_test_property": null, "notes_last_contacted": null, "notes_last_updated": null, "notes_next_activity_date": null, "num_associated_deals": null, "num_contacted_notes": null, "num_conversion_events": 0, "num_notes": null, "num_unique_conversion_events": 0, "numemployees": null, "phone": null, "recent_conversion_date": null, "recent_conversion_event_name": null, "recent_deal_amount": null, "recent_deal_close_date": null, "relationship_status": null, "salutation": null, "school": null, "seniority": null, "start_date": null, "state": null, "surveymonkeyeventlastupdated": null, "test": null, "total_revenue": null, "twitterhandle": null, "webinareventlastupdated": null, "website": null, "work_email": null, "zip": null}, "createdAt": "2023-01-31T00:11:58.499Z", "updatedAt": "2023-04-03T20:29:54.560Z", "archived": false}, "emitted_at": 1688977122798} +{"stream": "contacts", "data": {"id": "2601", "properties": {"address": null, "annualrevenue": null, "associatedcompanyid": null, "associatedcompanylastupdated": null, "city": null, "closedate": null, "company": null, "company_size": null, "country": null, "createdate": "2023-02-01T13:08:49.766000+00:00", "currentlyinworkflow": null, "date_of_birth": null, "days_to_close": null, "degree": null, "email": "test.person@airbyte.com", "engagements_last_meeting_booked": null, "engagements_last_meeting_booked_campaign": null, "engagements_last_meeting_booked_medium": null, "engagements_last_meeting_booked_source": null, "fax": null, "field_of_study": null, "first_conversion_date": null, "first_conversion_event_name": null, "first_deal_created_date": null, "firstname": "TEST", "gender": null, "graduation_date": null, "hs_additional_emails": null, "hs_all_accessible_team_ids": null, "hs_all_contact_vids": "2601", "hs_all_owner_ids": "52550153", "hs_all_team_ids": null, "hs_analytics_average_page_views": 0, "hs_analytics_first_referrer": null, "hs_analytics_first_timestamp": "2023-02-01T13:08:49.735000+00:00", "hs_analytics_first_touch_converting_campaign": null, "hs_analytics_first_url": null, "hs_analytics_first_visit_timestamp": null, "hs_analytics_last_referrer": null, "hs_analytics_last_timestamp": null, "hs_analytics_last_touch_converting_campaign": null, "hs_analytics_last_url": null, "hs_analytics_last_visit_timestamp": null, "hs_analytics_num_event_completions": 0, "hs_analytics_num_page_views": 0, "hs_analytics_num_visits": 0, "hs_analytics_revenue": 0.0, "hs_analytics_source": "OFFLINE", "hs_analytics_source_data_1": "CRM_UI", "hs_analytics_source_data_2": "userId:12282590", "hs_avatar_filemanager_key": null, "hs_buying_role": null, "hs_calculated_form_submissions": null, "hs_calculated_merged_vids": null, "hs_calculated_mobile_number": null, "hs_calculated_phone_number": null, "hs_calculated_phone_number_area_code": null, "hs_calculated_phone_number_country_code": null, "hs_calculated_phone_number_region_code": null, "hs_clicked_linkedin_ad": null, "hs_content_membership_email": null, "hs_content_membership_email_confirmed": null, "hs_content_membership_notes": null, "hs_content_membership_registered_at": null, "hs_content_membership_registration_domain_sent_to": null, "hs_content_membership_registration_email_sent_at": null, "hs_content_membership_status": null, "hs_conversations_visitor_email": null, "hs_count_is_unworked": 1, "hs_count_is_worked": 0, "hs_created_by_conversations": null, "hs_created_by_user_id": 12282590, "hs_createdate": null, "hs_date_entered_customer": null, "hs_date_entered_evangelist": null, "hs_date_entered_lead": "2023-02-01T13:08:49.735000+00:00", "hs_date_entered_marketingqualifiedlead": null, "hs_date_entered_opportunity": null, "hs_date_entered_other": null, "hs_date_entered_salesqualifiedlead": null, "hs_date_entered_subscriber": null, "hs_date_exited_customer": null, "hs_date_exited_evangelist": null, "hs_date_exited_lead": null, "hs_date_exited_marketingqualifiedlead": null, "hs_date_exited_opportunity": null, "hs_date_exited_other": null, "hs_date_exited_salesqualifiedlead": null, "hs_date_exited_subscriber": null, "hs_document_last_revisited": null, "hs_email_bad_address": null, "hs_email_bounce": null, "hs_email_click": null, "hs_email_customer_quarantined_reason": null, "hs_email_delivered": null, "hs_email_domain": "airbyte.com", "hs_email_first_click_date": null, "hs_email_first_open_date": null, "hs_email_first_reply_date": null, "hs_email_first_send_date": null, "hs_email_hard_bounce_reason": null, "hs_email_hard_bounce_reason_enum": null, "hs_email_is_ineligible": null, "hs_email_last_click_date": null, "hs_email_last_email_name": null, "hs_email_last_open_date": null, "hs_email_last_reply_date": null, "hs_email_last_send_date": null, "hs_email_open": null, "hs_email_optout": null, "hs_email_optout_10798197": null, "hs_email_optout_11890603": null, "hs_email_optout_11890831": null, "hs_email_optout_23704464": null, "hs_email_optout_94692364": null, "hs_email_quarantined": null, "hs_email_quarantined_reason": null, "hs_email_recipient_fatigue_recovery_time": null, "hs_email_replied": null, "hs_email_sends_since_last_engagement": null, "hs_emailconfirmationstatus": null, "hs_facebook_ad_clicked": null, "hs_facebook_click_id": null, "hs_feedback_last_nps_follow_up": null, "hs_feedback_last_nps_rating": null, "hs_feedback_last_survey_date": null, "hs_feedback_show_nps_web_survey": null, "hs_first_engagement_object_id": null, "hs_first_outreach_date": null, "hs_first_subscription_create_date": null, "hs_google_click_id": null, "hs_has_active_subscription": null, "hs_ip_timezone": null, "hs_is_contact": true, "hs_is_unworked": true, "hs_language": null, "hs_last_sales_activity_date": null, "hs_last_sales_activity_timestamp": null, "hs_last_sales_activity_type": null, "hs_lastmodifieddate": null, "hs_latest_meeting_activity": null, "hs_latest_sequence_ended_date": null, "hs_latest_sequence_enrolled": null, "hs_latest_sequence_enrolled_date": null, "hs_latest_sequence_finished_date": null, "hs_latest_sequence_unenrolled_date": null, "hs_latest_source": "OFFLINE", "hs_latest_source_data_1": "CRM_UI", "hs_latest_source_data_2": "userId:12282590", "hs_latest_source_timestamp": "2023-02-01T13:08:49.863000+00:00", "hs_latest_subscription_create_date": null, "hs_lead_status": null, "hs_legal_basis": "Performance of a contract", "hs_lifecyclestage_customer_date": null, "hs_lifecyclestage_evangelist_date": null, "hs_lifecyclestage_lead_date": "2023-02-01T13:08:49.735000+00:00", "hs_lifecyclestage_marketingqualifiedlead_date": null, "hs_lifecyclestage_opportunity_date": null, "hs_lifecyclestage_other_date": null, "hs_lifecyclestage_salesqualifiedlead_date": null, "hs_lifecyclestage_subscriber_date": null, "hs_linkedin_ad_clicked": null, "hs_marketable_reason_id": "12282590", "hs_marketable_reason_type": "USER_SET", "hs_marketable_status": "true", "hs_marketable_until_renewal": "false", "hs_merged_object_ids": null, "hs_object_id": 2601, "hs_persona": null, "hs_pinned_engagement_id": null, "hs_pipeline": "contacts-lifecycle-pipeline", "hs_predictivecontactscore": null, "hs_predictivecontactscore_v2": 3.15, "hs_predictivecontactscorebucket": null, "hs_predictivescoringtier": "tier_1", "hs_read_only": null, "hs_sa_first_engagement_date": null, "hs_sa_first_engagement_descr": null, "hs_sa_first_engagement_object_type": null, "hs_sales_email_last_clicked": null, "hs_sales_email_last_opened": null, "hs_sales_email_last_replied": null, "hs_searchable_calculated_international_mobile_number": null, "hs_searchable_calculated_international_phone_number": null, "hs_searchable_calculated_mobile_number": null, "hs_searchable_calculated_phone_number": null, "hs_sequences_actively_enrolled_count": 0, "hs_sequences_enrolled_count": null, "hs_sequences_is_enrolled": null, "hs_testpurge": null, "hs_testrollback": null, "hs_time_between_contact_creation_and_deal_close": null, "hs_time_between_contact_creation_and_deal_creation": null, "hs_time_in_customer": null, "hs_time_in_evangelist": null, "hs_time_in_lead": 13720193051, "hs_time_in_marketingqualifiedlead": null, "hs_time_in_opportunity": null, "hs_time_in_other": null, "hs_time_in_salesqualifiedlead": null, "hs_time_in_subscriber": null, "hs_time_to_first_engagement": null, "hs_time_to_move_from_lead_to_customer": null, "hs_time_to_move_from_marketingqualifiedlead_to_customer": null, "hs_time_to_move_from_opportunity_to_customer": null, "hs_time_to_move_from_salesqualifiedlead_to_customer": null, "hs_time_to_move_from_subscriber_to_customer": null, "hs_timezone": null, "hs_unique_creation_key": null, "hs_updated_by_user_id": 12282590, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": "12282590", "hs_was_imported": null, "hs_whatsapp_phone_number": null, "hubspot_owner_assigneddate": "2023-02-01T13:08:49.735000+00:00", "hubspot_owner_id": "52550153", "hubspot_team_id": null, "hubspotscore": null, "industry": null, "ip_city": null, "ip_country": null, "ip_country_code": null, "ip_latlon": null, "ip_state": null, "ip_state_code": null, "ip_zipcode": null, "job_function": null, "jobtitle": null, "lastmodifieddate": "2023-04-03T20:29:58.691000+00:00", "lastname": "TEST", "lifecyclestage": "lead", "marital_status": null, "message": null, "military_status": null, "mobilephone": null, "my_custom_test_property": null, "notes_last_contacted": null, "notes_last_updated": null, "notes_next_activity_date": null, "num_associated_deals": null, "num_contacted_notes": null, "num_conversion_events": 0, "num_notes": null, "num_unique_conversion_events": 0, "numemployees": null, "phone": null, "recent_conversion_date": null, "recent_conversion_event_name": null, "recent_deal_amount": null, "recent_deal_close_date": null, "relationship_status": null, "salutation": null, "school": null, "seniority": null, "start_date": null, "state": null, "surveymonkeyeventlastupdated": null, "test": null, "total_revenue": null, "twitterhandle": null, "webinareventlastupdated": null, "website": null, "work_email": null, "zip": null}, "createdAt": "2023-02-01T13:08:49.766Z", "updatedAt": "2023-04-03T20:29:58.691Z", "archived": false}, "emitted_at": 1688977122799} {"stream": "contacts_list_memberships", "data": {"canonical-vid": 2501, "static-list-id": 60, "internal-list-id": 2147483643, "timestamp": 1675124235515, "vid": 2501, "is-member": true}, "emitted_at": 1685387177140} {"stream": "contacts_list_memberships", "data": {"canonical-vid": 2501, "static-list-id": 61, "internal-list-id": 2147483643, "timestamp": 1675124259228, "vid": 2501, "is-member": true}, "emitted_at": 1685387177141} {"stream": "contacts_list_memberships", "data": {"canonical-vid": 2501, "static-list-id": 166, "internal-list-id": 2147483643, "timestamp": 1675120848102, "vid": 2501, "is-member": true}, "emitted_at": 1685387177141} @@ -20,11 +18,7 @@ {"stream":"deals","data":{"id":"4280411910","properties":{"amount":6,"amount_in_home_currency":6,"closed_lost_reason":null,"closed_won_reason":null,"closedate":"2014-08-31T00:00:00+00:00","createdate":"2021-02-22T14:01:11.762000+00:00","days_to_close":0,"dealname":"Test Deal 332","dealstage":"appointmentscheduled","dealtype":"newbusiness","description":"Test deal","engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"hs_acv":95,"hs_all_accessible_team_ids":null,"hs_all_collaborator_owner_ids":null,"hs_all_deal_split_owner_ids":null,"hs_all_owner_ids":"52550153","hs_all_team_ids":null,"hs_analytics_latest_source":null,"hs_analytics_latest_source_company":null,"hs_analytics_latest_source_contact":null,"hs_analytics_latest_source_data_1":null,"hs_analytics_latest_source_data_1_company":null,"hs_analytics_latest_source_data_1_contact":null,"hs_analytics_latest_source_data_2":null,"hs_analytics_latest_source_data_2_company":null,"hs_analytics_latest_source_data_2_contact":null,"hs_analytics_latest_source_timestamp":null,"hs_analytics_latest_source_timestamp_company":null,"hs_analytics_latest_source_timestamp_contact":null,"hs_analytics_source":null,"hs_analytics_source_data_1":null,"hs_analytics_source_data_2":null,"hs_arr":0,"hs_campaign":null,"hs_closed_amount":0,"hs_closed_amount_in_home_currency":0,"hs_closed_won_count":null,"hs_closed_won_date":null,"hs_created_by_user_id":null,"hs_createdate":"2021-02-22T14:01:11.762000+00:00","hs_date_entered_66894120":null,"hs_date_entered_9567448":null,"hs_date_entered_9567449":null,"hs_date_entered_appointmentscheduled":"2021-02-22T14:01:11.762000+00:00","hs_date_entered_closedlost":null,"hs_date_entered_closedwon":null,"hs_date_entered_contractsent":null,"hs_date_entered_customclosedwonstage":null,"hs_date_entered_decisionmakerboughtin":null,"hs_date_entered_presentationscheduled":null,"hs_date_entered_qualifiedtobuy":null,"hs_date_exited_66894120":null,"hs_date_exited_9567448":null,"hs_date_exited_9567449":null,"hs_date_exited_appointmentscheduled":null,"hs_date_exited_closedlost":null,"hs_date_exited_closedwon":null,"hs_date_exited_contractsent":null,"hs_date_exited_customclosedwonstage":null,"hs_date_exited_decisionmakerboughtin":null,"hs_date_exited_presentationscheduled":null,"hs_date_exited_qualifiedtobuy":null,"hs_deal_amount_calculation_preference":null,"hs_deal_stage_probability":0.2,"hs_deal_stage_probability_shadow":null,"hs_exchange_rate":null,"hs_forecast_amount":6,"hs_forecast_probability":null,"hs_is_closed":false,"hs_is_closed_won":false,"hs_is_deal_split":false,"hs_lastmodifieddate":"2023-04-04T21:28:37.824000+00:00","hs_latest_meeting_activity":null,"hs_likelihood_to_close":null,"hs_line_item_global_term_hs_discount_percentage":null,"hs_line_item_global_term_hs_discount_percentage_enabled":null,"hs_line_item_global_term_hs_recurring_billing_period":null,"hs_line_item_global_term_hs_recurring_billing_period_enabled":null,"hs_line_item_global_term_hs_recurring_billing_start_date":null,"hs_line_item_global_term_hs_recurring_billing_start_date_enabled":null,"hs_line_item_global_term_recurringbillingfrequency":null,"hs_line_item_global_term_recurringbillingfrequency_enabled":null,"hs_manual_forecast_category":null,"hs_merged_object_ids":null,"hs_mrr":0,"hs_next_step":null,"hs_num_associated_deal_splits":null,"hs_num_of_associated_line_items":1,"hs_num_target_accounts":0,"hs_object_id":4280411910,"hs_pinned_engagement_id":null,"hs_predicted_amount":null,"hs_predicted_amount_in_home_currency":null,"hs_priority":null,"hs_projected_amount":1.2000000000000002,"hs_projected_amount_in_home_currency":1.2000000000000002,"hs_read_only":null,"hs_sales_email_last_replied":null,"hs_tag_ids":null,"hs_tcv":95,"hs_time_in_66894120":null,"hs_time_in_9567448":null,"hs_time_in_9567449":null,"hs_time_in_appointmentscheduled":74056484652,"hs_time_in_closedlost":null,"hs_time_in_closedwon":null,"hs_time_in_contractsent":null,"hs_time_in_customclosedwonstage":null,"hs_time_in_decisionmakerboughtin":null,"hs_time_in_presentationscheduled":null,"hs_time_in_qualifiedtobuy":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":null,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"12282590","hs_was_imported":null,"hubspot_owner_assigneddate":"2021-02-22T14:01:11.762000+00:00","hubspot_owner_id":"52550153","hubspot_team_id":null,"notes_last_contacted":null,"notes_last_updated":null,"notes_next_activity_date":null,"num_associated_contacts":0,"num_contacted_notes":null,"num_notes":null,"pipeline":"default"},"createdAt":"2021-02-22T14:01:11.762Z","updatedAt":"2023-04-04T21:28:37.824Z","archived":false,"companies":["5183409178","5183409178"],"line_items":["5153237390"]},"emitted_at":1688058956544} {"stream":"deals","data":{"id":"4315375411","properties":{"amount":10,"amount_in_home_currency":10,"closed_lost_reason":null,"closed_won_reason":null,"closedate":"2021-02-28T20:20:10.826000+00:00","createdate":"2021-02-23T20:20:10.826000+00:00","days_to_close":5,"dealname":"Test deal 2","dealstage":"appointmentscheduled","dealtype":null,"description":null,"engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"hs_acv":10,"hs_all_accessible_team_ids":null,"hs_all_collaborator_owner_ids":null,"hs_all_deal_split_owner_ids":null,"hs_all_owner_ids":"52550153","hs_all_team_ids":null,"hs_analytics_latest_source":"","hs_analytics_latest_source_company":null,"hs_analytics_latest_source_contact":"","hs_analytics_latest_source_data_1":"","hs_analytics_latest_source_data_1_company":null,"hs_analytics_latest_source_data_1_contact":"","hs_analytics_latest_source_data_2":"","hs_analytics_latest_source_data_2_company":null,"hs_analytics_latest_source_data_2_contact":"","hs_analytics_latest_source_timestamp":null,"hs_analytics_latest_source_timestamp_company":null,"hs_analytics_latest_source_timestamp_contact":null,"hs_analytics_source":"","hs_analytics_source_data_1":"","hs_analytics_source_data_2":"","hs_arr":0,"hs_campaign":null,"hs_closed_amount":0,"hs_closed_amount_in_home_currency":0,"hs_closed_won_count":null,"hs_closed_won_date":null,"hs_created_by_user_id":12282590,"hs_createdate":"2021-02-23T20:21:32.862000+00:00","hs_date_entered_66894120":null,"hs_date_entered_9567448":null,"hs_date_entered_9567449":null,"hs_date_entered_appointmentscheduled":"2021-02-23T20:21:32.862000+00:00","hs_date_entered_closedlost":null,"hs_date_entered_closedwon":null,"hs_date_entered_contractsent":null,"hs_date_entered_customclosedwonstage":null,"hs_date_entered_decisionmakerboughtin":null,"hs_date_entered_presentationscheduled":null,"hs_date_entered_qualifiedtobuy":null,"hs_date_exited_66894120":null,"hs_date_exited_9567448":null,"hs_date_exited_9567449":null,"hs_date_exited_appointmentscheduled":null,"hs_date_exited_closedlost":null,"hs_date_exited_closedwon":null,"hs_date_exited_contractsent":null,"hs_date_exited_customclosedwonstage":null,"hs_date_exited_decisionmakerboughtin":null,"hs_date_exited_presentationscheduled":null,"hs_date_exited_qualifiedtobuy":null,"hs_deal_amount_calculation_preference":null,"hs_deal_stage_probability":0.2,"hs_deal_stage_probability_shadow":null,"hs_exchange_rate":null,"hs_forecast_amount":10,"hs_forecast_probability":null,"hs_is_closed":false,"hs_is_closed_won":false,"hs_is_deal_split":false,"hs_lastmodifieddate":"2023-01-30T23:10:56.577000+00:00","hs_latest_meeting_activity":null,"hs_likelihood_to_close":null,"hs_line_item_global_term_hs_discount_percentage":null,"hs_line_item_global_term_hs_discount_percentage_enabled":null,"hs_line_item_global_term_hs_recurring_billing_period":null,"hs_line_item_global_term_hs_recurring_billing_period_enabled":null,"hs_line_item_global_term_hs_recurring_billing_start_date":null,"hs_line_item_global_term_hs_recurring_billing_start_date_enabled":null,"hs_line_item_global_term_recurringbillingfrequency":null,"hs_line_item_global_term_recurringbillingfrequency_enabled":null,"hs_manual_forecast_category":null,"hs_merged_object_ids":null,"hs_mrr":0,"hs_next_step":null,"hs_num_associated_deal_splits":null,"hs_num_of_associated_line_items":1,"hs_num_target_accounts":null,"hs_object_id":4315375411,"hs_pinned_engagement_id":null,"hs_predicted_amount":null,"hs_predicted_amount_in_home_currency":null,"hs_priority":null,"hs_projected_amount":2,"hs_projected_amount_in_home_currency":2,"hs_read_only":null,"hs_sales_email_last_replied":null,"hs_tag_ids":null,"hs_tcv":10,"hs_time_in_66894120":null,"hs_time_in_9567448":null,"hs_time_in_9567449":null,"hs_time_in_appointmentscheduled":73947263553,"hs_time_in_closedlost":null,"hs_time_in_closedwon":null,"hs_time_in_contractsent":null,"hs_time_in_customclosedwonstage":null,"hs_time_in_decisionmakerboughtin":null,"hs_time_in_presentationscheduled":null,"hs_time_in_qualifiedtobuy":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"12282590","hs_was_imported":null,"hubspot_owner_assigneddate":"2021-02-23T20:21:32.862000+00:00","hubspot_owner_id":"52550153","hubspot_team_id":null,"notes_last_contacted":null,"notes_last_updated":"2021-02-26T06:00:00+00:00","notes_next_activity_date":null,"num_associated_contacts":0,"num_contacted_notes":0,"num_notes":2,"pipeline":"default"},"createdAt":"2021-02-23T20:20:10.826Z","updatedAt":"2023-01-30T23:10:56.577Z","archived":false,"line_items":["1188257165"]},"emitted_at":1688058956545} {"stream":"deals","data":{"id":"5313445525","properties":{"amount":60,"amount_in_home_currency":60,"closed_lost_reason":null,"closed_won_reason":null,"closedate":"2021-05-31T10:21:28.593000+00:00","createdate":"2021-05-21T10:21:28.593000+00:00","days_to_close":10,"dealname":"Test Deal AAAA","dealstage":"appointmentscheduled","dealtype":"newbusiness","description":null,"engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"hs_acv":60,"hs_all_accessible_team_ids":null,"hs_all_collaborator_owner_ids":null,"hs_all_deal_split_owner_ids":null,"hs_all_owner_ids":"52550153","hs_all_team_ids":null,"hs_analytics_latest_source":"","hs_analytics_latest_source_company":null,"hs_analytics_latest_source_contact":"","hs_analytics_latest_source_data_1":"","hs_analytics_latest_source_data_1_company":null,"hs_analytics_latest_source_data_1_contact":"","hs_analytics_latest_source_data_2":"","hs_analytics_latest_source_data_2_company":null,"hs_analytics_latest_source_data_2_contact":"","hs_analytics_latest_source_timestamp":null,"hs_analytics_latest_source_timestamp_company":null,"hs_analytics_latest_source_timestamp_contact":null,"hs_analytics_source":"","hs_analytics_source_data_1":"","hs_analytics_source_data_2":"","hs_arr":60,"hs_campaign":null,"hs_closed_amount":0,"hs_closed_amount_in_home_currency":0,"hs_closed_won_count":null,"hs_closed_won_date":null,"hs_created_by_user_id":12282590,"hs_createdate":"2021-05-21T10:22:40.228000+00:00","hs_date_entered_66894120":null,"hs_date_entered_9567448":null,"hs_date_entered_9567449":null,"hs_date_entered_appointmentscheduled":"2021-05-21T10:22:40.228000+00:00","hs_date_entered_closedlost":null,"hs_date_entered_closedwon":null,"hs_date_entered_contractsent":null,"hs_date_entered_customclosedwonstage":null,"hs_date_entered_decisionmakerboughtin":null,"hs_date_entered_presentationscheduled":null,"hs_date_entered_qualifiedtobuy":null,"hs_date_exited_66894120":null,"hs_date_exited_9567448":null,"hs_date_exited_9567449":null,"hs_date_exited_appointmentscheduled":null,"hs_date_exited_closedlost":null,"hs_date_exited_closedwon":null,"hs_date_exited_contractsent":null,"hs_date_exited_customclosedwonstage":null,"hs_date_exited_decisionmakerboughtin":null,"hs_date_exited_presentationscheduled":null,"hs_date_exited_qualifiedtobuy":null,"hs_deal_amount_calculation_preference":null,"hs_deal_stage_probability":0.2,"hs_deal_stage_probability_shadow":0.2,"hs_exchange_rate":null,"hs_forecast_amount":60,"hs_forecast_probability":null,"hs_is_closed":false,"hs_is_closed_won":false,"hs_is_deal_split":false,"hs_lastmodifieddate":"2023-01-23T15:35:59.701000+00:00","hs_latest_meeting_activity":null,"hs_likelihood_to_close":null,"hs_line_item_global_term_hs_discount_percentage":null,"hs_line_item_global_term_hs_discount_percentage_enabled":null,"hs_line_item_global_term_hs_recurring_billing_period":null,"hs_line_item_global_term_hs_recurring_billing_period_enabled":null,"hs_line_item_global_term_hs_recurring_billing_start_date":null,"hs_line_item_global_term_hs_recurring_billing_start_date_enabled":null,"hs_line_item_global_term_recurringbillingfrequency":null,"hs_line_item_global_term_recurringbillingfrequency_enabled":null,"hs_manual_forecast_category":null,"hs_merged_object_ids":null,"hs_mrr":20,"hs_next_step":null,"hs_num_associated_deal_splits":0,"hs_num_of_associated_line_items":1,"hs_num_target_accounts":0,"hs_object_id":5313445525,"hs_pinned_engagement_id":null,"hs_predicted_amount":null,"hs_predicted_amount_in_home_currency":null,"hs_priority":"medium","hs_projected_amount":12,"hs_projected_amount_in_home_currency":12,"hs_read_only":null,"hs_sales_email_last_replied":null,"hs_tag_ids":null,"hs_tcv":60,"hs_time_in_66894120":null,"hs_time_in_9567448":null,"hs_time_in_9567449":null,"hs_time_in_appointmentscheduled":66466396185,"hs_time_in_closedlost":null,"hs_time_in_closedwon":null,"hs_time_in_contractsent":null,"hs_time_in_customclosedwonstage":null,"hs_time_in_decisionmakerboughtin":null,"hs_time_in_presentationscheduled":null,"hs_time_in_qualifiedtobuy":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"12282590","hs_was_imported":null,"hubspot_owner_assigneddate":"2021-05-21T10:22:40.228000+00:00","hubspot_owner_id":"52550153","hubspot_team_id":null,"notes_last_contacted":null,"notes_last_updated":null,"notes_next_activity_date":null,"num_associated_contacts":0,"num_contacted_notes":null,"num_notes":null,"pipeline":"default"},"createdAt":"2021-05-21T10:21:28.593Z","updatedAt":"2023-01-23T15:35:59.701Z","archived":false,"companies":["5438025334","5438025334"],"line_items":["1510167477"]},"emitted_at":1688058956546} -{"stream":"deals_archived","data":{"id":"11936210032","properties":{"amount":34,"amount_in_home_currency":34,"closed_lost_reason":null,"closed_won_reason":null,"closedate":"2023-01-30T23:41:04.079000+00:00","createdate":"2023-01-30T23:41:12.865000+00:00","days_to_close":0,"dealname":"test","dealstage":"appointmentscheduled","dealtype":"newbusiness","description":null,"engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"hs_acv":34,"hs_all_accessible_team_ids":null,"hs_all_collaborator_owner_ids":null,"hs_all_deal_split_owner_ids":null,"hs_all_owner_ids":"52550153","hs_all_team_ids":null,"hs_analytics_latest_source":"OFFLINE","hs_analytics_latest_source_company":null,"hs_analytics_latest_source_contact":"OFFLINE","hs_analytics_latest_source_data_1":"CRM_UI","hs_analytics_latest_source_data_1_company":null,"hs_analytics_latest_source_data_1_contact":"CRM_UI","hs_analytics_latest_source_data_2":"userId:12282590","hs_analytics_latest_source_data_2_company":null,"hs_analytics_latest_source_data_2_contact":"userId:12282590","hs_analytics_latest_source_timestamp":"2023-01-30T23:17:10.053000+00:00","hs_analytics_latest_source_timestamp_company":null,"hs_analytics_latest_source_timestamp_contact":"2023-01-30T23:17:10.053000+00:00","hs_analytics_source":"OFFLINE","hs_analytics_source_data_1":"CRM_UI","hs_analytics_source_data_2":"userId:12282590","hs_arr":0,"hs_campaign":null,"hs_closed_amount":0,"hs_closed_amount_in_home_currency":0,"hs_closed_won_count":null,"hs_closed_won_date":null,"hs_created_by_user_id":12282590,"hs_createdate":"2023-01-30T23:41:12.865000+00:00","hs_date_entered_66894120":null,"hs_date_entered_9567448":null,"hs_date_entered_9567449":null,"hs_date_entered_appointmentscheduled":"2023-01-30T23:41:12.865000+00:00","hs_date_entered_closedlost":null,"hs_date_entered_closedwon":null,"hs_date_entered_contractsent":null,"hs_date_entered_customclosedwonstage":null,"hs_date_entered_decisionmakerboughtin":null,"hs_date_entered_presentationscheduled":null,"hs_date_entered_qualifiedtobuy":null,"hs_date_exited_66894120":null,"hs_date_exited_9567448":null,"hs_date_exited_9567449":null,"hs_date_exited_appointmentscheduled":null,"hs_date_exited_closedlost":null,"hs_date_exited_closedwon":null,"hs_date_exited_contractsent":null,"hs_date_exited_customclosedwonstage":null,"hs_date_exited_decisionmakerboughtin":null,"hs_date_exited_presentationscheduled":null,"hs_date_exited_qualifiedtobuy":null,"hs_deal_amount_calculation_preference":null,"hs_deal_stage_probability":0.2,"hs_deal_stage_probability_shadow":0.2,"hs_exchange_rate":null,"hs_forecast_amount":34,"hs_forecast_probability":null,"hs_is_closed":false,"hs_is_closed_won":false,"hs_is_deal_split":false,"hs_lastmodifieddate":"2023-04-04T15:07:16.048000+00:00","hs_latest_meeting_activity":null,"hs_likelihood_to_close":null,"hs_line_item_global_term_hs_discount_percentage":null,"hs_line_item_global_term_hs_discount_percentage_enabled":null,"hs_line_item_global_term_hs_recurring_billing_period":null,"hs_line_item_global_term_hs_recurring_billing_period_enabled":null,"hs_line_item_global_term_hs_recurring_billing_start_date":null,"hs_line_item_global_term_hs_recurring_billing_start_date_enabled":null,"hs_line_item_global_term_recurringbillingfrequency":null,"hs_line_item_global_term_recurringbillingfrequency_enabled":null,"hs_manual_forecast_category":null,"hs_merged_object_ids":null,"hs_mrr":0,"hs_next_step":null,"hs_num_associated_deal_splits":0,"hs_num_of_associated_line_items":null,"hs_num_target_accounts":0,"hs_object_id":11936210032,"hs_pinned_engagement_id":null,"hs_predicted_amount":null,"hs_predicted_amount_in_home_currency":null,"hs_priority":null,"hs_projected_amount":6.800000000000001,"hs_projected_amount_in_home_currency":6.800000000000001,"hs_read_only":null,"hs_sales_email_last_replied":null,"hs_tag_ids":null,"hs_tcv":34,"hs_time_in_66894120":null,"hs_time_in_9567448":null,"hs_time_in_9567449":null,"hs_time_in_appointmentscheduled":12937341171,"hs_time_in_closedlost":null,"hs_time_in_closedwon":null,"hs_time_in_contractsent":null,"hs_time_in_customclosedwonstage":null,"hs_time_in_decisionmakerboughtin":null,"hs_time_in_presentationscheduled":null,"hs_time_in_qualifiedtobuy":null,"hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"12282590","hs_was_imported":null,"hubspot_owner_assigneddate":"2023-01-30T23:41:12.865000+00:00","hubspot_owner_id":"52550153","hubspot_team_id":null,"notes_last_contacted":null,"notes_last_updated":"2023-02-03T07:00:00+00:00","notes_next_activity_date":null,"num_associated_contacts":1,"num_contacted_notes":0,"num_notes":2,"pipeline":"default"},"createdAt":"2023-01-30T23:41:12.865Z","updatedAt":"2023-04-04T15:07:16.048Z","archived":true,"archivedAt":"2023-04-04T15:11:44.712Z"},"emitted_at":1688059414123} -{"stream":"deals_archived","data":{"id":"4307833946","properties":{"amount":123,"amount_in_home_currency":123,"closed_lost_reason":null,"closed_won_reason":null,"closedate":"2023-04-04T15:08:40.475000+00:00","createdate":"2021-02-23T20:20:10.826000+00:00","days_to_close":769,"dealname":"Test deal","dealstage":"closedwon","dealtype":"existingbusiness","description":null,"engagements_last_meeting_booked":null,"engagements_last_meeting_booked_campaign":null,"engagements_last_meeting_booked_medium":null,"engagements_last_meeting_booked_source":null,"hs_acv":123,"hs_all_accessible_team_ids":null,"hs_all_collaborator_owner_ids":null,"hs_all_deal_split_owner_ids":null,"hs_all_owner_ids":"52550153","hs_all_team_ids":null,"hs_analytics_latest_source":"OFFLINE","hs_analytics_latest_source_company":"OFFLINE","hs_analytics_latest_source_contact":"","hs_analytics_latest_source_data_1":"CONTACTS","hs_analytics_latest_source_data_1_company":"CONTACTS","hs_analytics_latest_source_data_1_contact":"","hs_analytics_latest_source_data_2":"CRM_UI","hs_analytics_latest_source_data_2_company":"CRM_UI","hs_analytics_latest_source_data_2_contact":"","hs_analytics_latest_source_timestamp":null,"hs_analytics_latest_source_timestamp_company":null,"hs_analytics_latest_source_timestamp_contact":null,"hs_analytics_source":"OFFLINE","hs_analytics_source_data_1":"CONTACTS","hs_analytics_source_data_2":"CRM_UI","hs_arr":0,"hs_campaign":null,"hs_closed_amount":123,"hs_closed_amount_in_home_currency":123,"hs_closed_won_count":null,"hs_closed_won_date":null,"hs_created_by_user_id":12282590,"hs_createdate":"2021-02-23T20:21:05.293000+00:00","hs_date_entered_66894120":null,"hs_date_entered_9567448":null,"hs_date_entered_9567449":null,"hs_date_entered_appointmentscheduled":"2021-02-23T20:21:05.293000+00:00","hs_date_entered_closedlost":null,"hs_date_entered_closedwon":"2023-04-04T15:08:40.710000+00:00","hs_date_entered_contractsent":"2023-04-04T15:08:40.710000+00:00","hs_date_entered_customclosedwonstage":null,"hs_date_entered_decisionmakerboughtin":"2023-04-04T15:08:40.710000+00:00","hs_date_entered_presentationscheduled":"2023-04-04T15:08:40.710000+00:00","hs_date_entered_qualifiedtobuy":"2023-04-04T15:08:40.710000+00:00","hs_date_exited_66894120":null,"hs_date_exited_9567448":null,"hs_date_exited_9567449":null,"hs_date_exited_appointmentscheduled":"2023-04-04T15:08:40.710000+00:00","hs_date_exited_closedlost":null,"hs_date_exited_closedwon":null,"hs_date_exited_contractsent":"2023-04-04T15:08:40.710000+00:00","hs_date_exited_customclosedwonstage":null,"hs_date_exited_decisionmakerboughtin":"2023-04-04T15:08:40.710000+00:00","hs_date_exited_presentationscheduled":"2023-04-04T15:08:40.710000+00:00","hs_date_exited_qualifiedtobuy":"2023-04-04T15:08:40.710000+00:00","hs_deal_amount_calculation_preference":null,"hs_deal_stage_probability":1,"hs_deal_stage_probability_shadow":1,"hs_exchange_rate":null,"hs_forecast_amount":123,"hs_forecast_probability":null,"hs_is_closed":true,"hs_is_closed_won":true,"hs_is_deal_split":false,"hs_lastmodifieddate":"2023-04-04T15:08:41.191000+00:00","hs_latest_meeting_activity":null,"hs_likelihood_to_close":null,"hs_line_item_global_term_hs_discount_percentage":null,"hs_line_item_global_term_hs_discount_percentage_enabled":null,"hs_line_item_global_term_hs_recurring_billing_period":null,"hs_line_item_global_term_hs_recurring_billing_period_enabled":null,"hs_line_item_global_term_hs_recurring_billing_start_date":null,"hs_line_item_global_term_hs_recurring_billing_start_date_enabled":null,"hs_line_item_global_term_recurringbillingfrequency":null,"hs_line_item_global_term_recurringbillingfrequency_enabled":null,"hs_manual_forecast_category":null,"hs_merged_object_ids":null,"hs_mrr":0,"hs_next_step":null,"hs_num_associated_deal_splits":null,"hs_num_of_associated_line_items":null,"hs_num_target_accounts":0,"hs_object_id":4307833946,"hs_pinned_engagement_id":null,"hs_predicted_amount":null,"hs_predicted_amount_in_home_currency":null,"hs_priority":null,"hs_projected_amount":123,"hs_projected_amount_in_home_currency":123,"hs_read_only":null,"hs_sales_email_last_replied":null,"hs_tag_ids":null,"hs_tcv":123,"hs_time_in_66894120":null,"hs_time_in_9567448":null,"hs_time_in_9567449":null,"hs_time_in_appointmentscheduled":66509255417,"hs_time_in_closedlost":null,"hs_time_in_closedwon":7438493326,"hs_time_in_contractsent":0,"hs_time_in_customclosedwonstage":null,"hs_time_in_decisionmakerboughtin":0,"hs_time_in_presentationscheduled":0,"hs_time_in_qualifiedtobuy":0,"hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"12282590","hs_was_imported":null,"hubspot_owner_assigneddate":"2021-02-23T20:21:05.293000+00:00","hubspot_owner_id":"52550153","hubspot_team_id":null,"notes_last_contacted":null,"notes_last_updated":null,"notes_next_activity_date":null,"num_associated_contacts":0,"num_contacted_notes":null,"num_notes":null,"pipeline":"default"},"createdAt":"2021-02-23T20:20:10.826Z","updatedAt":"2023-04-04T15:08:41.191Z","archived":true,"archivedAt":"2023-04-04T15:12:51.602Z"},"emitted_at":1688059414130} -{"stream": "email_events", "data": {"id": "cd276838-3925-4649-9a38-2b61761362c4", "source": "SOURCE_HUBSPOT_CUSTOMER", "subscriptions": [{"id": 23704464, "status": "SUBSCRIBED", "legalBasisChange": {"legalBasisType": "LEGITIMATE_INTEREST_CLIENT", "legalBasisExplanation": "test", "optState": "OPT_IN"}}], "recipient": "testingapicontact_0@hubspot.com", "created": 1675123491624, "sourceId": "Self Service Resubscription", "type": "STATUSCHANGE", "portalId": 8727216, "appId": 0, "emailCampaignId": 0}, "emitted_at": 1685387181597} -{"stream": "email_events", "data": {"appName": "Batch", "id": "4dcb9481-77e6-42d8-ab46-c1e3ed9395db", "emailCampaignId": 243851494, "recipient": "test@test.com", "portalId": 8727216, "appId": 113, "created": 1675121674226, "dropMessage": "Email not allowed to be sent to the specified recipient in a sandbox portal", "dropReason": "VALIDATION_FAILED", "from": "\"Team Airbyte\" ", "cc": [], "bcc": [], "replyTo": ["integration-test@airbyte.io"], "subject": "test", "type": "DROPPED", "sentBy": {"id": "4dcb9481-77e6-42d8-ab46-c1e3ed9395db", "created": 1675121674226}, "smtpId": null}, "emitted_at": 1685387181598} -{"stream": "email_events", "data": {"appName": "BatchTest", "location": {"country": "UNITED STATES", "state": "california", "city": "mountain view", "latitude": 37.40599, "longitude": -122.078514, "zipcode": "94043"}, "id": "b750d85b-fec1-38f4-80e1-47cb01672e72", "duration": 0, "deviceType": "COMPUTER", "created": 1634042988255, "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246 Mozilla/5.0", "browser": {"name": "Microsoft Edge 12.246", "family": "Microsoft Edge", "producer": "Microsoft Corporation.", "producerUrl": "https://www.microsoft.com/about/", "type": "Browser", "url": "https://en.wikipedia.org/wiki/Microsoft_Edge", "version": ["12.246"]}, "type": "OPEN", "recipient": "integration-test@airbyte.io", "sentBy": {"id": "e98ee9c2-9ea4-4f7c-84e3-caace1c0a68b", "created": 1634042982506}, "smtpId": null, "portalId": 8727216, "filteredEvent": true, "appId": 20053, "emailCampaignId": 2}, "emitted_at": 1687291149869} +{"stream": "email_events", "data": {"id": "cd276838-3925-4649-9a38-2b61761362c4", "source": "SOURCE_HUBSPOT_CUSTOMER", "recipient": "testingapicontact_0@hubspot.com", "subscriptions": [{"id": 23704464, "status": "SUBSCRIBED", "legalBasisChange": {"legalBasisType": "LEGITIMATE_INTEREST_CLIENT", "legalBasisExplanation": "test", "optState": "OPT_IN"}}], "sourceId": "Self Service Resubscription", "created": 1675123491624, "type": "STATUSCHANGE", "portalId": 8727216, "appId": 0, "emailCampaignId": 0}, "emitted_at": 1688977609453} {"stream": "email_subscriptions", "data": {"id": 23704464, "portalId": 8727216, "name": "Test sub", "description": "Test sub", "active": true, "internal": false, "category": "Marketing", "channel": "Email", "businessUnitId": 0}, "emitted_at": 1685387183303} {"stream": "email_subscriptions", "data": {"id": 10798197, "portalId": 8727216, "name": "DONT USE ME", "description": "Receive feedback requests and customer service information.", "active": true, "internal": true, "category": "Service", "channel": "Email", "order": 0, "internalName": "SERVICE_HUB_FEEDBACK", "businessUnitId": 0}, "emitted_at": 1685387183304} {"stream": "email_subscriptions", "data": {"id": 11890603, "portalId": 8727216, "name": "DONT USE ME ", "description": "TTTT", "active": true, "internal": false, "category": "", "channel": "", "order": 1, "businessUnitId": 0}, "emitted_at": 1685387183304} @@ -39,9 +33,9 @@ {"stream": "forms", "data": {"id": "03e69987-1dcb-4d55-9cb6-d3812ac00ee6", "name": "New form 93", "createdAt": "2023-02-13T16:56:33.108Z", "updatedAt": "2023-02-13T16:56:33.108Z", "archived": false, "fieldGroups": [{"groupType": "default_group", "richTextType": "text", "fields": [{"objectTypeId": "0-1", "name": "email", "label": "Email", "required": true, "hidden": false, "fieldType": "email", "validation": {"blockedEmailDomains": [], "useDefaultBlockList": false}}]}], "configuration": {"language": "en", "cloneable": true, "postSubmitAction": {"type": "thank_you", "value": "Thanks for submitting the form."}, "editable": true, "archivable": true, "recaptchaEnabled": false, "notifyContactOwner": false, "notifyRecipients": ["12282590"], "createNewContactForNewEmail": false, "prePopulateKnownValues": true, "allowLinkToResetKnownValues": false}, "displayOptions": {"renderRawHtml": false, "theme": "default_style", "submitButtonText": "Submit", "style": {"fontFamily": "arial, helvetica, sans-serif", "backgroundWidth": "100%", "labelTextColor": "#33475b", "labelTextSize": "14px", "helpTextColor": "#7C98B6", "helpTextSize": "11px", "legalConsentTextColor": "#33475b", "legalConsentTextSize": "14px", "submitColor": "#ff7a59", "submitAlignment": "left", "submitFontColor": "#ffffff", "submitSize": "12px"}, "cssClass": "hs-form stacked"}, "legalConsentOptions": {"type": "implicit_consent_to_process", "communicationConsentText": "integrationtest is committed to protecting and respecting your privacy, and we\u2019ll only use your personal information to administer your account and to provide the products and services you requested from us. From time to time, we would like to contact you about our products and services, as well as other content that may be of interest to you. If you consent to us contacting you for this purpose, please tick below to say how you would like us to contact you:", "communicationsCheckboxes": [{"required": false, "subscriptionTypeId": 23704464, "label": "I agree to receive other communications from [MAIN] integration test account."}], "privacyText": "You may unsubscribe from these communications at any time. For more information on how to unsubscribe, our privacy practices, and how we are committed to protecting and respecting your privacy, please review our Privacy Policy.", "consentToProcessText": "By clicking submit below, you consent to allow integrationtest to store and process the personal information submitted above to provide you the content requested."}, "formType": "hubspot"}, "emitted_at": 1685387195424} {"stream": "forms", "data": {"id": "0a7fd84f-471e-444a-a4e0-ca36d39f8af7", "name": "New form 27", "createdAt": "2023-02-13T16:45:22.640Z", "updatedAt": "2023-02-13T16:45:22.640Z", "archived": false, "fieldGroups": [{"groupType": "default_group", "richTextType": "text", "fields": [{"objectTypeId": "0-1", "name": "email", "label": "Email", "required": true, "hidden": false, "fieldType": "email", "validation": {"blockedEmailDomains": [], "useDefaultBlockList": false}}]}], "configuration": {"language": "en", "cloneable": true, "postSubmitAction": {"type": "thank_you", "value": "Thanks for submitting the form."}, "editable": true, "archivable": true, "recaptchaEnabled": false, "notifyContactOwner": false, "notifyRecipients": ["12282590"], "createNewContactForNewEmail": false, "prePopulateKnownValues": true, "allowLinkToResetKnownValues": false}, "displayOptions": {"renderRawHtml": false, "theme": "default_style", "submitButtonText": "Submit", "style": {"fontFamily": "arial, helvetica, sans-serif", "backgroundWidth": "100%", "labelTextColor": "#33475b", "labelTextSize": "14px", "helpTextColor": "#7C98B6", "helpTextSize": "11px", "legalConsentTextColor": "#33475b", "legalConsentTextSize": "14px", "submitColor": "#ff7a59", "submitAlignment": "left", "submitFontColor": "#ffffff", "submitSize": "12px"}, "cssClass": "hs-form stacked"}, "legalConsentOptions": {"type": "implicit_consent_to_process", "communicationConsentText": "integrationtest is committed to protecting and respecting your privacy, and we\u2019ll only use your personal information to administer your account and to provide the products and services you requested from us. From time to time, we would like to contact you about our products and services, as well as other content that may be of interest to you. If you consent to us contacting you for this purpose, please tick below to say how you would like us to contact you:", "communicationsCheckboxes": [{"required": false, "subscriptionTypeId": 23704464, "label": "I agree to receive other communications from [MAIN] integration test account."}], "privacyText": "You may unsubscribe from these communications at any time. For more information on how to unsubscribe, our privacy practices, and how we are committed to protecting and respecting your privacy, please review our Privacy Policy.", "consentToProcessText": "By clicking submit below, you consent to allow integrationtest to store and process the personal information submitted above to provide you the content requested."}, "formType": "hubspot"}, "emitted_at": 1685387195425} {"stream": "forms", "data": {"id": "0bf0c00f-e68d-4de2-8cd9-d9b04e41072f", "name": "New form 55", "createdAt": "2023-02-13T16:50:27.345Z", "updatedAt": "2023-02-13T16:50:27.345Z", "archived": false, "fieldGroups": [{"groupType": "default_group", "richTextType": "text", "fields": [{"objectTypeId": "0-1", "name": "email", "label": "Email", "required": true, "hidden": false, "fieldType": "email", "validation": {"blockedEmailDomains": [], "useDefaultBlockList": false}}]}], "configuration": {"language": "en", "cloneable": true, "postSubmitAction": {"type": "thank_you", "value": "Thanks for submitting the form."}, "editable": true, "archivable": true, "recaptchaEnabled": false, "notifyContactOwner": false, "notifyRecipients": ["12282590"], "createNewContactForNewEmail": false, "prePopulateKnownValues": true, "allowLinkToResetKnownValues": false}, "displayOptions": {"renderRawHtml": false, "theme": "default_style", "submitButtonText": "Submit", "style": {"fontFamily": "arial, helvetica, sans-serif", "backgroundWidth": "100%", "labelTextColor": "#33475b", "labelTextSize": "14px", "helpTextColor": "#7C98B6", "helpTextSize": "11px", "legalConsentTextColor": "#33475b", "legalConsentTextSize": "14px", "submitColor": "#ff7a59", "submitAlignment": "left", "submitFontColor": "#ffffff", "submitSize": "12px"}, "cssClass": "hs-form stacked"}, "legalConsentOptions": {"type": "implicit_consent_to_process", "communicationConsentText": "integrationtest is committed to protecting and respecting your privacy, and we\u2019ll only use your personal information to administer your account and to provide the products and services you requested from us. From time to time, we would like to contact you about our products and services, as well as other content that may be of interest to you. If you consent to us contacting you for this purpose, please tick below to say how you would like us to contact you:", "communicationsCheckboxes": [{"required": false, "subscriptionTypeId": 23704464, "label": "I agree to receive other communications from [MAIN] integration test account."}], "privacyText": "You may unsubscribe from these communications at any time. For more information on how to unsubscribe, our privacy practices, and how we are committed to protecting and respecting your privacy, please review our Privacy Policy.", "consentToProcessText": "By clicking submit below, you consent to allow integrationtest to store and process the personal information submitted above to provide you the content requested."}, "formType": "hubspot"}, "emitted_at": 1685387195425} -{"stream":"goals","data":{"id":"221880757009","properties":{"hs__migration_soft_delete":null,"hs_ad_account_asset_ids":null,"hs_ad_campaign_asset_ids":null,"hs_all_accessible_team_ids":null,"hs_all_assigned_business_unit_ids":null,"hs_all_owner_ids":null,"hs_all_team_ids":null,"hs_assignee_team_id":null,"hs_assignee_user_id":26748728,"hs_contact_lifecycle_stage":null,"hs_created_by_user_id":12282590,"hs_createdate":"2023-04-10T13:57:36.691000+00:00","hs_currency":null,"hs_deal_pipeline_ids":null,"hs_edit_updates_notification_frequency":"weekly","hs_end_date":null,"hs_end_datetime":"2023-07-31T23:59:59.999000+00:00","hs_fiscal_year_offset":0,"hs_goal_name":"Integration Test Goal Hubspot","hs_goal_target_group_id":221880750627,"hs_goal_type":"average_ticket_response_time","hs_group_correlation_uuid":"5c49f251-be20-43c6-87c7-dd273732b3a4","hs_is_forecastable":"true","hs_is_legacy":null,"hs_kpi_display_unit":"hour","hs_kpi_filter_groups":"[{\"filters\":[{\"property\":\"hubspot_owner_id\",\"operator\":\"EQ\",\"value\":\"111730024\"},{\"property\":\"hs_pipeline\",\"operator\":\"IN\",\"values\":[\"0\"]}]}]","hs_kpi_metric_type":"AVG","hs_kpi_object_type":"TICKET","hs_kpi_object_type_id":"0-5","hs_kpi_progress_percent":null,"hs_kpi_property_name":"time_to_first_agent_reply","hs_kpi_single_object_custom_goal_type_name":null,"hs_kpi_time_period_property":"createdate","hs_kpi_tracking_method":"LOWER_IS_BETTER","hs_kpi_unit_type":"duration","hs_kpi_value":0,"hs_kpi_value_calculated_at":null,"hs_kpi_value_last_calculated_at":"2023-04-10T22:31:24.463000+00:00","hs_lastmodifieddate":"2023-05-18T21:29:49.662000+00:00","hs_legacy_active":null,"hs_legacy_created_at":null,"hs_legacy_created_by":null,"hs_legacy_quarterly_target_composite_id":null,"hs_legacy_sql_id":null,"hs_legacy_unique_sql_id":null,"hs_legacy_updated_at":null,"hs_legacy_updated_by":null,"hs_merged_object_ids":null,"hs_migration_soft_delete":null,"hs_milestone":"monthly","hs_object_id":221880757009,"hs_outcome":"in_progress","hs_owner_ids_of_all_owners":"111730024","hs_participant_type":"users","hs_pipelines":"0","hs_progress_updates_notification_frequency":"weekly","hs_read_only":null,"hs_should_notify_on_achieved":"false","hs_should_notify_on_edit_updates":"false","hs_should_notify_on_exceeded":"false","hs_should_notify_on_kickoff":"false","hs_should_notify_on_missed":"false","hs_should_notify_on_progress_updates":"false","hs_should_recalculate":"false","hs_start_date":null,"hs_start_datetime":"2023-07-01T00:00:00+00:00","hs_static_kpi_filter_groups":"[]","hs_status":"pending","hs_status_display_order":5,"hs_target_amount":0,"hs_target_amount_in_home_currency":0,"hs_team_id":null,"hs_ticket_pipeline_ids":"0","hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_id":null,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"26748728","hs_was_imported":null,"hubspot_owner_assigneddate":null,"hubspot_owner_id":null,"hubspot_team_id":null},"createdAt":"2023-04-10T13:57:36.691Z","updatedAt":"2023-05-18T21:29:49.662Z","archived":false},"emitted_at":1688060209781} -{"stream":"goals","data":{"id":"221880757010","properties":{"hs__migration_soft_delete":null,"hs_ad_account_asset_ids":null,"hs_ad_campaign_asset_ids":null,"hs_all_accessible_team_ids":null,"hs_all_assigned_business_unit_ids":null,"hs_all_owner_ids":null,"hs_all_team_ids":null,"hs_assignee_team_id":null,"hs_assignee_user_id":26748728,"hs_contact_lifecycle_stage":null,"hs_created_by_user_id":12282590,"hs_createdate":"2023-04-10T13:57:36.691000+00:00","hs_currency":null,"hs_deal_pipeline_ids":null,"hs_edit_updates_notification_frequency":"weekly","hs_end_date":null,"hs_end_datetime":"2023-09-30T23:59:59.999000+00:00","hs_fiscal_year_offset":0,"hs_goal_name":"Integration Test Goal Hubspot","hs_goal_target_group_id":221880750627,"hs_goal_type":"average_ticket_response_time","hs_group_correlation_uuid":"5c49f251-be20-43c6-87c7-dd273732b3a4","hs_is_forecastable":"true","hs_is_legacy":null,"hs_kpi_display_unit":"hour","hs_kpi_filter_groups":"[{\"filters\":[{\"property\":\"hubspot_owner_id\",\"operator\":\"EQ\",\"value\":\"111730024\"},{\"property\":\"hs_pipeline\",\"operator\":\"IN\",\"values\":[\"0\"]}]}]","hs_kpi_metric_type":"AVG","hs_kpi_object_type":"TICKET","hs_kpi_object_type_id":"0-5","hs_kpi_progress_percent":null,"hs_kpi_property_name":"time_to_first_agent_reply","hs_kpi_single_object_custom_goal_type_name":null,"hs_kpi_time_period_property":"createdate","hs_kpi_tracking_method":"LOWER_IS_BETTER","hs_kpi_unit_type":"duration","hs_kpi_value":0,"hs_kpi_value_calculated_at":null,"hs_kpi_value_last_calculated_at":"2023-04-10T22:31:22.345000+00:00","hs_lastmodifieddate":"2023-05-18T21:29:49.662000+00:00","hs_legacy_active":null,"hs_legacy_created_at":null,"hs_legacy_created_by":null,"hs_legacy_quarterly_target_composite_id":null,"hs_legacy_sql_id":null,"hs_legacy_unique_sql_id":null,"hs_legacy_updated_at":null,"hs_legacy_updated_by":null,"hs_merged_object_ids":null,"hs_migration_soft_delete":null,"hs_milestone":"monthly","hs_object_id":221880757010,"hs_outcome":"in_progress","hs_owner_ids_of_all_owners":"111730024","hs_participant_type":"users","hs_pipelines":"0","hs_progress_updates_notification_frequency":"weekly","hs_read_only":null,"hs_should_notify_on_achieved":"false","hs_should_notify_on_edit_updates":"false","hs_should_notify_on_exceeded":"false","hs_should_notify_on_kickoff":"false","hs_should_notify_on_missed":"false","hs_should_notify_on_progress_updates":"false","hs_should_recalculate":"false","hs_start_date":null,"hs_start_datetime":"2023-09-01T00:00:00+00:00","hs_static_kpi_filter_groups":"[]","hs_status":"pending","hs_status_display_order":5,"hs_target_amount":0,"hs_target_amount_in_home_currency":0,"hs_team_id":null,"hs_ticket_pipeline_ids":"0","hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_id":null,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"26748728","hs_was_imported":null,"hubspot_owner_assigneddate":null,"hubspot_owner_id":null,"hubspot_team_id":null},"createdAt":"2023-04-10T13:57:36.691Z","updatedAt":"2023-05-18T21:29:49.662Z","archived":false},"emitted_at":1688060209785} -{"stream":"goals","data":{"id":"221880757011","properties":{"hs__migration_soft_delete":null,"hs_ad_account_asset_ids":null,"hs_ad_campaign_asset_ids":null,"hs_all_accessible_team_ids":null,"hs_all_assigned_business_unit_ids":null,"hs_all_owner_ids":null,"hs_all_team_ids":null,"hs_assignee_team_id":null,"hs_assignee_user_id":26748728,"hs_contact_lifecycle_stage":null,"hs_created_by_user_id":12282590,"hs_createdate":"2023-04-10T13:57:36.691000+00:00","hs_currency":null,"hs_deal_pipeline_ids":null,"hs_edit_updates_notification_frequency":"weekly","hs_end_date":null,"hs_end_datetime":"2023-08-31T23:59:59.999000+00:00","hs_fiscal_year_offset":0,"hs_goal_name":"Integration Test Goal Hubspot","hs_goal_target_group_id":221880750627,"hs_goal_type":"average_ticket_response_time","hs_group_correlation_uuid":"5c49f251-be20-43c6-87c7-dd273732b3a4","hs_is_forecastable":"true","hs_is_legacy":null,"hs_kpi_display_unit":"hour","hs_kpi_filter_groups":"[{\"filters\":[{\"property\":\"hubspot_owner_id\",\"operator\":\"EQ\",\"value\":\"111730024\"},{\"property\":\"hs_pipeline\",\"operator\":\"IN\",\"values\":[\"0\"]}]}]","hs_kpi_metric_type":"AVG","hs_kpi_object_type":"TICKET","hs_kpi_object_type_id":"0-5","hs_kpi_progress_percent":null,"hs_kpi_property_name":"time_to_first_agent_reply","hs_kpi_single_object_custom_goal_type_name":null,"hs_kpi_time_period_property":"createdate","hs_kpi_tracking_method":"LOWER_IS_BETTER","hs_kpi_unit_type":"duration","hs_kpi_value":0,"hs_kpi_value_calculated_at":null,"hs_kpi_value_last_calculated_at":"2023-04-10T22:31:20.800000+00:00","hs_lastmodifieddate":"2023-05-18T21:29:49.662000+00:00","hs_legacy_active":null,"hs_legacy_created_at":null,"hs_legacy_created_by":null,"hs_legacy_quarterly_target_composite_id":null,"hs_legacy_sql_id":null,"hs_legacy_unique_sql_id":null,"hs_legacy_updated_at":null,"hs_legacy_updated_by":null,"hs_merged_object_ids":null,"hs_migration_soft_delete":null,"hs_milestone":"monthly","hs_object_id":221880757011,"hs_outcome":"in_progress","hs_owner_ids_of_all_owners":"111730024","hs_participant_type":"users","hs_pipelines":"0","hs_progress_updates_notification_frequency":"weekly","hs_read_only":null,"hs_should_notify_on_achieved":"false","hs_should_notify_on_edit_updates":"false","hs_should_notify_on_exceeded":"false","hs_should_notify_on_kickoff":"false","hs_should_notify_on_missed":"false","hs_should_notify_on_progress_updates":"false","hs_should_recalculate":"false","hs_start_date":null,"hs_start_datetime":"2023-08-01T00:00:00+00:00","hs_static_kpi_filter_groups":"[]","hs_status":"pending","hs_status_display_order":5,"hs_target_amount":0,"hs_target_amount_in_home_currency":0,"hs_team_id":null,"hs_ticket_pipeline_ids":"0","hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_user_id":null,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":"26748728","hs_was_imported":null,"hubspot_owner_assigneddate":null,"hubspot_owner_id":null,"hubspot_team_id":null},"createdAt":"2023-04-10T13:57:36.691Z","updatedAt":"2023-05-18T21:29:49.662Z","archived":false},"emitted_at":1688060209787} +{"stream": "goals", "data": {"id": "221880757009", "properties": {"hs__migration_soft_delete": null, "hs_ad_account_asset_ids": null, "hs_ad_campaign_asset_ids": null, "hs_all_accessible_team_ids": null, "hs_all_assigned_business_unit_ids": null, "hs_all_owner_ids": null, "hs_all_team_ids": null, "hs_assignee_team_id": null, "hs_assignee_user_id": 26748728, "hs_contact_lifecycle_stage": null, "hs_created_by_user_id": 12282590, "hs_createdate": "2023-04-10T13:57:36.691000+00:00", "hs_currency": null, "hs_deal_pipeline_ids": null, "hs_edit_updates_notification_frequency": "weekly", "hs_end_date": null, "hs_end_datetime": "2023-07-31T23:59:59.999000+00:00", "hs_fiscal_year_offset": 0, "hs_goal_name": "Integration Test Goal Hubspot", "hs_goal_target_group_id": 221880750627, "hs_goal_type": "average_ticket_response_time", "hs_group_correlation_uuid": "5c49f251-be20-43c6-87c7-dd273732b3a4", "hs_is_forecastable": "true", "hs_is_legacy": null, "hs_kpi_display_unit": "hour", "hs_kpi_filter_groups": "[{\"filters\":[{\"property\":\"hubspot_owner_id\",\"operator\":\"EQ\",\"value\":\"111730024\"},{\"property\":\"hs_pipeline\",\"operator\":\"IN\",\"values\":[\"0\"]}]}]", "hs_kpi_metric_type": "AVG", "hs_kpi_object_type": "TICKET", "hs_kpi_object_type_id": "0-5", "hs_kpi_progress_percent": null, "hs_kpi_property_name": "time_to_first_agent_reply", "hs_kpi_single_object_custom_goal_type_name": null, "hs_kpi_time_period_property": "createdate", "hs_kpi_tracking_method": "LOWER_IS_BETTER", "hs_kpi_unit_type": "duration", "hs_kpi_value": 0.0, "hs_kpi_value_calculated_at": null, "hs_kpi_value_last_calculated_at": "2023-07-12T22:30:43.771000+00:00", "hs_lastmodifieddate": "2023-07-12T22:30:43.805000+00:00", "hs_legacy_active": null, "hs_legacy_created_at": null, "hs_legacy_created_by": null, "hs_legacy_quarterly_target_composite_id": null, "hs_legacy_sql_id": null, "hs_legacy_unique_sql_id": null, "hs_legacy_updated_at": null, "hs_legacy_updated_by": null, "hs_merged_object_ids": null, "hs_migration_soft_delete": null, "hs_milestone": "monthly", "hs_object_id": 221880757009, "hs_outcome": "in_progress", "hs_owner_ids_of_all_owners": "111730024", "hs_participant_type": "users", "hs_pipelines": "0", "hs_progress_updates_notification_frequency": "weekly", "hs_read_only": null, "hs_should_notify_on_achieved": "false", "hs_should_notify_on_edit_updates": "false", "hs_should_notify_on_exceeded": "false", "hs_should_notify_on_kickoff": "false", "hs_should_notify_on_missed": "false", "hs_should_notify_on_progress_updates": "false", "hs_should_recalculate": "false", "hs_start_date": null, "hs_start_datetime": "2023-07-01T00:00:00+00:00", "hs_static_kpi_filter_groups": "[]", "hs_status": "in_progress", "hs_status_display_order": 1, "hs_target_amount": 0.0, "hs_target_amount_in_home_currency": 0.0, "hs_team_id": null, "hs_ticket_pipeline_ids": "0", "hs_unique_creation_key": null, "hs_updated_by_user_id": 12282590, "hs_user_id": null, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": "26748728", "hs_was_imported": null, "hubspot_owner_assigneddate": null, "hubspot_owner_id": null, "hubspot_team_id": null}, "createdAt": "2023-04-10T13:57:36.691Z", "updatedAt": "2023-07-12T22:30:43.805Z", "archived": false}, "emitted_at": 1689245983526} +{"stream": "goals", "data": {"id": "221880757010", "properties": {"hs__migration_soft_delete": null, "hs_ad_account_asset_ids": null, "hs_ad_campaign_asset_ids": null, "hs_all_accessible_team_ids": null, "hs_all_assigned_business_unit_ids": null, "hs_all_owner_ids": null, "hs_all_team_ids": null, "hs_assignee_team_id": null, "hs_assignee_user_id": 26748728, "hs_contact_lifecycle_stage": null, "hs_created_by_user_id": 12282590, "hs_createdate": "2023-04-10T13:57:36.691000+00:00", "hs_currency": null, "hs_deal_pipeline_ids": null, "hs_edit_updates_notification_frequency": "weekly", "hs_end_date": null, "hs_end_datetime": "2023-09-30T23:59:59.999000+00:00", "hs_fiscal_year_offset": 0, "hs_goal_name": "Integration Test Goal Hubspot", "hs_goal_target_group_id": 221880750627, "hs_goal_type": "average_ticket_response_time", "hs_group_correlation_uuid": "5c49f251-be20-43c6-87c7-dd273732b3a4", "hs_is_forecastable": "true", "hs_is_legacy": null, "hs_kpi_display_unit": "hour", "hs_kpi_filter_groups": "[{\"filters\":[{\"property\":\"hubspot_owner_id\",\"operator\":\"EQ\",\"value\":\"111730024\"},{\"property\":\"hs_pipeline\",\"operator\":\"IN\",\"values\":[\"0\"]}]}]", "hs_kpi_metric_type": "AVG", "hs_kpi_object_type": "TICKET", "hs_kpi_object_type_id": "0-5", "hs_kpi_progress_percent": null, "hs_kpi_property_name": "time_to_first_agent_reply", "hs_kpi_single_object_custom_goal_type_name": null, "hs_kpi_time_period_property": "createdate", "hs_kpi_tracking_method": "LOWER_IS_BETTER", "hs_kpi_unit_type": "duration", "hs_kpi_value": 0.0, "hs_kpi_value_calculated_at": null, "hs_kpi_value_last_calculated_at": "2023-04-10T22:31:22.345000+00:00", "hs_lastmodifieddate": "2023-05-18T21:29:49.662000+00:00", "hs_legacy_active": null, "hs_legacy_created_at": null, "hs_legacy_created_by": null, "hs_legacy_quarterly_target_composite_id": null, "hs_legacy_sql_id": null, "hs_legacy_unique_sql_id": null, "hs_legacy_updated_at": null, "hs_legacy_updated_by": null, "hs_merged_object_ids": null, "hs_migration_soft_delete": null, "hs_milestone": "monthly", "hs_object_id": 221880757010, "hs_outcome": "in_progress", "hs_owner_ids_of_all_owners": "111730024", "hs_participant_type": "users", "hs_pipelines": "0", "hs_progress_updates_notification_frequency": "weekly", "hs_read_only": null, "hs_should_notify_on_achieved": "false", "hs_should_notify_on_edit_updates": "false", "hs_should_notify_on_exceeded": "false", "hs_should_notify_on_kickoff": "false", "hs_should_notify_on_missed": "false", "hs_should_notify_on_progress_updates": "false", "hs_should_recalculate": "false", "hs_start_date": null, "hs_start_datetime": "2023-09-01T00:00:00+00:00", "hs_static_kpi_filter_groups": "[]", "hs_status": "pending", "hs_status_display_order": 5, "hs_target_amount": 0.0, "hs_target_amount_in_home_currency": 0.0, "hs_team_id": null, "hs_ticket_pipeline_ids": "0", "hs_unique_creation_key": null, "hs_updated_by_user_id": 12282590, "hs_user_id": null, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": "26748728", "hs_was_imported": null, "hubspot_owner_assigneddate": null, "hubspot_owner_id": null, "hubspot_team_id": null}, "createdAt": "2023-04-10T13:57:36.691Z", "updatedAt": "2023-05-18T21:29:49.662Z", "archived": false}, "emitted_at": 1689245983528} +{"stream": "goals", "data": {"id": "221880757011", "properties": {"hs__migration_soft_delete": null, "hs_ad_account_asset_ids": null, "hs_ad_campaign_asset_ids": null, "hs_all_accessible_team_ids": null, "hs_all_assigned_business_unit_ids": null, "hs_all_owner_ids": null, "hs_all_team_ids": null, "hs_assignee_team_id": null, "hs_assignee_user_id": 26748728, "hs_contact_lifecycle_stage": null, "hs_created_by_user_id": 12282590, "hs_createdate": "2023-04-10T13:57:36.691000+00:00", "hs_currency": null, "hs_deal_pipeline_ids": null, "hs_edit_updates_notification_frequency": "weekly", "hs_end_date": null, "hs_end_datetime": "2023-08-31T23:59:59.999000+00:00", "hs_fiscal_year_offset": 0, "hs_goal_name": "Integration Test Goal Hubspot", "hs_goal_target_group_id": 221880750627, "hs_goal_type": "average_ticket_response_time", "hs_group_correlation_uuid": "5c49f251-be20-43c6-87c7-dd273732b3a4", "hs_is_forecastable": "true", "hs_is_legacy": null, "hs_kpi_display_unit": "hour", "hs_kpi_filter_groups": "[{\"filters\":[{\"property\":\"hubspot_owner_id\",\"operator\":\"EQ\",\"value\":\"111730024\"},{\"property\":\"hs_pipeline\",\"operator\":\"IN\",\"values\":[\"0\"]}]}]", "hs_kpi_metric_type": "AVG", "hs_kpi_object_type": "TICKET", "hs_kpi_object_type_id": "0-5", "hs_kpi_progress_percent": null, "hs_kpi_property_name": "time_to_first_agent_reply", "hs_kpi_single_object_custom_goal_type_name": null, "hs_kpi_time_period_property": "createdate", "hs_kpi_tracking_method": "LOWER_IS_BETTER", "hs_kpi_unit_type": "duration", "hs_kpi_value": 0.0, "hs_kpi_value_calculated_at": null, "hs_kpi_value_last_calculated_at": "2023-04-10T22:31:20.800000+00:00", "hs_lastmodifieddate": "2023-05-18T21:29:49.662000+00:00", "hs_legacy_active": null, "hs_legacy_created_at": null, "hs_legacy_created_by": null, "hs_legacy_quarterly_target_composite_id": null, "hs_legacy_sql_id": null, "hs_legacy_unique_sql_id": null, "hs_legacy_updated_at": null, "hs_legacy_updated_by": null, "hs_merged_object_ids": null, "hs_migration_soft_delete": null, "hs_milestone": "monthly", "hs_object_id": 221880757011, "hs_outcome": "in_progress", "hs_owner_ids_of_all_owners": "111730024", "hs_participant_type": "users", "hs_pipelines": "0", "hs_progress_updates_notification_frequency": "weekly", "hs_read_only": null, "hs_should_notify_on_achieved": "false", "hs_should_notify_on_edit_updates": "false", "hs_should_notify_on_exceeded": "false", "hs_should_notify_on_kickoff": "false", "hs_should_notify_on_missed": "false", "hs_should_notify_on_progress_updates": "false", "hs_should_recalculate": "false", "hs_start_date": null, "hs_start_datetime": "2023-08-01T00:00:00+00:00", "hs_static_kpi_filter_groups": "[]", "hs_status": "pending", "hs_status_display_order": 5, "hs_target_amount": 0.0, "hs_target_amount_in_home_currency": 0.0, "hs_team_id": null, "hs_ticket_pipeline_ids": "0", "hs_unique_creation_key": null, "hs_updated_by_user_id": 12282590, "hs_user_id": null, "hs_user_ids_of_all_notification_followers": null, "hs_user_ids_of_all_notification_unfollowers": null, "hs_user_ids_of_all_owners": "26748728", "hs_was_imported": null, "hubspot_owner_assigneddate": null, "hubspot_owner_id": null, "hubspot_team_id": null}, "createdAt": "2023-04-10T13:57:36.691Z", "updatedAt": "2023-05-18T21:29:49.662Z", "archived": false}, "emitted_at": 1689245983528} {"stream":"line_items","data":{"id":"4617680695","properties":{"amount":34,"createdate":"2023-01-31T00:31:29.812000+00:00","description":null,"discount":null,"hs_acv":34,"hs_all_accessible_team_ids":null,"hs_all_assigned_business_unit_ids":null,"hs_all_owner_ids":null,"hs_all_team_ids":null,"hs_allow_buyer_selected_quantity":null,"hs_arr":0,"hs_billing_start_delay_days":null,"hs_billing_start_delay_months":null,"hs_billing_start_delay_type":null,"hs_cost_of_goods_sold":null,"hs_created_by_user_id":12282590,"hs_createdate":null,"hs_discount_percentage":null,"hs_external_id":null,"hs_images":null,"hs_lastmodifieddate":"2023-01-31T00:31:29.812000+00:00","hs_line_item_currency_code":null,"hs_margin":34,"hs_margin_acv":34,"hs_margin_arr":0,"hs_margin_mrr":0,"hs_margin_tcv":34,"hs_merged_object_ids":null,"hs_mrr":0,"hs_object_id":4617680695,"hs_position_on_quote":0,"hs_pre_discount_amount":34,"hs_product_id":null,"hs_product_type":null,"hs_read_only":null,"hs_recurring_billing_end_date":null,"hs_recurring_billing_number_of_payments":1,"hs_recurring_billing_period":null,"hs_recurring_billing_start_date":null,"hs_recurring_billing_terms":null,"hs_sku":null,"hs_sync_amount":null,"hs_tcv":34,"hs_term_in_months":null,"hs_total_discount":0,"hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_url":null,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":null,"hs_variant_id":null,"hs_was_imported":null,"hubspot_owner_assigneddate":null,"hubspot_owner_id":null,"hubspot_team_id":null,"name":"test","price":34,"quantity":1,"recurringbillingfrequency":null,"tax":null,"test":null,"test_product_price":null},"createdAt":"2023-01-31T00:31:29.812Z","updatedAt":"2023-01-31T00:31:29.812Z","archived":false},"emitted_at":1688060433363} {"stream":"line_items","data":{"id":"5153237390","properties":{"amount":95,"createdate":"2023-04-04T21:28:36.663000+00:00","description":"Baseball hat, medium","discount":5,"hs_acv":95,"hs_all_accessible_team_ids":null,"hs_all_assigned_business_unit_ids":null,"hs_all_owner_ids":null,"hs_all_team_ids":null,"hs_allow_buyer_selected_quantity":null,"hs_arr":0,"hs_billing_start_delay_days":null,"hs_billing_start_delay_months":null,"hs_billing_start_delay_type":null,"hs_cost_of_goods_sold":5,"hs_created_by_user_id":12282590,"hs_createdate":null,"hs_discount_percentage":null,"hs_external_id":null,"hs_images":null,"hs_lastmodifieddate":"2023-04-04T21:28:36.663000+00:00","hs_line_item_currency_code":null,"hs_margin":90,"hs_margin_acv":90,"hs_margin_arr":0,"hs_margin_mrr":0,"hs_margin_tcv":90,"hs_merged_object_ids":null,"hs_mrr":0,"hs_object_id":5153237390,"hs_position_on_quote":0,"hs_pre_discount_amount":100,"hs_product_id":646778218,"hs_product_type":null,"hs_read_only":null,"hs_recurring_billing_end_date":null,"hs_recurring_billing_number_of_payments":1,"hs_recurring_billing_period":null,"hs_recurring_billing_start_date":null,"hs_recurring_billing_terms":null,"hs_sku":null,"hs_sync_amount":null,"hs_tcv":95,"hs_term_in_months":null,"hs_total_discount":5,"hs_unique_creation_key":null,"hs_updated_by_user_id":12282590,"hs_url":null,"hs_user_ids_of_all_notification_followers":null,"hs_user_ids_of_all_notification_unfollowers":null,"hs_user_ids_of_all_owners":null,"hs_variant_id":null,"hs_was_imported":null,"hubspot_owner_assigneddate":null,"hubspot_owner_id":null,"hubspot_team_id":null,"name":"Blue Hat","price":100,"quantity":1,"recurringbillingfrequency":null,"tax":null,"test":null,"test_product_price":null},"createdAt":"2023-04-04T21:28:36.663Z","updatedAt":"2023-04-04T21:28:36.663Z","archived":false},"emitted_at":1688060433365} {"stream":"marketing_emails","data":{"ab":false,"abHoursToWait":4,"abSampleSizeDefault":null,"abSamplingDefault":null,"abSuccessMetric":null,"abTestPercentage":50,"abVariation":false,"absoluteUrl":"http://integrationtest-dev-8727216-8727216.hs-sites.com/-temporary-slug-86812db1-e3c8-43cd-ae80-69a0934cd1de","allEmailCampaignIds":[243851494],"analyticsPageId":"100523515217","analyticsPageType":"email","archivedAt":0,"archivedInDashboard":false,"audienceAccess":"PUBLIC","author":"integration-test@airbyte.io","authorName":"Team-1 Airbyte","blogRssSettings":null,"canSpamSettingsId":36765207029,"categoryId":2,"contentAccessRuleIds":[],"contentAccessRuleTypes":[],"contentTypeCategory":2,"createPage":false,"created":1675121582718,"createdById":12282590,"currentState":"PUBLISHED","currentlyPublished":true,"customReplyTo":"","customReplyToEnabled":false,"domain":"","emailBody":"{% content_attribute \"email_body\" %}{{ default_email_body }}{% end_content_attribute %}","emailNote":"","emailTemplateMode":"DRAG_AND_DROP","emailType":"BATCH_EMAIL","emailbodyPlaintext":"","feedbackSurveyId":null,"flexAreas":{"main":{"boxed":false,"isSingleColumnFullWidth":false,"sections":[{"columns":[{"id":"column-0-0","widgets":["module-0-0-0"],"width":12}],"id":"section-0","style":{"backgroundColor":"#eaf0f6","backgroundType":"CONTENT","paddingBottom":"10px","paddingTop":"10px"}},{"columns":[{"id":"column-1-0","widgets":["module-1-0-0"],"width":12}],"id":"section-1","style":{"backgroundType":"CONTENT","paddingBottom":"30px","paddingTop":"30px"}},{"columns":[{"id":"column-2-0","widgets":["module-2-0-0"],"width":12}],"id":"section-2","style":{"backgroundColor":"","backgroundType":"CONTENT","paddingBottom":"20px","paddingTop":"20px"}}]}},"freezeDate":1675121645993,"fromName":"Team Airbyte","hasContentAccessRules":false,"htmlTitle":"","id":100523515217,"isCreatedFomSandboxSync":false,"isGraymailSuppressionEnabled":true,"isInstanceLayoutPage":false,"isPublished":true,"isRecipientFatigueSuppressionEnabled":null,"language":"en","layoutSections":{},"liveDomain":"integrationtest-dev-8727216-8727216.hs-sites.com","mailingListsExcluded":[],"mailingListsIncluded":[],"maxRssEntries":5,"metaDescription":"","name":"test","pageExpiryEnabled":false,"pageRedirected":false,"pastMabExperimentIds":[],"portalId":8727216,"previewKey":"nlkwziGL","primaryEmailCampaignId":243851494,"processingStatus":"PUBLISHED","publishDate":1675121645997,"publishImmediately":true,"publishedAt":1675121646297,"publishedByEmail":"integration-test@airbyte.io","publishedById":12282590,"publishedByName":"Team-1 Airbyte","publishedUrl":"http://integrationtest-dev-8727216-8727216.hs-sites.com/-temporary-slug-86812db1-e3c8-43cd-ae80-69a0934cd1de","replyTo":"integration-test@airbyte.io","resolvedDomain":"integrationtest-dev-8727216-8727216.hs-sites.com","rssEmailByText":"By","rssEmailClickThroughText":"Read more »","rssEmailCommentText":"Comment »","rssEmailEntryTemplateEnabled":false,"rssEmailImageMaxWidth":0,"rssEmailUrl":"","sections":{},"securityState":"NONE","selected":0,"slug":"-temporary-slug-86812db1-e3c8-43cd-ae80-69a0934cd1de","smartEmailFields":{},"state":"PUBLISHED","stats":{"counters":{"sent":0,"open":0,"delivered":0,"bounce":0,"unsubscribed":0,"click":0,"reply":0,"dropped":1,"selected":1,"spamreport":0,"suppressed":0,"hardbounced":0,"softbounced":0,"pending":0,"contactslost":0,"notsent":1},"deviceBreakdown":{"open_device_type":{"computer":0,"mobile":0,"unknown":0},"click_device_type":{"computer":0,"mobile":0,"unknown":0}},"failedToLoad":false,"qualifierStats":{},"ratios":{"clickratio":0,"clickthroughratio":0,"deliveredratio":0,"openratio":0,"replyratio":0,"unsubscribedratio":0,"spamreportratio":0,"bounceratio":0,"hardbounceratio":0,"softbounceratio":0,"contactslostratio":0,"pendingratio":0,"notsentratio":100}},"styleSettings":{"background_color":"#EAF0F6","background_image":null,"background_image_type":null,"body_border_color":"#EAF0F6","body_border_color_choice":"BORDER_MANUAL","body_border_width":"1","body_color":"#ffffff","color_picker_favorite1":null,"color_picker_favorite2":null,"color_picker_favorite3":null,"color_picker_favorite4":null,"color_picker_favorite5":null,"color_picker_favorite6":null,"email_body_padding":null,"email_body_width":null,"heading_one_font":{"bold":null,"color":null,"font":null,"font_style":{},"italic":null,"size":"28","underline":null},"heading_two_font":{"bold":null,"color":null,"font":null,"font_style":{},"italic":null,"size":"22","underline":null},"links_font":{"bold":false,"color":"#00a4bd","font":null,"font_style":{},"italic":false,"size":null,"underline":true},"primary_accent_color":null,"primary_font":"Arial, sans-serif","primary_font_color":"#23496d","primary_font_line_height":null,"primary_font_size":"15","secondary_accent_color":null,"secondary_font":"Arial, sans-serif","secondary_font_color":"#23496d","secondary_font_line_height":null,"secondary_font_size":"12","use_email_client_default_settings":false,"user_module_defaults":{"button_email":{"background_color":"#00a4bd","corner_radius":8,"font":"Arial, sans-serif","font_color":"#ffffff","font_size":16,"font_style":{"color":"#ffffff","font":"Arial, sans-serif","size":{"units":"px","value":16},"styles":{"bold":false,"italic":false,"underline":false}}},"email_divider":{"color":{"color":"#23496d","opacity":100},"height":1,"line_type":"solid"}}},"subcategory":"batch","subject":"test","subscription":23704464,"subscriptionName":"Test sub","teamPerms":[],"templatePath":"@hubspot/email/dnd/welcome.html","transactional":false,"translations":{},"unpublishedAt":0,"updated":1675121702583,"updatedById":12282590,"url":"http://integrationtest-dev-8727216-8727216.hs-sites.com/-temporary-slug-86812db1-e3c8-43cd-ae80-69a0934cd1de","useRssHeadlineAsSubject":false,"userPerms":[],"vidsExcluded":[],"vidsIncluded":[2501],"visibleToAll":true},"emitted_at":1688060624527} From 1f3bd5632a065878fce160c1c77e73ddba637400 Mon Sep 17 00:00:00 2001 From: Arsen Losenko <20901439+arsenlosenko@users.noreply.github.com> Date: Thu, 13 Jul 2023 15:14:30 +0300 Subject: [PATCH 56/63] Source Pipedrive: update expected records (#28272) --- .../integration_tests/expected_records.jsonl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/airbyte-integrations/connectors/source-pipedrive/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-pipedrive/integration_tests/expected_records.jsonl index d261083c3f5f..0b32389953fe 100644 --- a/airbyte-integrations/connectors/source-pipedrive/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-pipedrive/integration_tests/expected_records.jsonl @@ -38,12 +38,12 @@ {"stream": "permission_sets", "data": {"id": "79b42bf0-fb6d-11eb-a18f-a7e2db4435cf", "name": "Deals admin", "assignment_count": 1, "app": "sales", "type": "admin"}, "emitted_at": 1683115313946} {"stream": "permission_sets", "data": {"id": "79b42bf1-fb6d-11eb-a18f-a7e2db4435cf", "name": "Deals regular user", "assignment_count": 4, "app": "sales", "type": "regular"}, "emitted_at": 1683115313947} {"stream": "permission_sets", "data": {"id": "fa17fff0-db56-11ec-93f1-e9cfc58fcd59", "name": "Global admin", "assignment_count": 1, "app": "global", "type": "admin"}, "emitted_at": 1683115313947} -{"stream": "persons", "data": {"id": 5, "company_id": 7780468, "owner_id": 11884360, "org_id": 1, "name": "User2 Sample", "first_name": "User2", "last_name": "Sample", "open_deals_count": 2, "related_open_deals_count": 0, "closed_deals_count": 0, "related_closed_deals_count": 0, "participant_open_deals_count": 0, "participant_closed_deals_count": 0, "email_messages_count": 0, "activities_count": 0, "done_activities_count": 0, "undone_activities_count": 0, "files_count": 0, "notes_count": 0, "followers_count": 1, "won_deals_count": 0, "related_won_deals_count": 0, "lost_deals_count": 0, "related_lost_deals_count": 0, "active_flag": true, "phone": [{"label": "work", "value": "+14443332266", "primary": true}], "email": [{"label": "work", "value": "user2.sample.airbyte@gmail.com", "primary": true}], "first_char": "u", "update_time": "2023-02-22 10:44:49", "delete_time": null, "add_time": "2023-02-22 08:13:09", "visible_to": "3", "picture_id": null, "next_activity_date": null, "next_activity_time": null, "next_activity_id": null, "last_activity_id": null, "last_activity_date": null, "last_incoming_mail_time": null, "last_outgoing_mail_time": null, "label": 3, "picture_128_url": null, "org_name": "Test Organization1", "cc_email": "airbyte-sandbox@pipedrivemail.com", "owner_name": "Team Airbyte"}, "emitted_at": 1683115315035} -{"stream": "persons", "data": {"id": 6, "company_id": 7780468, "owner_id": 11884360, "org_id": 1, "name": "User3 Sample", "first_name": "User3", "last_name": "Sample", "open_deals_count": 1, "related_open_deals_count": 0, "closed_deals_count": 0, "related_closed_deals_count": 0, "participant_open_deals_count": 0, "participant_closed_deals_count": 0, "email_messages_count": 0, "activities_count": 0, "done_activities_count": 0, "undone_activities_count": 0, "files_count": 0, "notes_count": 0, "followers_count": 1, "won_deals_count": 0, "related_won_deals_count": 0, "lost_deals_count": 0, "related_lost_deals_count": 0, "active_flag": true, "phone": [{"label": "work", "value": "+15554442233", "primary": true}], "email": [{"label": "work", "value": "user3.sample.airbyte@outlook.com", "primary": true}], "first_char": "u", "update_time": "2023-02-22 10:45:52", "delete_time": null, "add_time": "2023-02-22 08:13:53", "visible_to": "3", "picture_id": null, "next_activity_date": null, "next_activity_time": null, "next_activity_id": null, "last_activity_id": null, "last_activity_date": null, "last_incoming_mail_time": null, "last_outgoing_mail_time": null, "label": 2, "picture_128_url": null, "org_name": "Test Organization1", "cc_email": "airbyte-sandbox@pipedrivemail.com", "owner_name": "Team Airbyte"}, "emitted_at": 1683115315037} -{"stream": "persons", "data": {"id": 2, "company_id": 7780468, "owner_id": 11884360, "org_id": 11, "name": "User4 Sample", "first_name": "User4", "last_name": "Sample", "open_deals_count": 2, "related_open_deals_count": 0, "closed_deals_count": 0, "related_closed_deals_count": 0, "participant_open_deals_count": 0, "participant_closed_deals_count": 0, "email_messages_count": 0, "activities_count": 1, "done_activities_count": 0, "undone_activities_count": 1, "files_count": 0, "notes_count": 0, "followers_count": 1, "won_deals_count": 0, "related_won_deals_count": 0, "lost_deals_count": 0, "related_lost_deals_count": 0, "active_flag": true, "phone": [{"label": "work", "value": "+16665552233", "primary": true}], "email": [{"label": "work", "value": "user4.sample.airbyte@outlook.com", "primary": true}], "first_char": "u", "update_time": "2023-02-22 11:46:49", "delete_time": null, "add_time": "2021-07-06 15:04:21", "visible_to": "3", "picture_id": null, "next_activity_date": "2023-03-15", "next_activity_time": "11:30:00", "next_activity_id": 24, "last_activity_id": null, "last_activity_date": null, "last_incoming_mail_time": null, "last_outgoing_mail_time": null, "label": 1, "picture_128_url": null, "org_name": "Test Organization 4", "cc_email": "airbyte-sandbox@pipedrivemail.com", "owner_name": "Team Airbyte"}, "emitted_at": 1683115315038} -{"stream":"person_fields","data":{"id":9039,"key":"name","name":"Name","order_nr":0,"field_type":"varchar","json_column_flag":false,"add_time":"2020-12-10 07:23:48","update_time":"2020-12-10 07:23:48","last_updated_by_user_id":null,"edit_flag":false,"details_visible_flag":false,"add_visible_flag":true,"important_flag":false,"bulk_edit_allowed":true,"filtering_allowed":true,"sortable_flag":true,"searchable_flag":false,"active_flag":true,"use_field":"id","link":"/person/","mandatory_flag":true},"emitted_at":1687176297747} -{"stream":"person_fields","data":{"id":9040,"key":"label","name":"Label","order_nr":0,"field_type":"enum","json_column_flag":false,"add_time":"2020-12-10 07:23:48","update_time":"2020-12-10 07:23:48","last_updated_by_user_id":null,"edit_flag":false,"details_visible_flag":true,"add_visible_flag":true,"important_flag":false,"bulk_edit_allowed":true,"filtering_allowed":true,"sortable_flag":true,"searchable_flag":false,"active_flag":true,"options":[{"id":1,"label":"Customer","color":"green"},{"id":2,"label":"Hot lead","color":"red"},{"id":3,"label":"Warm lead","color":"yellow"},{"id":4,"label":"Cold lead","color":"blue"}],"mandatory_flag":false},"emitted_at":1687176297747} -{"stream":"person_fields","data":{"id":9064,"key":"first_name","name":"First name","order_nr":0,"field_type":"varchar","json_column_flag":false,"add_time":"2020-12-10 07:23:49","update_time":"2020-12-10 07:23:49","last_updated_by_user_id":null,"edit_flag":false,"details_visible_flag":true,"add_visible_flag":false,"important_flag":false,"bulk_edit_allowed":true,"filtering_allowed":true,"sortable_flag":true,"searchable_flag":false,"active_flag":true,"mandatory_flag":false},"emitted_at":1687176297754} +{"stream": "persons", "data": {"id": 5, "company_id": 7780468, "owner_id": 11884360, "org_id": 1, "name": "User2 Sample", "first_name": "User2", "last_name": "Sample", "open_deals_count": 2, "related_open_deals_count": 0, "closed_deals_count": 0, "related_closed_deals_count": 0, "participant_open_deals_count": 0, "participant_closed_deals_count": 0, "email_messages_count": 0, "activities_count": 0, "done_activities_count": 0, "undone_activities_count": 0, "files_count": 0, "notes_count": 0, "followers_count": 1, "won_deals_count": 0, "related_won_deals_count": 0, "lost_deals_count": 0, "related_lost_deals_count": 0, "active_flag": true, "phone": [{"label": "work", "value": "+14443332266", "primary": true}], "email": [{"label": "work", "value": "user2.sample.airbyte@gmail.com", "primary": true}], "first_char": "u", "update_time": "2023-02-22 10:44:49", "delete_time": null, "add_time": "2023-02-22 08:13:09", "visible_to": "3", "picture_id": null, "next_activity_date": null, "next_activity_time": null, "next_activity_id": null, "last_activity_id": null, "last_activity_date": null, "last_incoming_mail_time": null, "last_outgoing_mail_time": null, "label": 3, "picture_128_url": null, "org_name": "Test Organization1", "aa02d059909fdc632d590bd578d7b3baf4bf9780": null, "owner_name": "Team Airbyte", "cc_email": "airbyte-sandbox@pipedrivemail.com"}, "emitted_at": 1689246323858} +{"stream": "persons", "data": {"id": 6, "company_id": 7780468, "owner_id": 11884360, "org_id": 1, "name": "User3 Sample", "first_name": "User3", "last_name": "Sample", "open_deals_count": 1, "related_open_deals_count": 0, "closed_deals_count": 0, "related_closed_deals_count": 0, "participant_open_deals_count": 0, "participant_closed_deals_count": 0, "email_messages_count": 0, "activities_count": 0, "done_activities_count": 0, "undone_activities_count": 0, "files_count": 0, "notes_count": 0, "followers_count": 1, "won_deals_count": 0, "related_won_deals_count": 0, "lost_deals_count": 0, "related_lost_deals_count": 0, "active_flag": true, "phone": [{"label": "work", "value": "+15554442233", "primary": true}], "email": [{"label": "work", "value": "user3.sample.airbyte@outlook.com", "primary": true}], "first_char": "u", "update_time": "2023-02-22 10:45:52", "delete_time": null, "add_time": "2023-02-22 08:13:53", "visible_to": "3", "picture_id": null, "next_activity_date": null, "next_activity_time": null, "next_activity_id": null, "last_activity_id": null, "last_activity_date": null, "last_incoming_mail_time": null, "last_outgoing_mail_time": null, "label": 2, "picture_128_url": null, "org_name": "Test Organization1", "aa02d059909fdc632d590bd578d7b3baf4bf9780": null, "owner_name": "Team Airbyte", "cc_email": "airbyte-sandbox@pipedrivemail.com"}, "emitted_at": 1689246323859} +{"stream": "persons", "data": {"id": 2, "company_id": 7780468, "owner_id": 11884360, "org_id": 11, "name": "User4 Sample", "first_name": "User4", "last_name": "Sample", "open_deals_count": 2, "related_open_deals_count": 0, "closed_deals_count": 0, "related_closed_deals_count": 0, "participant_open_deals_count": 0, "participant_closed_deals_count": 0, "email_messages_count": 0, "activities_count": 1, "done_activities_count": 0, "undone_activities_count": 1, "files_count": 0, "notes_count": 0, "followers_count": 1, "won_deals_count": 0, "related_won_deals_count": 0, "lost_deals_count": 0, "related_lost_deals_count": 0, "active_flag": true, "phone": [{"label": "work", "value": "+16665552233", "primary": true}], "email": [{"label": "work", "value": "user4.sample.airbyte@outlook.com", "primary": true}], "first_char": "u", "update_time": "2023-02-22 11:46:49", "delete_time": null, "add_time": "2021-07-06 15:04:21", "visible_to": "3", "picture_id": null, "next_activity_date": "2023-03-15", "next_activity_time": "11:30:00", "next_activity_id": 24, "last_activity_id": null, "last_activity_date": null, "last_incoming_mail_time": null, "last_outgoing_mail_time": null, "label": 1, "picture_128_url": null, "org_name": "Test Organization 4", "aa02d059909fdc632d590bd578d7b3baf4bf9780": null, "owner_name": "Team Airbyte", "cc_email": "airbyte-sandbox@pipedrivemail.com"}, "emitted_at": 1689246323859} +{"stream": "person_fields", "data": {"id": 9039, "key": "name", "name": "Name", "group_id": null, "order_nr": 0, "field_type": "varchar", "json_column_flag": false, "add_time": "2020-12-10 07:23:48", "update_time": "2020-12-10 07:23:48", "last_updated_by_user_id": null, "edit_flag": false, "details_visible_flag": false, "add_visible_flag": true, "important_flag": false, "bulk_edit_allowed": true, "filtering_allowed": true, "sortable_flag": true, "searchable_flag": false, "active_flag": true, "use_field": "id", "link": "/person/", "mandatory_flag": true}, "emitted_at": 1689246483384} +{"stream": "person_fields", "data": {"id": 9040, "key": "label", "name": "Label", "group_id": null, "order_nr": 0, "field_type": "enum", "json_column_flag": false, "add_time": "2020-12-10 07:23:48", "update_time": "2020-12-10 07:23:48", "last_updated_by_user_id": null, "edit_flag": false, "details_visible_flag": true, "add_visible_flag": true, "important_flag": false, "bulk_edit_allowed": true, "filtering_allowed": true, "sortable_flag": true, "searchable_flag": false, "active_flag": true, "options": [{"id": 1, "label": "Customer", "color": "green"}, {"id": 2, "label": "Hot lead", "color": "red"}, {"id": 3, "label": "Warm lead", "color": "yellow"}, {"id": 4, "label": "Cold lead", "color": "blue"}], "mandatory_flag": false}, "emitted_at": 1689246483384} +{"stream": "person_fields", "data": {"id": 9064, "key": "first_name", "name": "First name", "group_id": null, "order_nr": 0, "field_type": "varchar", "json_column_flag": false, "add_time": "2020-12-10 07:23:49", "update_time": "2020-12-10 07:23:49", "last_updated_by_user_id": null, "edit_flag": false, "details_visible_flag": true, "add_visible_flag": false, "important_flag": false, "bulk_edit_allowed": true, "filtering_allowed": true, "sortable_flag": true, "searchable_flag": false, "active_flag": true, "mandatory_flag": false}, "emitted_at": 1689246483386} {"stream": "pipelines", "data": {"id": 2, "name": "New pipeline", "url_title": "New-pipeline", "order_nr": 2, "active": true, "deal_probability": true, "add_time": "2021-07-06 15:24:11", "update_time": "2021-07-06 15:24:11"}, "emitted_at": 1683115317258} {"stream": "pipelines", "data": {"id": 3, "name": "New pipeline 2", "url_title": "New-pipeline-2", "order_nr": 3, "active": true, "deal_probability": true, "add_time": "2023-02-22 10:42:31", "update_time": "2023-02-22 10:42:31"}, "emitted_at": 1683115317259} {"stream": "pipelines", "data": {"id": 4, "name": "New pipeline 3", "url_title": "New-pipeline-3", "order_nr": 4, "active": true, "deal_probability": true, "add_time": "2023-02-22 10:43:12", "update_time": "2023-02-22 10:43:12"}, "emitted_at": 1683115317260} @@ -57,6 +57,6 @@ {"stream": "stages", "data": {"id": 11, "order_nr": 5, "name": "Negotiations Started", "active_flag": true, "deal_probability": 100, "pipeline_id": 2, "rotten_flag": false, "rotten_days": null, "add_time": "2021-07-06 15:24:11", "update_time": "2023-02-22 10:38:51", "pipeline_name": "New pipeline", "pipeline_deal_probability": true}, "emitted_at": 1683115322062} {"stream": "stages", "data": {"id": 10, "order_nr": 4, "name": "Proposal Made", "active_flag": true, "deal_probability": 100, "pipeline_id": 2, "rotten_flag": false, "rotten_days": null, "add_time": "2021-07-06 15:24:11", "update_time": "2023-02-22 10:38:51", "pipeline_name": "New pipeline", "pipeline_deal_probability": true}, "emitted_at": 1683115322063} {"stream": "stages", "data": {"id": 9, "order_nr": 3, "name": "Demo Scheduled", "active_flag": true, "deal_probability": 100, "pipeline_id": 2, "rotten_flag": false, "rotten_days": null, "add_time": "2021-07-06 15:24:11", "update_time": "2023-02-22 10:38:51", "pipeline_name": "New pipeline", "pipeline_deal_probability": true}, "emitted_at": 1683115322064} -{"stream": "users", "data": {"id": 11884360, "name": "Team Airbyte", "default_currency": "USD", "timezone_name": "Europe/Kiev", "timezone_offset": "+03:00", "locale": "en_US", "email": "integration-test@airbyte.io", "phone": null, "created": "2020-12-10 07:23:44", "modified": "2023-03-22 14:21:29", "lang": 1, "active_flag": true, "is_admin": 1, "last_login": "2023-03-22 14:21:29", "signup_flow_variation": "", "role_id": 1, "has_created_company": false, "icon_url": null, "is_you": true}, "emitted_at": 1683115324157} -{"stream": "users", "data": {"id": 18276123, "name": "User3 Sample", "default_currency": "USD", "timezone_name": "Europe/Kiev", "timezone_offset": "+03:00", "locale": "en_US", "email": "user3.sample.airbyte@outlook.com", "phone": null, "created": "2023-03-22 14:22:43", "modified": "2023-03-22 14:34:12", "lang": 1, "active_flag": true, "is_admin": 0, "last_login": "2023-03-22 14:34:12", "signup_flow_variation": "", "role_id": 1, "has_created_company": false, "icon_url": null, "is_you": false}, "emitted_at": 1683115324158} -{"stream": "users", "data": {"id": 18276134, "name": "User4 Sample", "default_currency": "USD", "timezone_name": "Europe/Kiev", "timezone_offset": "+03:00", "locale": "en_US", "email": "user4.sample.airbyte@outlook.com", "phone": null, "created": "2023-03-22 14:22:44", "modified": "2023-03-22 14:39:38", "lang": 1, "active_flag": true, "is_admin": 0, "last_login": "2023-03-22 14:39:38", "signup_flow_variation": "", "role_id": 1, "has_created_company": false, "icon_url": null, "is_you": false}, "emitted_at": 1683115324158} +{"stream": "users", "data": {"id": 11884360, "name": "Team Airbyte", "default_currency": "USD", "timezone_name": "America/New_York", "timezone_offset": "-04:00", "locale": "en_US", "email": "integration-test@airbyte.io", "phone": null, "created": "2020-12-10 07:23:44", "modified": "2023-07-12 17:50:18", "lang": 1, "active_flag": true, "is_admin": 1, "last_login": "2023-07-12 17:50:15", "signup_flow_variation": "", "role_id": 1, "has_created_company": false, "icon_url": null, "is_you": true}, "emitted_at": 1689246650077} +{"stream": "users", "data": {"id": 18276123, "name": "User3 Sample", "default_currency": "USD", "timezone_name": "Europe/Kiev", "timezone_offset": "+03:00", "locale": "en_US", "email": "user3.sample.airbyte@outlook.com", "phone": null, "created": "2023-03-22 14:22:43", "modified": "2023-03-22 14:34:12", "lang": 1, "active_flag": true, "is_admin": 0, "last_login": "2023-03-22 14:34:12", "signup_flow_variation": "", "role_id": 1, "has_created_company": false, "icon_url": null, "is_you": false}, "emitted_at": 1689246650076} +{"stream": "users", "data": {"id": 18276134, "name": "User4 Sample", "default_currency": "USD", "timezone_name": "Europe/Kiev", "timezone_offset": "+03:00", "locale": "en_US", "email": "user4.sample.airbyte@outlook.com", "phone": null, "created": "2023-03-22 14:22:44", "modified": "2023-03-22 14:39:38", "lang": 1, "active_flag": true, "is_admin": 0, "last_login": "2023-03-22 14:39:38", "signup_flow_variation": "", "role_id": 1, "has_created_company": false, "icon_url": null, "is_you": false}, "emitted_at": 1689246650077} From c6c3ee11b8d31037cdad7b26760de8cec7f416c1 Mon Sep 17 00:00:00 2001 From: btkcodedev Date: Thu, 13 Jul 2023 18:39:42 +0530 Subject: [PATCH 57/63] =?UTF-8?q?=E2=9C=A8Source=20Twilio:=20New=20streams?= =?UTF-8?q?=20UserConversations=20with=20parent=20Users=20(#27221)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * New stream UserConversations with parent Users * Update Docs * EOF streams.py * formatting fixes * Add account_sid as primary key * bump version * fix merge errors * fix catalog and expected records --------- Co-authored-by: Mal Hancock Co-authored-by: Daryna Ishchenko --- .../connectors/source-twilio/Dockerfile | 2 +- .../constant_records_catalog.json | 18 +++++ .../integration_tests/expected_records.jsonl | 4 + .../connectors/source-twilio/metadata.yaml | 2 +- .../schemas/user_conversations.json | 75 +++++++++++++++++++ .../source_twilio/schemas/users.json | 52 +++++++++++++ .../source-twilio/source_twilio/source.py | 4 + .../source-twilio/source_twilio/streams.py | 25 +++++++ .../source-twilio/unit_tests/test_source.py | 4 + docs/integrations/sources/twilio.md | 5 +- 10 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 airbyte-integrations/connectors/source-twilio/source_twilio/schemas/user_conversations.json create mode 100644 airbyte-integrations/connectors/source-twilio/source_twilio/schemas/users.json diff --git a/airbyte-integrations/connectors/source-twilio/Dockerfile b/airbyte-integrations/connectors/source-twilio/Dockerfile index da9ca91b6d97..d0d7df832113 100644 --- a/airbyte-integrations/connectors/source-twilio/Dockerfile +++ b/airbyte-integrations/connectors/source-twilio/Dockerfile @@ -12,5 +12,5 @@ COPY main.py ./ ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=0.8.1 +LABEL io.airbyte.version=0.9.0 LABEL io.airbyte.name=airbyte/source-twilio diff --git a/airbyte-integrations/connectors/source-twilio/integration_tests/constant_records_catalog.json b/airbyte-integrations/connectors/source-twilio/integration_tests/constant_records_catalog.json index 107c7de59a05..be98e5227061 100644 --- a/airbyte-integrations/connectors/source-twilio/integration_tests/constant_records_catalog.json +++ b/airbyte-integrations/connectors/source-twilio/integration_tests/constant_records_catalog.json @@ -228,6 +228,24 @@ "sync_mode": "full_refresh", "destination_sync_mode": "overwrite" }, + { + "stream": { + "name": "users", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "user_conversations", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, { "stream": { "name": "verify_services", diff --git a/airbyte-integrations/connectors/source-twilio/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-twilio/integration_tests/expected_records.jsonl index 18f35c457489..c177feb9981c 100644 --- a/airbyte-integrations/connectors/source-twilio/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-twilio/integration_tests/expected_records.jsonl @@ -64,4 +64,8 @@ {"stream": "trunks", "data": {"auth_type": "", "transfer_mode": "disable-all", "secure": false, "auth_type_set": [], "date_updated": "2023-05-10T17:29:44Z", "friendly_name": "integration-test-trunk", "domain_name": null, "disaster_recovery_url": null, "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "recording": {"trim": "do-not-trim", "mode": "do-not-record"}, "transfer_caller_id": "from-transferee", "disaster_recovery_method": null, "url": "https://trunking.twilio.com/v1/Trunks/TKdd4b0b21323f45ad4ce9164761d18237", "sid": "TKdd4b0b21323f45ad4ce9164761d18237", "date_created": "2023-05-10T17:27:17Z", "cnam_lookup_enabled": false, "links": {"phone_numbers": "https://trunking.twilio.com/v1/Trunks/TKdd4b0b21323f45ad4ce9164761d18237/PhoneNumbers", "ip_access_control_lists": "https://trunking.twilio.com/v1/Trunks/TKdd4b0b21323f45ad4ce9164761d18237/IpAccessControlLists", "origination_urls": "https://trunking.twilio.com/v1/Trunks/TKdd4b0b21323f45ad4ce9164761d18237/OriginationUrls", "credential_lists": "https://trunking.twilio.com/v1/Trunks/TKdd4b0b21323f45ad4ce9164761d18237/CredentialLists"}}, "emitted_at": 1684432326862} {"stream": "roles", "data": {"date_updated": "2023-03-21T13:35:15Z", "friendly_name": "service user", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "url": "https://chat.twilio.com/v2/Services/IS5fcc074f7ead44c99a0a24a374a7e19f/Roles/RL1c0ab592f9724a10992c2ea29709f6cd", "sid": "RL1c0ab592f9724a10992c2ea29709f6cd", "date_created": "2023-03-21T13:35:15Z", "service_sid": "IS5fcc074f7ead44c99a0a24a374a7e19f", "type": "deployment", "permissions": ["createChannel", "joinChannel", "editOwnUserInfo"]}, "emitted_at": 1684513502733} {"stream": "services", "data": {"typing_indicator_timeout": 5.0, "date_updated": "2023-03-21T13:35:15Z", "post_webhook_url": null, "read_status_enabled": true, "consumption_report_interval": 10.0, "pre_webhook_retry_count": 0.0, "default_service_role_sid": "RL1c0ab592f9724a10992c2ea29709f6cd", "media": {"compatibility_message": "Media messages are not supported by your client", "size_limit_mb": 150.0}, "default_channel_creator_role_sid": "RL3efa7fddc245451cbb76cde110621614", "reachability_enabled": false, "webhook_filters": null, "post_webhook_retry_count": 0.0, "sid": "IS5fcc074f7ead44c99a0a24a374a7e19f", "pre_webhook_url": null, "notifications": {"removed_from_channel": {"enabled": false}, "log_enabled": false, "added_to_channel": {"enabled": false}, "new_message": {"enabled": false}, "invited_to_channel": {"enabled": false}}, "webhook_method": null, "limits": {"user_channels": 1000.0, "channel_members": 1000.0}, "url": "https://chat.twilio.com/v2/Services/IS5fcc074f7ead44c99a0a24a374a7e19f", "friendly_name": "Default Conversations Service", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "date_created": "2023-03-21T13:35:15Z", "default_channel_role_sid": "RLca3ff6cb9bc9404caf14e43b63fed446", "links": {"channels": "https://chat.twilio.com/v2/Services/IS5fcc074f7ead44c99a0a24a374a7e19f/Channels", "bindings": "https://chat.twilio.com/v2/Services/IS5fcc074f7ead44c99a0a24a374a7e19f/Bindings", "users": "https://chat.twilio.com/v2/Services/IS5fcc074f7ead44c99a0a24a374a7e19f/Users", "roles": "https://chat.twilio.com/v2/Services/IS5fcc074f7ead44c99a0a24a374a7e19f/Roles"}}, "emitted_at": 1684513526771} +{"stream": "user_conversations", "data": {"notification_level": "default", "unique_name": null, "user_sid": "US4373c40fffca48dcab7498989c484a0d", "friendly_name": "Friendly Conversation", "conversation_sid": "CH0ed7b4c3498e455a96fa09fcccee720e", "unread_messages_count": null, "created_by": "system", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "last_read_message_index": null, "date_created": "2023-03-21T13:39:44Z", "timers": {}, "url": "https://conversations.twilio.com/v1/Users/US4373c40fffca48dcab7498989c484a0d/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e", "date_updated": "2023-03-21T13:39:44Z", "attributes": "{}", "participant_sid": "MB0a984a4238f14b828cf277becf880bd4", "conversation_state": "active", "chat_service_sid": "IS5fcc074f7ead44c99a0a24a374a7e19f", "links": {"conversation": "https://conversations.twilio.com/v1/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e", "participant": "https://conversations.twilio.com/v1/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e/Participants/MB0a984a4238f14b828cf277becf880bd4"}}, "emitted_at": 1687897600119} +{"stream": "user_conversations", "data": {"notification_level": "default", "unique_name": null, "user_sid": "US9d8279d5e8954fd1b9804c853be5baa3", "friendly_name": "Friendly Conversation", "conversation_sid": "CH0ed7b4c3498e455a96fa09fcccee720e", "unread_messages_count": null, "created_by": "system", "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "last_read_message_index": null, "date_created": "2023-03-21T13:39:44Z", "timers": {}, "url": "https://conversations.twilio.com/v1/Users/US9d8279d5e8954fd1b9804c853be5baa3/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e", "date_updated": "2023-03-21T13:39:44Z", "attributes": "{}", "participant_sid": "MB41bb002a3a5e412fa7f2459dcfb4925f", "conversation_state": "active", "chat_service_sid": "IS5fcc074f7ead44c99a0a24a374a7e19f", "links": {"conversation": "https://conversations.twilio.com/v1/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e", "participant": "https://conversations.twilio.com/v1/Conversations/CH0ed7b4c3498e455a96fa09fcccee720e/Participants/MB41bb002a3a5e412fa7f2459dcfb4925f"}}, "emitted_at": 1687897600263} +{"stream": "users", "data": {"is_notifiable": null, "date_updated": "2023-04-13T11:52:17Z", "is_online": null, "friendly_name": null, "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "url": "https://conversations.twilio.com/v1/Users/US4373c40fffca48dcab7498989c484a0d", "date_created": "2023-04-13T11:52:17Z", "role_sid": "RL1c0ab592f9724a10992c2ea29709f6cd", "sid": "US4373c40fffca48dcab7498989c484a0d", "attributes": "{}", "identity": "Integration Test 2", "chat_service_sid": "IS5fcc074f7ead44c99a0a24a374a7e19f", "links": {"user_conversations": "https://conversations.twilio.com/v1/Users/US4373c40fffca48dcab7498989c484a0d/Conversations"}}, "emitted_at": 1687897599313} +{"stream": "users", "data": {"is_notifiable": null, "date_updated": "2023-04-13T11:52:02Z", "is_online": null, "friendly_name": null, "account_sid": "ACdade166c12e160e9ed0a6088226718fb", "url": "https://conversations.twilio.com/v1/Users/US9d8279d5e8954fd1b9804c853be5baa3", "date_created": "2023-04-13T11:52:02Z", "role_sid": "RL1c0ab592f9724a10992c2ea29709f6cd", "sid": "US9d8279d5e8954fd1b9804c853be5baa3", "attributes": "{}", "identity": "Integration Test", "chat_service_sid": "IS5fcc074f7ead44c99a0a24a374a7e19f", "links": {"user_conversations": "https://conversations.twilio.com/v1/Users/US9d8279d5e8954fd1b9804c853be5baa3/Conversations"}}, "emitted_at": 1687897599315} {"stream": "verify_services", "data": {"default_template_sid":null,"tts_name":null,"psd2_enabled":false,"do_not_share_warning_enabled":false,"mailer_sid":null,"friendly_name":"MyServiceName","url":"https://verify.twilio.com/v2/Services/VAf7a6bc96c5a594a56b3ccacfaf4c2e6e","account_sid":"ACdade166c12e160e9ed0a6088226718fb","date_updated":"2022-12-01T04:35:52Z","totp":{"time_step":30,"skew":1,"code_length":6,"issuer":"MyServiceName"},"code_length":6,"custom_code_enabled":false,"sid":"VAf7a6bc96c5a594a56b3ccacfaf4c2e6e","push":{"apn_credential_sid":null,"include_date":false,"fcm_credential_sid":null},"date_created":"2022-12-01T04:35:52Z","dtmf_input_required":true,"skip_sms_to_landlines":false,"lookup_enabled":false,"links":{"verification_checks":"https://verify.twilio.com/v2/Services/VAf7a6bc96c5a594a56b3ccacfaf4c2e6e/VerificationCheck","rate_limits":"https://verify.twilio.com/v2/Services/VAf7a6bc96c5a594a56b3ccacfaf4c2e6e/RateLimits","entities":"https://verify.twilio.com/v2/Services/VAf7a6bc96c5a594a56b3ccacfaf4c2e6e/Entities","access_tokens":"https://verify.twilio.com/v2/Services/VAf7a6bc96c5a594a56b3ccacfaf4c2e6e/AccessTokens","verifications":"https://verify.twilio.com/v2/Services/VAf7a6bc96c5a594a56b3ccacfaf4c2e6e/Verifications","webhooks":"https://verify.twilio.com/v2/Services/VAf7a6bc96c5a594a56b3ccacfaf4c2e6e/Webhooks","messaging_configurations":"https://verify.twilio.com/v2/Services/VAf7a6bc96c5a594a56b3ccacfaf4c2e6e/MessagingConfigurations"}}, "emitted_at": 1684513526771} diff --git a/airbyte-integrations/connectors/source-twilio/metadata.yaml b/airbyte-integrations/connectors/source-twilio/metadata.yaml index 1c4f1646d71f..33437d9697bd 100644 --- a/airbyte-integrations/connectors/source-twilio/metadata.yaml +++ b/airbyte-integrations/connectors/source-twilio/metadata.yaml @@ -8,7 +8,7 @@ data: connectorSubtype: api connectorType: source definitionId: b9dc6155-672e-42ea-b10d-9f1f1fb95ab1 - dockerImageTag: 0.8.1 + dockerImageTag: 0.9.0 dockerRepository: airbyte/source-twilio githubIssueLabel: source-twilio icon: twilio.svg diff --git a/airbyte-integrations/connectors/source-twilio/source_twilio/schemas/user_conversations.json b/airbyte-integrations/connectors/source-twilio/source_twilio/schemas/user_conversations.json new file mode 100644 index 000000000000..6c69bb037d5f --- /dev/null +++ b/airbyte-integrations/connectors/source-twilio/source_twilio/schemas/user_conversations.json @@ -0,0 +1,75 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "User Conversation Schema", + "additionalProperties": true, + "type": ["null", "object"], + "properties": { + "notification_level": { + "type": ["null", "string"] + }, + "unique_name": { + "type": ["null", "string"] + }, + "user_sid": { + "type": ["null", "string"] + }, + "friendly_name": { + "type": ["null", "string"] + }, + "conversation_sid": { + "type": ["null", "string"] + }, + "unread_messages_count": { + "type": ["null", "integer"] + }, + "created_by": { + "type": ["null", "string"] + }, + "account_sid": { + "type": ["null", "string"] + }, + "last_read_message_index": { + "type": ["null", "integer"] + }, + "date_created": { + "type": ["null", "string"] + }, + "timers": { + "type": ["null", "object"], + "properties": { + "chat_service_sid": { + "type": ["null", "string"] + } + } + }, + "url": { + "type": ["null", "string"] + }, + "date_updated": { + "type": ["null", "string"] + }, + "attributes": { + "type": ["null", "string"] + }, + "participant_sid": { + "type": ["null", "string"] + }, + "conversation_state": { + "type": ["null", "string"] + }, + "chat_service_sid": { + "type": ["null", "string"] + }, + "links": { + "type": ["null", "object"], + "properties": { + "conversation": { + "type": ["null", "string"] + }, + "participant": { + "type": ["null", "string"] + } + } + } + } +} diff --git a/airbyte-integrations/connectors/source-twilio/source_twilio/schemas/users.json b/airbyte-integrations/connectors/source-twilio/source_twilio/schemas/users.json new file mode 100644 index 000000000000..d0942ed00aea --- /dev/null +++ b/airbyte-integrations/connectors/source-twilio/source_twilio/schemas/users.json @@ -0,0 +1,52 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Users Schema", + "additionalProperties": true, + "type": ["null", "object"], + "properties": { + "is_notifiable": { + "type": ["null", "string"] + }, + "date_updated": { + "type": ["null", "string"] + }, + "is_online": { + "type": ["null", "string"] + }, + "friendly_name": { + "type": ["null", "string"] + }, + "account_sid": { + "type": ["null", "string"] + }, + "url": { + "type": ["null", "string"] + }, + "date_created": { + "type": ["null", "string"] + }, + "role_sid": { + "type": ["null", "string"] + }, + "sid": { + "type": ["null", "string"] + }, + "attributes": { + "type": ["null", "string"] + }, + "identity": { + "type": ["null", "string"] + }, + "chat_service_sid": { + "type": ["null", "string"] + }, + "links": { + "type": ["null", "object"], + "properties": { + "user_conversations": { + "type": ["null", "string"] + } + } + } + } +} diff --git a/airbyte-integrations/connectors/source-twilio/source_twilio/source.py b/airbyte-integrations/connectors/source-twilio/source_twilio/source.py index ee1b20f6fff5..b5ed8ec1eb0d 100644 --- a/airbyte-integrations/connectors/source-twilio/source_twilio/source.py +++ b/airbyte-integrations/connectors/source-twilio/source_twilio/source.py @@ -42,6 +42,8 @@ Trunks, UsageRecords, UsageTriggers, + UserConversations, + Users, VerifyServices, ) @@ -120,6 +122,8 @@ def streams(self, config: Mapping[str, Any]) -> List[Stream]: Trunks(**full_refresh_stream_kwargs), UsageRecords(**incremental_stream_kwargs), UsageTriggers(**full_refresh_stream_kwargs), + Users(**full_refresh_stream_kwargs), + UserConversations(**full_refresh_stream_kwargs), VerifyServices(**full_refresh_stream_kwargs), ] return streams diff --git a/airbyte-integrations/connectors/source-twilio/source_twilio/streams.py b/airbyte-integrations/connectors/source-twilio/source_twilio/streams.py index fc0153f36b42..ef29a9d791b5 100644 --- a/airbyte-integrations/connectors/source-twilio/source_twilio/streams.py +++ b/airbyte-integrations/connectors/source-twilio/source_twilio/streams.py @@ -626,3 +626,28 @@ def path(self, stream_slice: Mapping[str, Any], **kwargs): def parent_record_to_stream_slice(self, record: Mapping[str, Any]) -> Mapping[str, Any]: return {"conversation_sid": record["sid"]} + + +class Users(TwilioStream): + """https://www.twilio.com/docs/conversations/api/user-resource""" + + url_base = TWILIO_CONVERSATIONS_URL_BASE + + def path(self, **kwargs): + return self.name.title() + + +class UserConversations(TwilioNestedStream): + """https://www.twilio.com/docs/conversations/api/user-conversation-resource#list-all-of-a-users-conversations""" + + parent_stream = Users + url_base = TWILIO_CONVERSATIONS_URL_BASE + uri_from_subresource = False + data_field = "conversations" + primary_key = ["account_sid"] + + def path(self, stream_slice: Mapping[str, Any], **kwargs): + return f"Users/{stream_slice['user_sid']}/Conversations" + + def parent_record_to_stream_slice(self, record: Mapping[str, Any]) -> Mapping[str, Any]: + return {"user_sid": record["sid"]} diff --git a/airbyte-integrations/connectors/source-twilio/unit_tests/test_source.py b/airbyte-integrations/connectors/source-twilio/unit_tests/test_source.py index 890cf2d31602..837397a871c0 100644 --- a/airbyte-integrations/connectors/source-twilio/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-twilio/unit_tests/test_source.py @@ -32,6 +32,8 @@ Transcriptions, UsageRecords, UsageTriggers, + UserConversations, + Users, VerifyServices, ) @@ -101,6 +103,8 @@ def test_check_connection_handles_exceptions(mocker, config, exception, expected (UsageTriggers), (Conversations), (ConversationParticipants), + (Users), + (UserConversations), (VerifyServices), ], ) diff --git a/docs/integrations/sources/twilio.md b/docs/integrations/sources/twilio.md index e2b3d9a578c6..8e3864662482 100644 --- a/docs/integrations/sources/twilio.md +++ b/docs/integrations/sources/twilio.md @@ -81,6 +81,8 @@ The Twilio source connector supports the following [sync modes](https://docs.air * [Trunks](https://www.twilio.com/docs/sip-trunking/api/trunk-resource#trunk-properties) * [Usage Records](https://www.twilio.com/docs/usage/api/usage-record#read-multiple-usagerecord-resources) \(Incremental\) * [Usage Triggers](https://www.twilio.com/docs/usage/api/usage-trigger#read-multiple-usagetrigger-resources) +* [Users](https://www.twilio.com/docs/conversations/api/user-resource) +* [UserConversations](https://www.twilio.com/docs/conversations/api/user-conversation-resource#list-all-of-a-users-conversations) * [VerifyServices](https://www.twilio.com/docs/verify/api/service#maincontent) ## Performance considerations @@ -92,8 +94,9 @@ For more information, see [the Twilio docs for rate limitations](https://support | Version | Date | Pull Request | Subject | |:--------|:-----------|:----------------------------------------------------------|:--------------------------------------------------------------------------------------------------------| +| 0.9.0 | 2023-06-27 | [27221](https://github.com/airbytehq/airbyte/pull/27221) | Add new stream `UserConversations` with parent `Users` | | 0.8.1 | 2023-07-12 | [28216](https://github.com/airbytehq/airbyte/pull/28216) | Add property `channel_metadata` to `ConversationMessages` schema | -| 0.8.0 | 2023-06-11 | [*****](https://github.com/airbytehq/airbyte/pull/*****) | Add new stream `VerifyServices` | +| 0.8.0 | 2023-06-11 | [27231](https://github.com/airbytehq/airbyte/pull/27231) | Add new stream `VerifyServices` | | 0.7.0 | 2023-05-03 | [25781](https://github.com/airbytehq/airbyte/pull/25781) | Add new stream `Trunks` | | 0.6.0 | 2023-05-03 | [25783](https://github.com/airbytehq/airbyte/pull/25783) | Add new stream `Roles` with parent `Services` | | 0.5.0 | 2023-03-21 | [23995](https://github.com/airbytehq/airbyte/pull/23995) | Add new stream `Conversation Participants` | From c816d14fc19aaaa65f6c1e04ef588efdac68b2e3 Mon Sep 17 00:00:00 2001 From: Denys Davydov Date: Thu, 13 Jul 2023 16:53:08 +0300 Subject: [PATCH 58/63] :sparkles: :sparkles: Source Google Ads: add new streams (#28246) * Connector health: source hubspot, gitlab, snapchat-marketing: fix builds * add new streams * upd changelog * update CAT config * update expected records --- .../connectors/source-google-ads/Dockerfile | 2 +- .../acceptance-test-config.yml | 4 + .../integration_tests/abnormal_state.json | 14 ++ .../integration_tests/configured_catalog.json | 83 +++++++ .../integration_tests/expected_records.jsonl | 9 + .../incremental_catalog.json | 28 +++ .../source-google-ads/metadata.yaml | 2 +- .../source_google_ads/google_ads.py | 22 +- .../schemas/account_labels.json | 18 ++ .../schemas/ad_group_bidding_strategies.json | 96 ++++++++ .../schemas/ad_group_criterion_labels.json | 18 ++ .../schemas/ad_group_criterions.json | 225 ++++++++++++++++++ .../schemas/ad_listing_group_criterions.json | 75 ++++++ .../schemas/campaign_bidding_strategies.json | 96 ++++++++ .../source_google_ads/schemas/labels.json | 24 ++ .../source_google_ads/source.py | 14 ++ .../source_google_ads/streams.py | 61 +++++ .../unit_tests/test_source.py | 2 +- docs/integrations/sources/google-ads.md | 8 +- 19 files changed, 790 insertions(+), 11 deletions(-) create mode 100644 airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/account_labels.json create mode 100644 airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/ad_group_bidding_strategies.json create mode 100644 airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/ad_group_criterion_labels.json create mode 100644 airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/ad_group_criterions.json create mode 100644 airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/ad_listing_group_criterions.json create mode 100644 airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/campaign_bidding_strategies.json create mode 100644 airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/labels.json diff --git a/airbyte-integrations/connectors/source-google-ads/Dockerfile b/airbyte-integrations/connectors/source-google-ads/Dockerfile index 7924661a6271..1f18eb8d5257 100644 --- a/airbyte-integrations/connectors/source-google-ads/Dockerfile +++ b/airbyte-integrations/connectors/source-google-ads/Dockerfile @@ -13,5 +13,5 @@ COPY main.py ./ ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=0.6.1 +LABEL io.airbyte.version=0.7.0 LABEL io.airbyte.name=airbyte/source-google-ads diff --git a/airbyte-integrations/connectors/source-google-ads/acceptance-test-config.yml b/airbyte-integrations/connectors/source-google-ads/acceptance-test-config.yml index dfa9ed46f596..f0c3f9051b53 100644 --- a/airbyte-integrations/connectors/source-google-ads/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-google-ads/acceptance-test-config.yml @@ -26,6 +26,10 @@ acceptance_tests: bypass_reason: "Floating data" - name: "display_topics_performance_report" bypass_reason: "Stream not filled yet." + - name: "account_labels" + bypass_reason: "Unable to seed the stream" + - name: "ad_group_criterion_labels" + bypass_reason: "Unable to seed the stream" - name: "click_view" bypass_reason: "Stream not filled yet." - name: "unhappytable" diff --git a/airbyte-integrations/connectors/source-google-ads/integration_tests/abnormal_state.json b/airbyte-integrations/connectors/source-google-ads/integration_tests/abnormal_state.json index 22056224a81b..f73a191680fd 100644 --- a/airbyte-integrations/connectors/source-google-ads/integration_tests/abnormal_state.json +++ b/airbyte-integrations/connectors/source-google-ads/integration_tests/abnormal_state.json @@ -96,5 +96,19 @@ "stream_state": { "4651612872": { "segments.date": "2222-01-01" }}, "stream_descriptor": { "name": "campaign_budget" } } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "4651612872": { "segments.date": "2222-01-01" }}, + "stream_descriptor": { "name": "campaign_bidding_strategies" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "4651612872": { "segments.date": "2222-01-01" }}, + "stream_descriptor": { "name": "ad_group_bidding_strategies" } + } } ] diff --git a/airbyte-integrations/connectors/source-google-ads/integration_tests/configured_catalog.json b/airbyte-integrations/connectors/source-google-ads/integration_tests/configured_catalog.json index c7fd7656577a..636e0ed23185 100644 --- a/airbyte-integrations/connectors/source-google-ads/integration_tests/configured_catalog.json +++ b/airbyte-integrations/connectors/source-google-ads/integration_tests/configured_catalog.json @@ -264,6 +264,89 @@ }, "sync_mode": "full_refresh", "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "labels", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"], + "source_defined_primary_key": [["label.id"]] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite", + "primary_key": [["label.id"]] + }, + { + "stream": { + "name": "account_labels", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"], + "source_defined_primary_key": [["customer_label.resource_name"]] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite", + "primary_key": [["customer_label.resource_name"]] + }, + { + "stream": { + "name": "campaign_bidding_strategies", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_primary_key": [["campaign.id"], ["bidding_strategy.id"], ["segments.date"]], + "source_defined_cursor": true, + "default_cursor_field": ["segments.date"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite", + "primary_key": [["campaign.id"], ["bidding_strategy.id"], ["segments.date"]], + "cursor_field": ["segments.date"] + }, + { + "stream": { + "name": "ad_group_bidding_strategies", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_primary_key": [["ad_group.id"], ["bidding_strategy.id"], ["segments.date"]], + "source_defined_cursor": true, + "default_cursor_field": ["segments.date"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite", + "primary_key": [["ad_group.id"], ["bidding_strategy.id"], ["segments.date"]], + "cursor_field": ["segments.date"] + }, + { + "stream": { + "name": "ad_group_criterions", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"], + "source_defined_primary_key": [["ad_group.id"], ["ad_group_criterion.criterion_id"]] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite", + "primary_key": [["ad_group.id"], ["ad_group_criterion.criterion_id"]] + }, + { + "stream": { + "name": "ad_listing_group_criterions", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"], + "source_defined_primary_key": [["ad_group.id"], ["ad_group_criterion.criterion_id"]] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite", + "primary_key": [["ad_group.id"], ["ad_group_criterion.criterion_id"]] + }, + { + "stream": { + "name": "ad_group_criterion_labels", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"], + "source_defined_primary_key": [["ad_group_criterion_label.resource_name"]] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite", + "primary_key": [["ad_group_criterion_label.resource_name"]] } ] } diff --git a/airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl index c05919161e0c..0afb8eb851e2 100644 --- a/airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-google-ads/integration_tests/expected_records.jsonl @@ -89,3 +89,12 @@ {"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} {"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} {"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} +{"stream": "labels", "data": {"label.id": 21585034471, "label.name": "edgao-example-label", "label.resource_name": "customers/4651612872/labels/21585034471", "label.status": "ENABLED", "label.text_label.background_color": "#E993EB", "label.text_label.description": "example label for edgao"}, "emitted_at": 1689230737253} +{"stream": "campaign_bidding_strategies", "data": {"campaign.id": 17354032686, "bidding_strategy.aligned_campaign_budget_id": 0, "bidding_strategy.campaign_count": 0, "bidding_strategy.currency_code": "", "bidding_strategy.effective_currency_code": "", "bidding_strategy.enhanced_cpc": "", "bidding_strategy.id": 0, "bidding_strategy.maximize_conversion_value.cpc_bid_ceiling_micros": 0, "bidding_strategy.maximize_conversion_value.cpc_bid_floor_micros": 0, "bidding_strategy.maximize_conversion_value.target_roas": 0.0, "bidding_strategy.maximize_conversions.cpc_bid_ceiling_micros": 0, "bidding_strategy.maximize_conversions.cpc_bid_floor_micros": 0, "bidding_strategy.maximize_conversions.target_cpa_micros": 0, "bidding_strategy.name": "", "bidding_strategy.non_removed_campaign_count": 0, "bidding_strategy.resource_name": "", "bidding_strategy.status": "UNSPECIFIED", "bidding_strategy.target_cpa.cpc_bid_ceiling_micros": 0, "bidding_strategy.target_cpa.cpc_bid_floor_micros": 0, "bidding_strategy.target_cpa.target_cpa_micros": 0, "bidding_strategy.target_impression_share.cpc_bid_ceiling_micros": 0, "bidding_strategy.target_impression_share.location": "UNSPECIFIED", "bidding_strategy.target_impression_share.location_fraction_micros": 0, "bidding_strategy.target_roas.cpc_bid_ceiling_micros": 0, "bidding_strategy.target_roas.cpc_bid_floor_micros": 0, "bidding_strategy.target_roas.target_roas": 0.0, "bidding_strategy.target_spend.cpc_bid_ceiling_micros": 0, "bidding_strategy.target_spend.target_spend_micros": 0, "bidding_strategy.type": "UNSPECIFIED", "segments.date": "2022-05-31"}, "emitted_at": 1689230742268} +{"stream": "campaign_bidding_strategies", "data": {"campaign.id": 17324459992, "bidding_strategy.aligned_campaign_budget_id": 0, "bidding_strategy.campaign_count": 0, "bidding_strategy.currency_code": "", "bidding_strategy.effective_currency_code": "", "bidding_strategy.enhanced_cpc": "", "bidding_strategy.id": 0, "bidding_strategy.maximize_conversion_value.cpc_bid_ceiling_micros": 0, "bidding_strategy.maximize_conversion_value.cpc_bid_floor_micros": 0, "bidding_strategy.maximize_conversion_value.target_roas": 0.0, "bidding_strategy.maximize_conversions.cpc_bid_ceiling_micros": 0, "bidding_strategy.maximize_conversions.cpc_bid_floor_micros": 0, "bidding_strategy.maximize_conversions.target_cpa_micros": 0, "bidding_strategy.name": "", "bidding_strategy.non_removed_campaign_count": 0, "bidding_strategy.resource_name": "", "bidding_strategy.status": "UNSPECIFIED", "bidding_strategy.target_cpa.cpc_bid_ceiling_micros": 0, "bidding_strategy.target_cpa.cpc_bid_floor_micros": 0, "bidding_strategy.target_cpa.target_cpa_micros": 0, "bidding_strategy.target_impression_share.cpc_bid_ceiling_micros": 0, "bidding_strategy.target_impression_share.location": "UNSPECIFIED", "bidding_strategy.target_impression_share.location_fraction_micros": 0, "bidding_strategy.target_roas.cpc_bid_ceiling_micros": 0, "bidding_strategy.target_roas.cpc_bid_floor_micros": 0, "bidding_strategy.target_roas.target_roas": 0.0, "bidding_strategy.target_spend.cpc_bid_ceiling_micros": 0, "bidding_strategy.target_spend.target_spend_micros": 0, "bidding_strategy.type": "UNSPECIFIED", "segments.date": "2022-06-01"}, "emitted_at": 1689230742269} +{"stream": "ad_group_bidding_strategies", "data": {"ad_group.id": 143992182864, "bidding_strategy.aligned_campaign_budget_id": 0, "bidding_strategy.campaign_count": 0, "bidding_strategy.currency_code": "", "bidding_strategy.effective_currency_code": "", "bidding_strategy.enhanced_cpc": "", "bidding_strategy.id": 0, "bidding_strategy.maximize_conversion_value.cpc_bid_ceiling_micros": 0, "bidding_strategy.maximize_conversion_value.cpc_bid_floor_micros": 0, "bidding_strategy.maximize_conversion_value.target_roas": 0.0, "bidding_strategy.maximize_conversions.cpc_bid_ceiling_micros": 0, "bidding_strategy.maximize_conversions.cpc_bid_floor_micros": 0, "bidding_strategy.maximize_conversions.target_cpa_micros": 0, "bidding_strategy.name": "", "bidding_strategy.non_removed_campaign_count": 0, "bidding_strategy.resource_name": "", "bidding_strategy.status": "UNSPECIFIED", "bidding_strategy.target_cpa.cpc_bid_ceiling_micros": 0, "bidding_strategy.target_cpa.cpc_bid_floor_micros": 0, "bidding_strategy.target_cpa.target_cpa_micros": 0, "bidding_strategy.target_impression_share.cpc_bid_ceiling_micros": 0, "bidding_strategy.target_impression_share.location": "UNSPECIFIED", "bidding_strategy.target_impression_share.location_fraction_micros": 0, "bidding_strategy.target_roas.cpc_bid_ceiling_micros": 0, "bidding_strategy.target_roas.cpc_bid_floor_micros": 0, "bidding_strategy.target_roas.target_roas": 0.0, "bidding_strategy.target_spend.cpc_bid_ceiling_micros": 0, "bidding_strategy.target_spend.target_spend_micros": 0, "bidding_strategy.type": "UNSPECIFIED", "segments.date": "2022-05-31"}, "emitted_at": 1689230746492} +{"stream": "ad_group_bidding_strategies", "data": {"ad_group.id": 138459160713, "bidding_strategy.aligned_campaign_budget_id": 0, "bidding_strategy.campaign_count": 0, "bidding_strategy.currency_code": "", "bidding_strategy.effective_currency_code": "", "bidding_strategy.enhanced_cpc": "", "bidding_strategy.id": 0, "bidding_strategy.maximize_conversion_value.cpc_bid_ceiling_micros": 0, "bidding_strategy.maximize_conversion_value.cpc_bid_floor_micros": 0, "bidding_strategy.maximize_conversion_value.target_roas": 0.0, "bidding_strategy.maximize_conversions.cpc_bid_ceiling_micros": 0, "bidding_strategy.maximize_conversions.cpc_bid_floor_micros": 0, "bidding_strategy.maximize_conversions.target_cpa_micros": 0, "bidding_strategy.name": "", "bidding_strategy.non_removed_campaign_count": 0, "bidding_strategy.resource_name": "", "bidding_strategy.status": "UNSPECIFIED", "bidding_strategy.target_cpa.cpc_bid_ceiling_micros": 0, "bidding_strategy.target_cpa.cpc_bid_floor_micros": 0, "bidding_strategy.target_cpa.target_cpa_micros": 0, "bidding_strategy.target_impression_share.cpc_bid_ceiling_micros": 0, "bidding_strategy.target_impression_share.location": "UNSPECIFIED", "bidding_strategy.target_impression_share.location_fraction_micros": 0, "bidding_strategy.target_roas.cpc_bid_ceiling_micros": 0, "bidding_strategy.target_roas.cpc_bid_floor_micros": 0, "bidding_strategy.target_roas.target_roas": 0.0, "bidding_strategy.target_spend.cpc_bid_ceiling_micros": 0, "bidding_strategy.target_spend.target_spend_micros": 0, "bidding_strategy.type": "UNSPECIFIED", "segments.date": "2022-06-01"}, "emitted_at": 1689230746493} +{"stream": "ad_group_criterions", "data": {"ad_group.id": 143992182864, "ad_group_criterion.ad_group": "customers/4651612872/adGroups/143992182864", "ad_group_criterion.age_range.type": "UNSPECIFIED", "ad_group_criterion.app_payment_model.type": "UNSPECIFIED", "ad_group_criterion.approval_status": "APPROVED", "ad_group_criterion.audience.audience": "", "ad_group_criterion.bid_modifier": 0.0, "ad_group_criterion.combined_audience.combined_audience": "", "ad_group_criterion.cpc_bid_micros": 0, "ad_group_criterion.cpm_bid_micros": 0, "ad_group_criterion.cpv_bid_micros": 0, "ad_group_criterion.criterion_id": 82426333464, "ad_group_criterion.custom_affinity.custom_affinity": "", "ad_group_criterion.custom_audience.custom_audience": "", "ad_group_criterion.custom_intent.custom_intent": "", "ad_group_criterion.disapproval_reasons": [], "ad_group_criterion.display_name": "uservertical::80530", "ad_group_criterion.effective_cpc_bid_micros": 0, "ad_group_criterion.effective_cpc_bid_source": "UNSPECIFIED", "ad_group_criterion.effective_cpm_bid_micros": 10000, "ad_group_criterion.effective_cpm_bid_source": "AD_GROUP", "ad_group_criterion.effective_cpv_bid_micros": 10000, "ad_group_criterion.effective_cpv_bid_source": "AD_GROUP", "ad_group_criterion.effective_percent_cpc_bid_micros": 0, "ad_group_criterion.effective_percent_cpc_bid_source": "UNSPECIFIED", "ad_group_criterion.final_mobile_urls": [], "ad_group_criterion.final_url_suffix": "", "ad_group_criterion.final_urls": [], "ad_group_criterion.gender.type": "UNSPECIFIED", "ad_group_criterion.income_range.type": "UNSPECIFIED", "ad_group_criterion.keyword.match_type": "UNSPECIFIED", "ad_group_criterion.keyword.text": "", "ad_group_criterion.labels": [], "ad_group_criterion.mobile_app_category.mobile_app_category_constant": "", "ad_group_criterion.mobile_application.app_id": "", "ad_group_criterion.mobile_application.name": "", "ad_group_criterion.negative": false, "ad_group_criterion.parental_status.type": "UNSPECIFIED", "ad_group_criterion.percent_cpc_bid_micros": 0, "ad_group_criterion.placement.url": "", "ad_group_criterion.position_estimates.estimated_add_clicks_at_first_position_cpc": 0, "ad_group_criterion.position_estimates.estimated_add_cost_at_first_position_cpc": 0, "ad_group_criterion.position_estimates.first_page_cpc_micros": 0, "ad_group_criterion.position_estimates.first_position_cpc_micros": 0, "ad_group_criterion.position_estimates.top_of_page_cpc_micros": 0, "ad_group_criterion.quality_info.creative_quality_score": "UNSPECIFIED", "ad_group_criterion.quality_info.post_click_quality_score": "UNSPECIFIED", "ad_group_criterion.quality_info.quality_score": 0, "ad_group_criterion.quality_info.search_predicted_ctr": "UNSPECIFIED", "ad_group_criterion.resource_name": "customers/4651612872/adGroupCriteria/143992182864~82426333464", "ad_group_criterion.status": "ENABLED", "ad_group_criterion.system_serving_status": "ELIGIBLE", "ad_group_criterion.topic.path": [], "ad_group_criterion.topic.topic_constant": "", "ad_group_criterion.tracking_url_template": "", "ad_group_criterion.type": "USER_INTEREST", "ad_group_criterion.url_custom_parameters": [], "ad_group_criterion.user_interest.user_interest_category": "customers/4651612872/userInterests/80530", "ad_group_criterion.user_list.user_list": "", "ad_group_criterion.webpage.conditions": [], "ad_group_criterion.webpage.coverage_percentage": 0.0, "ad_group_criterion.webpage.criterion_name": "", "ad_group_criterion.webpage.sample.sample_urls": [], "ad_group_criterion.youtube_channel.channel_id": "", "ad_group_criterion.youtube_video.video_id": ""}, "emitted_at": 1689230748366} +{"stream": "ad_group_criterions", "data": {"ad_group.id": 143992182864, "ad_group_criterion.ad_group": "customers/4651612872/adGroups/143992182864", "ad_group_criterion.age_range.type": "UNSPECIFIED", "ad_group_criterion.app_payment_model.type": "UNSPECIFIED", "ad_group_criterion.approval_status": "APPROVED", "ad_group_criterion.audience.audience": "", "ad_group_criterion.bid_modifier": 0.0, "ad_group_criterion.combined_audience.combined_audience": "", "ad_group_criterion.cpc_bid_micros": 0, "ad_group_criterion.cpm_bid_micros": 0, "ad_group_criterion.cpv_bid_micros": 0, "ad_group_criterion.criterion_id": 297422806498, "ad_group_criterion.custom_affinity.custom_affinity": "", "ad_group_criterion.custom_audience.custom_audience": "", "ad_group_criterion.custom_intent.custom_intent": "", "ad_group_criterion.disapproval_reasons": [], "ad_group_criterion.display_name": "api integration", "ad_group_criterion.effective_cpc_bid_micros": 0, "ad_group_criterion.effective_cpc_bid_source": "UNSPECIFIED", "ad_group_criterion.effective_cpm_bid_micros": 10000, "ad_group_criterion.effective_cpm_bid_source": "AD_GROUP", "ad_group_criterion.effective_cpv_bid_micros": 10000, "ad_group_criterion.effective_cpv_bid_source": "AD_GROUP", "ad_group_criterion.effective_percent_cpc_bid_micros": 0, "ad_group_criterion.effective_percent_cpc_bid_source": "UNSPECIFIED", "ad_group_criterion.final_mobile_urls": [], "ad_group_criterion.final_url_suffix": "", "ad_group_criterion.final_urls": [], "ad_group_criterion.gender.type": "UNSPECIFIED", "ad_group_criterion.income_range.type": "UNSPECIFIED", "ad_group_criterion.keyword.match_type": "BROAD", "ad_group_criterion.keyword.text": "api integration", "ad_group_criterion.labels": [], "ad_group_criterion.mobile_app_category.mobile_app_category_constant": "", "ad_group_criterion.mobile_application.app_id": "", "ad_group_criterion.mobile_application.name": "", "ad_group_criterion.negative": false, "ad_group_criterion.parental_status.type": "UNSPECIFIED", "ad_group_criterion.percent_cpc_bid_micros": 0, "ad_group_criterion.placement.url": "", "ad_group_criterion.position_estimates.estimated_add_clicks_at_first_position_cpc": 0, "ad_group_criterion.position_estimates.estimated_add_cost_at_first_position_cpc": 0, "ad_group_criterion.position_estimates.first_page_cpc_micros": 0, "ad_group_criterion.position_estimates.first_position_cpc_micros": 0, "ad_group_criterion.position_estimates.top_of_page_cpc_micros": 0, "ad_group_criterion.quality_info.creative_quality_score": "UNSPECIFIED", "ad_group_criterion.quality_info.post_click_quality_score": "UNSPECIFIED", "ad_group_criterion.quality_info.quality_score": 0, "ad_group_criterion.quality_info.search_predicted_ctr": "UNSPECIFIED", "ad_group_criterion.resource_name": "customers/4651612872/adGroupCriteria/143992182864~297422806498", "ad_group_criterion.status": "ENABLED", "ad_group_criterion.system_serving_status": "ELIGIBLE", "ad_group_criterion.topic.path": [], "ad_group_criterion.topic.topic_constant": "", "ad_group_criterion.tracking_url_template": "", "ad_group_criterion.type": "KEYWORD", "ad_group_criterion.url_custom_parameters": [], "ad_group_criterion.user_interest.user_interest_category": "", "ad_group_criterion.user_list.user_list": "", "ad_group_criterion.webpage.conditions": [], "ad_group_criterion.webpage.coverage_percentage": 0.0, "ad_group_criterion.webpage.criterion_name": "", "ad_group_criterion.webpage.sample.sample_urls": [], "ad_group_criterion.youtube_channel.channel_id": "", "ad_group_criterion.youtube_video.video_id": ""}, "emitted_at": 1689230748368} +{"stream": "ad_listing_group_criterions", "data": {"ad_group.id": 143992182864, "ad_group_criterion.criterion_id": 82426333464, "ad_group_criterion.listing_group.case_value.activity_country.value": "", "ad_group_criterion.listing_group.case_value.activity_id.value": "", "ad_group_criterion.listing_group.case_value.activity_rating.value": 0, "ad_group_criterion.listing_group.case_value.hotel_city.city_criterion": "", "ad_group_criterion.listing_group.case_value.hotel_class.value": 0, "ad_group_criterion.listing_group.case_value.hotel_country_region.country_region_criterion": "", "ad_group_criterion.listing_group.case_value.hotel_id.value": "", "ad_group_criterion.listing_group.case_value.hotel_state.state_criterion": "", "ad_group_criterion.listing_group.case_value.product_bidding_category.id": 0, "ad_group_criterion.listing_group.case_value.product_bidding_category.level": "UNSPECIFIED", "ad_group_criterion.listing_group.case_value.product_brand.value": "", "ad_group_criterion.listing_group.case_value.product_channel.channel": "UNSPECIFIED", "ad_group_criterion.listing_group.case_value.product_channel_exclusivity.channel_exclusivity": "UNSPECIFIED", "ad_group_criterion.listing_group.case_value.product_condition.condition": "UNSPECIFIED", "ad_group_criterion.listing_group.case_value.product_custom_attribute.index": "UNSPECIFIED", "ad_group_criterion.listing_group.case_value.product_custom_attribute.value": "", "ad_group_criterion.listing_group.case_value.product_item_id.value": "", "ad_group_criterion.listing_group.case_value.product_type.level": "UNSPECIFIED", "ad_group_criterion.listing_group.case_value.product_type.value": "", "ad_group_criterion.listing_group.parent_ad_group_criterion": "", "ad_group_criterion.listing_group.type": "UNSPECIFIED"}, "emitted_at": 1689230749081} +{"stream": "ad_listing_group_criterions", "data": {"ad_group.id": 143992182864, "ad_group_criterion.criterion_id": 297422806498, "ad_group_criterion.listing_group.case_value.activity_country.value": "", "ad_group_criterion.listing_group.case_value.activity_id.value": "", "ad_group_criterion.listing_group.case_value.activity_rating.value": 0, "ad_group_criterion.listing_group.case_value.hotel_city.city_criterion": "", "ad_group_criterion.listing_group.case_value.hotel_class.value": 0, "ad_group_criterion.listing_group.case_value.hotel_country_region.country_region_criterion": "", "ad_group_criterion.listing_group.case_value.hotel_id.value": "", "ad_group_criterion.listing_group.case_value.hotel_state.state_criterion": "", "ad_group_criterion.listing_group.case_value.product_bidding_category.id": 0, "ad_group_criterion.listing_group.case_value.product_bidding_category.level": "UNSPECIFIED", "ad_group_criterion.listing_group.case_value.product_brand.value": "", "ad_group_criterion.listing_group.case_value.product_channel.channel": "UNSPECIFIED", "ad_group_criterion.listing_group.case_value.product_channel_exclusivity.channel_exclusivity": "UNSPECIFIED", "ad_group_criterion.listing_group.case_value.product_condition.condition": "UNSPECIFIED", "ad_group_criterion.listing_group.case_value.product_custom_attribute.index": "UNSPECIFIED", "ad_group_criterion.listing_group.case_value.product_custom_attribute.value": "", "ad_group_criterion.listing_group.case_value.product_item_id.value": "", "ad_group_criterion.listing_group.case_value.product_type.level": "UNSPECIFIED", "ad_group_criterion.listing_group.case_value.product_type.value": "", "ad_group_criterion.listing_group.parent_ad_group_criterion": "", "ad_group_criterion.listing_group.type": "UNSPECIFIED"}, "emitted_at": 1689230749082} diff --git a/airbyte-integrations/connectors/source-google-ads/integration_tests/incremental_catalog.json b/airbyte-integrations/connectors/source-google-ads/integration_tests/incremental_catalog.json index 071e65aa7c40..afddf1ceca7d 100644 --- a/airbyte-integrations/connectors/source-google-ads/integration_tests/incremental_catalog.json +++ b/airbyte-integrations/connectors/source-google-ads/integration_tests/incremental_catalog.json @@ -182,6 +182,34 @@ "sync_mode": "incremental", "destination_sync_mode": "overwrite", "cursor_field": ["segments.date"] + }, + { + "stream": { + "name": "campaign_bidding_strategies", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_primary_key": [["campaign.id"], ["bidding_strategy.id"], ["segments.date"]], + "source_defined_cursor": true, + "default_cursor_field": ["segments.date"] + }, + "sync_mode": "incremental", + "destination_sync_mode": "append", + "primary_key": [["campaign.id"], ["bidding_strategy.id"], ["segments.date"]], + "cursor_field": ["segments.date"] + }, + { + "stream": { + "name": "ad_group_bidding_strategies", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_primary_key": [["ad_group.id"], ["bidding_strategy.id"], ["segments.date"]], + "source_defined_cursor": true, + "default_cursor_field": ["segments.date"] + }, + "sync_mode": "incremental", + "destination_sync_mode": "append", + "primary_key": [["ad_group.id"], ["bidding_strategy.id"], ["segments.date"]], + "cursor_field": ["segments.date"] } ] } diff --git a/airbyte-integrations/connectors/source-google-ads/metadata.yaml b/airbyte-integrations/connectors/source-google-ads/metadata.yaml index ba2a4e207391..912b514a5b5d 100644 --- a/airbyte-integrations/connectors/source-google-ads/metadata.yaml +++ b/airbyte-integrations/connectors/source-google-ads/metadata.yaml @@ -6,7 +6,7 @@ data: connectorSubtype: api connectorType: source definitionId: 253487c0-2246-43ba-a21f-5116b20a2c50 - dockerImageTag: 0.6.1 + dockerImageTag: 0.7.0 dockerRepository: airbyte/source-google-ads githubIssueLabel: source-google-ads icon: google-adwords.svg diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/google_ads.py b/airbyte-integrations/connectors/source-google-ads/source_google_ads/google_ads.py index 414f784893dd..dc67173a5d85 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/google_ads.py +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/google_ads.py @@ -18,25 +18,33 @@ REPORT_MAPPING = { "accounts": "customer", - "service_accounts": "customer", + "account_labels": "customer_label", + "account_performance_report": "customer", "ad_group_ads": "ad_group_ad", "ad_group_ad_labels": "ad_group_ad_label", + "ad_group_ad_report": "ad_group_ad", "ad_groups": "ad_group", + "ad_group_bidding_strategies": "ad_group", + "ad_group_criterions": "ad_group_criterion", + "ad_group_criterion_labels": "ad_group_criterion_label", "ad_group_labels": "ad_group_label", + "ad_listing_group_criterions": "ad_group_criterion", + "audience": "audience", "campaigns": "campaign", + "campaign_real_time_bidding_settings": "campaign", + "campaign_bidding_strategies": "campaign", "campaign_budget": "campaign_budget", "campaign_labels": "campaign_label", - "account_performance_report": "customer", - "ad_group_ad_report": "ad_group_ad", + "click_view": "click_view", "display_keyword_performance_report": "display_keyword_view", "display_topics_performance_report": "topic_view", - "shopping_performance_report": "shopping_performance_view", - "user_location_report": "user_location_view", - "click_view": "click_view", "geographic_report": "geographic_view", "keyword_report": "keyword_view", + "labels": "label", + "service_accounts": "customer", + "shopping_performance_report": "shopping_performance_view", "user_interest": "user_interest", - "audience": "audience", + "user_location_report": "user_location_view", } API_VERSION = "v13" logger = logging.getLogger("airbyte") diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/account_labels.json b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/account_labels.json new file mode 100644 index 000000000000..294e82084a59 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/account_labels.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "customer_label.resource_name": { + "type": ["null", "string"] + }, + "customer_label.customer": { + "type": ["null", "string"] + }, + "customer.id": { + "type": ["null", "integer"] + }, + "customer_label.label": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/ad_group_bidding_strategies.json b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/ad_group_bidding_strategies.json new file mode 100644 index 000000000000..bc1b798dc61e --- /dev/null +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/ad_group_bidding_strategies.json @@ -0,0 +1,96 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "ad_group.id": { + "type": ["null", "integer"] + }, + "bidding_strategy.aligned_campaign_budget_id": { + "type": ["null", "integer"] + }, + "bidding_strategy.campaign_count": { + "type": ["null", "integer"] + }, + "bidding_strategy.currency_code": { + "type": ["null", "string"] + }, + "bidding_strategy.effective_currency_code": { + "type": ["null", "string"] + }, + "bidding_strategy.enhanced_cpc": { + "type": ["null", "string"] + }, + "bidding_strategy.id": { + "type": ["null", "integer"] + }, + "bidding_strategy.maximize_conversion_value.cpc_bid_ceiling_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.maximize_conversion_value.cpc_bid_floor_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.maximize_conversion_value.target_roas": { + "type": ["null", "number"] + }, + "bidding_strategy.maximize_conversions.cpc_bid_ceiling_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.maximize_conversions.cpc_bid_floor_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.maximize_conversions.target_cpa_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.name": { + "type": ["null", "string"] + }, + "bidding_strategy.non_removed_campaign_count": { + "type": ["null", "integer"] + }, + "bidding_strategy.resource_name": { + "type": ["null", "string"] + }, + "bidding_strategy.status": { + "type": ["null", "string"] + }, + "bidding_strategy.target_cpa.cpc_bid_ceiling_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.target_cpa.cpc_bid_floor_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.target_cpa.target_cpa_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.target_impression_share.cpc_bid_ceiling_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.target_impression_share.location": { + "type": ["null", "string"] + }, + "bidding_strategy.target_impression_share.location_fraction_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.target_roas.cpc_bid_ceiling_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.target_roas.cpc_bid_floor_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.target_roas.target_roas": { + "type": ["null", "number"] + }, + "bidding_strategy.target_spend.cpc_bid_ceiling_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.target_spend.target_spend_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.type": { + "type": ["null", "string"] + }, + "segments.date": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/ad_group_criterion_labels.json b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/ad_group_criterion_labels.json new file mode 100644 index 000000000000..16d04dd4720c --- /dev/null +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/ad_group_criterion_labels.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "ad_group_criterion_label.ad_group_criterion": { + "type": ["null", "string"] + }, + "ad_group_criterion_label.label": { + "type": ["null", "string"] + }, + "ad_group_criterion_label.resource_name": { + "type": ["null", "string"] + }, + "ad_group_criterion.criterion_id": { + "type": ["null", "integer"] + } + } +} diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/ad_group_criterions.json b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/ad_group_criterions.json new file mode 100644 index 000000000000..bf90272fbb3c --- /dev/null +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/ad_group_criterions.json @@ -0,0 +1,225 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "ad_group.id": { + "type": ["null", "integer"] + }, + "ad_group_criterion.ad_group": { + "type": ["null", "string"] + }, + "ad_group_criterion.age_range.type": { + "type": ["null", "string"] + }, + "ad_group_criterion.app_payment_model.type": { + "type": ["null", "string"] + }, + "ad_group_criterion.approval_status": { + "type": ["null", "string"] + }, + "ad_group_criterion.audience.audience": { + "type": ["null", "string"] + }, + "ad_group_criterion.bid_modifier": { + "type": ["null", "number"] + }, + "ad_group_criterion.combined_audience.combined_audience": { + "type": ["null", "string"] + }, + "ad_group_criterion.cpc_bid_micros": { + "type": ["null", "integer"] + }, + "ad_group_criterion.cpm_bid_micros": { + "type": ["null", "integer"] + }, + "ad_group_criterion.cpv_bid_micros": { + "type": ["null", "integer"] + }, + "ad_group_criterion.criterion_id": { + "type": ["null", "integer"] + }, + "ad_group_criterion.custom_affinity.custom_affinity": { + "type": ["null", "string"] + }, + "ad_group_criterion.custom_audience.custom_audience": { + "type": ["null", "string"] + }, + "ad_group_criterion.custom_intent.custom_intent": { + "type": ["null", "string"] + }, + "ad_group_criterion.disapproval_reasons": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "ad_group_criterion.display_name": { + "type": ["null", "string"] + }, + "ad_group_criterion.effective_cpc_bid_micros": { + "type": ["null", "integer"] + }, + "ad_group_criterion.effective_cpc_bid_source": { + "type": ["null", "string"] + }, + "ad_group_criterion.effective_cpm_bid_micros": { + "type": ["null", "integer"] + }, + "ad_group_criterion.effective_cpm_bid_source": { + "type": ["null", "string"] + }, + "ad_group_criterion.effective_cpv_bid_micros": { + "type": ["null", "integer"] + }, + "ad_group_criterion.effective_cpv_bid_source": { + "type": ["null", "string"] + }, + "ad_group_criterion.effective_percent_cpc_bid_micros": { + "type": ["null", "integer"] + }, + "ad_group_criterion.effective_percent_cpc_bid_source": { + "type": ["null", "string"] + }, + "ad_group_criterion.final_mobile_urls": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "ad_group_criterion.final_url_suffix": { + "type": ["null", "string"] + }, + "ad_group_criterion.final_urls": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "ad_group_criterion.gender.type": { + "type": ["null", "string"] + }, + "ad_group_criterion.income_range.type": { + "type": ["null", "string"] + }, + "ad_group_criterion.keyword.match_type": { + "type": ["null", "string"] + }, + "ad_group_criterion.keyword.text": { + "type": ["null", "string"] + }, + "ad_group_criterion.labels": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "ad_group_criterion.mobile_app_category.mobile_app_category_constant": { + "type": ["null", "string"] + }, + "ad_group_criterion.mobile_application.app_id": { + "type": ["null", "string"] + }, + "ad_group_criterion.mobile_application.name": { + "type": ["null", "string"] + }, + "ad_group_criterion.negative": { + "type": ["null", "boolean"] + }, + "ad_group_criterion.parental_status.type": { + "type": ["null", "string"] + }, + "ad_group_criterion.percent_cpc_bid_micros": { + "type": ["null", "integer"] + }, + "ad_group_criterion.placement.url": { + "type": ["null", "string"] + }, + "ad_group_criterion.position_estimates.estimated_add_clicks_at_first_position_cpc": { + "type": ["null", "integer"] + }, + "ad_group_criterion.position_estimates.estimated_add_cost_at_first_position_cpc": { + "type": ["null", "integer"] + }, + "ad_group_criterion.position_estimates.first_page_cpc_micros": { + "type": ["null", "integer"] + }, + "ad_group_criterion.position_estimates.first_position_cpc_micros": { + "type": ["null", "integer"] + }, + "ad_group_criterion.position_estimates.top_of_page_cpc_micros": { + "type": ["null", "integer"] + }, + "ad_group_criterion.quality_info.creative_quality_score": { + "type": ["null", "string"] + }, + "ad_group_criterion.quality_info.post_click_quality_score": { + "type": ["null", "string"] + }, + "ad_group_criterion.quality_info.quality_score": { + "type": ["null", "integer"] + }, + "ad_group_criterion.quality_info.search_predicted_ctr": { + "type": ["null", "string"] + }, + "ad_group_criterion.resource_name": { + "type": ["null", "string"] + }, + "ad_group_criterion.status": { + "type": ["null", "string"] + }, + "ad_group_criterion.system_serving_status": { + "type": ["null", "string"] + }, + "ad_group_criterion.topic.path": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "ad_group_criterion.topic.topic_constant": { + "type": ["null", "string"] + }, + "ad_group_criterion.tracking_url_template": { + "type": ["null", "string"] + }, + "ad_group_criterion.type": { + "type": ["null", "string"] + }, + "ad_group_criterion.url_custom_parameters": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"] + } + }, + "ad_group_criterion.user_interest.user_interest_category": { + "type": ["null", "string"] + }, + "ad_group_criterion.user_list.user_list": { + "type": ["null", "string"] + }, + "ad_group_criterion.webpage.conditions": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "ad_group_criterion.webpage.coverage_percentage": { + "type": ["null", "number"] + }, + "ad_group_criterion.webpage.criterion_name": { + "type": ["null", "string"] + }, + "ad_group_criterion.webpage.sample.sample_urls": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "ad_group_criterion.youtube_channel.channel_id": { + "type": ["null", "string"] + }, + "ad_group_criterion.youtube_video.video_id": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/ad_listing_group_criterions.json b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/ad_listing_group_criterions.json new file mode 100644 index 000000000000..bfd193ddef36 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/ad_listing_group_criterions.json @@ -0,0 +1,75 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "ad_group.id": { + "type": ["null", "integer"] + }, + "ad_group_criterion.criterion_id": { + "type": ["null", "integer"] + }, + "ad_group_criterion.listing_group.case_value.activity_country.value": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.case_value.activity_id.value": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.case_value.activity_rating.value": { + "type": ["null", "integer"] + }, + "ad_group_criterion.listing_group.case_value.hotel_city.city_criterion": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.case_value.hotel_class.value": { + "type": ["null", "integer"] + }, + "ad_group_criterion.listing_group.case_value.hotel_country_region.country_region_criterion": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.case_value.hotel_id.value": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.case_value.hotel_state.state_criterion": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.case_value.product_bidding_category.id": { + "type": ["null", "integer"] + }, + "ad_group_criterion.listing_group.case_value.product_bidding_category.level": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.case_value.product_brand.value": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.case_value.product_channel.channel": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.case_value.product_channel_exclusivity.channel_exclusivity": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.case_value.product_condition.condition": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.case_value.product_custom_attribute.index": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.case_value.product_custom_attribute.value": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.case_value.product_item_id.value": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.case_value.product_type.level": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.case_value.product_type.value": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.parent_ad_group_criterion": { + "type": ["null", "string"] + }, + "ad_group_criterion.listing_group.type": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/campaign_bidding_strategies.json b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/campaign_bidding_strategies.json new file mode 100644 index 000000000000..32493bfd957e --- /dev/null +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/campaign_bidding_strategies.json @@ -0,0 +1,96 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "campaign.id": { + "type": ["null", "integer"] + }, + "bidding_strategy.aligned_campaign_budget_id": { + "type": ["null", "integer"] + }, + "bidding_strategy.campaign_count": { + "type": ["null", "integer"] + }, + "bidding_strategy.currency_code": { + "type": ["null", "string"] + }, + "bidding_strategy.effective_currency_code": { + "type": ["null", "string"] + }, + "bidding_strategy.enhanced_cpc": { + "type": ["null", "string"] + }, + "bidding_strategy.id": { + "type": ["null", "integer"] + }, + "bidding_strategy.maximize_conversion_value.cpc_bid_ceiling_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.maximize_conversion_value.cpc_bid_floor_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.maximize_conversion_value.target_roas": { + "type": ["null", "number"] + }, + "bidding_strategy.maximize_conversions.cpc_bid_ceiling_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.maximize_conversions.cpc_bid_floor_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.maximize_conversions.target_cpa_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.name": { + "type": ["null", "string"] + }, + "bidding_strategy.non_removed_campaign_count": { + "type": ["null", "integer"] + }, + "bidding_strategy.resource_name": { + "type": ["null", "string"] + }, + "bidding_strategy.status": { + "type": ["null", "string"] + }, + "bidding_strategy.target_cpa.cpc_bid_ceiling_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.target_cpa.cpc_bid_floor_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.target_cpa.target_cpa_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.target_impression_share.cpc_bid_ceiling_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.target_impression_share.location": { + "type": ["null", "string"] + }, + "bidding_strategy.target_impression_share.location_fraction_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.target_roas.cpc_bid_ceiling_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.target_roas.cpc_bid_floor_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.target_roas.target_roas": { + "type": ["null", "number"] + }, + "bidding_strategy.target_spend.cpc_bid_ceiling_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.target_spend.target_spend_micros": { + "type": ["null", "integer"] + }, + "bidding_strategy.type": { + "type": ["null", "string"] + }, + "segments.date": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/labels.json b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/labels.json new file mode 100644 index 000000000000..1621d5831bc2 --- /dev/null +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/schemas/labels.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "label.id": { + "type": ["null", "integer"] + }, + "label.name": { + "type": ["null", "string"] + }, + "label.resource_name": { + "type": ["null", "string"] + }, + "label.status": { + "type": ["null", "string"] + }, + "label.text_label.background_color": { + "type": ["null", "string"] + }, + "label.text_label.description": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py b/airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py index ec5f59d998af..e7c485e08e63 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/source.py @@ -20,14 +20,20 @@ from .google_ads import GoogleAds from .models import Customer from .streams import ( + AccountLabels, AccountPerformanceReport, Accounts, AdGroupAdLabels, AdGroupAdReport, AdGroupAds, + AdGroupBiddingStrategies, + AdGroupCriterionLabels, + AdGroupCriterions, AdGroupLabels, AdGroups, + AdListingGroupCriterions, Audience, + CampaignBiddingStrategies, CampaignBudget, CampaignLabels, Campaigns, @@ -36,6 +42,7 @@ DisplayTopicsPerformanceReport, GeographicReport, KeywordReport, + Labels, ServiceAccounts, ShoppingPerformanceReport, UserInterest, @@ -149,12 +156,19 @@ def streams(self, config: Mapping[str, Any]) -> List[Stream]: AdGroupAds(**incremental_config), AdGroupAdLabels(google_api, customers=customers), AdGroups(**incremental_config), + AdGroupBiddingStrategies(**incremental_config), + AdGroupCriterions(google_api, customers=customers), + AdGroupCriterionLabels(google_api, customers=customers), AdGroupLabels(google_api, customers=customers), + AdListingGroupCriterions(google_api, customers=customers), Accounts(**incremental_config), + AccountLabels(google_api, customers=customers), Audience(google_api, customers=customers), + CampaignBiddingStrategies(**incremental_config), CampaignBudget(**incremental_config), CampaignLabels(google_api, customers=customers), ClickView(**incremental_config), + Labels(google_api, customers=customers), UserInterest(google_api, customers=customers), ] # Metrics streams cannot be requested for a manager account. diff --git a/airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py b/airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py index 6a08b30ad57c..839ba20af121 100644 --- a/airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py +++ b/airbyte-integrations/connectors/source-google-ads/source_google_ads/streams.py @@ -260,6 +260,14 @@ class Accounts(IncrementalGoogleAdsStream): primary_key = ["customer.id", "segments.date"] +class AccountLabels(GoogleAdsStream): + """ + Account Labels stream: https://developers.google.com/google-ads/api/fields/v14/customer_label + """ + + primary_key = ["customer_label.resource_name"] + + class ServiceAccounts(GoogleAdsStream): """ This stream is intended to be used as a service class, not exposed to a user @@ -287,6 +295,15 @@ class CampaignBudget(IncrementalGoogleAdsStream): primary_key = ["campaign_budget.id", "segments.date"] +class CampaignBiddingStrategies(IncrementalGoogleAdsStream): + """ + Campaign Bidding Strategies stream: https://developers.google.com/google-ads/api/fields/v14/campaign + """ + + transformer = TypeTransformer(TransformConfig.DefaultSchemaNormalization) + primary_key = ["campaign.id", "bidding_strategy.id", "segments.date"] + + class CampaignLabels(GoogleAdsStream): """ Campaign labels stream: https://developers.google.com/google-ads/api/fields/v11/campaign_label @@ -313,6 +330,42 @@ class AdGroupLabels(GoogleAdsStream): primary_key = ["ad_group_label.resource_name"] +class AdGroupBiddingStrategies(IncrementalGoogleAdsStream): + """ + Ad Group Bidding Strategies stream: https://developers.google.com/google-ads/api/fields/v14/ad_group + """ + + transformer = TypeTransformer(TransformConfig.DefaultSchemaNormalization) + primary_key = ["ad_group.id", "bidding_strategy.id", "segments.date"] + + +class AdGroupCriterions(GoogleAdsStream): + """ + Ad Group Criterions stream: https://developers.google.com/google-ads/api/fields/v14/ad_group_criterion + """ + + transformer = TypeTransformer(TransformConfig.DefaultSchemaNormalization) + primary_key = ["ad_group.id", "ad_group_criterion.criterion_id"] + + +class AdGroupCriterionLabels(GoogleAdsStream): + """ + Ad Group Criterion Labels stream: https://developers.google.com/google-ads/api/fields/v14/ad_group_criterion_label + """ + + transformer = TypeTransformer(TransformConfig.DefaultSchemaNormalization) + primary_key = ["ad_group_criterion_label.resource_name"] + + +class AdListingGroupCriterions(GoogleAdsStream): + """ + Ad Group Criterions stream: https://developers.google.com/google-ads/api/fields/v14/ad_group_criterion + """ + + transformer = TypeTransformer(TransformConfig.DefaultSchemaNormalization) + primary_key = ["ad_group.id", "ad_group_criterion.criterion_id"] + + class AdGroupAds(IncrementalGoogleAdsStream): """ AdGroups stream: https://developers.google.com/google-ads/api/fields/v11/ad_group_ad @@ -408,3 +461,11 @@ class Audience(GoogleAdsStream): """ primary_key = ["audience.id"] + + +class Labels(GoogleAdsStream): + """ + Labels stream: https://developers.google.com/google-ads/api/fields/v14/label + """ + + primary_key = ["label.id"] diff --git a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_source.py b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_source.py index b11f74ea591b..96223925dbfd 100644 --- a/airbyte-integrations/connectors/source-google-ads/unit_tests/test_source.py +++ b/airbyte-integrations/connectors/source-google-ads/unit_tests/test_source.py @@ -144,7 +144,7 @@ def test_chunk_date_range(): def test_streams_count(config, mock_account_info): source = SourceGoogleAds() streams = source.streams(config) - expected_streams_number = 22 + expected_streams_number = 29 assert len(streams) == expected_streams_number diff --git a/docs/integrations/sources/google-ads.md b/docs/integrations/sources/google-ads.md index 667f331109bc..4d240fa6bb56 100644 --- a/docs/integrations/sources/google-ads.md +++ b/docs/integrations/sources/google-ads.md @@ -106,13 +106,18 @@ The Google Ads source connector can sync the following tables. It can also sync Note that `ad_groups`, `ad_group_ads`, and `campaigns` contain a `labels` field, which should be joined against their respective `*_labels` streams if you want to view the actual labels. For example, the `ad_groups` stream contains an `ad_group.labels` field, which you would join against the `ad_group_labels` stream's `label.resource_name` field. ### Report Tables - + +- [ad_groups](https://developers.google.com/google-ads/api/fields/v14/ad_group) +- [ad_group_criterions](https://developers.google.com/google-ads/api/fields/v14/ad_group_criterion) +- [ad_group_criterion_labels](https://developers.google.com/google-ads/api/fields/v14/ad_group_criterion_label) - [campaigns](https://developers.google.com/google-ads/api/fields/v11/campaign) - [campaign budget](https://developers.google.com/google-ads/api/fields/v13/campaign_budget) +- [customer_labels](https://developers.google.com/google-ads/api/fields/v14/customer_label) - [account_performance_report](https://developers.google.com/google-ads/api/docs/migration/mapping#account_performance) - [ad_group_ad_report](https://developers.google.com/google-ads/api/docs/migration/mapping#ad_performance) - [display_keyword_report](https://developers.google.com/google-ads/api/docs/migration/mapping#display_keyword_performance) - [display_topics_report](https://developers.google.com/google-ads/api/docs/migration/mapping#display_topics_performance) +- [labels](https://developers.google.com/google-ads/api/fields/v14/label) - [shopping_performance_report](https://developers.google.com/google-ads/api/docs/migration/mapping#shopping_performance) - [user_location_report](https://developers.google.com/google-ads/api/fields/v11/user_location_view) @@ -162,6 +167,7 @@ Due to a limitation in the Google Ads API which does not allow getting performan | Version | Date | Pull Request | Subject | |:---------|:-----------|:---------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------| +| `0.7.0` | 2023-07-12 | [28246](https://github.com/airbytehq/airbyte/pull/28246) | Add new streams: labels, criterions, biddig strategies | | `0.6.1` | 2023-07-12 | [28230](https://github.com/airbytehq/airbyte/pull/28230) | Reduce amount of logs produced by the connector while working with big amount of data | | `0.6.0` | 2023-07-10 | [28078](https://github.com/airbytehq/airbyte/pull/28078) | Add new stream `Campaign Budget` | | `0.5.0` | 2023-07-07 | [28042](https://github.com/airbytehq/airbyte/pull/28042) | Add metrics & segment to `Campaigns` stream | From 48843cf8075c48d47197628abc4356ed634d20b7 Mon Sep 17 00:00:00 2001 From: Catherine Noll Date: Thu, 13 Jul 2023 11:59:42 -0400 Subject: [PATCH 59/63] File-based CDK: handle user-input schema (#28052) --- .../config/file_based_stream_config.py | 10 +- ...efault_file_based_availability_strategy.py | 13 +- .../sources/file_based/exceptions.py | 7 +- .../sources/file_based/file_based_source.py | 24 +- .../file_based/file_types/avro_parser.py | 13 +- .../file_based/file_types/csv_parser.py | 109 ++- .../file_based/file_types/file_type_parser.py | 15 +- .../file_based/file_types/jsonl_parser.py | 13 +- .../file_based/file_types/parquet_parser.py | 13 +- .../sources/file_based/schema_helpers.py | 76 +- .../abstract_schema_validation_policy.py | 1 + .../default_schema_validation_policies.py | 1 + .../stream/abstract_file_based_stream.py | 11 +- .../stream/default_file_based_stream.py | 51 +- .../file_based/file_types/test_csv_parser.py | 66 ++ .../unit_tests/sources/file_based/helpers.py | 1 + .../file_based/scenarios/check_scenarios.py | 4 +- .../file_based/scenarios/csv_scenarios.py | 23 +- .../scenarios/incremental_scenarios.py | 172 ++--- .../file_based/scenarios/scenario_builder.py | 7 +- .../scenarios/user_input_schema_scenarios.py | 720 ++++++++++++++++++ .../scenarios/validation_policy_scenarios.py | 72 +- .../sources/file_based/test_scenarios.py | 145 ++-- .../sources/file_based/test_schema_helpers.py | 104 ++- 24 files changed, 1415 insertions(+), 256 deletions(-) create mode 100644 airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_csv_parser.py create mode 100644 airbyte-cdk/python/unit_tests/sources/file_based/scenarios/user_input_schema_scenarios.py diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py index b55f98adeef8..6ee98c839a8d 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py @@ -4,8 +4,9 @@ import codecs from enum import Enum -from typing import Any, Dict, List, Mapping, Optional, Union +from typing import Any, List, Mapping, Optional, Union +from airbyte_cdk.sources.file_based.schema_helpers import type_mapping_to_jsonschema from pydantic import BaseModel, validator PrimaryKeyType = Optional[Union[str, List[str], List[List[str]]]] @@ -65,7 +66,7 @@ class FileBasedStreamConfig(BaseModel): file_type: str globs: Optional[List[str]] validation_policy: str - input_schema: Optional[Dict[str, Any]] + input_schema: Optional[Union[str, Mapping[str, Any]]] primary_key: PrimaryKeyType days_to_sync_if_history_is_full: int = 3 format: Optional[Mapping[str, CsvFormat]] # this will eventually be a Union once we have more than one format type @@ -86,3 +87,8 @@ def transform_format(cls, v): raise ValueError(f"Format filetype {file_type} is not a supported file type") return {file_type: {key: val for key, val in v.items()}} return v + + @validator("input_schema", pre=True) + def transform_input_schema(cls, v): + if v: + return type_mapping_to_jsonschema(v) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/default_file_based_availability_strategy.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/default_file_based_availability_strategy.py index b9cda94713cf..6b051f0b1af6 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/default_file_based_availability_strategy.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/default_file_based_availability_strategy.py @@ -10,6 +10,7 @@ from airbyte_cdk.sources.file_based.exceptions import CheckAvailabilityError, FileBasedSourceError from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader from airbyte_cdk.sources.file_based.remote_file import RemoteFile +from airbyte_cdk.sources.file_based.schema_helpers import conforms_to_schema from airbyte_cdk.sources.file_based.stream import AbstractFileBasedStream from airbyte_cdk.sources.streams.availability_strategy import AvailabilityStrategy @@ -39,7 +40,7 @@ def check_availability( """ try: files = self._check_list_files(stream) - self._check_parse_record(stream, files[0]) + self._check_parse_record(stream, files[0], logger) except CheckAvailabilityError: return False, "".join(traceback.format_exc()) @@ -59,11 +60,11 @@ def _check_list_files(self, stream: AbstractFileBasedStream) -> List[RemoteFile] return files - def _check_parse_record(self, stream: AbstractFileBasedStream, file: RemoteFile): + def _check_parse_record(self, stream: AbstractFileBasedStream, file: RemoteFile, logger: logging.Logger): parser = stream.get_parser(stream.config.file_type) try: - record = next(iter(parser.parse_records(stream.config, file, self.stream_reader))) + record = next(iter(parser.parse_records(stream.config, file, self.stream_reader, logger))) except StopIteration: # The file is empty. We've verified that we can open it, so will # consider the connection check successful even though it means @@ -72,11 +73,11 @@ def _check_parse_record(self, stream: AbstractFileBasedStream, file: RemoteFile) except Exception as exc: raise CheckAvailabilityError(FileBasedSourceError.ERROR_READING_FILE, stream=stream.name, file=file.uri) from exc - if stream.config.input_schema: - if not stream.record_passes_validation_policy(record): + schema = stream.catalog_schema or stream.config.input_schema + if schema and stream.validation_policy.validate_schema_before_sync: + if not conforms_to_schema(record, schema): raise CheckAvailabilityError( FileBasedSourceError.ERROR_VALIDATING_RECORD, stream=stream.name, file=file.uri, - validation_policy=stream.config.validation_policy, ) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/exceptions.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/exceptions.py index acad810899e3..a5829bc84346 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/exceptions.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/exceptions.py @@ -11,6 +11,9 @@ class FileBasedSourceError(Enum): GLOB_PARSE_ERROR = ( "Error parsing glob pattern. Please refer to the glob pattern rules at https://facelessuser.github.io/wcmatch/glob/#split." ) + ERROR_CASTING_VALUE = "Could not cast the value to the expected type." + ERROR_CASTING_VALUE_UNRECOGNIZED_TYPE = "Could not cast the value to the expected type because the type is not recognized. Valid types are null, array, boolean, integer, number, object, and string." + ERROR_DECODING_VALUE = "Expected a JSON-decodeable value but could not decode record." ERROR_LISTING_FILES = ( "Error listing files. Please check the credentials provided in the config and verify that they provide permission to list files." ) @@ -18,14 +21,14 @@ class FileBasedSourceError(Enum): "Error opening file. Please check the credentials provided in the config and verify that they provide permission to read files." ) ERROR_PARSING_RECORD = "Error parsing record. This could be due to a mismatch between the config's file type and the actual file type, or because the file or record is not parseable." - ERROR_PARSING_USER_PROVIDED_SCHEMA = "The provided schema could not be transformed into valid JSON Schema." # TODO + ERROR_PARSING_USER_PROVIDED_SCHEMA = "The provided schema could not be transformed into valid JSON Schema." ERROR_VALIDATING_RECORD = "One or more records do not pass the schema validation policy. Please modify your input schema, or select a more lenient validation policy." STOP_SYNC_PER_SCHEMA_VALIDATION_POLICY = ( "Stopping sync in accordance with the configured validation policy. Records in file did not conform to the schema." ) NULL_VALUE_IN_SCHEMA = "Error during schema inference: no type was detected for key." UNRECOGNIZED_TYPE = "Error during schema inference: unrecognized type." - SCHEMA_INFERENCE_ERROR = "Error inferring schema for file. Is the file valid?" + SCHEMA_INFERENCE_ERROR = "Error inferring schema from files. Are the files valid?" INVALID_SCHEMA_ERROR = "No fields were identified for this schema. This may happen if the stream is empty. Please check your configuration to verify that there are files that match the stream's glob patterns." CONFIG_VALIDATION_ERROR = "Error creating stream config object." MISSING_SCHEMA = "Expected `json_schema` in the configured catalog but it is missing." diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py index c456b847acca..0d175a96dc7f 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_based_source.py @@ -47,6 +47,7 @@ def __init__( self.validation_policies = validation_policies self.stream_schemas = {s.stream.name: s.stream.json_schema for s in catalog.streams} if catalog else {} self.max_history_size = max_history_size + self.logger = logging.getLogger(f"airbyte.{self.name}") def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> Tuple[bool, Optional[Any]]: """ @@ -82,14 +83,6 @@ def check_connection(self, logger: logging.Logger, config: Mapping[str, Any]) -> return not bool(errors), (errors or None) - def _validate_stream_config(self, stream_config: FileBasedStreamConfig): - if stream_config.validation_policy not in self.validation_policies: - raise ValidationError( - f"`validation_policy` must be one of {list(self.validation_policies.keys())}", model=FileBasedStreamConfig - ) - if stream_config.input_schema and stream_config.schemaless: - raise ValidationError("`input_schema` and `schemaless` options cannot both be set", model=FileBasedStreamConfig) - def streams(self, config: Mapping[str, Any]) -> List[AbstractFileBasedStream]: """ Return a list of this source's streams. @@ -98,7 +91,7 @@ def streams(self, config: Mapping[str, Any]) -> List[AbstractFileBasedStream]: parsed_config = self.spec_class(**config) streams = [] for stream_config in parsed_config.streams: - self._validate_stream_config(stream_config) + self._validate_input_schema(stream_config) streams.append( DefaultFileBasedStream( config=stream_config, @@ -107,7 +100,7 @@ def streams(self, config: Mapping[str, Any]) -> List[AbstractFileBasedStream]: availability_strategy=self.availability_strategy, discovery_policy=self.discovery_policy, parsers=self.parsers, - validation_policies=self.validation_policies, + validation_policy=self._validate_and_get_validation_policy(stream_config), cursor=DefaultFileBasedCursor(self.max_history_size, stream_config.days_to_sync_if_history_is_full), ) ) @@ -125,3 +118,14 @@ def spec(self, *args: Any, **kwargs: Any) -> ConnectorSpecification: documentationUrl=self.spec_class.documentation_url(), connectionSpecification=self.spec_class.schema(), ) + + def _validate_and_get_validation_policy(self, stream_config: FileBasedStreamConfig): + if stream_config.validation_policy not in self.validation_policies: + raise ValidationError( + f"`validation_policy` must be one of {list(self.validation_policies.keys())}", model=FileBasedStreamConfig + ) + return self.validation_policies[stream_config.validation_policy] + + def _validate_input_schema(self, stream_config: FileBasedStreamConfig): + if stream_config.schemaless and stream_config.input_schema: + raise ValidationError("`input_schema` and `schemaless` options cannot both be set", model=FileBasedStreamConfig) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/avro_parser.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/avro_parser.py index d5c5d471ecb1..338ada88017d 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/avro_parser.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/avro_parser.py @@ -2,6 +2,7 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # +import logging from typing import Any, Dict, Iterable from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig @@ -12,11 +13,19 @@ class AvroParser(FileTypeParser): async def infer_schema( - self, config: FileBasedStreamConfig, file: RemoteFile, stream_reader: AbstractFileBasedStreamReader + self, + config: FileBasedStreamConfig, + file: RemoteFile, + stream_reader: AbstractFileBasedStreamReader, + logger: logging.Logger, ) -> Dict[str, Any]: ... def parse_records( - self, config: FileBasedStreamConfig, file: RemoteFile, stream_reader: AbstractFileBasedStreamReader + self, + config: FileBasedStreamConfig, + file: RemoteFile, + stream_reader: AbstractFileBasedStreamReader, + logger: logging.Logger, ) -> Iterable[Dict[str, Any]]: ... diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/csv_parser.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/csv_parser.py index a8ed9f4a0c87..ad297d2afc09 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/csv_parser.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/csv_parser.py @@ -3,12 +3,17 @@ # import csv -from typing import Any, Dict, Iterable +import json +import logging +from distutils.util import strtobool +from typing import Any, Dict, Iterable, Mapping, Optional from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig, QuotingBehavior +from airbyte_cdk.sources.file_based.exceptions import FileBasedSourceError from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader from airbyte_cdk.sources.file_based.file_types.file_type_parser import FileTypeParser from airbyte_cdk.sources.file_based.remote_file import RemoteFile +from airbyte_cdk.sources.file_based.schema_helpers import TYPE_PYTHON_MAPPING DIALECT_NAME = "_config_dialect" @@ -22,7 +27,11 @@ class CsvParser(FileTypeParser): async def infer_schema( - self, config: FileBasedStreamConfig, file: RemoteFile, stream_reader: AbstractFileBasedStreamReader + self, + config: FileBasedStreamConfig, + file: RemoteFile, + stream_reader: AbstractFileBasedStreamReader, + logger: logging.Logger, ) -> Dict[str, Any]: config_format = config.format.get(config.file_type) if config.format else None if config_format: @@ -48,8 +57,13 @@ async def infer_schema( return {field.strip(): {"type": "string"} for field in next(reader)} def parse_records( - self, config: FileBasedStreamConfig, file: RemoteFile, stream_reader: AbstractFileBasedStreamReader + self, + config: FileBasedStreamConfig, + file: RemoteFile, + stream_reader: AbstractFileBasedStreamReader, + logger: logging.Logger, ) -> Iterable[Dict[str, Any]]: + schema = config.input_schema config_format = config.format.get(config.file_type) if config.format else None if config_format: # Formats are configured individually per-stream so a unique dialect should be registered for each stream. @@ -67,8 +81,93 @@ def parse_records( # todo: the existing InMemoryFilesSource.open_file() test source doesn't currently require an encoding, but actual # sources will likely require one. Rather than modify the interface now we can wait until the real use case reader = csv.DictReader(fp, dialect=dialect_name) - yield from reader + yield from self._read_and_cast_types(reader, schema, logger) else: with stream_reader.open_file(file) as fp: reader = csv.DictReader(fp) - yield from reader + yield from self._read_and_cast_types(reader, schema, logger) + + @staticmethod + def _read_and_cast_types( + reader: csv.DictReader, schema: Optional[Mapping[str, str]], logger: logging.Logger + ) -> Iterable[Dict[str, Any]]: + """ + If the user provided a schema, attempt to cast the record values to the associated type. + + If a column is not in the schema or cannot be cast to an appropriate python type, + cast it to a string. Downstream, the user's validation policy will determine whether the + record should be emitted. + """ + if not schema: + yield from reader + + else: + property_types = {col: prop["type"] for col, prop in schema["properties"].items()} + for row in reader: + yield cast_types(row, property_types, logger) + + +def cast_types(row: Dict[str, str], property_types: Dict[str, Any], logger: logging.Logger) -> Dict[str, Any]: + """ + Casts the values in the input 'row' dictionary according to the types defined in the JSON schema. + + Array and object types are only handled if they can be deserialized as JSON. + + If any errors are encountered, the value will be emitted as a string. + """ + warnings = [] + result = {} + + for key, value in row.items(): + prop_type = property_types.get(key) + cast_value = value + + if prop_type in TYPE_PYTHON_MAPPING: + _, python_type = TYPE_PYTHON_MAPPING[prop_type] + + if python_type is None: + if value == "": + cast_value = None + else: + warnings.append(_format_warning(key, value, prop_type)) + + elif python_type == bool: + try: + cast_value = strtobool(value) + except ValueError: + warnings.append(_format_warning(key, value, prop_type)) + + elif python_type == dict: + try: + cast_value = json.loads(value) + except json.JSONDecodeError: + warnings.append(_format_warning(key, value, prop_type)) + + elif python_type == list: + try: + parsed_value = json.loads(value) + if isinstance(parsed_value, list): + cast_value = parsed_value + except json.JSONDecodeError: + warnings.append(_format_warning(key, value, prop_type)) + + elif python_type: + try: + cast_value = python_type(value) + except ValueError: + warnings.append(_format_warning(key, value, prop_type)) + + else: + warnings.append(_format_warning(key, value, prop_type)) + + result[key] = cast_value + + if warnings: + logger.warning( + f"{FileBasedSourceError.ERROR_CASTING_VALUE.value}: {','.join([w for w in warnings])}", + ) + return result + + +def _format_warning(key: str, value: str, expected_type: str) -> str: + return f"{key}: value={value},expected_type={expected_type}" diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/file_type_parser.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/file_type_parser.py index 119d81fcabce..4f8c75694d76 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/file_type_parser.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/file_type_parser.py @@ -2,6 +2,7 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # +import logging from abc import ABC, abstractmethod from typing import Any, Dict, Iterable @@ -20,7 +21,13 @@ class FileTypeParser(ABC): """ @abstractmethod - async def infer_schema(self, config: FileBasedStreamConfig, file: RemoteFile, stream_reader: AbstractFileBasedStreamReader) -> Schema: + async def infer_schema( + self, + config: FileBasedStreamConfig, + file: RemoteFile, + stream_reader: AbstractFileBasedStreamReader, + logger: logging.Logger, + ) -> Schema: """ Infer the JSON Schema for this file. """ @@ -28,7 +35,11 @@ async def infer_schema(self, config: FileBasedStreamConfig, file: RemoteFile, st @abstractmethod def parse_records( - self, config: FileBasedStreamConfig, file: RemoteFile, stream_reader: AbstractFileBasedStreamReader + self, + config: FileBasedStreamConfig, + file: RemoteFile, + stream_reader: AbstractFileBasedStreamReader, + logger: logging.Logger, ) -> Iterable[Record]: """ Parse and emit each record. diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/jsonl_parser.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/jsonl_parser.py index accc7579ff3c..ec5a06b8f0ad 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/jsonl_parser.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/jsonl_parser.py @@ -2,6 +2,7 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # +import logging from typing import Any, Dict, Iterable from airbyte_cdk.sources.file_based.config.file_based_stream_config import FileBasedStreamConfig @@ -15,11 +16,19 @@ class JsonlParser(FileTypeParser): MAX_BYTES_PER_FILE_FOR_SCHEMA_INFERENCE = 1_000_000 async def infer_schema( - self, config: FileBasedStreamConfig, file: RemoteFile, stream_reader: AbstractFileBasedStreamReader + self, + config: FileBasedStreamConfig, + file: RemoteFile, + stream_reader: AbstractFileBasedStreamReader, + logger: logging.Logger, ) -> Dict[str, Any]: ... def parse_records( - self, config: FileBasedStreamConfig, file: RemoteFile, stream_reader: AbstractFileBasedStreamReader + self, + config: FileBasedStreamConfig, + file: RemoteFile, + stream_reader: AbstractFileBasedStreamReader, + logger: logging.Logger, ) -> Iterable[Dict[str, Any]]: ... diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/parquet_parser.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/parquet_parser.py index 03b45000dcef..5b87679188ac 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/parquet_parser.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/file_types/parquet_parser.py @@ -3,6 +3,7 @@ # import json +import logging from typing import Any, Dict, Iterable, Mapping import pyarrow as pa @@ -16,7 +17,11 @@ class ParquetParser(FileTypeParser): async def infer_schema( - self, config: FileBasedStreamConfig, file: RemoteFile, stream_reader: AbstractFileBasedStreamReader + self, + config: FileBasedStreamConfig, + file: RemoteFile, + stream_reader: AbstractFileBasedStreamReader, + logger: logging.Logger, ) -> Dict[str, Any]: # Pyarrow can detect the schema of a parquet file by reading only its metadata. # https://github.com/apache/arrow/blob/main/python/pyarrow/_parquet.pyx#L1168-L1243 @@ -26,7 +31,11 @@ async def infer_schema( return schema def parse_records( - self, config: FileBasedStreamConfig, file: RemoteFile, stream_reader: AbstractFileBasedStreamReader + self, + config: FileBasedStreamConfig, + file: RemoteFile, + stream_reader: AbstractFileBasedStreamReader, + logger: logging.Logger, ) -> Iterable[Dict[str, Any]]: table = pq.read_table(stream_reader.open_file(file)) for batch in table.to_batches(): diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_helpers.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_helpers.py index 9954dbe5e442..61a445f64e8b 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_helpers.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_helpers.py @@ -2,19 +2,18 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # +import json from copy import deepcopy from enum import Enum from functools import total_ordering -from typing import Any, Dict, List, Literal, Mapping, Union +from typing import Any, Dict, List, Literal, Mapping, Optional, Union -from airbyte_cdk.sources.file_based.exceptions import FileBasedSourceError, SchemaInferenceError - -type_widths = {str: 0} +from airbyte_cdk.sources.file_based.exceptions import ConfigValidationError, FileBasedSourceError, SchemaInferenceError JsonSchemaSupportedType = Union[List, Literal["string"], str] SchemaType = Dict[str, Dict[str, JsonSchemaSupportedType]] -schemaless_schema = {"data": {"type": "object"}} +schemaless_schema = {"type": "object", "properties": {"data": {"type": "object"}}} @total_ordering @@ -33,6 +32,18 @@ def __lt__(self, other): return NotImplemented +TYPE_PYTHON_MAPPING = { + "null": ("null", None), + "array": ("array", list), + "boolean": ("boolean", bool), + "float": ("number", float), + "integer": ("integer", int), + "number": ("number", float), + "object": ("object", dict), + "string": ("string", str), +} + + def get_comparable_type(value: Any) -> ComparableType: if value == "null": return ComparableType.NULL @@ -116,11 +127,13 @@ def _choose_wider_type(key: str, t1: Dict[str, Any], t2: Dict[str, Any]) -> Dict detected_types=f"{t1},{t2}", ) else: - comparable_t1 = get_comparable_type(t1["type"]) - comparable_t2 = get_comparable_type(t2["type"]) + comparable_t1 = get_comparable_type(TYPE_PYTHON_MAPPING[t1["type"]][0]) # accessing the type_mapping value + comparable_t2 = get_comparable_type(TYPE_PYTHON_MAPPING[t2["type"]][0]) # accessing the type_mapping value if not comparable_t1 and comparable_t2: raise SchemaInferenceError(FileBasedSourceError.UNRECOGNIZED_TYPE, key=key, detected_types=f"{t1},{t2}") - return max([t1, t2], key=lambda x: ComparableType(get_comparable_type(x["type"]))) + return max( + [t1, t2], key=lambda x: ComparableType(get_comparable_type(TYPE_PYTHON_MAPPING[x["type"]][0])) + ) # accessing the type_mapping value def is_equal_or_narrower_type(value: Any, expected_type: str): @@ -172,8 +185,51 @@ def conforms_to_schema(record: Mapping[str, Any], schema: Mapping[str, str]) -> return True -def type_mapping_to_jsonschema(type_mapping: Mapping[str, Any]) -> Mapping[str, str]: +def _parse_json_input(input_schema: Optional[Union[str, Dict[str, str]]]) -> Optional[Mapping[str, str]]: + try: + schema = json.loads(input_schema) + if not all(isinstance(s, str) for s in schema.values()): + raise ConfigValidationError( + FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA, details="Invalid input schema; nested schemas are not supported." + ) + + except json.decoder.JSONDecodeError: + return None + + return schema + + +def type_mapping_to_jsonschema(input_schema: Optional[Union[str, Mapping[str, str]]]) -> Optional[Mapping[str, str]]: """ Return the user input schema (type mapping), transformed to JSON Schema format. + + Verify that the input schema: + - is a key:value map + - all values in the map correspond to a JsonSchema datatype """ - ... + if not input_schema: + return None + + result_schema = {} + + json_mapping = _parse_json_input(input_schema) or {} + + for col_name, type_name in json_mapping.items(): + col_name, type_name = col_name.strip(), type_name.strip() + if not (col_name and type_name): + raise ConfigValidationError( + FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA, + details=f"Invalid input schema; expected mapping in the format column_name: type, got {input_schema}.", + ) + + _json_schema_type = TYPE_PYTHON_MAPPING.get(type_name.casefold()) + + if not _json_schema_type: + raise ConfigValidationError( + FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA, details=f"Invalid type '{type_name}' for property '{col_name}'." + ) + + json_schema_type = _json_schema_type[0] + result_schema[col_name] = {"type": json_schema_type} + + return {"type": "object", "properties": result_schema} diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/abstract_schema_validation_policy.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/abstract_schema_validation_policy.py index 43ed3dd697a8..4b64d74c7dab 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/abstract_schema_validation_policy.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/abstract_schema_validation_policy.py @@ -8,6 +8,7 @@ class AbstractSchemaValidationPolicy(ABC): name: str + validate_schema_before_sync = False # Whether to verify that records conform to the schema during the stream's availabilty check @abstractmethod def record_passes_validation_policy(self, record: Mapping[str, Any], schema: Mapping[str, Any]) -> bool: diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/default_schema_validation_policies.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/default_schema_validation_policies.py index 102797b45f18..1877542342a6 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/default_schema_validation_policies.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/schema_validation_policies/default_schema_validation_policies.py @@ -25,6 +25,7 @@ def record_passes_validation_policy(self, record: Mapping[str, Any], schema: Map class WaitForDiscoverPolicy(AbstractSchemaValidationPolicy): name = "wait_for_discover" + validate_schema_before_sync = True def record_passes_validation_policy(self, record: Mapping[str, Any], schema: Mapping[str, Any]) -> bool: if not conforms_to_schema(record, schema): diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py index f538b2924cd2..9e880e713ad8 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/abstract_file_based_stream.py @@ -43,16 +43,16 @@ def __init__( availability_strategy: AvailabilityStrategy, discovery_policy: AbstractDiscoveryPolicy, parsers: Dict[str, FileTypeParser], - validation_policies: Dict[str, AbstractSchemaValidationPolicy], + validation_policy: AbstractSchemaValidationPolicy, ): super().__init__() self.config = config - self._catalog_schema = catalog_schema + self.catalog_schema = catalog_schema + self.validation_policy = validation_policy self._stream_reader = stream_reader self._discovery_policy = discovery_policy self._availability_strategy = availability_strategy self._parsers = parsers - self._validation_policies = validation_policies @property @abstractmethod @@ -125,9 +125,8 @@ def get_parser(self, file_type: str) -> FileTypeParser: raise UndefinedParserError(FileBasedSourceError.UNDEFINED_PARSER, stream=self.name, file_type=file_type) def record_passes_validation_policy(self, record: Mapping[str, Any]) -> bool: - validation_policy = self._validation_policies.get(self.config.validation_policy) - if validation_policy: - return validation_policy.record_passes_validation_policy(record=record, schema=self._catalog_schema) + if self.validation_policy: + return self.validation_policy.record_passes_validation_policy(record=record, schema=self.catalog_schema) else: raise RecordParseError( FileBasedSourceError.UNDEFINED_VALIDATION_POLICY, stream=self.name, validation_policy=self.config.validation_policy diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/default_file_based_stream.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/default_file_based_stream.py index a125a7716694..67a17dddbd41 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/default_file_based_stream.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/stream/default_file_based_stream.py @@ -4,7 +4,6 @@ import asyncio import itertools -import logging import traceback from functools import cache from typing import Any, Dict, Iterable, List, Mapping, MutableMapping, Optional, Union @@ -65,8 +64,11 @@ def compute_slices(self) -> Iterable[Optional[Mapping[str, Any]]]: def read_records_from_slice(self, stream_slice: StreamSlice) -> Iterable[Mapping[str, Any]]: """ Yield all records from all remote files in `list_files_for_this_sync`. + + If an error is encountered reading records from a file, log a message and do not attempt + to sync the rest of the file. """ - schema = self._catalog_schema + schema = self.catalog_schema if schema is None: # On read requests we should always have the catalog available raise MissingSchemaError(FileBasedSourceError.MISSING_SCHEMA, stream=self.name) @@ -77,7 +79,7 @@ def read_records_from_slice(self, stream_slice: StreamSlice) -> Iterable[Mapping n_skipped = line_no = 0 try: - for record in parser.parse_records(self.config, file, self._stream_reader): + for record in parser.parse_records(self.config, file, self._stream_reader, self.logger): line_no += 1 if self.config.schemaless: record = {"data": record} @@ -93,29 +95,30 @@ def read_records_from_slice(self, stream_slice: StreamSlice) -> Iterable[Mapping yield AirbyteMessage( type=Type.LOG, log=AirbyteLogMessage( - level=Level.INFO, + level=Level.WARN, message=f"Stopping sync in accordance with the configured validation policy. Records in file did not conform to the schema. stream={self.name} file={file.uri} validation_policy={self.config.validation_policy} n_skipped={n_skipped}", ), ) break - except Exception as exc: + except Exception: yield AirbyteMessage( type=Type.LOG, log=AirbyteLogMessage( level=Level.ERROR, message=f"{FileBasedSourceError.ERROR_PARSING_RECORD.value} stream={self.name} file={file.uri} line_no={line_no} n_skipped={n_skipped}", - stack_trace="\n".join(traceback.format_exception(etype=type(exc), value=exc, tb=exc.__traceback__)), + stack_trace=traceback.format_exc(), ), ) + break else: if n_skipped: yield AirbyteMessage( type=Type.LOG, log=AirbyteLogMessage( - level=Level.INFO, - message=f"Records in file did not pass validation policy. stream={self.name} file={file.uri} n_skipped={n_skipped} validation_policy={self.config.validation_policy}", + level=Level.WARN, + message=f"Records in file did not pass validation policy. stream={self.name} file={file.uri} n_skipped={n_skipped} validation_policy={self.validation_policy.name}", ), ) @@ -138,27 +141,35 @@ def get_json_schema(self) -> JsonSchema: except Exception as exc: raise SchemaInferenceError(FileBasedSourceError.SCHEMA_INFERENCE_ERROR, stream=self.name) from exc else: - if not schema: - raise InvalidSchemaError( - FileBasedSourceError.INVALID_SCHEMA_ERROR, - details=f"Empty schema. Please check that the files are valid {self.config.file_type}", - stream=self.name, - ) - return {"type": "object", "properties": {**extra_fields, **schema}} + schema["properties"] = {**extra_fields, **schema["properties"]} + return schema def _get_raw_json_schema(self) -> JsonSchema: if self.config.input_schema: - schema = self.config.input_schema + return self.config.input_schema elif self.config.schemaless: return schemaless_schema else: files = self.list_files() + total_n_files = len(files) max_n_files_for_schema_inference = self._discovery_policy.max_n_files_for_schema_inference - if len(files) > max_n_files_for_schema_inference: + if total_n_files > max_n_files_for_schema_inference: # Use the most recent files for schema inference, so we pick up schema changes during discovery. files = sorted(files, key=lambda x: x.last_modified, reverse=True)[:max_n_files_for_schema_inference] - logging.warning(f"Refusing to infer schema for {len(files)} files; using {max_n_files_for_schema_inference} files.") - schema = self.infer_schema(files) + self.logger.warn( + msg=f"Refusing to infer schema for all {total_n_files} files; using {max_n_files_for_schema_inference} files." + ) + + inferred_schema = self.infer_schema(files) + + if not inferred_schema: + raise InvalidSchemaError( + FileBasedSourceError.INVALID_SCHEMA_ERROR, + details=f"Empty schema. Please check that the files are valid {self.config.file_type}", + stream=self.name, + ) + + schema = {"type": "object", "properties": inferred_schema} return schema @@ -201,7 +212,7 @@ async def _infer_schema(self, files: List[RemoteFile]) -> Mapping[str, Any]: async def _infer_file_schema(self, file: RemoteFile) -> Mapping[str, Any]: try: - return await self.get_parser(self.config.file_type).infer_schema(self.config, file, self._stream_reader) + return await self.get_parser(self.config.file_type).infer_schema(self.config, file, self._stream_reader, self.logger) except Exception as exc: raise SchemaInferenceError( FileBasedSourceError.SCHEMA_INFERENCE_ERROR, diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_csv_parser.py b/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_csv_parser.py new file mode 100644 index 000000000000..746ea7671817 --- /dev/null +++ b/airbyte-cdk/python/unit_tests/sources/file_based/file_types/test_csv_parser.py @@ -0,0 +1,66 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import logging + +import pytest +from airbyte_cdk.sources.file_based.file_types.csv_parser import cast_types + +PROPERTY_TYPES = { + "col1": "null", + "col2": "boolean", + "col3": "integer", + "col4": "number", + "col5": "string", + "col6": "object", + "col7": "array", + "col8": "array", + "col9": "array", +} + +logger = logging.getLogger() + + +@pytest.mark.parametrize( + "row,expected_output", + [ + pytest.param( + { + "col1": "", + "col2": "true", + "col3": "1", + "col4": "1.1", + "col5": "asdf", + "col6": '{"a": "b"}', + "col7": '[1, 2]', + "col8": '["1", "2"]', + "col9": '[{"a": "b"}, {"a": "c"}]', + }, { + "col1": None, + "col2": True, + "col3": 1, + "col4": 1.1, + "col5": "asdf", + "col6": {"a": "b"}, + "col7": [1, 2], + "col8": ["1", "2"], + "col9": [{"a": "b"}, {"a": "c"}], + }, id="cast-all-cols"), + pytest.param({"col1": "1"}, {"col1": "1"}, id="cannot-cast-to-null"), + pytest.param({"col2": "1"}, {"col2": True}, id="cast-1-to-bool"), + pytest.param({"col2": "0"}, {"col2": False}, id="cast-0-to-bool"), + pytest.param({"col2": "yes"}, {"col2": True}, id="cast-yes-to-bool"), + pytest.param({"col2": "no"}, {"col2": False}, id="cast-no-to-bool"), + pytest.param({"col2": "10"}, {"col2": "10"}, id="cannot-cast-to-bool"), + pytest.param({"col3": "1.1"}, {"col3": "1.1"}, id="cannot-cast-to-int"), + pytest.param({"col4": "asdf"}, {"col4": "asdf"}, id="cannot-cast-to-float"), + pytest.param({"col6": "{'a': 'b'}"}, {"col6": "{'a': 'b'}"}, id="cannot-cast-to-dict"), + pytest.param({"col7": "['a', 'b']"}, {"col7": "['a', 'b']"}, id="cannot-cast-to-list-of-ints"), + pytest.param({"col8": "['a', 'b']"}, {"col8": "['a', 'b']"}, id="cannot-cast-to-list-of-strings"), + pytest.param({"col9": "['a', 'b']"}, {"col9": "['a', 'b']"}, id="cannot-cast-to-list-of-objects"), + pytest.param({"col10": "x"}, {"col10": "x"}, id="item-not-in-props-doesn't-error"), + ] +) +def test_cast_to_python_type(row, expected_output): + assert cast_types(row, PROPERTY_TYPES, logger) == expected_output diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/helpers.py b/airbyte-cdk/python/unit_tests/sources/file_based/helpers.py index 3610ac8fffc5..1ee4e4e9a922 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/helpers.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/helpers.py @@ -42,6 +42,7 @@ def open_file(self, file: RemoteFile) -> IOBase: class FailingSchemaValidationPolicy(AbstractSchemaValidationPolicy): ALWAYS_FAIL = "always_fail" + validate_schema_before_sync = True def record_passes_validation_policy(self, record: Mapping[str, Any], schema: Mapping[str, Any]) -> bool: return False diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/check_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/check_scenarios.py index 97edcbc36e30..218c1e2d5cf4 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/check_scenarios.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/check_scenarios.py @@ -112,7 +112,7 @@ "file_type": "csv", "globs": ["*.csv"], "validation_policy": "emit_record", - "input_schema": {"col1": "string", "col2": "string"}, + "input_schema": '{"col1": "string", "col2": "string"}', } ], } @@ -169,7 +169,7 @@ "file_type": "csv", "globs": ["*.csv"], "validation_policy": "always_fail", - "input_schema": {"col1": "number", "col2": "string"}, + "input_schema": '{"col1": "number", "col2": "string"}', } ], } diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py index 2edc40b0ebac..3a4d74b0f9b0 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py @@ -2,7 +2,7 @@ # Copyright (c) 2023 Airbyte, Inc., all rights reserved. # -from airbyte_cdk.sources.file_based.exceptions import ConfigValidationError, FileBasedSourceError, InvalidSchemaError, SchemaInferenceError +from airbyte_cdk.sources.file_based.exceptions import ConfigValidationError, FileBasedSourceError, SchemaInferenceError from unit_tests.sources.file_based.helpers import EmptySchemaParser, LowInferenceLimitDiscoveryPolicy from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenarioBuilder @@ -79,9 +79,12 @@ "title": "Validation Policy", "type": "string" }, - "input_schema": { - "title": "Input Schema", - "type": "object" + 'input_schema': { + 'title': 'Input Schema', + 'anyOf': [ + {'type': 'object'}, + {'type': 'string'}, + ], }, "primary_key": { "title": "Primary Key", @@ -298,7 +301,7 @@ multi_csv_stream_n_file_exceeds_limit_for_inference = ( TestScenarioBuilder() - .set_name("multi_csv_stream_n_file_exceeds_limit") + .set_name("multi_csv_stream_n_file_exceeds_limit_for_inference") .set_config( { "streams": [ @@ -372,6 +375,8 @@ "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, ] ) + .set_expected_logs({ + "discover": [{"level": "WARN", "message": "Refusing to infer schema for all 2 files; using 1 files."}]}) .set_discovery_policy(LowInferenceLimitDiscoveryPolicy()) ).build() @@ -433,14 +438,14 @@ ) .set_expected_records([]) .set_expected_discover_error(SchemaInferenceError, FileBasedSourceError.SCHEMA_INFERENCE_ERROR.value) - .set_expected_logs( - [ + .set_expected_logs({ + "read": [ { "level": "ERROR", "message": f"{FileBasedSourceError.ERROR_PARSING_RECORD.value} stream=stream1 file=a.csv line_no=1 n_skipped=0", }, ] - ) + }) ).build() csv_single_stream_scenario = ( @@ -1003,7 +1008,7 @@ } ) .set_parsers({'csv': EmptySchemaParser()}) - .set_expected_discover_error(InvalidSchemaError, FileBasedSourceError.INVALID_SCHEMA_ERROR.value) + .set_expected_discover_error(SchemaInferenceError, FileBasedSourceError.SCHEMA_INFERENCE_ERROR.value) .set_expected_records( [ {"data": {"col1": "val11", "col2": "val12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/incremental_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/incremental_scenarios.py index 865ee9ad59be..87e71c0064e6 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/incremental_scenarios.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/incremental_scenarios.py @@ -48,8 +48,8 @@ )) .set_expected_records( [ - {"col1": "val11", "col2": "val12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, - {"col1": "val21", "col2": "val22", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, + {"data": {"col1": "val11", "col2": "val12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21", "col2": "val22", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -217,8 +217,8 @@ )) .set_expected_records( [ - {"col1": "val11", "col2": "val12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, - {"col1": "val21", "col2": "val22", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, + {"data": {"col1": "val11", "col2": "val12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21", "col2": "val22", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -316,8 +316,8 @@ ) .set_expected_records( [ - {"col1": "val11", "col2": "val12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, - {"col1": "val21", "col2": "val22", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, + {"data": {"col1": "val11", "col2": "val12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21", "col2": "val22", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -401,12 +401,12 @@ ) .set_expected_records( [ - {"col1": "val11a", "col2": "val12a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, - {"col1": "val21a", "col2": "val22a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, - {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "b.csv"}, - {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "b.csv"}, + {"data": {"col1": "val11a", "col2": "val12a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21a", "col2": "val22a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -479,8 +479,8 @@ ) .set_expected_records( [ - {"col1": "val11", "col2": "val12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, - {"col1": "val21", "col2": "val22", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, + {"data": {"col1": "val11", "col2": "val12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21", "col2": "val22", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -576,8 +576,8 @@ ) .set_expected_records( [ - {"col1": "val11a", "col2": "val12a", "_ab_source_file_last_modified": "2023-06-04T03:54:07Z", "_ab_source_file_url": "a.csv"}, - {"col1": "val21a", "col2": "val22a", "_ab_source_file_last_modified": "2023-06-04T03:54:07Z", "_ab_source_file_url": "a.csv"}, + {"data": {"col1": "val11a", "col2": "val12a", "_ab_source_file_last_modified": "2023-06-04T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21a", "col2": "val22a", "_ab_source_file_last_modified": "2023-06-04T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -585,10 +585,10 @@ }, } }, - {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "b.csv"}, - {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "b.csv"}, + {"data": {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -681,12 +681,12 @@ ) .set_expected_records( [ - {"col1": "val11a", "col2": "val12a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, - {"col1": "val21a", "col2": "val22a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, - {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "b.csv"}, - {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "b.csv"}, + {"data": {"col1": "val11a", "col2": "val12a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21a", "col2": "val22a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -695,10 +695,10 @@ }, } }, - {"col1": "val11c", "col2": "val12c", "col3": "val13c", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", - "_ab_source_file_url": "c.csv"}, - {"col1": "val21c", "col2": "val22c", "col3": "val23c", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", - "_ab_source_file_url": "c.csv"}, + {"data": {"col1": "val11c", "col2": "val12c", "col3": "val13c", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", + "_ab_source_file_url": "c.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21c", "col2": "val22c", "col3": "val23c", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", + "_ab_source_file_url": "c.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -792,12 +792,12 @@ ) .set_expected_records( [ - # {"col1": "val11a", "col2": "val12a"}, # this file is skipped - # {"col1": "val21a", "col2": "val22a"}, # this file is skipped - {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "b.csv"}, - {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "b.csv"}, + # {"data": {"col1": "val11a", "col2": "val12a"}, "stream": "stream1"}, # this file is skipped + # {"data": {"col1": "val21a", "col2": "val22a"}, "stream": "stream1"}, # this file is skipped + {"data": {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -806,10 +806,10 @@ }, } }, - {"col1": "val11c", "col2": "val12c", "col3": "val13c", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", - "_ab_source_file_url": "c.csv"}, - {"col1": "val21c", "col2": "val22c", "col3": "val23c", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", - "_ab_source_file_url": "c.csv"}, + {"data": {"col1": "val11c", "col2": "val12c", "col3": "val13c", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", + "_ab_source_file_url": "c.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21c", "col2": "val22c", "col3": "val23c", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", + "_ab_source_file_url": "c.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -912,14 +912,14 @@ ) .set_expected_records( [ - # {"col1": "val11a", "col2": "val12a"}, # this file is skipped - # {"col1": "val21a", "col2": "val22a"}, # this file is skipped - {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "b.csv"}, - {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "b.csv"}, - # {"col1": "val11c", "col2": "val12c", "col3": "val13c"}, # this file is skipped - # {"col1": "val21c", "col2": "val22c", "col3": "val23c"}, # this file is skipped + # {"data": {"col1": "val11a", "col2": "val12a"}, "stream": "stream1"}, # this file is skipped + # {"data": {"col1": "val21a", "col2": "val22a"}, "stream": "stream1"}, # this file is skipped + {"data": {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, + # {"data": {"col1": "val11c", "col2": "val12c", "col3": "val13c"}, "stream": "stream1"}, # this file is skipped + # {"data": {"col1": "val21c", "col2": "val22c", "col3": "val23c"}, "stream": "stream1"}, # this file is skipped { "stream1": { "history": { @@ -1026,8 +1026,8 @@ ) .set_expected_records( [ - {"col1": "val11a", "col2": "val12a", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", "_ab_source_file_url": "a.csv"}, - {"col1": "val21a", "col2": "val22a", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", "_ab_source_file_url": "a.csv"}, + {"data": {"col1": "val11a", "col2": "val12a", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21a", "col2": "val22a", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -1037,10 +1037,10 @@ }, } }, - {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-07T03:54:07Z", - "_ab_source_file_url": "b.csv"}, - {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-07T03:54:07Z", - "_ab_source_file_url": "b.csv"}, + {"data": {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-07T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-07T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -1050,10 +1050,10 @@ }, } }, - {"col1": "val11c", "col2": "val12c", "col3": "val13c", "_ab_source_file_last_modified": "2023-06-10T03:54:07Z", - "_ab_source_file_url": "c.csv"}, - {"col1": "val21c", "col2": "val22c", "col3": "val23c", "_ab_source_file_last_modified": "2023-06-10T03:54:07Z", - "_ab_source_file_url": "c.csv"}, + {"data": {"col1": "val11c", "col2": "val12c", "col3": "val13c", "_ab_source_file_last_modified": "2023-06-10T03:54:07Z", + "_ab_source_file_url": "c.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21c", "col2": "val22c", "col3": "val23c", "_ab_source_file_last_modified": "2023-06-10T03:54:07Z", + "_ab_source_file_url": "c.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -1170,20 +1170,20 @@ ) .set_expected_records( [ - {"col1": "val11a", "col2": "val12a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, - {"col1": "val21a", "col2": "val22a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, - {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "b.csv"}, - {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "b.csv"}, - {"col1": "val11c", "col2": "val12c", "col3": "val13c", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "c.csv"}, - {"col1": "val21c", "col2": "val22c", "col3": "val23c", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "c.csv"}, - {"col1": "val11d", "col2": "val12d", "col3": "val13d", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "d.csv"}, - {"col1": "val21d", "col2": "val22d", "col3": "val23d", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "d.csv"}, + {"data": {"col1": "val11a", "col2": "val12a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21a", "col2": "val22a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, + {"data": {"col1": "val11c", "col2": "val12c", "col3": "val13c", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "c.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21c", "col2": "val22c", "col3": "val23c", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "c.csv"}, "stream": "stream1"}, + {"data": {"col1": "val11d", "col2": "val12d", "col3": "val13d", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "d.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21d", "col2": "val22d", "col3": "val23d", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "d.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -1403,12 +1403,12 @@ ) .set_expected_records( [ - # {"col1": "val11a", "col2": "val12a"}, # This file is skipped because it is older than the time_window - # {"col1": "val21a", "col2": "val22a"}, - {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", - "_ab_source_file_url": "b.csv"}, - {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", - "_ab_source_file_url": "b.csv"}, + # {"data": {"col1": "val11a", "col2": "val12a"}, "stream": "stream1"}, # This file is skipped because it is older than the time_window + # {"data": {"col1": "val21a", "col2": "val22a"}, "stream": "stream1"}, + {"data": {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -1525,10 +1525,10 @@ ) .set_expected_records( [ - {"col1": "val11a", "col2": "val12a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "a.csv"}, - {"col1": "val21a", "col2": "val22a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", - "_ab_source_file_url": "a.csv"}, + {"data": {"col1": "val11a", "col2": "val12a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21a", "col2": "val22a", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, { "stream1": { "history": { @@ -1538,10 +1538,10 @@ }, } }, - {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", - "_ab_source_file_url": "b.csv"}, - {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", - "_ab_source_file_url": "b.csv"}, + {"data": {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-06T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, { "stream1": { "history": { diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/scenario_builder.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/scenario_builder.py index 831071cf5277..0477febc930b 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/scenario_builder.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/scenario_builder.py @@ -32,7 +32,7 @@ def __init__( expected_spec: Optional[Dict[str, Any]], expected_check_status: Optional[str], expected_catalog: Optional[Dict[str, Any]], - expected_logs: Optional[Dict[str, Any]], + expected_logs: Optional[Dict[str, Dict[str, Any]]], expected_records: Optional[Dict[str, Any]], availability_strategy: Optional[AvailabilityStrategy], discovery_policy: Optional[AbstractDiscoveryPolicy], @@ -56,6 +56,7 @@ def __init__( self.expected_check_error = expected_check_error self.expected_discover_error = expected_discover_error self.expected_read_error = expected_read_error + self.expected_logs = expected_logs self.source = InMemoryFilesSource( files, file_type, @@ -110,7 +111,7 @@ def __init__(self): self._expected_spec = None self._expected_check_status = None self._expected_catalog = {} - self._expected_logs = {} + self._expected_logs = None self._expected_records = {} self._availability_strategy = None self._discovery_policy = DefaultDiscoveryPolicy() @@ -152,7 +153,7 @@ def set_expected_catalog(self, expected_catalog: Dict[str, Any]): self._expected_catalog = expected_catalog return self - def set_expected_logs(self, expected_logs: Dict[str, Any]): + def set_expected_logs(self, expected_logs: Dict[str, List[Dict[str, Any]]]): self._expected_logs = expected_logs return self diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/user_input_schema_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/user_input_schema_scenarios.py new file mode 100644 index 000000000000..85106fec9541 --- /dev/null +++ b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/user_input_schema_scenarios.py @@ -0,0 +1,720 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +from airbyte_cdk.sources.file_based.exceptions import ConfigValidationError, FileBasedSourceError +from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenarioBuilder + +""" +User input schema rules: + - `check`: Successful if the schema conforms to a record, otherwise ConfigValidationError. + - `discover`: User-input schema is output if the schema is valid, otherwise ConfigValidationError. + - `read`: If the schema is valid, record values are cast to types in the schema; if this is successful + the records are emitted. otherwise an error is logged. If the schema is not valid, ConfigValidationError. +""" + + +_base_user_input_schema_scenario = ( + TestScenarioBuilder() + .set_files( + { + "a.csv": { + "contents": [ + ("col1", "col2"), + ("val11", "val12"), + ("val21", "val22"), + ], + "last_modified": "2023-06-05T03:54:07.000Z", + } + } + ) + .set_file_type("csv") + .set_expected_catalog( + { + "streams": [ + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "col1": { + "type": "string" + }, + "col2": { + "type": "string" + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + }, + }, + "name": "stream1", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + } + ] + } + ) + .set_expected_records( + [ + {"data": {"col1": "val11", "col2": "val12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val21", "col2": "val22", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + ] + ) +) + + +valid_single_stream_user_input_schema_scenario = ( + _base_user_input_schema_scenario.copy() + .set_name("valid_single_stream_user_input_schema_scenario") + .set_config( + { + "streams": [ + { + "name": "stream1", + "file_type": "csv", + "globs": ["*"], + "validation_policy": "emit_record", + "input_schema": '{"col1": "string", "col2": "string"}', + } + ] + } + ) + .set_expected_check_status("SUCCEEDED") +).build() + + +single_stream_user_input_schema_scenario_schema_is_invalid = ( + _base_user_input_schema_scenario.copy() + .set_name("single_stream_user_input_schema_scenario_schema_is_invalid") + .set_config( + { + "streams": [ + { + "name": "stream1", + "file_type": "csv", + "globs": ["*"], + "validation_policy": "emit_record", + "input_schema": '{"col1": "x", "col2": "string"}', + } + ] + } + ) + .set_expected_check_status("FAILED") + .set_expected_check_error(None, FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA.value) + .set_expected_discover_error(ConfigValidationError, FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA.value) + .set_expected_read_error(ConfigValidationError, FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA.value) +).build() + + +single_stream_user_input_schema_scenario_emit_nonconforming_records = ( + _base_user_input_schema_scenario.copy() + .set_name("single_stream_user_input_schema_scenario_emit_nonconforming_records") + .set_config( + { + "streams": [ + { + "name": "stream1", + "file_type": "csv", + "globs": ["*"], + "validation_policy": "emit_record", + "input_schema": '{"col1": "integer", "col2": "string"}', + } + ] + } + ) + .set_expected_check_status("FAILED") + .set_expected_check_error(None, FileBasedSourceError.SCHEMA_INFERENCE_ERROR.value) + .set_expected_catalog( + { + "streams": [ + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "col1": { + "type": "integer" + }, + "col2": { + "type": "string" + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + }, + }, + "name": "stream1", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + } + ] + } + ) +).build() + + +single_stream_user_input_schema_scenario_skip_nonconforming_records = ( + _base_user_input_schema_scenario.copy() + .set_name("single_stream_user_input_schema_scenario_skip_nonconforming_records") + .set_config( + { + "streams": [ + { + "name": "stream1", + "file_type": "csv", + "globs": ["*"], + "validation_policy": "skip_record", + "input_schema": '{"col1": "integer", "col2": "string"}', + } + ] + } + ) + .set_expected_check_status("FAILED") + .set_expected_check_error(None, FileBasedSourceError.SCHEMA_INFERENCE_ERROR.value) + .set_expected_catalog( + { + "streams": [ + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "col1": { + "type": "integer" + }, + "col2": { + "type": "string" + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + }, + }, + "name": "stream1", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + } + ] + } + ) + .set_expected_records([]) + .set_expected_logs({ + "read": [ + { + 'level': 'WARN', + 'message': 'Records in file did not pass validation policy. stream=stream1 file=a.csv n_skipped=2 validation_policy=skip_record', + }, + { + 'level': 'WARNING', + 'message': 'Could not cast the value to the expected type.: col1: value=val11,expected_type=integer', + }, + { + 'level': 'WARNING', + 'message': 'Could not cast the value to the expected type.: col1: value=val11,expected_type=integer', + }, + { + 'level': 'WARNING', + 'message': 'Could not cast the value to the expected type.: col1: value=val21,expected_type=integer', + }, + ] + }) +).build() + + +_base_multi_stream_user_input_schema_scenario = ( + TestScenarioBuilder() + .set_files( + { + "a.csv": { + "contents": [ + ("col1", "col2"), + ("val11a", 21), + ("val12a", 22), + ], + "last_modified": "2023-06-05T03:54:07.000Z", + }, + "b.csv": { + "contents": [ + ("col1", "col2", "col3"), + ("val11b", "val12b", "val13b"), + ("val21b", "val22b", "val23b"), + ], + "last_modified": "2023-06-05T03:54:07.000Z", + }, + "c.csv": { + "contents": [ + ("col1",), + ("val11c",), + ("val21c",), + ], + "last_modified": "2023-06-05T03:54:07.000Z", + }, + } + ) + .set_file_type("csv") + .set_expected_catalog( + { + "streams": [ + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "col1": { + "type": "string", + }, + "col2": { + "type": "integer", + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + } + }, + "name": "stream1", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + }, + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "col1": { + "type": "string", + }, + "col2": { + "type": "string", + }, + "col3": { + "type": "string", + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + } + }, + "name": "stream2", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + }, + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "col1": { + "type": "string", + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + } + }, + "name": "stream3", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + }, + ] + } + ) + .set_expected_records( + [ + {"data": {"col1": "val11a", "col2": 21, "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val12a", "col2": 22, "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + # The files in b.csv are emitted despite having an invalid schema + {"data": {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream2"}, + {"data": {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream2"}, + {"data": {"col1": "val11c", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "c.csv"}, "stream": "stream3"}, + {"data": {"col1": "val21c", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "c.csv"}, "stream": "stream3"}, + ] + ) +) + + +valid_multi_stream_user_input_schema_scenario = ( + _base_multi_stream_user_input_schema_scenario.copy() + .set_name("valid_multi_stream_user_input_schema_scenario") + .set_config( + { + "streams": [ + { + "name": "stream1", + "file_type": "csv", + "globs": ["a.csv"], + "validation_policy": "emit_record", + "input_schema": '{"col1": "string", "col2": "integer"}', + }, + { + "name": "stream2", + "file_type": "csv", + "globs": ["b.csv"], + "validation_policy": "emit_record", + "input_schema": '{"col1": "string", "col2": "string", "col3": "string"}', + }, + { + "name": "stream3", + "file_type": "csv", + "globs": ["c.csv"], + "validation_policy": "emit_record", + }, + + ] + } + ) + .set_expected_check_status("SUCCEEDED") +).build() + + +multi_stream_user_input_schema_scenario_schema_is_invalid = ( + _base_multi_stream_user_input_schema_scenario.copy() + .set_name("multi_stream_user_input_schema_scenario_schema_is_invalid") + .set_config( + { + "streams": [ + { + "name": "stream1", + "file_type": "csv", + "globs": ["a.csv"], + "validation_policy": "emit_record", + "input_schema": '{"col1": "string", "col2": "integer"}', + }, + { + "name": "stream2", + "file_type": "csv", + "globs": ["b.csv"], + "validation_policy": "emit_record", + "input_schema": '{"col1": "x", "col2": "string", "col3": "string"}', # this stream's schema is invalid + }, + { + "name": "stream3", + "file_type": "csv", + "globs": ["c.csv"], + "validation_policy": "emit_record", + }, + + ] + } + ) + .set_expected_check_status("FAILED") + .set_expected_check_error(None, FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA.value) + .set_expected_discover_error(ConfigValidationError, FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA.value) + .set_expected_read_error(ConfigValidationError, FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA.value) +).build() + + +multi_stream_user_input_schema_scenario_emit_nonconforming_records = ( + _base_multi_stream_user_input_schema_scenario.copy() + .set_name("multi_stream_user_input_schema_scenario_emit_nonconforming_records") + .set_config( + { + "streams": [ + { + "name": "stream1", + "file_type": "csv", + "globs": ["a.csv"], + "validation_policy": "emit_record", + "input_schema": '{"col1": "string", "col2": "integer"}', + }, + { + "name": "stream2", + "file_type": "csv", + "globs": ["b.csv"], + "validation_policy": "emit_record", + "input_schema": '{"col1": "string", "col2": "integer", "col3": "string"}', # this stream's records do not conform to the schema + }, + { + "name": "stream3", + "file_type": "csv", + "globs": ["c.csv"], + "validation_policy": "emit_record", + }, + + ] + } + ) + .set_expected_catalog( + { + "streams": [ + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "col1": { + "type": "string" + }, + "col2": { + "type": "integer" + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + }, + }, + "name": "stream1", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + }, + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "col1": { + "type": "string" + }, + "col2": { + "type": "integer" + }, + "col3": { + "type": "string" + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + }, + }, + "name": "stream2", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + }, + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "col1": { + "type": "string", + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + }, + }, + "name": "stream3", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + }, + ] + } + ) + .set_expected_check_status("FAILED") + .set_expected_check_error(None, FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA.value) + .set_expected_records( + [ + {"data": {"col1": "val11a", "col2": 21, "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val12a", "col2": 22, "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream2"}, + {"data": {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "b.csv"}, "stream": "stream2"}, + {"data": {"col1": "val11c", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "c.csv"}, "stream": "stream3"}, + {"data": {"col1": "val21c", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "c.csv"}, "stream": "stream3"}, + ] + ) + .set_expected_logs({ + "read": [ + { + 'level': 'WARNING', + 'message': 'Could not cast the value to the expected type.: col2: value=val12b,expected_type=integer', + }, + { + 'level': 'WARNING', + 'message': 'Could not cast the value to the expected type.: col2: value=val12b,expected_type=integer', + }, + { + 'level': 'WARNING', + 'message': 'Could not cast the value to the expected type.: col2: value=val22b,expected_type=integer', + }, + ] + + }) +).build() + + +multi_stream_user_input_schema_scenario_skip_nonconforming_records = ( + _base_multi_stream_user_input_schema_scenario.copy() + .set_name("multi_stream_user_input_schema_scenario_skip_nonconforming_records") + .set_config( + { + "streams": [ + { + "name": "stream1", + "file_type": "csv", + "globs": ["a.csv"], + "validation_policy": "emit_record", + "input_schema": '{"col1": "string", "col2": "integer"}', + }, + { + "name": "stream2", + "file_type": "csv", + "globs": ["b.csv"], + "validation_policy": "skip_record", + "input_schema": '{"col1": "string", "col2": "integer", "col3": "string"}', # this stream's records do not conform to the schema + }, + { + "name": "stream3", + "file_type": "csv", + "globs": ["c.csv"], + "validation_policy": "emit_record", + }, + + ] + } + ) + .set_expected_catalog( + { + "streams": [ + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "col1": { + "type": "string" + }, + "col2": { + "type": "integer" + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + }, + }, + "name": "stream1", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + }, + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "col1": { + "type": "string" + }, + "col2": { + "type": "integer" + }, + "col3": { + "type": "string" + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + }, + }, + "name": "stream2", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + }, + { + "default_cursor_field": ["_ab_source_file_last_modified"], + "json_schema": { + "type": "object", + "properties": { + "col1": { + "type": "string", + }, + "_ab_source_file_last_modified": { + "type": "string" + }, + "_ab_source_file_url": { + "type": "string" + }, + }, + }, + "name": "stream3", + "source_defined_cursor": True, + "supported_sync_modes": ["full_refresh", "incremental"], + }, + ] + } + ) + .set_expected_check_status("FAILED") + .set_expected_check_error(None, FileBasedSourceError.ERROR_PARSING_USER_PROVIDED_SCHEMA.value) + .set_expected_records( + [ + {"data": {"col1": "val11a", "col2": 21, "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + {"data": {"col1": "val12a", "col2": 22, "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "a.csv"}, "stream": "stream1"}, + # {"data": {"col1": "val11b", "col2": "val12b", "col3": "val13b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + # "_ab_source_file_url": "b.csv"}, "stream": "stream2"}, + # {"data": {"col1": "val21b", "col2": "val22b", "col3": "val23b", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + # "_ab_source_file_url": "b.csv"}, "stream": "stream2"}, + {"data": {"col1": "val11c", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "c.csv"}, "stream": "stream3"}, + {"data": {"col1": "val21c", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", + "_ab_source_file_url": "c.csv"}, "stream": "stream3"}, + ] + ) + .set_expected_logs({ + "read": [ + { + 'level': 'WARN', + 'message': 'Records in file did not pass validation policy. stream=stream2 file=b.csv n_skipped=2 validation_policy=skip_record', + }, + { + 'level': 'WARNING', + 'message': 'Could not cast the value to the expected type.: col2: value=val12b,expected_type=integer', + }, + { + 'level': 'WARNING', + 'message': 'Could not cast the value to the expected type.: col2: value=val12b,expected_type=integer', + }, + { + 'level': 'WARNING', + 'message': 'Could not cast the value to the expected type.: col2: value=val22b,expected_type=integer', + }, + ] + }) +).build() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/validation_policy_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/validation_policy_scenarios.py index 955168f86deb..ec5645d92886 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/validation_policy_scenarios.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/validation_policy_scenarios.py @@ -223,18 +223,18 @@ {"data": {"col1": "val_d_11", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "d.csv"}, "stream": "stream1"}, ] ) - .set_expected_logs( - [ + .set_expected_logs({ + "read": [ { - "level": "INFO", + "level": "WARN", "message": "Records in file did not pass validation policy. stream=stream1 file=a.csv n_skipped=2 validation_policy=skip_record", }, { - "level": "INFO", + "level": "WARN", "message": "Records in file did not pass validation policy. stream=stream1 file=c.csv n_skipped=1 validation_policy=skip_record", }, ] - ) + }) ).build() @@ -278,22 +278,22 @@ {"data": {"col1": "val_bb3_12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "b/b3.csv"}, "stream": "stream2"}, ] ) - .set_expected_logs( - [ + .set_expected_logs({ + "read": [ { - "level": "INFO", + "level": "WARN", "message": "Records in file did not pass validation policy. stream=stream1 file=a/a1.csv n_skipped=2 validation_policy=skip_record", }, { - "level": "INFO", + "level": "WARN", "message": "Records in file did not pass validation policy. stream=stream1 file=a/a3.csv n_skipped=1 validation_policy=skip_record", }, { - "level": "INFO", + "level": "WARN", "message": "Records in file did not pass validation policy. stream=stream2 file=b/b2.csv n_skipped=2 validation_policy=skip_record", }, ] - ) + }) ).build() @@ -320,18 +320,18 @@ {"data": {"col1": "val_b_12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "b.csv"}, "stream": "stream1"}, {"data": {"col1": "val_c_11", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "c.csv"}, "stream": "stream1"}, # {"data": {"col1": "val_c_12", None: "val_c_22", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "c.csv"}, "stream": "stream1"}, # This record is malformed so should not be emitted - # {"data": {"col1": "val_c_13", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "c.csv"}, "stream": "stream1"}, # No more records from this file are emitted after we hit a parse error - {"data": {"col1": "val_d_11", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "d.csv"}, "stream": "stream1"}, + # {"data": {"col1": "val_c_13", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "c.csv"}, "stream": "stream1"}, # No more records from this stream are emitted after we hit a parse error + # {"data": {"col1": "val_d_11", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "d.csv"}, "stream": "stream1"}, ] ) - .set_expected_logs( - [ + .set_expected_logs({ + "read": [ { "level": "ERROR", "message": f"{FileBasedSourceError.ERROR_PARSING_RECORD.value} stream=stream1 file=c.csv line_no=2 n_skipped=0", }, ] - ) + }) ).build() @@ -365,8 +365,8 @@ {"data": {"col1": "val_aa2_12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a/a2.csv"}, "stream": "stream1"}, {"data": {"col1": "val_aa3_11", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a/a3.csv"}, "stream": "stream1"}, # {"data": {"col1": "val_aa3_12", None: "val_aa3_22", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a/a3.csv"}, "stream": "stream1"}, # This record is malformed so should not be emitted - # {"data": {"col1": "val_aa3_13", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a/a3.csv"}, "stream": "stream1"}, # No more records from this file are emitted after we hit a parse error - {"data": {"col1": "val_aa4_11", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a/a4.csv"}, "stream": "stream1"}, + # {"data": {"col1": "val_aa3_13", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a/a3.csv"}, "stream": "stream1"}, # No more records from this stream are emitted after we hit a parse error + # {"data": {"col1": "val_aa4_11", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "a/a4.csv"}, "stream": "stream1"}, {"data": {"col1": "val_bb1_11", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "b/b1.csv"}, "stream": "stream2"}, {"data": {"col1": "val_bb1_12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "b/b1.csv"}, "stream": "stream2"}, {"data": {"col1": "val_bb2_11", "col2": "val_bb2_21", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "b/b2.csv"}, "stream": "stream2"}, @@ -375,14 +375,14 @@ {"data": {"col1": "val_bb3_12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "b/b3.csv"}, "stream": "stream2"}, ] ) - .set_expected_logs( - [ + .set_expected_logs({ + "read": [ { "level": "ERROR", "message": f"{FileBasedSourceError.ERROR_PARSING_RECORD.value} stream=stream1 file=a/a3.csv line_no=2 n_skipped=0", }, ] - ) + }) ).build() @@ -404,14 +404,16 @@ .set_expected_records( [] # No records are expected because the very first file did not conform to the schema ) - .set_expected_logs( - [ + .set_expected_logs({ + "read": [ { - "level": "INFO", - "message": "Stopping sync in accordance with the configured validation policy. Records in file did not conform to the schema. stream=stream1 file=a.csv validation_policy=wait_for_discover n_skipped=0", + # For this stream, the record that we check during the availability check does conform to the schema, but during the sync + # we encounter a record that does not, so stop the in-progress sync. + "level": "WARNING", + "message": "Skipped syncing stream 'stream1' because it was unavailable.", }, ] - ) + }) ).build() @@ -455,18 +457,22 @@ # {"data": {"col1": "val_bb3_12", "_ab_source_file_last_modified": "2023-06-05T03:54:07Z", "_ab_source_file_url": "b/b3.csv"}, "stream": "stream2"}, ] ) - .set_expected_logs( - [ + .set_expected_logs({ + "read": [ { - "level": "INFO", - "message": "Stopping sync in accordance with the configured validation policy. Records in file did not conform to the schema. stream=stream1 file=a/a1.csv validation_policy=wait_for_discover n_skipped=0", + # For this stream, the record that we check during the availability check does not conform to the schema so we do not proceed + # with the sync for that stream. + "level": "WARN", + "message": "Stopping sync in accordance with the configured validation policy. Records in file did not conform to the schema. stream=stream2 file=b/b2.csv validation_policy=wait_for_discover n_skipped=0", }, { - "level": "INFO", - "message": "Stopping sync in accordance with the configured validation policy. Records in file did not conform to the schema. stream=stream2 file=b/b2.csv validation_policy=wait_for_discover n_skipped=0", + # For this stream, the record that we check during the availability check does conform to the schema, but during the sync + # we encounter a record that does not, so stop the in-progress sync. + "level": "WARNING", + "message": "Skipped syncing stream 'stream1' because it was unavailable.", }, ] - ) + }) ).build() diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py index 16f7efdf3a47..ae372056a6e3 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py @@ -64,6 +64,16 @@ single_parquet_scenario, ) from unit_tests.sources.file_based.scenarios.scenario_builder import TestScenario +from unit_tests.sources.file_based.scenarios.user_input_schema_scenarios import ( + multi_stream_user_input_schema_scenario_emit_nonconforming_records, + multi_stream_user_input_schema_scenario_schema_is_invalid, + multi_stream_user_input_schema_scenario_skip_nonconforming_records, + single_stream_user_input_schema_scenario_emit_nonconforming_records, + single_stream_user_input_schema_scenario_schema_is_invalid, + single_stream_user_input_schema_scenario_skip_nonconforming_records, + valid_multi_stream_user_input_schema_scenario, + valid_single_stream_user_input_schema_scenario, +) from unit_tests.sources.file_based.scenarios.validation_policy_scenarios import ( emit_record_scenario_multi_stream, emit_record_scenario_single_stream, @@ -108,19 +118,34 @@ schemaless_csv_multi_stream_scenario, schemaless_with_user_input_schema_fails_connection_check_multi_stream_scenario, schemaless_with_user_input_schema_fails_connection_check_scenario, + single_stream_user_input_schema_scenario_schema_is_invalid, + single_stream_user_input_schema_scenario_emit_nonconforming_records, + single_stream_user_input_schema_scenario_skip_nonconforming_records, + multi_stream_user_input_schema_scenario_emit_nonconforming_records, + multi_stream_user_input_schema_scenario_skip_nonconforming_records, + multi_stream_user_input_schema_scenario_schema_is_invalid, + valid_multi_stream_user_input_schema_scenario, + valid_single_stream_user_input_schema_scenario, ] @pytest.mark.parametrize("scenario", discover_scenarios, ids=[s.name for s in discover_scenarios]) def test_discover(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> None: expected_exc, expected_msg = scenario.expected_discover_error + expected_logs = scenario.expected_logs if expected_exc: with pytest.raises(expected_exc) as exc: discover(capsys, tmp_path, scenario) if expected_msg: assert expected_msg in get_error_message_from_exc(exc) else: - assert discover(capsys, tmp_path, scenario) == scenario.expected_catalog + output = discover(capsys, tmp_path, scenario) + catalog, logs = output["catalog"], output["logs"] + assert catalog == scenario.expected_catalog + if expected_logs: + expected_logs = expected_logs.get("discover", []) + logs = [log for log in logs if log.get("log", {}).get("level") in ("ERROR", "WARN")] + _verify_expected_logs(logs, expected_logs) read_scenarios = discover_scenarios + [ @@ -137,61 +162,63 @@ def test_discover(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: Te @pytest.mark.parametrize("scenario", read_scenarios, ids=[s.name for s in read_scenarios]) @freeze_time("2023-06-09T00:00:00Z") -def test_read(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> None: +def test_read(capsys: CaptureFixture[str], caplog: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario): if scenario.incremental_scenario_config: - run_test_read_incremental(capsys, tmp_path, scenario) + run_test_read_incremental(capsys, caplog, tmp_path, scenario) else: - run_test_read_full_refresh(capsys, tmp_path, scenario) + run_test_read_full_refresh(capsys, caplog, tmp_path, scenario) -def run_test_read_full_refresh(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> None: +def run_test_read_full_refresh(capsys: CaptureFixture[str], caplog: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> None: expected_exc, expected_msg = scenario.expected_read_error - expected_records = scenario.expected_records - expected_logs = scenario.expected_logs if expected_exc: with pytest.raises(expected_exc) as exc: # noqa - read(capsys, tmp_path, scenario) + read(capsys, caplog, tmp_path, scenario) if expected_msg: assert expected_msg in get_error_message_from_exc(exc) else: - output = read(capsys, tmp_path, scenario) - records, logs = output["records"], output["logs"] - assert len(records) == len(expected_records) - assert len(logs) == len(expected_logs) - assert_expected_records_match_output(records, expected_records) - assert_expected_logs_match_output(logs, expected_logs) - - -def assert_expected_records_match_output(output: List[Mapping[str, Any]], expected_output: List[Mapping[str, Any]]) -> None: - for actual, expected in zip(output, expected_output): - for key, value in actual["record"]["data"].items(): - if isinstance(value, float): - assert math.isclose(value, expected["data"][key], abs_tol=1e-06) - else: - assert value == expected["data"][key] - assert actual["record"]["stream"] == expected["stream"] + output = read(capsys, caplog, tmp_path, scenario) + _verify_read_output(output, scenario) -def assert_expected_logs_match_output(logs: List[Mapping[str, Any]], expected_logs: List[Mapping[str, Any]]) -> None: - for actual, expected in zip(logs, expected_logs): - assert actual["log"]["level"] == expected["level"] - assert actual["log"]["message"] == expected["message"] - - -def run_test_read_incremental(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> None: +def run_test_read_incremental(capsys: CaptureFixture[str], caplog: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> None: expected_exc, expected_msg = scenario.expected_read_error if expected_exc: with pytest.raises(expected_exc): - read_with_state(capsys, tmp_path, scenario) + read_with_state(capsys, caplog, tmp_path, scenario) else: - output = read_with_state(capsys, tmp_path, scenario) - expected_output = scenario.expected_records - assert len(output) == len(expected_output) - for actual, expected in zip(output, expected_output): - if "record" in actual: - assert actual["record"]["data"] == expected - elif "state" in actual: - assert actual["state"]["data"] == expected + output = read_with_state(capsys, caplog, tmp_path, scenario) + _verify_read_output(output, scenario) + + +def _verify_read_output(output, scenario): + records, logs = output["records"], output["logs"] + logs = [log for log in logs if log.get("level") in ("ERROR", "WARN", "WARNING")] + expected_records = scenario.expected_records + assert len(records) == len(expected_records) + for actual, expected in zip(records, expected_records): + if "record" in actual: + for key, value in actual["record"]["data"].items(): + if isinstance(value, float): + assert math.isclose(value, expected["data"][key], abs_tol=1e-06) + else: + assert value == expected["data"][key] + assert actual["record"]["stream"] == expected["stream"] + elif "state" in actual: + assert actual["state"]["data"] == expected + + if scenario.expected_logs: + expected_logs = scenario.expected_logs.get("read", []) + assert len(logs) == len(expected_logs) + _verify_expected_logs(logs, expected_logs) + + +def _verify_expected_logs(logs: List[Dict[str, Any]], expected_logs: List[Dict[str, Any]]): + for actual, expected in zip(logs, expected_logs): + actual_level, actual_message = actual["level"], actual["message"] + expected_level, expected_message = expected["level"], expected["message"] + assert actual_level == expected_level + assert expected_message in actual_message spec_scenarios = [ @@ -202,7 +229,7 @@ def run_test_read_incremental(capsys: CaptureFixture[str], tmp_path: PosixPath, @pytest.mark.parametrize("scenario", spec_scenarios, ids=[c.name for c in spec_scenarios]) def test_spec(capsys, scenario): - assert spec(capsys, single_csv_scenario) == single_csv_scenario.expected_spec + assert spec(capsys, scenario) == single_csv_scenario.expected_spec check_scenarios = [ @@ -218,6 +245,7 @@ def test_spec(capsys, scenario): success_user_provided_schema_scenario, schemaless_with_user_input_schema_fails_connection_check_multi_stream_scenario, schemaless_with_user_input_schema_fails_connection_check_scenario, + valid_single_stream_user_input_schema_scenario, ] @@ -261,11 +289,15 @@ def discover(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestSce scenario.source, ["discover", "--config", make_file(tmp_path / "config.json", scenario.config)], ) - captured = capsys.readouterr() - return json.loads(captured.out.splitlines()[0])["catalog"] # type: ignore + output = [json.loads(line) for line in capsys.readouterr().out.splitlines()] + [catalog] = [o["catalog"] for o in output if o.get("catalog")] # type: ignore + return { + "catalog": catalog, + "logs": [o["log"] for o in output if o.get("log")], + } -def read(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> Dict[str, Any]: +def read(capsys: CaptureFixture[str], caplog: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> Dict[str, Any]: launch( scenario.source, [ @@ -277,6 +309,7 @@ def read(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenari ], ) captured = capsys.readouterr().out.splitlines() + logs = caplog.records return { "records": [ msg @@ -284,14 +317,14 @@ def read(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenari if msg["type"] == "RECORD" ], "logs": [ - msg + msg["log"] for msg in (json.loads(line) for line in captured) if msg["type"] == "LOG" - ] + ] + [{"level": log.levelname, "message": log.message} for log in logs] } -def read_with_state(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> List[Dict[str, Any]]: +def read_with_state(capsys: CaptureFixture[str], caplog: CaptureFixture[str], tmp_path: PosixPath, scenario: TestScenario) -> Dict[str, List[Any]]: launch( scenario.source, [ @@ -305,11 +338,19 @@ def read_with_state(capsys: CaptureFixture[str], tmp_path: PosixPath, scenario: ], ) captured = capsys.readouterr() - return [ - msg - for msg in (json.loads(line) for line in captured.out.splitlines()) - if msg["type"] in ("RECORD", "STATE") - ] + logs = caplog.records + return { + "records": [ + msg + for msg in (json.loads(line) for line in captured.out.splitlines()) + if msg["type"] in ("RECORD", "STATE") + ], + "logs": [ + msg["log"] + for msg in (json.loads(line) for line in captured.out.splitlines()) + if msg["type"] == "LOG" + ] + [{"level": log.levelname, "message": log.message} for log in logs] + } def make_file(path: Path, file_contents: Optional[Union[Mapping[str, Any], List[Mapping[str, Any]]]]) -> str: diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/test_schema_helpers.py b/airbyte-cdk/python/unit_tests/sources/file_based/test_schema_helpers.py index eec34a8d9e47..72dfe6b719ec 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/test_schema_helpers.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/test_schema_helpers.py @@ -5,8 +5,8 @@ from typing import Any, Mapping import pytest -from airbyte_cdk.sources.file_based.exceptions import SchemaInferenceError -from airbyte_cdk.sources.file_based.schema_helpers import ComparableType, conforms_to_schema, merge_schemas +from airbyte_cdk.sources.file_based.exceptions import ConfigValidationError, SchemaInferenceError +from airbyte_cdk.sources.file_based.schema_helpers import ComparableType, conforms_to_schema, merge_schemas, type_mapping_to_jsonschema COMPLETE_CONFORMING_RECORD = { "null_field": None, @@ -243,3 +243,103 @@ def test_merge_schemas(schema1, schema2, expected_result): else: with pytest.raises(SchemaInferenceError): merge_schemas(schema1, schema2) + + +@pytest.mark.parametrize( + "type_mapping,expected_schema,expected_exc_msg", + [ + pytest.param( + '{"col1": "null", "col2": "array", "col3": "boolean", "col4": "float", "col5": "integer", "col6": "number", "col7": "object", "col8": "string"}', + { + "type": "object", + "properties": { + "col1": { + "type": "null" + }, + "col2": { + "type": "array" + }, + "col3": { + "type": "boolean" + }, + "col4": { + "type": "number" + }, + "col5": { + "type": "integer" + }, + "col6": { + "type": "number" + }, + "col7": { + "type": "object" + }, + "col8": { + "type": "string" + } + } + }, + None, + id="valid_all_types" + ), + pytest.param( + '{"col1 ": " string", "col2": " integer"}', + { + "type": "object", + "properties": { + "col1": { + "type": "string" + }, + "col2": { + "type": "integer" + } + } + }, + None, + id="valid_extra_spaces", + ), + pytest.param( + "", + None, + None, + id="valid_empty_string", + ), + pytest.param( + '{"col1": "x", "col2": "integer"}', + None, + "Invalid type 'x' for property 'col1'", + id="invalid_type", + ), + pytest.param( + '{"col1": "", "col2": "integer"}', + None, + "Invalid input schema", + id="invalid_missing_type", + ), + pytest.param( + '{"": "string", "col2": "integer"}', + None, + "Invalid input schema", + id="invalid_missing_name", + ), + pytest.param( + '{"type": "object", "properties": {"col1": {"type": "string"}, "col2": {"type": "integer"}}}', + None, + "Invalid input schema; nested schemas are not supported.", + id="invalid_nested_input_string", + ), + pytest.param( + '{"type": "object", "properties": {"col1": {"type": "string"}, "col2": {"type": "integer"}}}', + None, + "Invalid input schema; nested schemas are not supported.", + id="invalid_nested_input_json", + ), + ], +) +def test_type_mapping_to_jsonschema(type_mapping, expected_schema, expected_exc_msg): + if expected_exc_msg: + with pytest.raises(ConfigValidationError) as exc: + type_mapping_to_jsonschema(type_mapping) + assert expected_exc_msg in exc.value.args[0] + else: + assert type_mapping_to_jsonschema(type_mapping) == expected_schema From 633c939d46756a064939652d1a06ae9bc9ce317a Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Thu, 13 Jul 2023 09:12:34 -0700 Subject: [PATCH 60/63] [Source-postgres] Set default cursor value for cdc mode (#27442) * use LSN as default cursor for postgres CDC * Fixed static constant * Set lsn default cursor value for postgres sync * Bumped metadata and dockerfile versions * Disable acceptance backwards compatibility discovery test as this is a breaking change --------- Co-authored-by: Conor --- .../integrations/debezium/CdcSourceTest.java | 6 ++++++ .../source/mssql/CdcMssqlSourceTest.java | 5 +++++ .../source/mysql/CdcMysqlSourceTest.java | 5 +++++ .../source-postgres-strict-encrypt/Dockerfile | 2 +- .../source-postgres-strict-encrypt/metadata.yaml | 2 +- .../connectors/source-postgres/Dockerfile | 2 +- .../source-postgres/acceptance-test-config.yml | 2 ++ .../connectors/source-postgres/metadata.yaml | 2 +- .../source/postgres/PostgresCatalogHelper.java | 13 ++++++++++++- .../source/postgres/PostgresSource.java | 1 + .../source/postgres/CdcPostgresSourceTest.java | 5 +++++ .../source/postgres/PostgresCatalogHelperTest.java | 12 ++++++++++++ docs/integrations/sources/postgres.md | 1 + 13 files changed, 53 insertions(+), 5 deletions(-) diff --git a/airbyte-integrations/bases/debezium/src/testFixtures/java/io/airbyte/integrations/debezium/CdcSourceTest.java b/airbyte-integrations/bases/debezium/src/testFixtures/java/io/airbyte/integrations/debezium/CdcSourceTest.java index e8fdaa3bee90..0c397ec05669 100644 --- a/airbyte-integrations/bases/debezium/src/testFixtures/java/io/airbyte/integrations/debezium/CdcSourceTest.java +++ b/airbyte-integrations/bases/debezium/src/testFixtures/java/io/airbyte/integrations/debezium/CdcSourceTest.java @@ -770,6 +770,7 @@ protected AirbyteCatalog expectedCatalogForDiscover() { // stream with PK streams.get(0).setSourceDefinedCursor(true); addCdcMetadataColumns(streams.get(0)); + addCdcDefaultCursorField(streams.get(0)); final AirbyteStream streamWithoutPK = CatalogHelpers.createAirbyteStream( MODELS_STREAM_NAME + "_2", @@ -779,6 +780,7 @@ protected AirbyteCatalog expectedCatalogForDiscover() { Field.of(COL_MODEL, JsonSchemaType.STRING)); streamWithoutPK.setSourceDefinedPrimaryKey(Collections.emptyList()); streamWithoutPK.setSupportedSyncModes(List.of(SyncMode.FULL_REFRESH)); + addCdcDefaultCursorField(streamWithoutPK); addCdcMetadataColumns(streamWithoutPK); final AirbyteStream randomStream = CatalogHelpers.createAirbyteStream( @@ -790,6 +792,8 @@ protected AirbyteCatalog expectedCatalogForDiscover() { .withSourceDefinedCursor(true) .withSupportedSyncModes(Lists.newArrayList(SyncMode.FULL_REFRESH, SyncMode.INCREMENTAL)) .withSourceDefinedPrimaryKey(List.of(List.of(COL_ID + "_random"))); + + addCdcDefaultCursorField(randomStream); addCdcMetadataColumns(randomStream); streams.add(streamWithoutPK); @@ -815,6 +819,8 @@ protected AirbyteCatalog expectedCatalogForDiscover() { protected abstract void addCdcMetadataColumns(final AirbyteStream stream); + protected abstract void addCdcDefaultCursorField(final AirbyteStream stream); + protected abstract Source getSource(); protected abstract JsonNode getConfig(); diff --git a/airbyte-integrations/connectors/source-mssql/src/test/java/io/airbyte/integrations/source/mssql/CdcMssqlSourceTest.java b/airbyte-integrations/connectors/source-mssql/src/test/java/io/airbyte/integrations/source/mssql/CdcMssqlSourceTest.java index b12183fe125b..4e220fc2425c 100644 --- a/airbyte-integrations/connectors/source-mssql/src/test/java/io/airbyte/integrations/source/mssql/CdcMssqlSourceTest.java +++ b/airbyte-integrations/connectors/source-mssql/src/test/java/io/airbyte/integrations/source/mssql/CdcMssqlSourceTest.java @@ -436,6 +436,11 @@ protected void addCdcMetadataColumns(final AirbyteStream stream) { } + @Override + protected void addCdcDefaultCursorField(final AirbyteStream stream) { + // Leaving empty until cdc default cursor is implemented for MSSQL + } + @Override protected Source getSource() { return new MssqlSource(); diff --git a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/CdcMysqlSourceTest.java b/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/CdcMysqlSourceTest.java index 281336c46fdb..3e5a90efb3ee 100644 --- a/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/CdcMysqlSourceTest.java +++ b/airbyte-integrations/connectors/source-mysql/src/test/java/io/airbyte/integrations/source/mysql/CdcMysqlSourceTest.java @@ -191,6 +191,11 @@ protected void addCdcMetadataColumns(final AirbyteStream stream) { properties.set(CDC_DELETED_AT, stringType); } + @Override + protected void addCdcDefaultCursorField(final AirbyteStream stream) { + // Leaving empty until cdc default cursor is implemented for MySQL + } + @Override protected Source getSource() { return source; diff --git a/airbyte-integrations/connectors/source-postgres-strict-encrypt/Dockerfile b/airbyte-integrations/connectors/source-postgres-strict-encrypt/Dockerfile index ce02dc3becff..df9d0fb81ba1 100644 --- a/airbyte-integrations/connectors/source-postgres-strict-encrypt/Dockerfile +++ b/airbyte-integrations/connectors/source-postgres-strict-encrypt/Dockerfile @@ -24,5 +24,5 @@ ENV APPLICATION source-postgres-strict-encrypt COPY --from=build /airbyte /airbyte -LABEL io.airbyte.version=2.1.1 +LABEL io.airbyte.version=3.0.0 LABEL io.airbyte.name=airbyte/source-postgres-strict-encrypt diff --git a/airbyte-integrations/connectors/source-postgres-strict-encrypt/metadata.yaml b/airbyte-integrations/connectors/source-postgres-strict-encrypt/metadata.yaml index 61911e508dcc..fa34c9909b8b 100644 --- a/airbyte-integrations/connectors/source-postgres-strict-encrypt/metadata.yaml +++ b/airbyte-integrations/connectors/source-postgres-strict-encrypt/metadata.yaml @@ -12,7 +12,7 @@ data: connectorType: source definitionId: decd338e-5647-4c0b-adf4-da0e75f5a750 maxSecondsBetweenMessages: 7200 - dockerImageTag: 2.1.1 + dockerImageTag: 3.0.0 dockerRepository: airbyte/source-postgres-strict-encrypt githubIssueLabel: source-postgres icon: postgresql.svg diff --git a/airbyte-integrations/connectors/source-postgres/Dockerfile b/airbyte-integrations/connectors/source-postgres/Dockerfile index dec76967e02c..7b00c165f570 100644 --- a/airbyte-integrations/connectors/source-postgres/Dockerfile +++ b/airbyte-integrations/connectors/source-postgres/Dockerfile @@ -24,5 +24,5 @@ ENV APPLICATION source-postgres COPY --from=build /airbyte /airbyte -LABEL io.airbyte.version=2.1.1 +LABEL io.airbyte.version=3.0.0 LABEL io.airbyte.name=airbyte/source-postgres diff --git a/airbyte-integrations/connectors/source-postgres/acceptance-test-config.yml b/airbyte-integrations/connectors/source-postgres/acceptance-test-config.yml index df176559bffd..73b7e3102aa5 100644 --- a/airbyte-integrations/connectors/source-postgres/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-postgres/acceptance-test-config.yml @@ -24,6 +24,8 @@ acceptance_tests: tests: - config_path: "secrets/config.json" - config_path: "secrets/config_cdc.json" + backward_compatibility_tests_config: + disable_for_version: "2.1.1" basic_read: tests: - config_path: "secrets/config.json" diff --git a/airbyte-integrations/connectors/source-postgres/metadata.yaml b/airbyte-integrations/connectors/source-postgres/metadata.yaml index 8e27e690892e..0473ab60375b 100644 --- a/airbyte-integrations/connectors/source-postgres/metadata.yaml +++ b/airbyte-integrations/connectors/source-postgres/metadata.yaml @@ -6,7 +6,7 @@ data: connectorSubtype: database connectorType: source definitionId: decd338e-5647-4c0b-adf4-da0e75f5a750 - dockerImageTag: 2.1.1 + dockerImageTag: 3.0.0 maxSecondsBetweenMessages: 7200 dockerRepository: airbyte/source-postgres githubIssueLabel: source-postgres diff --git a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresCatalogHelper.java b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresCatalogHelper.java index d2fd7b3f7725..c7444134c5db 100644 --- a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresCatalogHelper.java +++ b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresCatalogHelper.java @@ -4,8 +4,11 @@ package io.airbyte.integrations.source.postgres; +import static io.airbyte.integrations.debezium.internals.DebeziumEventUtils.CDC_LSN; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import io.airbyte.commons.json.Jsons; @@ -123,7 +126,7 @@ public static Set getPublicizedTables(final Jdbc } /** - * This method is used for xmin synsc in order to overwrite sync modes for cursor fields. For xmin, we want streams to only have incremental mode + * This method is used for xmin syncs in order to overwrite sync modes for cursor fields. For xmin, we want streams to only have incremental mode * enabled. * * @param stream - airbyte stream @@ -133,4 +136,12 @@ public static AirbyteStream overrideSyncModesForXmin(final AirbyteStream stream) return stream.withSupportedSyncModes(Lists.newArrayList(SyncMode.INCREMENTAL)); } + /* + * To prepare for Destination v2, cdc streams must have a default cursor field + * this defaults to lsn as a cursor as it is monotonically increasing and unique + */ + public static AirbyteStream setDefaultCursorFieldForCdc(final AirbyteStream stream) { + stream.setDefaultCursorField(ImmutableList.of(CDC_LSN)); + return stream; + } } diff --git a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresSource.java b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresSource.java index 6847974f3241..695a9aa292d9 100644 --- a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresSource.java +++ b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresSource.java @@ -275,6 +275,7 @@ public AirbyteCatalog discover(final JsonNode config) throws Exception { .map(PostgresCatalogHelper::overrideSyncModes) .map(PostgresCatalogHelper::removeIncrementalWithoutPk) .map(PostgresCatalogHelper::setIncrementalToSourceDefined) + .map(PostgresCatalogHelper::setDefaultCursorFieldForCdc) .map(PostgresCatalogHelper::addCdcMetadataColumns) // If we're in CDC mode and a stream is not in the publication, the user should only be able to sync // this in FULL_REFRESH mode diff --git a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/CdcPostgresSourceTest.java b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/CdcPostgresSourceTest.java index 7b3267ebc7f1..555f879541ed 100644 --- a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/CdcPostgresSourceTest.java +++ b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/CdcPostgresSourceTest.java @@ -293,6 +293,11 @@ protected void addCdcMetadataColumns(final AirbyteStream stream) { } + @Override + protected void addCdcDefaultCursorField(final AirbyteStream stream) { + stream.setDefaultCursorField(ImmutableList.of(CDC_LSN)); + } + @Override protected Source getSource() { return source; diff --git a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/PostgresCatalogHelperTest.java b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/PostgresCatalogHelperTest.java index 6d269d216843..7f403c1a18fb 100644 --- a/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/PostgresCatalogHelperTest.java +++ b/airbyte-integrations/connectors/source-postgres/src/test/java/io/airbyte/integrations/source/postgres/PostgresCatalogHelperTest.java @@ -4,6 +4,7 @@ package io.airbyte.integrations.source.postgres; +import static io.airbyte.integrations.debezium.internals.DebeziumEventUtils.CDC_LSN; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -16,6 +17,7 @@ import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; +import org.testcontainers.shaded.com.google.common.collect.ImmutableList; class PostgresCatalogHelperTest { @@ -64,6 +66,16 @@ public void testSetIncrementalToSourceDefined() { .setIncrementalToSourceDefined(noIncremental) .getSourceDefinedCursor()); } + @Test + public void testSetDefaultCursorFieldForCdc() { + final AirbyteStream cdcIncrementalStream = new AirbyteStream() + .withSourceDefinedCursor(true) + .withSupportedSyncModes(List.of(SyncMode.FULL_REFRESH)); + PostgresCatalogHelper.setDefaultCursorFieldForCdc(cdcIncrementalStream); + + assertTrue(cdcIncrementalStream.getSourceDefinedCursor()); + assertEquals(cdcIncrementalStream.getDefaultCursorField(), ImmutableList.of(CDC_LSN)); + } @Test public void testAddCdcMetadataColumns() { diff --git a/docs/integrations/sources/postgres.md b/docs/integrations/sources/postgres.md index a63756b938f0..17a8227d1c05 100644 --- a/docs/integrations/sources/postgres.md +++ b/docs/integrations/sources/postgres.md @@ -407,6 +407,7 @@ Some larger tables may encounter an error related to the temporary file size lim | Version | Date | Pull Request | Subject | | :------ | :--------- | :------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | +| 3.0.0 | 2023-07-12 | [27442](https://github.com/airbytehq/airbyte/pull/27442) | Set _ab_cdc_lsn as the source defined cursor for CDC mode to prepare for Destination v2 normalization | | 2.1.1 | 2023-07-06 | [26723](https://github.com/airbytehq/airbyte/pull/26723) | Add new xmin replication method. | | 2.1.0 | 2023-06-26 | [27737](https://github.com/airbytehq/airbyte/pull/27737) | License Update: Elv2 | | 2.0.34 | 2023-06-20 | [27212](https://github.com/airbytehq/airbyte/pull/27212) | Fix silent exception swallowing in StreamingJdbcDatabase | From 8e835963c1f594f65409fbfe3a1e43c4af276c2b Mon Sep 17 00:00:00 2001 From: Brian Lai <51336873+brianjlai@users.noreply.github.com> Date: Thu, 13 Jul 2023 15:14:05 -0400 Subject: [PATCH 61/63] [file-based cdk] spec schema improvements and fixes (#28263) * fix spec schema incompatibility with ui and improve spec documentation and titles * fix schema to account for latest changes pulled from main * tests * remove duplicate test --- .../config/abstract_file_based_spec.py | 25 ++++-- .../config/file_based_stream_config.py | 77 +++++++++++++++---- .../file_based/scenarios/csv_scenarios.py | 59 ++++++++------ .../sources/file_based/test_scenarios.py | 5 +- 4 files changed, 117 insertions(+), 49 deletions(-) diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py index 22ef663b0cf1..55a466f2aea1 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/abstract_file_based_spec.py @@ -19,9 +19,7 @@ class AbstractFileBasedSpec(BaseModel): streams: List[FileBasedStreamConfig] = Field( title="The list of streams to sync", - description="Streams defines the behavior for grouping files together that will be synced to the downstream destination. Each " - "stream has it own independent configuration to handle which files to sync, how files should be parsed, and the " - "validation of records against the schema.", + description='Each instance of this configuration defines a stream. Use this to define which files belong in the stream, their format, and how they should be parsed and validated. When sending data to warehouse destination such as Snowflake or BigQuery, each stream is a separate table.', order=10, ) @@ -40,16 +38,18 @@ def schema(cls, *args: Any, **kwargs: Any) -> Dict[str, Any]: schema = super().schema(*args, **kwargs) transformed_schema = copy.deepcopy(schema) schema_helpers.expand_refs(transformed_schema) - cls.remove_enum_allOf(transformed_schema) + cls.replace_enum_allOf_and_anyOf(transformed_schema) cls.add_legacy_format(transformed_schema) return transformed_schema @staticmethod - def remove_enum_allOf(schema: dict) -> dict: + def replace_enum_allOf_and_anyOf(schema: dict) -> dict: """ allOfs are not supported by the UI, but pydantic is automatically writing them for enums. Unpacks the enums under allOf and moves them up a level under the enum key + anyOfs are also not supported by the UI, so we replace them with the similar oneOf, with the + additional validation that an incoming config only matches exactly one of a field's types. """ # this will need to add ["anyOf"] once we have more than one format type and loop over the list of elements objects_to_check = schema["properties"]["streams"]["items"]["properties"]["format"] @@ -59,6 +59,12 @@ def remove_enum_allOf(schema: dict) -> dict: if "allOf" in object_property and "enum" in object_property["allOf"][0]: object_property["enum"] = object_property["allOf"][0]["enum"] object_property.pop("allOf") + + properties_to_change = ["primary_key", "input_schema"] + for property_to_change in properties_to_change: + schema["properties"]["streams"]["items"]["properties"][property_to_change]["oneOf"] = schema["properties"]["streams"]["items"][ + "properties" + ][property_to_change].pop("anyOf") return schema @staticmethod @@ -69,7 +75,14 @@ def add_legacy_format(schema: dict) -> dict: config must be adjusted to support the generic mapping object. Once configs no longer adhere to the old format we can remove this change. """ + legacy_format_options = { + "title": "Legacy Format", + # Explicitly require this field to make it mutually exclusive (oneOf) with the new format mapping file_type -> format + "required": ["filetype"], + "type": "object", + "properties": {"filetype": {"title": "Filetype", "type": "string"}}, + } csv_format_options = schema["properties"]["streams"]["items"]["properties"]["format"] - union_format = {"anyOf": [csv_format_options, {"type": "object"}]} + union_format = {"oneOf": [csv_format_options, legacy_format_options]} schema["properties"]["streams"]["items"]["properties"]["format"] = union_format return schema diff --git a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py index 6ee98c839a8d..34d8a451bd40 100644 --- a/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py +++ b/airbyte-cdk/python/airbyte_cdk/sources/file_based/config/file_based_stream_config.py @@ -7,9 +7,9 @@ from typing import Any, List, Mapping, Optional, Union from airbyte_cdk.sources.file_based.schema_helpers import type_mapping_to_jsonschema -from pydantic import BaseModel, validator +from pydantic import BaseModel, Field, validator -PrimaryKeyType = Optional[Union[str, List[str], List[List[str]]]] +PrimaryKeyType = Optional[Union[str, List[str]]] VALID_FILE_TYPES = {"avro", "csv", "jsonl", "parquet"} @@ -22,12 +22,33 @@ class QuotingBehavior(Enum): class CsvFormat(BaseModel): - delimiter: str = "," - quote_char: str = '"' - escape_char: Optional[str] - encoding: Optional[str] = "utf8" - double_quote: bool - quoting_behavior: Optional[QuotingBehavior] = QuotingBehavior.QUOTE_SPECIAL_CHARACTERS + delimiter: str = Field( + title="Delimiter", + description="The character delimiting individual cells in the CSV data. This may only be a 1-character string. For tab-delimited data enter '\\t'.", + default=",", + ) + quote_char: str = Field( + title="Quote Character", + default='"', + description="The character used for quoting CSV values. To disallow quoting, make this field blank.", + ) + escape_char: Optional[str] = Field( + title="Escape Character", + default=None, + description="The character used for escaping special characters. To disallow escaping, leave this field blank.", + ) + encoding: Optional[str] = Field( + default="utf8", + description='The character encoding of the CSV data. Leave blank to default to UTF8. See list of python encodings for allowable options.', + ) + double_quote: bool = Field( + title="Double Quote", default=True, description="Whether two quotes in a quoted CSV value denote a single quote in the data." + ) + quoting_behavior: Optional[QuotingBehavior] = Field( + title="Quoting Behavior", + default=QuotingBehavior.QUOTE_SPECIAL_CHARACTERS, + description="The quoting behavior determines when a value in a row should have quote marks added around it. For example, if Quote Non-numeric is specified, while reading, quotes are expected for row values that do not contain numbers. Or for Quote All, every row value will be expecting quotes.", + ) # Noting that the existing S3 connector had a config option newlines_in_values. This was only supported by pyarrow and not # the Python csv package. It has a little adoption, but long term we should ideally phase this out because of the drawbacks # of using pyarrow @@ -62,15 +83,37 @@ def validate_encoding(cls, v): class FileBasedStreamConfig(BaseModel): - name: str - file_type: str - globs: Optional[List[str]] - validation_policy: str - input_schema: Optional[Union[str, Mapping[str, Any]]] - primary_key: PrimaryKeyType - days_to_sync_if_history_is_full: int = 3 - format: Optional[Mapping[str, CsvFormat]] # this will eventually be a Union once we have more than one format type - schemaless: bool = False + name: str = Field(title="Name", description="The name of the stream.") + file_type: str = Field(title="File Type", description="The data file type that is being extracted for a stream.") + globs: Optional[List[str]] = Field( + title="Globs", + description='The pattern used to specify which files should be selected from the file system. For more information on glob pattern matching look here.', + ) + validation_policy: str = Field( + title="Validation Policy", + description="The name of the validation policy that dictates sync behavior when a record does not adhere to the stream schema.", + ) + input_schema: Optional[Union[str, Mapping[str, Any]]] = Field( + title="Input Schema", + description="The schema that will be used to validate records extracted from the file. This will override the stream schema that is auto-detected from incoming files.", + ) + primary_key: PrimaryKeyType = Field( + title="Primary Key", description="The column or columns (for a composite key) that serves as the unique identifier of a record." + ) + days_to_sync_if_history_is_full: int = Field( + title="Days To Sync If History Is Full", + description="When the state history of the file store is full, syncs will only read files that were last modified in the provided day range.", + default=3, + ) + format: Optional[Mapping[str, CsvFormat]] = Field( + title="Format", + description="The configuration options that are used to alter how to read incoming files that deviate from the standard formatting.", + ) # this will eventually be a Union once we have more than one format type + schemaless: bool = Field( + title="Schemaless", + description="When enabled, syncs will not validate or structure records against the stream's schema.", + default=False, + ) @validator("file_type", pre=True) def validate_file_type(cls, v): diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py index 3a4d74b0f9b0..8149694bf087 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/scenarios/csv_scenarios.py @@ -46,9 +46,7 @@ "properties": { "streams": { "title": "The list of streams to sync", - "description": "Streams defines the behavior for grouping files together that will be synced to the downstream " - "destination. Each stream has it own independent configuration to handle which files to sync, " - "how files should be parsed, and the validation of records against the schema.", + "description": "Each instance of this configuration defines a stream. Use this to define which files belong in the stream, their format, and how they should be parsed and validated. When sending data to warehouse destination such as Snowflake or BigQuery, each stream is a separate table.", "order": 10, "type": "array", "items": { @@ -57,14 +55,17 @@ "properties": { "name": { "title": "Name", + "description": "The name of the stream.", "type": "string" }, "file_type": { "title": "File Type", + "description": "The data file type that is being extracted for a stream.", "type": "string" }, "globs": { "title": "Globs", + "description": "The pattern used to specify which files should be selected from the file system. For more information on glob pattern matching look here.", "type": "array", "items": { "type": "string" @@ -72,23 +73,27 @@ }, "schemaless": { "title": "Schemaless", + "description": "When enabled, syncs will not validate or structure records against the stream's schema.", "default": False, "type": "boolean" }, "validation_policy": { "title": "Validation Policy", + "description": "The name of the validation policy that dictates sync behavior when a record does not adhere to the stream schema.", "type": "string" }, - 'input_schema': { - 'title': 'Input Schema', - 'anyOf': [ - {'type': 'object'}, - {'type': 'string'}, + "input_schema": { + "title": "Input Schema", + "description": "The schema that will be used to validate records extracted from the file. This will override the stream schema that is auto-detected from incoming files.", + "oneOf": [ + {"type": "object"}, + {"type": "string"}, ], }, "primary_key": { "title": "Primary Key", - "anyOf": [ + "description": "The column or columns (for a composite key) that serves as the unique identifier of a record.", + "oneOf": [ { "type": "string" }, @@ -97,27 +102,20 @@ "items": { "type": "string" } - }, - { - "type": "array", - "items": { - "type": "array", - "items": { - "type": "string" - } - } } ] }, "days_to_sync_if_history_is_full": { "title": "Days To Sync If History Is Full", + "description": "When the state history of the file store is full, syncs will only read files that were last modified in the provided day range.", "default": 3, "type": "integer" }, "format": { - "anyOf": [ + "oneOf": [ { "title": "Format", + "description": "The configuration options that are used to alter how to read incoming files that deviate from the standard formatting.", "type": "object", "additionalProperties": { "title": "CsvFormat", @@ -125,37 +123,52 @@ "properties": { "delimiter": { "title": "Delimiter", + "description": "The character delimiting individual cells in the CSV data. This may only be a 1-character string. For tab-delimited data enter '\\t'.", "default": ",", "type": "string" }, "quote_char": { - "title": "Quote Char", + "title": "Quote Character", + "description": "The character used for quoting CSV values. To disallow quoting, make this field blank.", "default": "\"", "type": "string" }, "escape_char": { - "title": "Escape Char", + "title": "Escape Character", + "description": "The character used for escaping special characters. To disallow escaping, leave this field blank.", "type": "string" }, "encoding": { "title": "Encoding", + "description": "The character encoding of the CSV data. Leave blank to default to UTF8. See list of python encodings for allowable options.", "default": "utf8", "type": "string" }, "double_quote": { "title": "Double Quote", + "description": "Whether two quotes in a quoted CSV value denote a single quote in the data.", + "default": True, "type": "boolean" }, "quoting_behavior": { + "title": "Quoting Behavior", + "description": "The quoting behavior determines when a value in a row should have quote marks added around it. For example, if Quote Non-numeric is specified, while reading, quotes are expected for row values that do not contain numbers. Or for Quote All, every row value will be expecting quotes.", "default": "Quote Special Characters", "enum": ["Quote All", "Quote Special Characters", "Quote Non-numeric", "Quote None"] } }, - "required": ["double_quote"] } }, { - "type": "object" + "title": "Legacy Format", + "required": ["filetype"], + "type": "object", + "properties": { + "filetype": { + "title": "Filetype", + "type": "string" + } + }, } ] } diff --git a/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py b/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py index ae372056a6e3..7f6d461062cf 100644 --- a/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py +++ b/airbyte-cdk/python/unit_tests/sources/file_based/test_scenarios.py @@ -222,14 +222,13 @@ def _verify_expected_logs(logs: List[Dict[str, Any]], expected_logs: List[Dict[s spec_scenarios = [ - csv_multi_stream_scenario, - csv_single_stream_scenario, + single_csv_scenario, ] @pytest.mark.parametrize("scenario", spec_scenarios, ids=[c.name for c in spec_scenarios]) def test_spec(capsys, scenario): - assert spec(capsys, scenario) == single_csv_scenario.expected_spec + assert spec(capsys, scenario) == scenario.expected_spec check_scenarios = [ From 67a01d6be2f5064456c6c53b87301dafcd465153 Mon Sep 17 00:00:00 2001 From: Ben Church Date: Thu, 13 Jul 2023 14:15:41 -0600 Subject: [PATCH 62/63] Add explicit registry to metadata file for langchain and gainsight (#28296) * DNC * Fix metadata files * Revert "DNC" This reverts commit 85ba0cedbadd46a39a58d3985c7e17a052c7b704. --- .../connectors/destination-langchain/metadata.yaml | 4 +++- .../connectors/source-gainsight-px/metadata.yaml | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/airbyte-integrations/connectors/destination-langchain/metadata.yaml b/airbyte-integrations/connectors/destination-langchain/metadata.yaml index be1010642e03..64430fcbd32f 100644 --- a/airbyte-integrations/connectors/destination-langchain/metadata.yaml +++ b/airbyte-integrations/connectors/destination-langchain/metadata.yaml @@ -1,7 +1,9 @@ data: registries: - oss: + cloud: enabled: false + oss: + enabled: true connectorSubtype: database connectorType: destination definitionId: cf98d52c-ba5a-4dfd-8ada-c1baebfa6e73 diff --git a/airbyte-integrations/connectors/source-gainsight-px/metadata.yaml b/airbyte-integrations/connectors/source-gainsight-px/metadata.yaml index 81022b5d0cb6..9fb2ac8fb816 100644 --- a/airbyte-integrations/connectors/source-gainsight-px/metadata.yaml +++ b/airbyte-integrations/connectors/source-gainsight-px/metadata.yaml @@ -3,6 +3,8 @@ data: hosts: - api.aptrinsic.com/v1 registries: + cloud: + enabled: false oss: enabled: true connectorSubtype: api From 792878b253afbdb470ac723ef0537a6d15ae795f Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Thu, 13 Jul 2023 15:34:12 -0700 Subject: [PATCH 63/63] [Source-Postgres] Handle empty table when syncing via Ctid -> cursor-based (#28298) * Only build cursorbased stream state with cursor value when table has data * Add statetype and version to empty state * only put entry in map once --- .../source/postgres/PostgresQueryUtils.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresQueryUtils.java b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresQueryUtils.java index c9874bd2aaf0..7876f9ca5085 100644 --- a/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresQueryUtils.java +++ b/airbyte-integrations/connectors/source-postgres/src/main/java/io/airbyte/integrations/source/postgres/PostgresQueryUtils.java @@ -158,17 +158,19 @@ public static Map getCursorBa name); final List jsonNodes = database.bufferedResultSetQuery(conn -> conn.prepareStatement(cursorBasedSyncStatusQuery).executeQuery(), resultSet -> JdbcUtils.getDefaultSourceOperations().rowToJson(resultSet)); - final JsonNode result = jsonNodes.get(0); final CursorBasedStatus cursorBasedStatus = new CursorBasedStatus(); - cursorBasedStatus.setStateType(StateType.CURSOR_BASED); cursorBasedStatus.setVersion(2L); - cursorBasedStatus.setCursorField(ImmutableList.of(cursorField)); - cursorBasedStatus.setCursor(result.get(cursorField).asText()); - cursorBasedStatus.setCursorRecordCount((long) jsonNodes.size()); cursorBasedStatus.setStreamName(name); cursorBasedStatus.setStreamNamespace(namespace); + cursorBasedStatus.setCursorField(ImmutableList.of(cursorField)); + if (!jsonNodes.isEmpty()) { + final JsonNode result = jsonNodes.get(0); + cursorBasedStatus.setCursor(result.get(cursorField).asText()); + cursorBasedStatus.setCursorRecordCount((long) jsonNodes.size()); + } + cursorBasedStatusMap.put(new AirbyteStreamNameNamespacePair(name, namespace), cursorBasedStatus); } catch (final SQLException e) { throw new RuntimeException(e);