Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Source Zendesk Support: Migrate to low code #36823

Merged
merged 16 commits into from
Apr 29, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,18 @@
"sync_mode": "full_refresh",
"destination_sync_mode": "append"
},
{
"stream": {
"name": "ticket_activities",
"json_schema": {},
"supported_sync_modes": ["full_refresh", "incremental"],
"source_defined_cursor": true,
"default_cursor_field": ["created_at"],
"source_defined_primary_key": [["id"]]
},
"sync_mode": "full_refresh",
"destination_sync_mode": "append"
},
{
"stream": {
"name": "ticket_comments",
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ data:
connectorSubtype: api
connectorType: source
definitionId: 79c1aa37-dae3-42ae-b333-d1c105477715
dockerImageTag: 2.5.0
dockerImageTag: 2.6.0
dockerRepository: airbyte/source-zendesk-support
documentationUrl: https://docs.airbyte.com/integrations/sources/zendesk-support
githubIssueLabel: source-zendesk-support
Expand Down Expand Up @@ -57,5 +57,5 @@ data:
supportLevel: certified
tags:
- language:python
- cdk:python
- cdk:low-code
metadataSpecVersion: "1.0"
60 changes: 30 additions & 30 deletions airbyte-integrations/connectors/source-zendesk-support/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",]
build-backend = "poetry.core.masonry.api"

[tool.poetry]
version = "2.5.0"
version = "2.6.0"
name = "source-zendesk-support"
description = "Source implementation for Zendesk Support."
authors = [ "Airbyte <contact@airbyte.io>",]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.

from dataclasses import dataclass
from typing import Any, List, Mapping, MutableMapping, Optional

import requests
from airbyte_cdk.sources.declarative.extractors.record_extractor import RecordExtractor
from airbyte_cdk.sources.declarative.incremental import DatetimeBasedCursor
from airbyte_cdk.sources.declarative.migrations.state_migration import StateMigration
from airbyte_cdk.sources.declarative.requesters.request_option import RequestOptionType
from airbyte_cdk.sources.declarative.types import StreamSlice, StreamState


@dataclass
class ZendeskSupportAuditLogsIncrementalSync(DatetimeBasedCursor):
"""
This class is created for the Audit Logs stream. List with time range is used for record filtering.
"""

def get_request_params(
self,
*,
stream_state: Optional[StreamState] = None,
stream_slice: Optional[StreamSlice] = None,
next_page_token: Optional[Mapping[str, Any]] = None,
) -> Mapping[str, Any]:
option_type = RequestOptionType.request_parameter
options: MutableMapping[str, Any] = {}
if not stream_slice:
return options

# set list with time range
if self.start_time_option and self.start_time_option.inject_into == option_type:
start_time = stream_slice.get(self._partition_field_start.eval(self.config))
options[self.start_time_option.field_name.eval(config=self.config)] = [start_time] # type: ignore # field_name is always casted to an interpolated string
if self.end_time_option and self.end_time_option.inject_into == option_type:
options[self.end_time_option.field_name.eval(config=self.config)].append(stream_slice.get(self._partition_field_end.eval(self.config))) # type: ignore # field_name is always casted to an interpolated string
return options


class ZendeskSupportExtractorEvents(RecordExtractor):
def extract_records(self, response: requests.Response) -> List[Mapping[str, Any]]:
try:
records = response.json().get("ticket_events") or []
except requests.exceptions.JSONDecodeError:
records = []

events = []
for record in records:
for event in record.get("child_events", []):
if event.get("event_type") == "Comment":
for prop in ["via_reference_id", "ticket_id", "timestamp"]:
event[prop] = record.get(prop)

# https://github.com/airbytehq/oncall/issues/1001
if not isinstance(event.get("via"), dict):
event["via"] = None
events.append(event)
return events


class ZendeskSupportAttributeDefinitionsExtractor(RecordExtractor):
def extract_records(self, response: requests.Response) -> List[Mapping[str, Any]]:
try:
records = []
for definition in response.json()["definitions"]["conditions_all"]:
definition["condition"] = "all"
records.append(definition)
for definition in response.json()["definitions"]["conditions_any"]:
definition["condition"] = "any"
records.append(definition)
except requests.exceptions.JSONDecodeError:
records = []
return records
Loading
Loading