diff --git a/airbyte-config/init/src/main/resources/seed/source_definitions.yaml b/airbyte-config/init/src/main/resources/seed/source_definitions.yaml index f673a484605c..be0b47b42202 100644 --- a/airbyte-config/init/src/main/resources/seed/source_definitions.yaml +++ b/airbyte-config/init/src/main/resources/seed/source_definitions.yaml @@ -1241,14 +1241,6 @@ icon: sentry.svg sourceType: api releaseStage: generally_available -- name: Zoom - sourceDefinitionId: aea2fd0d-377d-465e-86c0-4fdc4f688e51 - dockerRepository: airbyte/source-zoom-singer - dockerImageTag: 0.2.4 - documentationUrl: https://docs.airbyte.com/integrations/sources/zoom - icon: zoom.svg - sourceType: api - releaseStage: alpha - name: Zuora sourceDefinitionId: 3dc3037c-5ce8-4661-adc2-f7a9e3c5ece5 dockerRepository: airbyte/source-zuora @@ -1299,3 +1291,11 @@ documentationUrl: https://docs.airbyte.com/integrations/sources/yandex-metrica sourceType: api releaseStage: alpha +- name: Zoom + sourceDefinitionId: cbfd9856-1322-44fb-bcf1-0b39b7a8e92e + dockerRepository: airbyte/source-zoom + dockerImageTag: 0.1.0 + documentationUrl: https://docs.airbyte.io/integrations/sources/zoom + sourceType: api + icon: zoom.svg + releaseStage: alpha diff --git a/airbyte-config/init/src/main/resources/seed/source_specs.yaml b/airbyte-config/init/src/main/resources/seed/source_specs.yaml index ad20ec663c8b..52c84ba1c9ad 100644 --- a/airbyte-config/init/src/main/resources/seed/source_specs.yaml +++ b/airbyte-config/init/src/main/resources/seed/source_specs.yaml @@ -12545,26 +12545,6 @@ supportsNormalization: false supportsDBT: false supported_destination_sync_modes: [] -- dockerImage: "airbyte/source-zoom-singer:0.2.4" - spec: - documentationUrl: "https://docs.airbyte.com/integrations/sources/zoom" - connectionSpecification: - $schema: "http://json-schema.org/draft-07/schema#" - title: "Source Zoom Singer Spec" - type: "object" - required: - - "jwt" - additionalProperties: false - properties: - jwt: - title: "JWT Token" - type: "string" - description: "Zoom JWT Token. See the docs for more information on how to obtain this key." - airbyte_secret: true - supportsNormalization: false - supportsDBT: false - supported_destination_sync_modes: [] - dockerImage: "airbyte/source-zuora:0.1.3" spec: documentationUrl: "https://docs.airbyte.com/integrations/sources/zuora" @@ -13016,3 +12996,21 @@ supportsNormalization: false supportsDBT: false supported_destination_sync_modes: [] +- dockerImage: "airbyte/source-zoom:0.1.0" + spec: + documentationUrl: "https://docs.airbyte.com/integrations/sources/zoom" + connectionSpecification: + $schema: "http://json-schema.org/draft-07/schema#" + title: "Zoom Spec" + type: "object" + required: + - "jwt_token" + additionalProperties: true + properties: + jwt_token: + type: "string" + description: "JWT Token" + airbyte_secret: true + supportsNormalization: false + supportsDBT: false + supported_destination_sync_modes: [] diff --git a/airbyte-integrations/connectors/source-zoom-singer/.dockerignore b/airbyte-integrations/connectors/source-zoom-singer/.dockerignore deleted file mode 100644 index 540fc080488d..000000000000 --- a/airbyte-integrations/connectors/source-zoom-singer/.dockerignore +++ /dev/null @@ -1,3 +0,0 @@ -build -.venv - diff --git a/airbyte-integrations/connectors/source-zoom-singer/.gitignore b/airbyte-integrations/connectors/source-zoom-singer/.gitignore deleted file mode 100644 index 29fffc6a50cc..000000000000 --- a/airbyte-integrations/connectors/source-zoom-singer/.gitignore +++ /dev/null @@ -1 +0,0 @@ -NEW_SOURCE_CHECKLIST.md diff --git a/airbyte-integrations/connectors/source-zoom-singer/README.md b/airbyte-integrations/connectors/source-zoom-singer/README.md deleted file mode 100644 index 0177fc2c5f6c..000000000000 --- a/airbyte-integrations/connectors/source-zoom-singer/README.md +++ /dev/null @@ -1,113 +0,0 @@ -# Source Zoom Singer - -This is the repository for the Zoom source connector, based on a Singer tap. -For information about how to use this connector within Airbyte, see [the User Documentation](https://docs.airbyte.io/integrations/sources/zoom). - -## Local development - -### Prerequisites -**To iterate on this connector, make sure to complete this prerequisites section.** - -#### Minimum Python version required `= 3.7.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:source-zoom:build -``` - -#### Create credentials -**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.io/integrations/sources/zoom) -to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_zoom_singer/spec.json` file. -Note that the `secrets` directory is gitignored by default, so there is no danger of accidentally checking in sensitive information. -See `sample_files/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 zoom test creds` -and place them into `secrets/config.json`. - -### Locally running the connector -``` -python main_dev.py spec -python main_dev.py check --config secrets/config.json -python main_dev.py discover --config secrets/config.json -python main_dev.py read --config secrets/config.json --catalog sample_files/configured_catalog.json -``` - -### Unit Tests -To run unit tests locally, from the connector root run: -``` -pytest unit_tests -``` - -### Locally running the connector -``` -python main_dev.py spec -python main_dev.py check --config secrets/config.json -python main_dev.py discover --config secrets/config.json -python main_dev.py read --config secrets/config.json --catalog sample_files/configured_catalog.json -``` - -### Unit Tests -To run unit tests locally, from the connector directory run: -``` -python -m pytest unit_tests -``` - -### Locally running the connector docker image - -#### Build -First, make sure you build the latest Docker image: -``` -docker build . -t airbyte/source-zoom-singer:dev -``` - -You can also build the connector image via Gradle: -``` -./gradlew :airbyte-integrations:connectors:source-zoom: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-zoom-singer:dev spec -docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-zoom-singer:dev check --config /secrets/config.json -docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-zoom-singer:dev discover --config /secrets/config.json -docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/sample_files:/sample_files airbyte/source-zoom-singer:dev read --config /secrets/config.json --catalog /sample_files/configured_catalog.json -``` - -### Integration Tests -1. From the airbyte project root, run `./gradlew :airbyte-integrations:connectors:source-zoom-singer:integrationTest` to run the standard integration test suite. -1. To run additional integration tests, create a directory `integration_tests` which contain your tests and run them with `pytest integration_tests`. - 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. - -## 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. - -### 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). -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-zoom-singer/build.gradle b/airbyte-integrations/connectors/source-zoom-singer/build.gradle deleted file mode 100644 index 408979685851..000000000000 --- a/airbyte-integrations/connectors/source-zoom-singer/build.gradle +++ /dev/null @@ -1,21 +0,0 @@ -plugins { - id 'airbyte-python' - id 'airbyte-docker' - id 'airbyte-standard-source-test-file' -} - -airbytePython { - moduleDirectory 'source_zoom_singer' -} - -airbyteStandardSourceTestFile { - specPath = "source_zoom_singer/spec.json" - configPath = "secrets/config.json" - configuredCatalogPath = "sample_files/configured_catalog.json" -} - - - -dependencies { - implementation files(project(':airbyte-integrations:bases:base-standard-source-test-file').airbyteDocker.outputs) -} diff --git a/airbyte-integrations/connectors/source-zoom-singer/requirements.txt b/airbyte-integrations/connectors/source-zoom-singer/requirements.txt deleted file mode 100644 index 7b9114ed5867..000000000000 --- a/airbyte-integrations/connectors/source-zoom-singer/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -# This file is autogenerated -- only edit if you know what you are doing. Use setup.py for declaring dependencies. --e . diff --git a/airbyte-integrations/connectors/source-zoom-singer/sample_files/configured_catalog.json b/airbyte-integrations/connectors/source-zoom-singer/sample_files/configured_catalog.json deleted file mode 100644 index 0d10357b06a4..000000000000 --- a/airbyte-integrations/connectors/source-zoom-singer/sample_files/configured_catalog.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "streams": [ - { - "stream": { - "name": "users", - "json_schema": { - "properties": { - "id": { - "type": ["string"] - }, - "first_name": { - "type": ["null", "string"] - }, - "last_name": { - "type": ["null", "string"] - }, - "email": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "integer"] - }, - "status": { - "type": ["null", "string"] - }, - "pmi": { - "type": ["null", "integer"] - }, - "timezone": { - "type": ["null", "string"] - }, - "dept": { - "type": ["null", "string"] - }, - "created_at": { - "format": "date-time", - "type": ["null", "string"] - }, - "last_login_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "last_client_version": { - "type": ["null", "string"] - }, - "group_ids": { - "items": { - "type": ["string"] - }, - "type": ["null", "array"] - }, - "im_group_ids": { - "items": { - "type": ["string"] - }, - "type": ["null", "array"] - }, - "verified": { - "type": ["null", "integer"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - } - ] -} diff --git a/airbyte-integrations/connectors/source-zoom-singer/sample_files/full_configured_catalog.json b/airbyte-integrations/connectors/source-zoom-singer/sample_files/full_configured_catalog.json deleted file mode 100644 index 6859a4e1e9e0..000000000000 --- a/airbyte-integrations/connectors/source-zoom-singer/sample_files/full_configured_catalog.json +++ /dev/null @@ -1,1462 +0,0 @@ -{ - "streams": [ - { - "stream": { - "name": "meeting_polls", - "json_schema": { - "properties": { - "id": { - "type": ["string"] - }, - "meeting_id": { - "type": ["string"] - }, - "status": { - "type": ["null", "string"] - }, - "title": { - "type": ["null", "string"] - }, - "questions": { - "items": { - "properties": { - "name": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "string"] - }, - "answers": { - "items": { - "type": ["string"] - }, - "type": ["null", "array"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "report_webinar_participants", - "json_schema": { - "properties": { - "id": { - "type": ["string"] - }, - "user_id": { - "type": ["string"] - }, - "webinar_id": { - "type": ["string"] - }, - "name": { - "type": ["null", "string"] - }, - "user_email": { - "type": ["null", "string"] - }, - "join_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "leave_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "duration": { - "type": ["null", "string"] - }, - "attentiveness_score": { - "type": ["null", "string"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "meeting_files", - "json_schema": { - "properties": { - "meeting_uuid": { - "type": ["string"] - }, - "file_name": { - "type": ["null", "string"] - }, - "download_url": { - "type": ["null", "string"] - }, - "file_size": { - "type": ["null", "integer"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "meeting_registrants", - "json_schema": { - "properties": { - "id": { - "type": ["string"] - }, - "meeting_id": { - "type": ["string"] - }, - "email": { - "type": ["null", "string"] - }, - "first_name": { - "type": ["null", "string"] - }, - "last_name": { - "type": ["null", "string"] - }, - "address": { - "type": ["null", "string"] - }, - "city": { - "type": ["null", "string"] - }, - "county": { - "type": ["null", "string"] - }, - "zip": { - "type": ["null", "string"] - }, - "state": { - "type": ["null", "string"] - }, - "phone": { - "type": ["null", "string"] - }, - "industry": { - "type": ["null", "string"] - }, - "org": { - "type": ["null", "string"] - }, - "job_title": { - "type": ["null", "string"] - }, - "purchasing_time_frame": { - "type": ["null", "string"] - }, - "role_in_purchase_process": { - "type": ["null", "string"] - }, - "no_of_employees": { - "type": ["null", "string"] - }, - "comments": { - "type": ["null", "string"] - }, - "custom_questions": { - "items": { - "properties": { - "title": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - }, - "status": { - "type": ["null", "string"] - }, - "create_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "join_url": { - "type": ["null", "string"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "users", - "json_schema": { - "properties": { - "id": { - "type": ["string"] - }, - "first_name": { - "type": ["null", "string"] - }, - "last_name": { - "type": ["null", "string"] - }, - "email": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "integer"] - }, - "status": { - "type": ["null", "string"] - }, - "pmi": { - "type": ["null", "integer"] - }, - "timezone": { - "type": ["null", "string"] - }, - "dept": { - "type": ["null", "string"] - }, - "created_at": { - "format": "date-time", - "type": ["null", "string"] - }, - "last_login_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "last_client_version": { - "type": ["null", "string"] - }, - "group_ids": { - "items": { - "type": ["string"] - }, - "type": ["null", "array"] - }, - "im_group_ids": { - "items": { - "type": ["string"] - }, - "type": ["null", "array"] - }, - "verified": { - "type": ["null", "integer"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "webinar_poll_results", - "json_schema": { - "properties": { - "webinar_uuid": { - "type": ["string"] - }, - "email": { - "type": ["string"] - }, - "name": { - "type": ["null", "string"] - }, - "question_details": { - "items": { - "properties": { - "question": { - "type": ["null", "string"] - }, - "answer": { - "type": ["null", "string"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "webinar_files", - "json_schema": { - "properties": { - "webinar_uuid": { - "type": ["string"] - }, - "file_name": { - "type": ["null", "string"] - }, - "download_url": { - "type": ["null", "string"] - }, - "file_size": { - "type": ["null", "integer"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "webinar_polls", - "json_schema": { - "properties": { - "id": { - "type": ["string"] - }, - "webinar_id": { - "type": ["string"] - }, - "status": { - "type": ["null", "string"] - }, - "title": { - "type": ["null", "string"] - }, - "questions": { - "items": { - "properties": { - "name": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "string"] - }, - "answers": { - "items": { - "type": ["string"] - }, - "type": ["null", "array"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "meetings", - "json_schema": { - "properties": { - "id": { - "type": ["integer"] - }, - "meeting_id": { - "type": ["string"] - }, - "uuid": { - "type": ["string"] - }, - "host_id": { - "type": ["null", "string"] - }, - "topic": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "integer"] - }, - "status": { - "type": ["null", "string"] - }, - "start_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "duration": { - "type": ["null", "integer"] - }, - "timezone": { - "type": ["null", "string"] - }, - "created_at": { - "format": "date-time", - "type": ["null", "string"] - }, - "agenda": { - "type": ["null", "string"] - }, - "start_url": { - "type": ["null", "string"] - }, - "join_url": { - "type": ["null", "string"] - }, - "password": { - "type": ["null", "string"] - }, - "h323_password": { - "type": ["null", "string"] - }, - "encrypted_Password": { - "type": ["null", "string"] - }, - "pmi": { - "type": ["null", "integer"] - }, - "tracking_fields": { - "items": { - "properties": { - "field": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - }, - "occurences": { - "items": { - "properties": { - "occurence_id": { - "type": ["null", "string"] - }, - "start_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "duration": { - "type": ["null", "integer"] - }, - "status": { - "type": ["null", "string"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - }, - "settings": { - "properties": { - "host_video": { - "type": ["null", "boolean"] - }, - "participant_video": { - "type": ["null", "boolean"] - }, - "cn_meeting": { - "type": ["null", "boolean"] - }, - "in_meeting": { - "type": ["null", "boolean"] - }, - "join_before_host": { - "type": ["null", "boolean"] - }, - "mute_upon_entry": { - "type": ["null", "boolean"] - }, - "watermark": { - "type": ["null", "boolean"] - }, - "use_pmi": { - "type": ["null", "boolean"] - }, - "approval_type": { - "type": ["null", "integer"] - }, - "registration_type": { - "type": ["null", "integer"] - }, - "audio": { - "type": ["null", "string"] - }, - "auto_recording": { - "type": ["null", "string"] - }, - "enforce_login": { - "type": ["null", "boolean"] - }, - "enforce_login_domains": { - "type": ["null", "string"] - }, - "alternative_hosts": { - "type": ["null", "string"] - }, - "close_registration": { - "type": ["null", "boolean"] - }, - "waiting_room": { - "type": ["null", "boolean"] - }, - "global_dial_in_countries": { - "items": { - "type": ["string"] - }, - "type": ["null", "array"] - }, - "global_dial_in_numbers": { - "items": { - "properties": { - "country": { - "type": ["null", "string"] - }, - "country_name": { - "type": ["null", "string"] - }, - "city": { - "type": ["null", "string"] - }, - "number": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "string"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - }, - "contact_name": { - "type": ["null", "boolean"] - }, - "contact_email": { - "type": ["null", "boolean"] - }, - "registrants_confirmation_email": { - "type": ["null", "boolean"] - }, - "registrants_email_notification": { - "type": ["null", "boolean"] - }, - "meeting_authentication": { - "type": ["null", "boolean"] - }, - "authentication_option": { - "type": ["null", "string"] - }, - "authentication_domains": { - "type": ["null", "string"] - } - }, - "type": ["null", "object"], - "additionalProperties": false - }, - "recurrence": { - "properties": { - "type": { - "type": ["null", "integer"] - }, - "repeat_interval": { - "type": ["null", "integer"] - }, - "weekly_days": { - "type": ["null", "integer"] - }, - "monthly_day": { - "type": ["null", "integer"] - }, - "monthly_week": { - "type": ["null", "integer"] - }, - "monthly_week_day": { - "type": ["null", "integer"] - }, - "end_times": { - "type": ["null", "integer"] - }, - "end_date_time": { - "format": "date-time", - "type": ["null", "string"] - } - }, - "type": ["null", "object"], - "additionalProperties": false - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "meeting_questions", - "json_schema": { - "properties": { - "meeting_id": { - "type": ["string"] - }, - "questions": { - "items": { - "properties": { - "field_name": { - "type": ["null", "string"] - }, - "required": { - "type": ["null", "boolean"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - }, - "custom_questions": { - "items": { - "properties": { - "title": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "string"] - }, - "required": { - "type": ["null", "boolean"] - }, - "answers": { - "items": { - "type": ["string"] - }, - "type": ["null", "array"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "webinar_registrants", - "json_schema": { - "properties": { - "id": { - "type": ["string"] - }, - "webinar_id": { - "type": ["string"] - }, - "email": { - "type": ["null", "string"] - }, - "first_name": { - "type": ["null", "string"] - }, - "last_name": { - "type": ["null", "string"] - }, - "address": { - "type": ["null", "string"] - }, - "city": { - "type": ["null", "string"] - }, - "county": { - "type": ["null", "string"] - }, - "zip": { - "type": ["null", "string"] - }, - "state": { - "type": ["null", "string"] - }, - "phone": { - "type": ["null", "string"] - }, - "industry": { - "type": ["null", "string"] - }, - "org": { - "type": ["null", "string"] - }, - "job_title": { - "type": ["null", "string"] - }, - "purchasing_time_frame": { - "type": ["null", "string"] - }, - "role_in_purchase_process": { - "type": ["null", "string"] - }, - "no_of_employees": { - "type": ["null", "string"] - }, - "comments": { - "type": ["null", "string"] - }, - "custom_questions": { - "items": { - "properties": { - "title": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - }, - "status": { - "type": ["null", "string"] - }, - "create_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "join_url": { - "type": ["null", "string"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "webinar_panelists", - "json_schema": { - "properties": { - "id": { - "type": ["string"] - }, - "webinar_id": { - "type": ["string"] - }, - "name": { - "type": ["null", "string"] - }, - "email": { - "type": ["null", "string"] - }, - "join_url": { - "type": ["null", "string"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "meeting_poll_results", - "json_schema": { - "properties": { - "meeting_uuid": { - "type": ["string"] - }, - "email": { - "type": ["string"] - }, - "name": { - "type": ["null", "string"] - }, - "question_details": { - "items": { - "properties": { - "question": { - "type": ["null", "string"] - }, - "answer": { - "type": ["null", "string"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "webinar_questions", - "json_schema": { - "properties": { - "webinar_id": { - "type": ["string"] - }, - "questions": { - "items": { - "properties": { - "field_name": { - "type": ["null", "string"] - }, - "required": { - "type": ["null", "boolean"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - }, - "custom_questions": { - "items": { - "properties": { - "title": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "string"] - }, - "required": { - "type": ["null", "boolean"] - }, - "answers": { - "items": { - "type": ["string"] - }, - "type": ["null", "array"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "report_meeting_participants", - "json_schema": { - "properties": { - "id": { - "type": ["string"] - }, - "user_id": { - "type": ["string"] - }, - "meeting_id": { - "type": ["string"] - }, - "name": { - "type": ["null", "string"] - }, - "user_email": { - "type": ["null", "string"] - }, - "join_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "leave_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "duration": { - "type": ["null", "string"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "webinars", - "json_schema": { - "properties": { - "uuid": { - "type": ["string"] - }, - "id": { - "type": ["string"] - }, - "host_id": { - "type": ["null", "string"] - }, - "topic": { - "type": ["null", "string"] - }, - "type": { - "type": ["null", "integer"] - }, - "start_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "duration": { - "type": ["null", "integer"] - }, - "timezone": { - "type": ["null", "string"] - }, - "agenda": { - "type": ["null", "string"] - }, - "created_at": { - "format": "date-time", - "type": ["null", "string"] - }, - "start_url": { - "type": ["null", "string"] - }, - "join_url": { - "type": ["null", "string"] - }, - "tracking_fields": { - "items": { - "properties": { - "field": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - }, - "occurences": { - "items": { - "properties": { - "occurence_id": { - "type": ["null", "string"] - }, - "start_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "duration": { - "type": ["null", "integer"] - }, - "status": { - "type": ["null", "string"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - }, - "settings": { - "properties": { - "host_video": { - "type": ["null", "boolean"] - }, - "panelists_video": { - "type": ["null", "boolean"] - }, - "practice_session": { - "type": ["null", "boolean"] - }, - "hd_video": { - "type": ["null", "boolean"] - }, - "approval_type": { - "type": ["null", "integer"] - }, - "registration_type": { - "type": ["null", "integer"] - }, - "audio": { - "type": ["null", "string"] - }, - "auto_recording": { - "type": ["null", "string"] - }, - "enforce_login": { - "type": ["null", "boolean"] - }, - "enforce_login_domains": { - "type": ["null", "string"] - }, - "alternative_hosts": { - "type": ["null", "string"] - }, - "close_registration": { - "type": ["null", "boolean"] - }, - "show_share_button": { - "type": ["null", "boolean"] - }, - "allow_multiple_devices": { - "type": ["null", "boolean"] - }, - "on_demand": { - "type": ["null", "boolean"] - }, - "global_dial_in_countries": { - "items": { - "type": ["string"] - }, - "type": ["null", "array"] - }, - "contact_name": { - "type": ["null", "boolean"] - }, - "contact_email": { - "type": ["null", "boolean"] - }, - "registrants_confirmation_email": { - "type": ["null", "boolean"] - }, - "registrants_restrict_number": { - "type": ["null", "integer"] - }, - "notify_registrants": { - "type": ["null", "boolean"] - }, - "post_webinar_survey": { - "type": ["null", "boolean"] - }, - "survey_url": { - "type": ["null", "string"] - }, - "registrants_email_notification": { - "type": ["null", "boolean"] - }, - "meeting_authentication": { - "type": ["null", "boolean"] - }, - "authentication_option": { - "type": ["null", "string"] - }, - "authentication_domains": { - "type": ["null", "string"] - } - }, - "type": ["null", "object"], - "additionalProperties": false - }, - "recurrence": { - "properties": { - "type": { - "type": ["null", "integer"] - }, - "repeat_interval": { - "type": ["null", "integer"] - }, - "weekly_days": { - "type": ["null", "integer"] - }, - "monthly_day": { - "type": ["null", "integer"] - }, - "monthly_week": { - "type": ["null", "integer"] - }, - "monthly_week_day": { - "type": ["null", "integer"] - }, - "end_times": { - "type": ["null", "integer"] - }, - "end_date_time": { - "format": "date-time", - "type": ["null", "string"] - } - }, - "type": ["null", "object"], - "additionalProperties": false - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "webinar_qna_results", - "json_schema": { - "properties": { - "webinar_uuid": { - "type": ["string"] - }, - "email": { - "type": ["string"] - }, - "name": { - "type": ["null", "string"] - }, - "question_details": { - "items": { - "properties": { - "question": { - "type": ["null", "string"] - }, - "answer": { - "type": ["null", "string"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "webinar_absentees", - "json_schema": { - "properties": { - "id": { - "type": ["string"] - }, - "webinar_uuid": { - "type": ["string"] - }, - "email": { - "type": ["null", "string"] - }, - "first_name": { - "type": ["null", "string"] - }, - "last_name": { - "type": ["null", "string"] - }, - "address": { - "type": ["null", "string"] - }, - "city": { - "type": ["null", "string"] - }, - "county": { - "type": ["null", "string"] - }, - "zip": { - "type": ["null", "string"] - }, - "state": { - "type": ["null", "string"] - }, - "phone": { - "type": ["null", "string"] - }, - "industry": { - "type": ["null", "string"] - }, - "org": { - "type": ["null", "string"] - }, - "job_title": { - "type": ["null", "string"] - }, - "purchasing_time_frame": { - "type": ["null", "string"] - }, - "role_in_purchase_process": { - "type": ["null", "string"] - }, - "no_of_employees": { - "type": ["null", "string"] - }, - "comments": { - "type": ["null", "string"] - }, - "custom_questions": { - "items": { - "properties": { - "title": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - }, - "status": { - "type": ["null", "string"] - }, - "create_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "join_url": { - "type": ["null", "string"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "webinar_tracking_sources", - "json_schema": { - "properties": { - "id": { - "type": ["string"] - }, - "webinar_id": { - "type": ["string"] - }, - "source_name": { - "type": ["null", "string"] - }, - "tracking_url": { - "type": ["null", "string"] - }, - "registration_count": { - "type": ["null", "integer"] - }, - "visitor_count": { - "type": ["null", "integer"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "report_meetings", - "json_schema": { - "properties": { - "meeting_id": { - "type": ["string"] - }, - "uuid": { - "type": ["string"] - }, - "id": { - "type": ["integer"] - }, - "type": { - "type": ["null", "integer"] - }, - "topic": { - "type": ["null", "string"] - }, - "user_name": { - "type": ["null", "string"] - }, - "user_email": { - "type": ["null", "string"] - }, - "start_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "end_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "duration": { - "type": ["null", "integer"] - }, - "total_minutes": { - "type": ["null", "integer"] - }, - "participants_count": { - "type": ["null", "integer"] - }, - "tracking_fields": { - "items": { - "properties": { - "field": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - }, - "dept": { - "type": ["null", "integer"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - }, - { - "stream": { - "name": "report_webinars", - "json_schema": { - "properties": { - "webinar_id": { - "type": ["string"] - }, - "uuid": { - "type": ["string"] - }, - "id": { - "type": ["integer"] - }, - "type": { - "type": ["null", "integer"] - }, - "topic": { - "type": ["null", "string"] - }, - "user_name": { - "type": ["null", "string"] - }, - "user_email": { - "type": ["null", "string"] - }, - "start_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "end_time": { - "format": "date-time", - "type": ["null", "string"] - }, - "duration": { - "type": ["null", "integer"] - }, - "total_minutes": { - "type": ["null", "integer"] - }, - "participants_count": { - "type": ["null", "integer"] - }, - "tracking_fields": { - "items": { - "properties": { - "field": { - "type": ["null", "string"] - }, - "value": { - "type": ["null", "string"] - } - }, - "type": ["object"], - "additionalProperties": false - }, - "type": ["null", "array"] - }, - "dept": { - "type": ["null", "integer"] - } - }, - "type": "object", - "additionalProperties": false - }, - "supported_sync_modes": ["full_refresh"] - }, - "sync_mode": "full_refresh", - "destination_sync_mode": "overwrite" - } - ] -} diff --git a/airbyte-integrations/connectors/source-zoom-singer/sample_files/sample_config.json b/airbyte-integrations/connectors/source-zoom-singer/sample_files/sample_config.json deleted file mode 100644 index 2975582744b1..000000000000 --- a/airbyte-integrations/connectors/source-zoom-singer/sample_files/sample_config.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "jwt": "" -} diff --git a/airbyte-integrations/connectors/source-zoom-singer/setup.py b/airbyte-integrations/connectors/source-zoom-singer/setup.py deleted file mode 100644 index 6387b921e852..000000000000 --- a/airbyte-integrations/connectors/source-zoom-singer/setup.py +++ /dev/null @@ -1,16 +0,0 @@ -# -# Copyright (c) 2022 Airbyte, Inc., all rights reserved. -# - - -from setuptools import find_packages, setup - -setup( - name="source_zoom_singer", - description="Source implementation for Zoom, built on the Singer tap implementation.", - author="Airbyte", - author_email="contact@airbyte.io", - packages=find_packages(), - install_requires=["airbyte-cdk", "tap-zoom==1.0.0", "pytest==6.1.2"], - package_data={"": ["*.json"]}, -) diff --git a/airbyte-integrations/connectors/source-zoom-singer/source_zoom_singer/__init__.py b/airbyte-integrations/connectors/source-zoom-singer/source_zoom_singer/__init__.py deleted file mode 100644 index dee834d0c068..000000000000 --- a/airbyte-integrations/connectors/source-zoom-singer/source_zoom_singer/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .source import SourceZoomSinger - -__all__ = ["SourceZoomSinger"] diff --git a/airbyte-integrations/connectors/source-zoom-singer/source_zoom_singer/source.py b/airbyte-integrations/connectors/source-zoom-singer/source_zoom_singer/source.py deleted file mode 100644 index 3dac31a63e8f..000000000000 --- a/airbyte-integrations/connectors/source-zoom-singer/source_zoom_singer/source.py +++ /dev/null @@ -1,24 +0,0 @@ -# -# Copyright (c) 2022 Airbyte, Inc., all rights reserved. -# - - -from airbyte_cdk import AirbyteLogger -from airbyte_cdk.sources.singer.source import BaseSingerSource -from requests import HTTPError -from tap_zoom.client import ZoomClient - - -class SourceZoomSinger(BaseSingerSource): - """ - Zoom API Reference: https://marketplace.zoom.us/docs/api-reference/zoom-api - """ - - tap_cmd = "tap-zoom" - tap_name = "Zoom API" - api_error = HTTPError - force_full_refresh = True - - def try_connect(self, logger: AirbyteLogger, config: dict): - client = ZoomClient(config=config, config_path="") - client.get(path="users") diff --git a/airbyte-integrations/connectors/source-zoom-singer/source_zoom_singer/spec.json b/airbyte-integrations/connectors/source-zoom-singer/source_zoom_singer/spec.json deleted file mode 100644 index ccd2b3111b35..000000000000 --- a/airbyte-integrations/connectors/source-zoom-singer/source_zoom_singer/spec.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "documentationUrl": "https://docs.airbyte.com/integrations/sources/zoom", - "connectionSpecification": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Source Zoom Singer Spec", - "type": "object", - "required": ["jwt"], - "additionalProperties": false, - "properties": { - "jwt": { - "title": "JWT Token", - "type": "string", - "description": "Zoom JWT Token. See the docs for more information on how to obtain this key.", - "airbyte_secret": true - } - } - } -} diff --git a/airbyte-integrations/connectors/source-zoom/.dockerignore b/airbyte-integrations/connectors/source-zoom/.dockerignore new file mode 100644 index 000000000000..0804d05bd68e --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/.dockerignore @@ -0,0 +1,6 @@ +* +!Dockerfile +!main.py +!source_zoom +!setup.py +!secrets diff --git a/airbyte-integrations/connectors/source-zoom-singer/Dockerfile b/airbyte-integrations/connectors/source-zoom/Dockerfile similarity index 79% rename from airbyte-integrations/connectors/source-zoom-singer/Dockerfile rename to airbyte-integrations/connectors/source-zoom/Dockerfile index 3b56601b682c..9ad7060d0685 100644 --- a/airbyte-integrations/connectors/source-zoom-singer/Dockerfile +++ b/airbyte-integrations/connectors/source-zoom/Dockerfile @@ -7,9 +7,7 @@ WORKDIR /airbyte/integration_code # upgrade pip to the latest version RUN apk --no-cache upgrade \ && pip install --upgrade pip \ - && apk --no-cache add tzdata \ - && apk --no-cache add git \ - && apk --no-cache add build-base + && apk --no-cache add tzdata build-base COPY setup.py ./ @@ -31,10 +29,12 @@ RUN apk --no-cache add bash # copy payload code only COPY main.py ./ -COPY source_zoom_singer ./source_zoom_singer +COPY source_zoom ./source_zoom + ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py" + ENTRYPOINT ["python", "/airbyte/integration_code/main.py"] -LABEL io.airbyte.version=0.2.4 -LABEL io.airbyte.name=airbyte/source-zoom-singer +LABEL io.airbyte.version=0.1.0 +LABEL io.airbyte.name=airbyte/source-zoom diff --git a/airbyte-integrations/connectors/source-zoom-singer/unit_tests/unit_test.py b/airbyte-integrations/connectors/source-zoom/__init__.py similarity index 57% rename from airbyte-integrations/connectors/source-zoom-singer/unit_tests/unit_test.py rename to airbyte-integrations/connectors/source-zoom/__init__.py index dddaea0060fa..1100c1c58cf5 100644 --- a/airbyte-integrations/connectors/source-zoom-singer/unit_tests/unit_test.py +++ b/airbyte-integrations/connectors/source-zoom/__init__.py @@ -1,7 +1,3 @@ # # Copyright (c) 2022 Airbyte, Inc., all rights reserved. # - - -def test_example_method(): - assert True diff --git a/airbyte-integrations/connectors/source-zoom/acceptance-test-config.yml b/airbyte-integrations/connectors/source-zoom/acceptance-test-config.yml new file mode 100644 index 000000000000..23948f4f26d1 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/acceptance-test-config.yml @@ -0,0 +1,44 @@ +# See [Source Acceptance Tests](https://docs.airbyte.io/connector-development/testing-connectors/source-acceptance-tests-reference) +# for more information about how to configure these tests +connector_image: airbyte/source-zoom:dev +tests: + spec: + - spec_path: "source_zoom/spec.yaml" + connection: + - config_path: "secrets/config.json" + status: "succeed" + - config_path: "integration_tests/invalid_config.json" + status: "failed" + discovery: + - config_path: "secrets/config.json" + basic_read: + - config_path: "secrets/config.json" + configured_catalog_path: "integration_tests/configured_catalog.json" + timeout_seconds: 3600 + empty_streams: + - "meeting_registrants" + - "meeting_polls" + - "meeting_poll_results" + - "meeting_registration_questions" + - "webinars" + - "webinar_panelists" + - "webinar_registrants" + - "webinar_absentees" + - "webinar_polls" + - "webinar_poll_results" + - "webinar_registration_questions" + - "webinar_tracking_sources" + - "webinar_qna_results" + - "report_meetings" + - "report_meeting_participants" + - "report_webinars" + - "report_webinar_participants" + full_refresh: + - config_path: "secrets/config.json" + configured_catalog_path: "integration_tests/configured_catalog.json" + ignored_fields: + "meetings": + - "start_url" + "webinars": + - "start_url" + timeout_seconds: 3600 diff --git a/airbyte-integrations/connectors/source-zoom/acceptance-test-docker.sh b/airbyte-integrations/connectors/source-zoom/acceptance-test-docker.sh new file mode 100755 index 000000000000..c51577d10690 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/acceptance-test-docker.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env sh + +# Build latest connector image +docker build . -t $(cat acceptance-test-config.yml | grep "connector_image" | head -n 1 | cut -d: -f2-) + +# Pull latest acctest image +docker pull airbyte/source-acceptance-test:latest + +# Run +docker run --rm -it \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /tmp:/tmp \ + -v $(pwd):/test_input \ + airbyte/source-acceptance-test \ + --acceptance-test-config /test_input + diff --git a/airbyte-integrations/connectors/source-zoom/build.gradle b/airbyte-integrations/connectors/source-zoom/build.gradle new file mode 100644 index 000000000000..fa9adb45e4e0 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/build.gradle @@ -0,0 +1,9 @@ +plugins { + id 'airbyte-python' + id 'airbyte-docker' + id 'airbyte-source-acceptance-test' +} + +airbytePython { + moduleDirectory 'source_zoom' +} diff --git a/airbyte-integrations/connectors/source-zoom/integration_tests/__init__.py b/airbyte-integrations/connectors/source-zoom/integration_tests/__init__.py new file mode 100644 index 000000000000..1100c1c58cf5 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/integration_tests/__init__.py @@ -0,0 +1,3 @@ +# +# Copyright (c) 2022 Airbyte, Inc., all rights reserved. +# diff --git a/airbyte-integrations/connectors/source-zoom/integration_tests/abnormal_state.json b/airbyte-integrations/connectors/source-zoom/integration_tests/abnormal_state.json new file mode 100644 index 000000000000..848a6177c4b7 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/integration_tests/abnormal_state.json @@ -0,0 +1,5 @@ +{ + "users": { + "updated_at": "2222-01-21T00:00:00.000Z" + } +} diff --git a/airbyte-integrations/connectors/source-zoom/integration_tests/acceptance.py b/airbyte-integrations/connectors/source-zoom/integration_tests/acceptance.py new file mode 100644 index 000000000000..950b53b59d41 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/integration_tests/acceptance.py @@ -0,0 +1,14 @@ +# +# Copyright (c) 2022 Airbyte, Inc., all rights reserved. +# + + +import pytest + +pytest_plugins = ("source_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.""" + yield diff --git a/airbyte-integrations/connectors/source-zoom/integration_tests/configured_catalog.json b/airbyte-integrations/connectors/source-zoom/integration_tests/configured_catalog.json new file mode 100644 index 000000000000..4be548978f15 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/integration_tests/configured_catalog.json @@ -0,0 +1,213 @@ +{ + "streams": [ + { + "stream": { + "name": "users", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "meetings", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "meeting_registrants", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "meeting_polls", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "meeting_poll_results", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "meeting_registration_questions", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "webinars", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "webinar_panelists", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "webinar_registrants", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "webinar_absentees", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "webinar_polls", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "webinar_poll_results", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "webinar_registration_questions", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "webinar_tracking_sources", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "webinar_qna_results", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "report_meetings", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "report_meeting_participants", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "report_webinars", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + }, + { + "stream": { + "name": "report_webinar_participants", + "json_schema": {}, + "supported_sync_modes": [ + "full_refresh" + ] + }, + "sync_mode": "full_refresh", + "destination_sync_mode": "overwrite" + } + ] +} diff --git a/airbyte-integrations/connectors/source-zoom/integration_tests/invalid_config.json b/airbyte-integrations/connectors/source-zoom/integration_tests/invalid_config.json new file mode 100644 index 000000000000..6a603fda8000 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/integration_tests/invalid_config.json @@ -0,0 +1,3 @@ +{ + "jwt_token": "dummy" +} diff --git a/airbyte-integrations/connectors/source-zoom/integration_tests/sample_config.json b/airbyte-integrations/connectors/source-zoom/integration_tests/sample_config.json new file mode 100644 index 000000000000..f875ad8416c6 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/integration_tests/sample_config.json @@ -0,0 +1,3 @@ +{ + "jwt_token": "abcd" +} diff --git a/airbyte-integrations/connectors/source-zoom/integration_tests/sample_state.json b/airbyte-integrations/connectors/source-zoom/integration_tests/sample_state.json new file mode 100644 index 000000000000..0151c6fc660e --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/integration_tests/sample_state.json @@ -0,0 +1,3 @@ +{ + +} diff --git a/airbyte-integrations/connectors/source-zoom-singer/main.py b/airbyte-integrations/connectors/source-zoom/main.py similarity index 68% rename from airbyte-integrations/connectors/source-zoom-singer/main.py rename to airbyte-integrations/connectors/source-zoom/main.py index 135a9790d88f..4b6bfd836670 100644 --- a/airbyte-integrations/connectors/source-zoom-singer/main.py +++ b/airbyte-integrations/connectors/source-zoom/main.py @@ -6,8 +6,8 @@ import sys from airbyte_cdk.entrypoint import launch -from source_zoom_singer import SourceZoomSinger +from source_zoom import SourceZoom if __name__ == "__main__": - source = SourceZoomSinger() + source = SourceZoom() launch(source, sys.argv[1:]) diff --git a/airbyte-integrations/connectors/source-zoom/requirements.txt b/airbyte-integrations/connectors/source-zoom/requirements.txt new file mode 100644 index 000000000000..0411042aa091 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/requirements.txt @@ -0,0 +1,2 @@ +-e ../../bases/source-acceptance-test +-e . diff --git a/airbyte-integrations/connectors/source-zoom/setup.py b/airbyte-integrations/connectors/source-zoom/setup.py new file mode 100644 index 000000000000..e646cdcd338b --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/setup.py @@ -0,0 +1,29 @@ +# +# Copyright (c) 2022 Airbyte, Inc., all rights reserved. +# + + +from setuptools import find_packages, setup + +MAIN_REQUIREMENTS = [ + "airbyte-cdk~=0.1", +] + +TEST_REQUIREMENTS = [ + "pytest~=6.1", + "pytest-mock~=3.6.1", + "source-acceptance-test", +] + +setup( + name="source_zoom", + description="Source implementation for Zoom.", + 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-zoom/source_zoom/__init__.py b/airbyte-integrations/connectors/source-zoom/source_zoom/__init__.py new file mode 100644 index 000000000000..4fb74e1fc140 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/__init__.py @@ -0,0 +1,8 @@ +# +# Copyright (c) 2022 Airbyte, Inc., all rights reserved. +# + + +from .source import SourceZoom + +__all__ = ["SourceZoom"] diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_poll_results.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_poll_results.json new file mode 100644 index 000000000000..0f4b97875223 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_poll_results.json @@ -0,0 +1,37 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "meeting_uuid": { + "type": "string" + }, + "email": { + "type": "string" + }, + "name": { + "type": "string" + }, + "question_details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "answer": { + "type": "string" + }, + "date_time": { + "type": "string" + }, + "polling_id": { + "type": "string" + }, + "question": { + "type": "string" + } + }, + "required": [] + } + } + }, + "required": [] +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_polls.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_polls.json new file mode 100644 index 000000000000..989fddd5626f --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_polls.json @@ -0,0 +1,96 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "meeting_id": { + "type": "number" + }, + "status": { + "type": "string" + }, + "anonymous": { + "type": "boolean" + }, + "poll_type": { + "type": "number" + }, + "questions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "answer_max_character": { + "type": "number" + }, + "answer_min_character": { + "type": "number" + }, + "answer_required": { + "type": "boolean" + }, + "answers": { + "type": "array", + "items": { + "type": "string" + } + }, + "case_sensitive": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "prompts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prompt_question": { + "type": "string" + }, + "prompt_right_answers": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [] + } + }, + "rating_max_label": { + "type": "string" + }, + "rating_max_value": { + "type": "number" + }, + "rating_min_label": { + "type": "string" + }, + "rating_min_value": { + "type": "number" + }, + "right_answers": { + "type": "array", + "items": { + "type": "string" + } + }, + "show_as_dropdown": { + "type": "boolean" + }, + "type": { + "type": "string" + } + }, + "required": [] + } + }, + "title": { + "type": "string" + } + } +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_registrants.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_registrants.json new file mode 100644 index 000000000000..c5dc946fb693 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_registrants.json @@ -0,0 +1,86 @@ +{ + "$schema":"http://json-schema.org/draft-07/schema#", + "properties": { + "meeting_id": { + "type": "number" + }, + "id": { + "type": "string" + }, + "address": { + "type": "string" + }, + "city": { + "type": "string" + }, + "comments": { + "type": "string" + }, + "country": { + "type": "string" + }, + "custom_questions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + ] + } + }, + "email": { + "type": "string" + }, + "first_name": { + "type": "string" + }, + "industry": { + "type": "string" + }, + "job_title": { + "type": "string" + }, + "last_name": { + "type": "string" + }, + "no_of_employees": { + "type": "string" + }, + "org": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "purchasing_time_frame": { + "type": "string" + }, + "role_in_purchase_process": { + "type": "string" + }, + "state": { + "type": "string" + }, + "status": { + "type": "string" + }, + "zip": { + "type": "string" + }, + "create_time": { + "type": "string" + }, + "join_url": { + "type": "string" + } + }, + "required": [ + ] +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_registration_questions.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_registration_questions.json new file mode 100644 index 000000000000..aa396bf02ef2 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meeting_registration_questions.json @@ -0,0 +1,50 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "meeting_id": { + "type": [ + "string" + ] + }, + "custom_questions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "answers": { + "type": "array", + "items": { + "type": "string" + } + }, + "required": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [] + } + }, + "questions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "field_name": { + "type": "string" + }, + "required": { + "type": "boolean" + } + }, + "required": [] + } + } + } +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meetings.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meetings.json new file mode 100644 index 000000000000..06c7d95dc1f1 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/meetings.json @@ -0,0 +1,408 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "properties": { + "assistant_id": { + "type": "string" + }, + "host_email": { + "type": "string" + }, + "host_id": { + "type": "string" + }, + "id": { + "type": "number" + }, + "uuid": { + "type": "string" + }, + "agenda": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "duration": { + "type": "number" + }, + "encrypted_password": { + "type": "string" + }, + "h323_password": { + "type": "string" + }, + "join_url": { + "type": "string" + }, + "occurrences": { + "type": "array", + "items": { + "type": "object", + "properties": { + "duration": { + "type": "number" + }, + "occurrence_id": { + "type": "string" + }, + "start_time": { + "type": "string" + }, + "status": { + "type": "string" + } + }, + "required": [ + ] + } + }, + "password": { + "type": "string" + }, + "pmi": { + "type": "string" + }, + "pre_schedule": { + "type": "boolean" + }, + "recurrence": { + "type": "object", + "properties": { + "end_date_time": { + "type": "string" + }, + "end_times": { + "type": "number" + }, + "monthly_day": { + "type": "number" + }, + "monthly_week": { + "type": "number" + }, + "monthly_week_day": { + "type": "number" + }, + "repeat_interval": { + "type": "number" + }, + "type": { + "type": "number" + }, + "weekly_days": { + "type": "string" + } + }, + "required": [ + ] + }, + "settings": { + "type": "object", + "properties": { + "allow_multiple_devices": { + "type": "boolean" + }, + "alternative_hosts": { + "type": "string" + }, + "alternative_hosts_email_notification": { + "type": "boolean" + }, + "alternative_host_update_polls": { + "type": "boolean" + }, + "approval_type": { + "type": "number" + }, + "approved_or_denied_countries_or_regions": { + "type": "object", + "properties": { + "approved_list": { + "type": "array", + "items": { + "type": "string" + } + }, + "denied_list": { + "type": "array", + "items": { + "type": "string" + } + }, + "enable": { + "type": "boolean" + }, + "method": { + "type": "string" + } + }, + "required": [ + ] + }, + "audio": { + "type": "string" + }, + "authentication_domains": { + "type": "string" + }, + "authentication_exception": { + "type": "array", + "items": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "name": { + "type": "string" + }, + "join_url": { + "type": "string" + } + }, + "required": [ + ] + } + }, + "authentication_name": { + "type": "string" + }, + "authentication_option": { + "type": "string" + }, + "auto_recording": { + "type": "string" + }, + "breakout_room": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "rooms": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "participants": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + ] + } + } + }, + "required": [ + ] + }, + "calendar_type": { + "type": "number" + }, + "close_registration": { + "type": "boolean" + }, + "contact_email": { + "type": "string" + }, + "contact_name": { + "type": "string" + }, + "custom_keys": { + "type": "array", + "items": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + ] + } + }, + "email_notification": { + "type": "boolean" + }, + "encryption_type": { + "type": "string" + }, + "focus_mode": { + "type": "boolean" + }, + "global_dial_in_countries": { + "type": "array", + "items": { + "type": "string" + } + }, + "global_dial_in_numbers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "city": { + "type": "string" + }, + "country": { + "type": "string" + }, + "country_name": { + "type": "string" + }, + "number": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + ] + } + }, + "host_video": { + "type": "boolean" + }, + "jbh_time": { + "type": "number" + }, + "join_before_host": { + "type": "boolean" + }, + "language_interpretation": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "interpreters": { + "type": "array", + "items": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "languages": { + "type": "string" + } + }, + "required": [ + ] + } + } + }, + "required": [ + ] + }, + "meeting_authentication": { + "type": "boolean" + }, + "mute_upon_entry": { + "type": "boolean" + }, + "participant_video": { + "type": "boolean" + }, + "private_meeting": { + "type": "boolean" + }, + "registrants_confirmation_email": { + "type": "boolean" + }, + "registrants_email_notification": { + "type": "boolean" + }, + "registration_type": { + "type": "number" + }, + "show_share_button": { + "type": "boolean" + }, + "use_pmi": { + "type": "boolean" + }, + "waiting_room": { + "type": "boolean" + }, + "waiting_room_options": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "admit_type": { + "type": "number" + }, + "auto_admit": { + "type": "number" + }, + "internal_user_auto_admit": { + "type": "number" + } + }, + "required": [ + ] + }, + "watermark": { + "type": "boolean" + }, + "host_save_video_order": { + "type": "boolean" + } + }, + "required": [ + ] + }, + "start_time": { + "type": "string" + }, + "start_url": { + "type": "string" + }, + "status": { + "type": "string" + }, + "timezone": { + "type": "string" + }, + "topic": { + "type": "string" + }, + "tracking_fields": { + "type": "array", + "items": { + "type": "object", + "properties": { + "field": { + "type": "string" + }, + "value": { + "type": "string" + }, + "visible": { + "type": "boolean" + } + }, + "required": [ + ] + } + }, + "type": { + "type": "number" + } + }, + "required": [ + ] + +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_meeting_participants.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_meeting_participants.json new file mode 100644 index 000000000000..763392427fc4 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_meeting_participants.json @@ -0,0 +1,46 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "meeting_uuid": { + "type": "string" + }, + "customer_key": { + "type": "string" + }, + "duration": { + "type": "number" + }, + "failover": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "join_time": { + "type": "string" + }, + "leave_time": { + "type": "string" + }, + "name": { + "type": "string" + }, + "registrant_id": { + "type": "string" + }, + "user_email": { + "type": "string" + }, + "user_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "bo_mtg_id": { + "type": "string" + } + }, + "required": [] +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_meetings.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_meetings.json new file mode 100644 index 000000000000..e7b31f338a72 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_meetings.json @@ -0,0 +1,76 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "meeting_uuid": { + "type": "string" + }, + "custom_keys": { + "type": "array", + "items": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [] + } + }, + "dept": { + "type": "string" + }, + "duration": { + "type": "number" + }, + "end_time": { + "type": "string" + }, + "id": { + "type": "number" + }, + "participants_count": { + "type": "number" + }, + "start_time": { + "type": "string" + }, + "topic": { + "type": "string" + }, + "total_minutes": { + "type": "number" + }, + "tracking_fields": { + "type": "array", + "items": { + "type": "object", + "properties": { + "field": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [] + } + }, + "type": { + "type": "number" + }, + "user_email": { + "type": "string" + }, + "user_name": { + "type": "string" + }, + "uuid": { + "type": "string" + } + }, + "required": [] +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_webinar_participants.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_webinar_participants.json new file mode 100644 index 000000000000..bfba6ff87d93 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_webinar_participants.json @@ -0,0 +1,55 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "webinar_uuid": { + "type": "string" + }, + "customer_key": { + "type": "string" + }, + "duration": { + "type": "number" + }, + "failover": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "join_time": { + "type": "string" + }, + "leave_time": { + "type": "string" + }, + "name": { + "type": "string" + }, + "registrant_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "user_email": { + "type": "string" + }, + "user_id": { + "type": "string" + } + }, + "required": [ + "customer_key", + "duration", + "failover", + "id", + "join_time", + "leave_time", + "name", + "registrant_id", + "status", + "user_email", + "user_id" + ] +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_webinars.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_webinars.json new file mode 100644 index 000000000000..b8ae1ed0ceac --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/report_webinars.json @@ -0,0 +1,76 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "webinar_uuid": { + "type": "string" + }, + "custom_keys": { + "type": "array", + "items": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [] + } + }, + "dept": { + "type": "string" + }, + "duration": { + "type": "number" + }, + "end_time": { + "type": "string" + }, + "id": { + "type": "number" + }, + "participants_count": { + "type": "number" + }, + "start_time": { + "type": "string" + }, + "topic": { + "type": "string" + }, + "total_minutes": { + "type": "number" + }, + "tracking_fields": { + "type": "array", + "items": { + "type": "object", + "properties": { + "field": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [] + } + }, + "type": { + "type": "number" + }, + "user_email": { + "type": "string" + }, + "user_name": { + "type": "string" + }, + "uuid": { + "type": "string" + } + }, + "required": [] +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/users.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/users.json new file mode 100644 index 000000000000..8e2bdef40615 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/users.json @@ -0,0 +1,86 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "properties": { + "created_at": { + "type": "string" + }, + "custom_attributes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + ] + } + }, + "dept": { + "type": "string" + }, + "email": { + "type": "string" + }, + "employee_unique_id": { + "type": "string" + }, + "first_name": { + "type": "string" + }, + "group_ids": { + "type": "array", + "items": { + "type": "string" + } + }, + "id": { + "type": "string" + }, + "im_group_ids": { + "type": "array", + "items": { + "type": "string" + } + }, + "last_client_version": { + "type": "string" + }, + "last_login_time": { + "type": "string" + }, + "last_name": { + "type": "string" + }, + "plan_united_type": { + "type": "string" + }, + "pmi": { + "type": "number" + }, + "role_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "timezone": { + "type": "string" + }, + "type": { + "type": "number" + }, + "verified": { + "type": "number" + } + }, + "required": [ + ] +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_absentees.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_absentees.json new file mode 100644 index 000000000000..ced32756af1a --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_absentees.json @@ -0,0 +1,85 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "webinar_uuid": { + "type": "string" + }, + "id": { + "type": "string" + }, + "address": { + "type": "string" + }, + "city": { + "type": "string" + }, + "comments": { + "type": "string" + }, + "country": { + "type": "string" + }, + "custom_questions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [] + } + }, + "email": { + "type": "string" + }, + "first_name": { + "type": "string" + }, + "industry": { + "type": "string" + }, + "job_title": { + "type": "string" + }, + "last_name": { + "type": "string" + }, + "no_of_employees": { + "type": "string" + }, + "org": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "purchasing_time_frame": { + "type": "string" + }, + "role_in_purchase_process": { + "type": "string" + }, + "state": { + "type": "string" + }, + "status": { + "type": "string" + }, + "zip": { + "type": "string" + }, + "create_time": { + "type": "string" + }, + "join_url": { + "type": "string" + } + }, + "required": [] +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_panelists.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_panelists.json new file mode 100644 index 000000000000..53801958fa0e --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_panelists.json @@ -0,0 +1,37 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "webinar_id": { + "type": "number" + }, + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "name": { + "type": "string" + }, + "join_url": { + "type": "string" + }, + "virtual_background_id": { + "type": "string" + }, + "name_tag_id": { + "type": "string" + }, + "name_tag_name": { + "type": "string" + }, + "name_tag_pronouns": { + "type": "string" + }, + "name_tag_description": { + "type": "string" + } + }, + "required": [] +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_poll_results.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_poll_results.json new file mode 100644 index 000000000000..dbb102491ec1 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_poll_results.json @@ -0,0 +1,37 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "webinar_uuid": { + "type": "string" + }, + "email": { + "type": "string" + }, + "name": { + "type": "string" + }, + "question_details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "answer": { + "type": "string" + }, + "date_time": { + "type": "string" + }, + "polling_id": { + "type": "string" + }, + "question": { + "type": "string" + } + }, + "required": [] + } + } + }, + "required": [] +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_polls.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_polls.json new file mode 100644 index 000000000000..35ed3e392162 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_polls.json @@ -0,0 +1,97 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "webinar_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "anonymous": { + "type": "boolean" + }, + "poll_type": { + "type": "number" + }, + "questions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "answer_max_character": { + "type": "number" + }, + "answer_min_character": { + "type": "number" + }, + "answer_required": { + "type": "boolean" + }, + "answers": { + "type": "array", + "items": { + "type": "string" + } + }, + "case_sensitive": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "prompts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "prompt_question": { + "type": "string" + }, + "prompt_right_answers": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [] + } + }, + "rating_max_label": { + "type": "string" + }, + "rating_max_value": { + "type": "number" + }, + "rating_min_label": { + "type": "string" + }, + "rating_min_value": { + "type": "number" + }, + "right_answers": { + "type": "array", + "items": { + "type": "string" + } + }, + "show_as_dropdown": { + "type": "boolean" + }, + "type": { + "type": "string" + } + }, + "required": [] + } + }, + "title": { + "type": "string" + } + }, + "required": [] +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_qna_results.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_qna_results.json new file mode 100644 index 000000000000..361b24a5fc56 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_qna_results.json @@ -0,0 +1,31 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "webinar_uuid": { + "type": "string" + }, + "email": { + "type": "string" + }, + "name": { + "type": "string" + }, + "question_details": { + "type": "array", + "items": { + "type": "object", + "properties": { + "answer": { + "type": "string" + }, + "question": { + "type": "string" + } + }, + "required": [] + } + } + }, + "required": [] +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_registrants.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_registrants.json new file mode 100644 index 000000000000..0b5a7cdaf6c2 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_registrants.json @@ -0,0 +1,85 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "webinar_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "address": { + "type": "string" + }, + "city": { + "type": "string" + }, + "comments": { + "type": "string" + }, + "country": { + "type": "string" + }, + "custom_questions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [] + } + }, + "email": { + "type": "string" + }, + "first_name": { + "type": "string" + }, + "industry": { + "type": "string" + }, + "job_title": { + "type": "string" + }, + "last_name": { + "type": "string" + }, + "no_of_employees": { + "type": "string" + }, + "org": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "purchasing_time_frame": { + "type": "string" + }, + "role_in_purchase_process": { + "type": "string" + }, + "state": { + "type": "string" + }, + "status": { + "type": "string" + }, + "zip": { + "type": "string" + }, + "create_time": { + "type": "string" + }, + "join_url": { + "type": "string" + } + }, + "required": [] +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_registration_questions.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_registration_questions.json new file mode 100644 index 000000000000..46f0dad22ea0 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_registration_questions.json @@ -0,0 +1,49 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "webinar_id": { + "type": "string" + }, + "custom_questions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "answers": { + "type": "array", + "items": { + "type": "string" + } + }, + "required": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [] + } + }, + "questions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "field_name": { + "type": "string" + }, + "required": { + "type": "boolean" + } + }, + "required": [] + } + } + }, + "required": [] +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_tracking_sources.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_tracking_sources.json new file mode 100644 index 000000000000..b7cab1839c57 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinar_tracking_sources.json @@ -0,0 +1,25 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "webinar_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "registration_count": { + "type": "number" + }, + "source_name": { + "type": "string" + }, + "tracking_url": { + "type": "string" + }, + "visitor_count": { + "type": "number" + } + }, + "required": [] +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinars.json b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinars.json new file mode 100644 index 000000000000..850b0c16c0c9 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/schemas/webinars.json @@ -0,0 +1,322 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "host_email": { + "type": "string" + }, + "host_id": { + "type": "string" + }, + "id": { + "type": "number" + }, + "uuid": { + "type": "string" + }, + "agenda": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "duration": { + "type": "number" + }, + "join_url": { + "type": "string" + }, + "occurrences": { + "type": "array", + "items": { + "type": "object", + "properties": { + "duration": { + "type": "number" + }, + "occurrence_id": { + "type": "string" + }, + "start_time": { + "type": "string" + }, + "status": { + "type": "string" + } + }, + "required": [] + } + }, + "password": { + "type": "string" + }, + "recurrence": { + "type": "object", + "properties": { + "end_date_time": { + "type": "string" + }, + "end_times": { + "type": "number" + }, + "monthly_day": { + "type": "number" + }, + "monthly_week": { + "type": "number" + }, + "monthly_week_day": { + "type": "number" + }, + "repeat_interval": { + "type": "number" + }, + "type": { + "type": "number" + }, + "weekly_days": { + "type": "string" + } + }, + "required": [] + }, + "settings": { + "type": "object", + "properties": { + "allow_multiple_devices": { + "type": "boolean" + }, + "alternative_hosts": { + "type": "string" + }, + "alternative_host_update_polls": { + "type": "boolean" + }, + "approval_type": { + "type": "number" + }, + "attendees_and_panelists_reminder_email_notification": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "type": { + "type": "number" + } + }, + "required": [] + }, + "audio": { + "type": "string" + }, + "authentication_domains": { + "type": "string" + }, + "authentication_name": { + "type": "string" + }, + "authentication_option": { + "type": "string" + }, + "auto_recording": { + "type": "string" + }, + "close_registration": { + "type": "boolean" + }, + "contact_email": { + "type": "string" + }, + "contact_name": { + "type": "string" + }, + "email_language": { + "type": "string" + }, + "follow_up_absentees_email_notification": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "type": { + "type": "number" + } + }, + "required": [] + }, + "follow_up_attendees_email_notification": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "type": { + "type": "number" + } + }, + "required": [] + }, + "global_dial_in_countries": { + "type": "array", + "items": { + "type": "string" + } + }, + "hd_video": { + "type": "boolean" + }, + "hd_video_for_attendees": { + "type": "boolean" + }, + "host_video": { + "type": "boolean" + }, + "language_interpretation": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "interpreters": { + "type": "array", + "items": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "languages": { + "type": "string" + } + }, + "required": [] + } + } + }, + "required": [] + }, + "panelist_authentication": { + "type": "boolean" + }, + "meeting_authentication": { + "type": "boolean" + }, + "add_watermark": { + "type": "boolean" + }, + "add_audio_watermark": { + "type": "boolean" + }, + "notify_registrants": { + "type": "boolean" + }, + "on_demand": { + "type": "boolean" + }, + "panelists_invitation_email_notification": { + "type": "boolean" + }, + "panelists_video": { + "type": "boolean" + }, + "post_webinar_survey": { + "type": "boolean" + }, + "practice_session": { + "type": "boolean" + }, + "question_and_answer": { + "type": "object", + "properties": { + "allow_anonymous_questions": { + "type": "boolean" + }, + "answer_questions": { + "type": "string" + }, + "attendees_can_comment": { + "type": "boolean" + }, + "attendees_can_upvote": { + "type": "boolean" + }, + "allow_auto_reply": { + "type": "boolean" + }, + "auto_reply_text": { + "type": "string" + }, + "enable": { + "type": "boolean" + } + }, + "required": [] + }, + "registrants_confirmation_email": { + "type": "boolean" + }, + "registrants_email_notification": { + "type": "boolean" + }, + "registrants_restrict_number": { + "type": "number" + }, + "registration_type": { + "type": "number" + }, + "send_1080p_video_to_attendees": { + "type": "boolean" + }, + "show_share_button": { + "type": "boolean" + }, + "survey_url": { + "type": "string" + }, + "enable_session_branding": { + "type": "boolean" + } + }, + "required": [] + }, + "start_time": { + "type": "string" + }, + "start_url": { + "type": "string" + }, + "timezone": { + "type": "string" + }, + "topic": { + "type": "string" + }, + "tracking_fields": { + "type": "array", + "items": { + "type": "object", + "properties": { + "field": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [] + } + }, + "type": { + "type": "number" + }, + "is_simulive": { + "type": "boolean" + }, + "record_file_id": { + "type": "string" + } + }, + "required": [] +} diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/source.py b/airbyte-integrations/connectors/source-zoom/source_zoom/source.py new file mode 100644 index 000000000000..f7c16e43a355 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/source.py @@ -0,0 +1,18 @@ +# +# Copyright (c) 2022 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 SourceZoom(YamlDeclarativeSource): + def __init__(self): + super().__init__(**{"path_to_yaml": "zoom.yaml"}) diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/spec.yaml b/airbyte-integrations/connectors/source-zoom/source_zoom/spec.yaml new file mode 100644 index 000000000000..a8170e08c3b7 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/spec.yaml @@ -0,0 +1,13 @@ +documentationUrl: https://docs.airbyte.com/integrations/sources/zoom +connectionSpecification: + $schema: http://json-schema.org/draft-07/schema# + title: Zoom Spec + type: object + required: + - jwt_token + additionalProperties: true + properties: + jwt_token: + type: string + description: JWT Token + airbyte_secret: true diff --git a/airbyte-integrations/connectors/source-zoom/source_zoom/zoom.yaml b/airbyte-integrations/connectors/source-zoom/source_zoom/zoom.yaml new file mode 100644 index 000000000000..77fae4e527d3 --- /dev/null +++ b/airbyte-integrations/connectors/source-zoom/source_zoom/zoom.yaml @@ -0,0 +1,815 @@ +version: "0.1.0" + +definitions: + requester: + url_base: "https://api.zoom.us/v2/" + http_method: "GET" + authenticator: + type: BearerAuthenticator + api_token: "{{ config['jwt_token'] }}" + + zoom_paginator: + type: DefaultPaginator + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.next_page_token }}" + stop_condition: "{{ response.next_page_token == '' }}" + page_size: 30 + page_size_option: + field_name: "page_size" + inject_into: "request_parameter" + page_token_option: + field_name: "next_page_token" + inject_into: "request_parameter" + url_base: "*ref(definitions.requester.url_base)" + + + retriever: + requester: + $ref: "*ref(definitions.requester)" + + schema_loader: + type: JsonSchema + file_path: "./source_zoom/schemas/{{ options['name'] }}.json" + + + users_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + retriever: + paginator: + $ref: "*ref(definitions.zoom_paginator)" + record_selector: + extractor: + type: DpathExtractor + field_pointer: ["users"] + $ref: "*ref(definitions.retriever)" + $options: + name: "users" + primary_key: "id" + path: "/users" + + + meetings_list_tmp_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "meetings_list_tmp" + primary_key: "id" + retriever: + paginator: + $ref: "*ref(definitions.zoom_paginator)" + record_selector: + extractor: + type: DpathExtractor + field_pointer: ["meetings"] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/users/{{ stream_slice.parent_id }}/meetings" + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.users_stream)" + parent_key: "id" + stream_slice_field: "parent_id" + + + + meetings_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "meetings" + primary_key: "id" + retriever: + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_pointer: [] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/meetings/{{ stream_slice.parent_id }}" + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.meetings_list_tmp_stream)" + parent_key: "id" + stream_slice_field: "parent_id" + + + meeting_registrants_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "meeting_registrants" + primary_key: "id" + retriever: + paginator: + $ref: "*ref(definitions.zoom_paginator)" + record_selector: + extractor: + type: DpathExtractor + field_pointer: ["registrants"] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/meetings/{{ stream_slice.parent_id }}/registrants" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + # Meeting {meetingId} is not found or has expired. This meeting has not set registration as required: {meetingId}. + - predicate: "{{ response.code == 300 }}" + action: IGNORE + - type: DefaultErrorHandler # we're adding this DefaultErrorHandler for 429, 5XX errors etc; + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.meetings_list_tmp_stream)" + parent_key: "id" + stream_slice_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: ["meeting_id"] + value: "{{ stream_slice.parent_id }}" + + + meeting_polls_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "meeting_polls" + primary_key: "id" + retriever: + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_pointer: ["polls"] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/meetings/{{ stream_slice.parent_id }}/polls" + error_handler: + type: CompositeErrorHandler + # ignore 400 error; We get this error if Meeting poll is not enabled for the meeting, or scheduling capabilities aren't in the account + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: [400] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.meetings_list_tmp_stream)" + parent_key: "id" + stream_slice_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: ["meeting_id"] + value: "{{ stream_slice.parent_id }}" + + + meeting_poll_results_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "meeting_poll_results" + retriever: + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_pointer: ["questions"] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/past_meetings/{{ stream_slice.parent_id }}/polls" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + # 400 error is thrown for meetings created an year ago + # 404 error is thrown if the meeting has not enabled polls (from observation, not written in docs) + - http_codes: [400,404] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.meetings_list_tmp_stream)" + parent_key: "uuid" + stream_slice_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: ["meeting_uuid"] + value: "{{ stream_slice.parent_id }}" + + + meeting_registration_questions_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "meeting_registration_questions" + retriever: + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_pointer: [] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/meetings/{{ stream_slice.parent_id }}/registrants/questions" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + # ignore 400 error; We get this error if Bad Request or Meeting hosting and scheduling capabilities are not allowed for your user account. + - http_codes: [400] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.meetings_list_tmp_stream)" + parent_key: "id" + stream_slice_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: ["meeting_id"] + value: "{{ stream_slice.parent_id }}" + + + webinars_list_tmp_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "webinars_list_tmp" + primary_key: "id" + retriever: + paginator: + $ref: "*ref(definitions.zoom_paginator)" + record_selector: + extractor: + type: DpathExtractor + field_pointer: ["webinars"] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/users/{{ stream_slice.parent_id }}/webinars" + error_handler: + type: CompositeErrorHandler + # ignore 400 error; We get this error if Meeting is more than created an year ago + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: [400] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.users_stream)" + parent_key: "id" + stream_slice_field: "parent_id" + + webinars_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "webinars" + primary_key: "id" + retriever: + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_pointer: [] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/webinars/{{ stream_slice.parent_id }}" + error_handler: + type: CompositeErrorHandler + # ignore 400 error + error_handlers: + - type: DefaultErrorHandler + response_filters: + # When parent stream throws error; then ideally we should have an empty array, and no /webinars/{id} should be called. But somehow we're calling it right now with None. :( + # More context: https://github.com/airbytehq/airbyte/issues/18046 + - http_codes: [400,404] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.webinars_list_tmp_stream)" + parent_key: "id" + stream_slice_field: "parent_id" + + webinar_panelists_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "webinar_panelists" + retriever: + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_pointer: ["panelists"] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/webinars/{{ stream_slice.parent_id }}/panelists" + error_handler: + type: CompositeErrorHandler + # ignore 400 error + error_handlers: + - type: DefaultErrorHandler + response_filters: + # Same problem as "webinars_stream" for 404! and we get 400 error if the account isn't PRO. + - http_codes: [400,404] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.webinars_list_tmp_stream)" + parent_key: "id" + stream_slice_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: ["webinar_id"] + value: "{{ stream_slice.parent_id }}" + + + webinar_registrants_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "webinar_registrants" + retriever: + paginator: + $ref: "*ref(definitions.zoom_paginator)" + record_selector: + extractor: + type: DpathExtractor + field_pointer: ["registrants"] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/webinars/{{ stream_slice.parent_id }}/registrants" + error_handler: + type: CompositeErrorHandler + # ignore 400 error + error_handlers: + - type: DefaultErrorHandler + response_filters: + # Same problem as "webinars_stream" for 404! 400 is for non PRO accounts. + - http_codes: [400,404] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.webinars_list_tmp_stream)" + parent_key: "id" + stream_slice_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: ["webinar_id"] + value: "{{ stream_slice.parent_id }}" + + + webinar_absentees_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "webinar_absentees" + primary_key: "id" + retriever: + paginator: + $ref: "*ref(definitions.zoom_paginator)" + record_selector: + extractor: + type: DpathExtractor + field_pointer: ["registrants"] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/past_webinars/{{ stream_slice.parent_uuid }}/absentees" + error_handler: + type: CompositeErrorHandler + # ignore 400 error + error_handlers: + - type: DefaultErrorHandler + response_filters: + # Same problem as "webinars_stream" for 404! 400 is for non PRO accounts. + - http_codes: [400,404] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.webinars_list_tmp_stream)" + parent_key: "uuid" + stream_slice_field: "parent_uuid" + transformations: + - type: AddFields + fields: + - path: ["webinar_uuid"] + value: "{{ stream_slice.parent_uuid }}" + + + webinar_polls_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "webinar_polls" + retriever: + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_pointer: ["polls"] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/webinars/{{ stream_slice.parent_id }}/polls" + error_handler: + type: CompositeErrorHandler + # ignore 400 error; We get this error if Webinar poll is disabled + error_handlers: + - type: DefaultErrorHandler + response_filters: + # Same problem as "webinars_stream" for 404! 400 is for non PRO accounts. + - http_codes: [400,404] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.webinars_list_tmp_stream)" + parent_key: "id" + stream_slice_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: ["webinar_id"] + value: "{{ stream_slice.parent_id }}" + + + + webinar_poll_results_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "webinar_poll_results" + retriever: + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_pointer: ["questions"] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/past_webinars/{{ stream_slice.parent_id }}/polls" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: [404] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.webinars_list_tmp_stream)" + parent_key: "uuid" + stream_slice_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: ["webinar_uuid"] + value: "{{ stream_slice.parent_id }}" + + + webinar_registration_questions_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "webinar_registration_questions" + retriever: + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_pointer: [] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/webinars/{{ stream_slice.parent_id }}/registrants/questions" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + # the docs says 404 code, but that's incorrect (from observation); + - http_codes: [400] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.webinars_list_tmp_stream)" + parent_key: "id" + stream_slice_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: ["webinar_id"] + value: "{{ stream_slice.parent_id }}" + + + + webinar_tracking_sources_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "webinar_tracking_sources" + primary_key: "id" + retriever: + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_pointer: ["tracking_sources"] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/webinars/{{ stream_slice.parent_id }}/tracking_sources" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: [400] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.webinars_list_tmp_stream)" + parent_key: "id" + stream_slice_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: ["webinar_id"] + value: "{{ stream_slice.parent_id }}" + + + webinar_qna_results_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "webinar_qna_results" + retriever: + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_pointer: ["questions"] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/past_webinars/{{ stream_slice.parent_id }}/qa" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: [400,404] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.webinars_list_tmp_stream)" + parent_key: "uuid" + stream_slice_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: ["webinar_uuid"] + value: "{{ stream_slice.parent_id }}" + + + + report_meetings_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "report_meetings" + primary_key: "id" + retriever: + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_pointer: ["tracking_sources"] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/report/meetings/{{ stream_slice.parent_id }}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: [400] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.meetings_list_tmp_stream)" + parent_key: "uuid" + stream_slice_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: ["meeting_uuid"] + value: "{{ stream_slice.parent_id }}" + + + + + + report_meeting_participants_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "report_meeting_participants" + primary_key: "id" + retriever: + paginator: + $ref: "*ref(definitions.zoom_paginator)" + record_selector: + extractor: + type: DpathExtractor + field_pointer: ["participants"] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/report/meetings/{{ stream_slice.parent_id }}/participants" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: [400] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.meetings_list_tmp_stream)" + parent_key: "uuid" + stream_slice_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: ["meeting_uuid"] + value: "{{ stream_slice.parent_id }}" + + + report_webinars_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "report_webinars" + retriever: + paginator: + type: NoPagination + record_selector: + extractor: + type: DpathExtractor + field_pointer: [] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/report/webinars/{{ stream_slice.parent_id }}" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: [400] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.webinars_list_tmp_stream)" + parent_key: "uuid" + stream_slice_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: ["webinar_uuid"] + value: "{{ stream_slice.parent_id }}" + + + + report_webinar_participants_stream: + schema_loader: + $ref: "*ref(definitions.schema_loader)" + $options: + name: "report_webinar_participants" + retriever: + paginator: + $ref: "*ref(definitions.zoom_paginator)" + record_selector: + extractor: + type: DpathExtractor + field_pointer: ["participants"] + $ref: "*ref(definitions.retriever)" + requester: + $ref: "*ref(definitions.requester)" + path: "/report/webinars/{{ stream_slice.parent_id }}/participants" + error_handler: + type: CompositeErrorHandler + error_handlers: + - type: DefaultErrorHandler + response_filters: + - http_codes: [400] + action: IGNORE + - type: DefaultErrorHandler + stream_slicer: + type: SubstreamSlicer + parent_stream_configs: + - stream: "*ref(definitions.webinars_list_tmp_stream)" + parent_key: "uuid" + stream_slice_field: "parent_id" + transformations: + - type: AddFields + fields: + - path: ["webinar_uuid"] + value: "{{ stream_slice.parent_id }}" + + +streams: + - "*ref(definitions.users_stream)" + - "*ref(definitions.meetings_stream)" + - "*ref(definitions.meeting_registrants_stream)" + - "*ref(definitions.meeting_polls_stream)" + - "*ref(definitions.meeting_poll_results_stream)" + - "*ref(definitions.meeting_registration_questions_stream)" + - "*ref(definitions.webinars_stream)" + - "*ref(definitions.webinar_panelists_stream)" + - "*ref(definitions.webinar_registrants_stream)" + - "*ref(definitions.webinar_absentees_stream)" + - "*ref(definitions.webinar_polls_stream)" + - "*ref(definitions.webinar_poll_results_stream)" + - "*ref(definitions.webinar_registration_questions_stream)" + - "*ref(definitions.webinar_tracking_sources_stream)" + - "*ref(definitions.webinar_qna_results_stream)" + - "*ref(definitions.report_meetings_stream)" + - "*ref(definitions.report_meeting_participants_stream)" + - "*ref(definitions.report_webinars_stream)" + - "*ref(definitions.report_webinar_participants_stream)" + + +check: + stream_names: + - "users" diff --git a/docs/integrations/sources/zoom.md b/docs/integrations/sources/zoom.md index 59f8fbcc25dc..861dc20ade09 100644 --- a/docs/integrations/sources/zoom.md +++ b/docs/integrations/sources/zoom.md @@ -2,13 +2,14 @@ ## Overview -The Zoom source supports Full Refresh syncs. That is, every time a sync is run, Airbyte will copy all rows in the tables and columns you set up for replication into the destination in a new table. -This Zoom source wraps the [Singer Zoom Tap](https://github.com/singer-io/tap-zoom). +The following connector allows airbyte users to fetch various meetings & webinar data points from the [Zoom](https://zoom.us) source. This connector is built entirely using the [low-code CDK](https://docs.airbyte.com/connector-development/config-based/low-code-cdk-overview/). + +Please note that currently, it only supports Full Refresh syncs. That is, every time a sync is run, Airbyte will copy all rows in the tables and columns you set up for replication into the destination in a new table. ### Output schema -Several output streams are available from this source: +Currently this source supports the following output streams/endpoints from Zoom: * [Users](https://marketplace.zoom.us/docs/api-reference/zoom-api/users/users) * [Meetings](https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetings) @@ -16,7 +17,6 @@ Several output streams are available from this source: * [Meeting Polls](https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingpolls) * [Meeting Poll Results](https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/listpastmeetingpolls) * [Meeting Questions](https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingregistrantsquestionsget) - * [Meeting Files](https://marketplace.zoom.us/docs/api-reference/zoom-api/deprecated-api-endpoints/listpastmeetingfiles) * [Webinars](https://marketplace.zoom.us/docs/api-reference/zoom-api/webinars/webinars) * [Webinar Panelists](https://marketplace.zoom.us/docs/api-reference/zoom-api/webinars/webinarpanelists) * [Webinar Registrants](https://marketplace.zoom.us/docs/api-reference/zoom-api/webinars/webinarregistrants) @@ -26,7 +26,6 @@ Several output streams are available from this source: * [Webinar Questions](https://marketplace.zoom.us/docs/api-reference/zoom-api/webinars/webinarregistrantsquestionsget) * [Webinar Tracking Sources](https://marketplace.zoom.us/docs/api-reference/zoom-api/webinars/gettrackingsources) * [Webinar Q&A Results](https://marketplace.zoom.us/docs/api-reference/zoom-api/webinars/listpastwebinarqa) - * [Webinar Files](https://marketplace.zoom.us/docs/api-reference/zoom-api/deprecated-api-endpoints/listpastwebinarfiles) * [Report Meetings](https://marketplace.zoom.us/docs/api-reference/zoom-api/reports/reportmeetingdetails) * [Report Meeting Participants](https://marketplace.zoom.us/docs/api-reference/zoom-api/reports/reportmeetingparticipants) * [Report Webinars](https://marketplace.zoom.us/docs/api-reference/zoom-api/reports/reportwebinardetails) @@ -46,9 +45,9 @@ If there are more endpoints you'd like Airbyte to support, please [create an iss ### Performance considerations -The connector is restricted by normal Zoom [requests limitation](https://marketplace.zoom.us/docs/api-reference/rate-limits#rate-limit-changes). +Most of the endpoints this connector access is restricted by standard Zoom [requests limitation](https://marketplace.zoom.us/docs/api-reference/rate-limits#rate-limit-changes), with a few exceptions. For more info, please check zoom API documentation. We’ve added appropriate retries if we hit the rate-limiting threshold. -The Zoom connector should not run into Zoom API limitations under normal usage. Please [create an issue](https://github.com/airbytehq/airbyte/issues) if you see any rate limit issues that are not automatically retried successfully. +Please [create an issue](https://github.com/airbytehq/airbyte/issues) if you see any rate limit issues that are not automatically retried successfully. ## Getting started @@ -60,7 +59,3 @@ The Zoom connector should not run into Zoom API limitations under normal usage. Please read [How to generate your JWT Token](https://marketplace.zoom.us/docs/guides/build/jwt-app). -| Version | Date | Pull Request | Subject | -| :--- | :--- | :--- | :--- | -| 0.2.4 | 2021-07-06 | [4539](https://github.com/airbytehq/airbyte/pull/4539) | Add `AIRBYTE_ENTRYPOINT` for Kubernetes support | -