diff --git a/airbyte-config-oss/init-oss/src/main/resources/icons/fullstory.svg b/airbyte-config-oss/init-oss/src/main/resources/icons/fullstory.svg new file mode 100644 index 0000000000000..f5cac0c767642 --- /dev/null +++ b/airbyte-config-oss/init-oss/src/main/resources/icons/fullstory.svg @@ -0,0 +1,189 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/airbyte-config-oss/init-oss/src/main/resources/seed/oss_catalog.json b/airbyte-config-oss/init-oss/src/main/resources/seed/oss_catalog.json index 36aafc390887f..9c94972a47013 100644 --- a/airbyte-config-oss/init-oss/src/main/resources/seed/oss_catalog.json +++ b/airbyte-config-oss/init-oss/src/main/resources/seed/oss_catalog.json @@ -13399,6 +13399,45 @@ "public": true, "custom": false, "releaseStage": "alpha" + }, { + "sourceDefinitionId": "263fd456-02d1-4a26-a35e-52ccaedad778", + "name": "Fullstory", + "dockerRepository": "airbyte/source-fullstory", + "dockerImageTag": "0.1.0", + "documentationUrl": "https://docs.airbyte.com/integrations/sources/fullstory", + "icon": "fullstory.svg", + "sourceType": "api", + "spec": { + "documentationUrl": "https://docs.airbyte.com/integrations/sources/fullstory", + "connectionSpecification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "fullstory.com Source Spec", + "type": "object", + "required": [ "api_key", "uid" ], + "additionalProperties": true, + "properties": { + "api_key": { + "title": "API Key", + "type": "string", + "description": "API Key for the fullstory.com API.", + "airbyte_secret": true + }, + "uid": { + "title": "User ID", + "type": "string", + "description": "User ID for the fullstory.com API.", + "airbyte_secret": true + } + } + }, + "supportsNormalization": false, + "supportsDBT": false, + "supported_destination_sync_modes": [ ] + }, + "tombstone": false, + "public": true, + "custom": false, + "releaseStage": "alpha" }, { "sourceDefinitionId": "2a8c41ae-8c23-4be0-a73f-2ab10ca1a820", "name": "GCS", diff --git a/airbyte-config-oss/init-oss/src/main/resources/seed/source_definitions.yaml b/airbyte-config-oss/init-oss/src/main/resources/seed/source_definitions.yaml index 8bf7dd32f466c..a7dbf2a3871f6 100644 --- a/airbyte-config-oss/init-oss/src/main/resources/seed/source_definitions.yaml +++ b/airbyte-config-oss/init-oss/src/main/resources/seed/source_definitions.yaml @@ -698,6 +698,14 @@ icon: freshservice.svg sourceType: api releaseStage: alpha +- name: Fullstory + sourceDefinitionId: 263fd456-02d1-4a26-a35e-52ccaedad778 + dockerRepository: airbyte/source-fullstory + dockerImageTag: 0.1.0 + documentationUrl: https://docs.airbyte.com/integrations/sources/fullstory + icon: fullstory.svg + sourceType: api + releaseStage: alpha - name: GCS sourceDefinitionId: 2a8c41ae-8c23-4be0-a73f-2ab10ca1a820 dockerRepository: airbyte/source-gcs diff --git a/airbyte-config-oss/init-oss/src/main/resources/seed/source_specs.yaml b/airbyte-config-oss/init-oss/src/main/resources/seed/source_specs.yaml index 8607e7dc789f1..cc146c7ed0446 100644 --- a/airbyte-config-oss/init-oss/src/main/resources/seed/source_specs.yaml +++ b/airbyte-config-oss/init-oss/src/main/resources/seed/source_specs.yaml @@ -5018,6 +5018,31 @@ supportsNormalization: false supportsDBT: false supported_destination_sync_modes: [] +- dockerImage: "airbyte/source-fullstory:0.1.0" + spec: + documentationUrl: "https://docs.airbyte.com/integrations/sources/fullstory" + connectionSpecification: + $schema: "http://json-schema.org/draft-07/schema#" + title: "fullstory.com Source Spec" + type: "object" + required: + - "api_key" + - "uid" + additionalProperties: true + properties: + api_key: + title: "API Key" + type: "string" + description: "API Key for the fullstory.com API." + airbyte_secret: true + uid: + title: "User ID" + type: "string" + description: "User ID for the fullstory.com API." + airbyte_secret: true + supportsNormalization: false + supportsDBT: false + supported_destination_sync_modes: [] - dockerImage: "airbyte/source-gcs:0.1.0" spec: documentationUrl: "https://docsurl.com" diff --git a/airbyte-integrations/connectors/source-fullstory/.dockerignore b/airbyte-integrations/connectors/source-fullstory/.dockerignore new file mode 100644 index 0000000000000..783e8f532eca9 --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/.dockerignore @@ -0,0 +1,6 @@ +* +!Dockerfile +!main.py +!source_fullstory +!setup.py +!secrets diff --git a/airbyte-integrations/connectors/source-fullstory/Dockerfile b/airbyte-integrations/connectors/source-fullstory/Dockerfile new file mode 100644 index 0000000000000..91998637757e3 --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/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_fullstory ./source_fullstory + +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-fullstory diff --git a/airbyte-integrations/connectors/source-fullstory/README.md b/airbyte-integrations/connectors/source-fullstory/README.md new file mode 100644 index 0000000000000..731e849dc434e --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/README.md @@ -0,0 +1,82 @@ +# Fullstory Source + +This is the repository for the Fullstory configuration based source connector. +For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.com/integrations/sources/fullstory). + +## 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-fullstory:build +``` + +#### Create credentials +**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/fullstory) +to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_fullstory/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 fullstory 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-fullstory:dev +``` + +You can also build the connector image via Gradle: +``` +./gradlew :airbyte-integrations:connectors:source-fullstory: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-fullstory:dev spec +docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-fullstory:dev check --config /secrets/config.json +docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-fullstory:dev discover --config /secrets/config.json +docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-fullstory: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-fullstory:unitTest +``` +To run acceptance and custom integration tests: +``` +./gradlew :airbyte-integrations:connectors:source-fullstory: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-fullstory/__init__.py b/airbyte-integrations/connectors/source-fullstory/__init__.py new file mode 100644 index 0000000000000..c941b30457953 --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/__init__.py @@ -0,0 +1,3 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# diff --git a/airbyte-integrations/connectors/source-fullstory/acceptance-test-config.yml b/airbyte-integrations/connectors/source-fullstory/acceptance-test-config.yml new file mode 100644 index 0000000000000..26db4753cce13 --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/acceptance-test-config.yml @@ -0,0 +1,41 @@ +# 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-fullstory:dev +test_strictness_level: low +acceptance_tests: + spec: + tests: + - spec_path: "source_fullstory/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: sessionTargetingRules + bypass_reason: "no data" + - name: webhooks + bypass_reason: "no data" + - name: geosettings + bypass_reason: "no data" + - name: domainsettings + bypass_reason: "no data" + - name: recordingfeatures + bypass_reason: "no data" + - name: blockrules + bypass_reason: "no data" + incremental: + bypass_reason: "This connector does not implement incremental sync" + + full_refresh: + tests: + - config_path: "secrets/config.json" + configured_catalog_path: "integration_tests/configured_catalog.json" diff --git a/airbyte-integrations/connectors/source-fullstory/acceptance-test-docker.sh b/airbyte-integrations/connectors/source-fullstory/acceptance-test-docker.sh new file mode 100755 index 0000000000000..b6d65deeccb43 --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/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-fullstory/build.gradle b/airbyte-integrations/connectors/source-fullstory/build.gradle new file mode 100644 index 0000000000000..c4ae1e3fc85de --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/build.gradle @@ -0,0 +1,9 @@ +plugins { + id 'airbyte-python' + id 'airbyte-docker' + id 'airbyte-connector-acceptance-test' +} + +airbytePython { + moduleDirectory 'source_fullstory' +} diff --git a/airbyte-integrations/connectors/source-fullstory/integration_tests/__init__.py b/airbyte-integrations/connectors/source-fullstory/integration_tests/__init__.py new file mode 100644 index 0000000000000..c941b30457953 --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/integration_tests/__init__.py @@ -0,0 +1,3 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# diff --git a/airbyte-integrations/connectors/source-fullstory/integration_tests/abnormal_state.json b/airbyte-integrations/connectors/source-fullstory/integration_tests/abnormal_state.json new file mode 100644 index 0000000000000..a04535c50385a --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/integration_tests/abnormal_state.json @@ -0,0 +1,9 @@ +[ + { + "type": "STREAM", + "stream": { + "stream_state": { "createdAt": "9999-04-12T18:13:36.000Z" }, + "stream_descriptor": { "name": "operations" } + } + } +] diff --git a/airbyte-integrations/connectors/source-fullstory/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-fullstory/integration_tests/acceptance.py new file mode 100644 index 0000000000000..9e6409236281f --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/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-fullstory/integration_tests/configured_catalog.json b/airbyte-integrations/connectors/source-fullstory/integration_tests/configured_catalog.json new file mode 100644 index 0000000000000..4287b498b5e3d --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/integration_tests/configured_catalog.json @@ -0,0 +1,94 @@ +{ + "streams": [ + { + "stream": { + "name": "segments", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "sessions", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "operations", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "blockrules", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "domainsettings", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "geosettings", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "recordingfeatures", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "sessionTargetingRules", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "webhooks", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "eventDefs", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + } + ] +} diff --git a/airbyte-integrations/connectors/source-fullstory/integration_tests/invalid_config.json b/airbyte-integrations/connectors/source-fullstory/integration_tests/invalid_config.json new file mode 100644 index 0000000000000..ab05dfc6b4571 --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/integration_tests/invalid_config.json @@ -0,0 +1,5 @@ +{ + "api_key": "Invalid_token", + "uid": "Invalid_token", + "start_date": "9999-03-01T00:00:00.000Z" +} diff --git a/airbyte-integrations/connectors/source-fullstory/integration_tests/sample_config.json b/airbyte-integrations/connectors/source-fullstory/integration_tests/sample_config.json new file mode 100644 index 0000000000000..5b848c9623757 --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/integration_tests/sample_config.json @@ -0,0 +1,5 @@ +{ + "api_key": "na1.by0xSzk0MlYtbmExL2Ftb2doc2hpdjk5QGdtYWlsLmNvbTrD51rZKTDT/ADUGEOzZdTSqH9pv2Uy0WK1iySTKXUd9C4u/34NZS5G", + "uid": "user_unique_id", + "start_date": "2022-04-20T00:00:00.000Z" +} diff --git a/airbyte-integrations/connectors/source-fullstory/integration_tests/sample_state.json b/airbyte-integrations/connectors/source-fullstory/integration_tests/sample_state.json new file mode 100644 index 0000000000000..f2785136956f1 --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/integration_tests/sample_state.json @@ -0,0 +1,16 @@ +[ + { + "type": "STREAM", + "stream": { + "stream_state": { "createdAt": "2023-04-20T18:13:36.000Z" }, + "stream_descriptor": { "name": "operations" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "created": "2023-04-20T18:13:36.000Z" }, + "stream_descriptor": { "name": "segments" } + } + } +] diff --git a/airbyte-integrations/connectors/source-fullstory/main.py b/airbyte-integrations/connectors/source-fullstory/main.py new file mode 100644 index 0000000000000..d9696f00cd3d0 --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/main.py @@ -0,0 +1,13 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +import sys + +from airbyte_cdk.entrypoint import launch +from source_fullstory import SourceFullstory + +if __name__ == "__main__": + source = SourceFullstory() + launch(source, sys.argv[1:]) diff --git a/airbyte-integrations/connectors/source-fullstory/requirements.txt b/airbyte-integrations/connectors/source-fullstory/requirements.txt new file mode 100644 index 0000000000000..cc57334ef619a --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/requirements.txt @@ -0,0 +1,2 @@ +-e ../../bases/connector-acceptance-test +-e . diff --git a/airbyte-integrations/connectors/source-fullstory/setup.py b/airbyte-integrations/connectors/source-fullstory/setup.py new file mode 100644 index 0000000000000..1b74c555ffaba --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/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_fullstory", + description="Source implementation for Fullstory.", + 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-fullstory/source_fullstory/__init__.py b/airbyte-integrations/connectors/source-fullstory/source_fullstory/__init__.py new file mode 100644 index 0000000000000..30b8e1fd0e27d --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/source_fullstory/__init__.py @@ -0,0 +1,8 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +from .source import SourceFullstory + +__all__ = ["SourceFullstory"] diff --git a/airbyte-integrations/connectors/source-fullstory/source_fullstory/manifest.yaml b/airbyte-integrations/connectors/source-fullstory/source_fullstory/manifest.yaml new file mode 100644 index 0000000000000..c6ad6a325d7b7 --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/source_fullstory/manifest.yaml @@ -0,0 +1,119 @@ +version: "0.29.0" + +definitions: + requester: + url_base: "https://api.fullstory.com" + http_method: "GET" + authenticator: + type: BearerAuthenticator + api_token: "{{ config['api_key'] }}" + retriever: + type: SimpleRetriever + record_selector: + type: RecordSelector + extractor: + type: DpathExtractor + field_path: ["{{ parameters.name }}"] + paginator: + type: "DefaultPaginator" + pagination_strategy: + type: "TokenBased" + token_field: "nextPaginationToken" + token_option: + type: "RequestOption" + inject_into: "request_parameter" + field_name: "pagination_token" + + requester: + $ref: "#/definitions/requester" + + base_stream: + retriever: + $ref: "#/definitions/retriever" + + operations_stream: + type: DeclarativeStream + $parameters: + name: "operations" + path: "/operations/v1" + $ref: "#/definitions/base_stream" + + sessions_stream: + type: DeclarativeStream + $parameters: + name: "sessions" + path: "/sessions/v2?{{ 'uid=' ~ config['uid'] }}" + $ref: "#/definitions/base_stream" + + segments_stream: + type: DeclarativeStream + $parameters: + name: "segments" + path: "/segments/v1" + $ref: "#/definitions/base_stream" + + blockrules_stream: + type: DeclarativeStream + $parameters: + name: "blockrules" + path: "/settings/recording/v1/blocking" + $ref: "#/definitions/base_stream" + + domainsettings_stream: + type: DeclarativeStream + $parameters: + name: "domainsettings" + path: "/settings/recording/v1/domain" + $ref: "#/definitions/base_stream" + + geosettings_stream: + type: DeclarativeStream + $parameters: + name: "geosettings" + path: "/settings/recording/v1/geo" + $ref: "#/definitions/base_stream" + + recordingfeatures_stream: + type: DeclarativeStream + $parameters: + name: "recordingfeatures" + path: "/settings/recording/v1/features" + $ref: "#/definitions/base_stream" + + targetrules_stream: + type: DeclarativeStream + $parameters: + name: "sessionTargetingRules" + path: "/settings/recording/v1/targeting" + $ref: "#/definitions/base_stream" + + webhooks_stream: + type: DeclarativeStream + $parameters: + name: "webhooks" + path: "/webhooks/v1/endpoints" + $ref: "#/definitions/base_stream" + + event-types_stream: + type: DeclarativeStream + $parameters: + name: "eventDefs" + path: "/webhooks/v1/event-types" + $ref: "#/definitions/base_stream" + +streams: + - "#/definitions/sessions_stream" + - "#/definitions/segments_stream" + - "#/definitions/operations_stream" + - "#/definitions/blockrules_stream" + - "#/definitions/domainsettings_stream" + - "#/definitions/geosettings_stream" + - "#/definitions/recordingfeatures_stream" + - "#/definitions/targetrules_stream" + - "#/definitions/webhooks_stream" + - "#/definitions/event-types_stream" + +check: + type: CheckStream + stream_names: + - "sessions" diff --git a/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/blockrules.json b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/blockrules.json new file mode 100644 index 0000000000000..35f9ae4ea9e46 --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/blockrules.json @@ -0,0 +1,26 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "BlockRules Schema", + "additionalProperties": true, + "type": "object", + "properties": { + "blockedIps": { + "type": ["null", "array"], + "items": { + "type": "string" + } + }, + "blockedUas": { + "type": ["null", "array"], + "items": { + "type": "string" + } + }, + "blockedAppIds": { + "type": ["null", "array"], + "items": { + "type": "string" + } + } + } +} diff --git a/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/domainsettings.json b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/domainsettings.json new file mode 100644 index 0000000000000..8d9436ae207b8 --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/domainsettings.json @@ -0,0 +1,25 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "DomainSettings Schema", + "additionalProperties": true, + "type": "object", + "properties": { + "onlyRecordKnownDomains": { + "type": ["null", "boolean"] + }, + "domains": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "properties": { + "disabled": { + "type": ["null", "boolean"] + }, + "domain": { + "type": ["null", "string"] + } + } + } + } + } +} diff --git a/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/eventDefs.json b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/eventDefs.json new file mode 100644 index 0000000000000..4945ea1c8335f --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/eventDefs.json @@ -0,0 +1,17 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "EventTypes Schema", + "type": "object", + "additionalProperties": true, + "properties": { + "eventName": { + "type": ["null", "string"] + }, + "displayName": { + "type": ["null", "string"] + }, + "hasSubcategories": { + "type": ["null", "boolean"] + } + } +} diff --git a/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/geosettings.json b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/geosettings.json new file mode 100644 index 0000000000000..cca1dcf8a736d --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/geosettings.json @@ -0,0 +1,17 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "GeoSettings Schema", + "additionalProperties": true, + "type": "object", + "properties": { + "record_geo_mode": { + "type": ["null", "string"] + }, + "record_geo_zones": { + "type": ["null", "array"], + "items": { + "type": "string" + } + } + } +} diff --git a/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/operations.json b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/operations.json new file mode 100644 index 0000000000000..525f2cc551b1f --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/operations.json @@ -0,0 +1,40 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Operations Schema", + "additionalProperties": true, + "type": "object", + "properties": { + "id": { + "type": ["null", "string"] + }, + "type": { + "type": ["null", "string"] + }, + "details": { + "type": ["null", "object"] + }, + "results": { + "type": ["null", "object"] + }, + "state": { + "type": ["null", "string"] + }, + "errorDetails": { + "type": ["null", "string"] + }, + "createdAt": { + "type": ["null", "string"], + "format": "date-time" + }, + "finishedAt": { + "type": ["null", "string"], + "format": "date-time" + }, + "estimatePctComplete": { + "type": ["null", "integer"] + }, + "step": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/recordingfeatures.json b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/recordingfeatures.json new file mode 100644 index 0000000000000..2d1a42113e97c --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/recordingfeatures.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "RecordingFeatures Schema", + "additionalProperties": true, + "type": "object", + "properties": { + "enabled": { + "type": ["null", "boolean"] + }, + "consoleWatcher": { + "type": ["null", "boolean"] + }, + "ajaxWatcher": { + "type": ["null", "boolean"] + }, + "resourceUploading": { + "type": ["null", "boolean"] + }, + "recordingShutoff": { + "type": ["null", "boolean"] + } + } +} diff --git a/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/segments.json b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/segments.json new file mode 100644 index 0000000000000..1891225737c5c --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/segments.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Segments Schema", + "additionalProperties": true, + "type": "object", + "properties": { + "id": { + "type": ["null", "string"] + }, + "name": { + "type": ["null", "string"] + }, + "creator": { + "type": ["null", "string"] + }, + "created": { + "type": ["null", "string"] + }, + "url": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/sessions.json b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/sessions.json new file mode 100644 index 0000000000000..820abba8a55f9 --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/sessions.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Sessions Schema", + "additionalProperties": true, + "type": "object", + "properties": { + "userId": { + "type": ["null", "integer", "string"] + }, + "sessionId": { + "type": ["null", "integer", "string"] + }, + "createdTime": { + "type": ["null", "integer", "string"] + }, + "fsUrl": { + "type": ["null", "string"] + } + } +} diff --git a/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/targetrules.json b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/targetrules.json new file mode 100644 index 0000000000000..8db2462f1fb7f --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/targetrules.json @@ -0,0 +1,73 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "TargetRules Schema", + "additionalProperties": true, + "type": "object", + "properties": { + "session_targeting_rules": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "properties": { + "id": { + "type": ["null", "string"] + }, + "notes": { + "type": ["null", "string"] + }, + "scope": { + "type": ["null", "string"] + }, + "conditions": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "properties": { + "attr": { + "type": ["null", "string"] + }, + "op": { + "type": ["null", "string"] + }, + "values": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "properties": { + "str_val": { + "type": ["null", "string"] + }, + "int_val": { + "type": ["null", "integer"] + }, + "version_val": { + "type": ["null", "object"] + } + } + } + }, + "join_previous": { + "type": ["null", "string"] + } + } + } + }, + "children": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "properties": { + "id": { + "type": ["null", "string"] + }, + "join_previous": { + "type": ["null", "string"] + } + } + } + } + } + } + } + } +} diff --git a/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/webhooks.json b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/webhooks.json new file mode 100644 index 0000000000000..28c4c2693f72b --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/source_fullstory/schemas/webhooks.json @@ -0,0 +1,45 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Webhooks Schema", + "additionalProperties": true, + "type": "object", + "properties": { + "endpoints": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "properties": { + "id": { + "type": ["null", "string"] + }, + "created": { + "type": ["null", "string"] + }, + "modified": { + "type": ["null", "string"] + }, + "enabled": { + "type": ["null", "boolean"] + }, + "url": { + "type": ["null", "string"] + }, + "event_types": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "properties": { + "event_name": { + "type": ["null", "string"] + }, + "subcategory": { + "type": ["null", "string"] + } + } + } + } + } + } + } + } +} diff --git a/airbyte-integrations/connectors/source-fullstory/source_fullstory/source.py b/airbyte-integrations/connectors/source-fullstory/source_fullstory/source.py new file mode 100644 index 0000000000000..9d406438860f2 --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/source_fullstory/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 SourceFullstory(YamlDeclarativeSource): + def __init__(self): + super().__init__(**{"path_to_yaml": "manifest.yaml"}) diff --git a/airbyte-integrations/connectors/source-fullstory/source_fullstory/spec.yaml b/airbyte-integrations/connectors/source-fullstory/source_fullstory/spec.yaml new file mode 100644 index 0000000000000..b9b38ea902216 --- /dev/null +++ b/airbyte-integrations/connectors/source-fullstory/source_fullstory/spec.yaml @@ -0,0 +1,20 @@ +documentationUrl: https://docs.airbyte.com/integrations/sources/fullstory +connectionSpecification: + $schema: http://json-schema.org/draft-07/schema# + title: fullstory.com Source Spec + type: object + required: + - api_key + - uid + additionalProperties: true + properties: + api_key: + title: API Key + type: string + description: API Key for the fullstory.com API. + airbyte_secret: true + uid: + title: User ID + type: string + description: User ID for the fullstory.com API. + airbyte_secret: true diff --git a/docs/integrations/sources/fullstory.md b/docs/integrations/sources/fullstory.md new file mode 100644 index 0000000000000..d3f3244cbe1ca --- /dev/null +++ b/docs/integrations/sources/fullstory.md @@ -0,0 +1,73 @@ +# FullStory + +This page contains the setup guide and reference information for the [FullStory](https://developer.fullstory.com/) source + +## Prerequisites + +API Key (which acts as bearer token) is mandate for this connector to work, It could be seen at settings (ref - https://app.fullstory.com/ui/o-1K942V-na1/settings/apikeys). + +## Setup guide + +### Step 1: Set up FullStory connection + +- Get a FullStory api key via settings (ref - https://app.fullstory.com/ui/o-1K942V-na1/settings/apikeys) +- Setup params (All params are required) +- Available params + - api_key: The generated api key + - uid: The unique identifier which can be configured in the fullstory script, under FS.identify + - start_date: Date filter for eligible streams, enter + +## Step 2: Set up the FullStory 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 FullStory connector and select **FullStory** from the Source type dropdown. +4. Enter your `api_key, uid and start_date`. +5. 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_id, api_token and start_date`. +4. Click **Set up source**. + +## Supported sync modes + +The FullStory 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 | Yes | +| Replicate Incremental Deletes | No | +| SSL connection | Yes | +| Namespaces | No | + +## Supported Streams + +- calls +- company +- contacts +- numbers +- tags +- user_availablity +- users +- teams +- webhooks + +## API method example + +GET https://api.fullstory.com/segments/v1 + +## Performance considerations + +FullStory [API reference](https://api.fullstory.com) has v1 at present. The connector as default uses v1. + +## Changelog + +| Version | Date | Pull Request | Subject | +| :------ | :--------- | :------------------------------------------------- | :------------- | +| 0.1.0 | 2023-04-25 | [Init](https://github.com/airbytehq/airbyte/pull/) | Initial commit |