From ba63c037d74581267027107143a615100815deed Mon Sep 17 00:00:00 2001 From: Henri Blancke Date: Tue, 10 Sep 2024 09:53:39 -0400 Subject: [PATCH] feat(source-zendesk-support): add automations and triggers streams (#44610) Signed-off-by: Henri Blancke Co-authored-by: Marcos Marx Co-authored-by: marcosmarxm --- .../integration_tests/configured_catalog.json | 24 ++++ .../integration_tests/expected_records.jsonl | 2 + .../source-zendesk-support/metadata.yaml | 2 +- .../source-zendesk-support/pyproject.toml | 2 +- .../source_zendesk_support/manifest.yaml | 21 ++++ .../schemas/automations.json | 93 ++++++++++++++++ .../schemas/triggers.json | 105 ++++++++++++++++++ .../source_zendesk_support/streams.py | 8 ++ .../unit_tests/unit_test.py | 6 +- docs/integrations/sources/zendesk-support.md | 3 + 10 files changed, 261 insertions(+), 5 deletions(-) create mode 100644 airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/schemas/automations.json create mode 100644 airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/schemas/triggers.json diff --git a/airbyte-integrations/connectors/source-zendesk-support/integration_tests/configured_catalog.json b/airbyte-integrations/connectors/source-zendesk-support/integration_tests/configured_catalog.json index 329f8938a35d..a7be2631ff3d 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/integration_tests/configured_catalog.json +++ b/airbyte-integrations/connectors/source-zendesk-support/integration_tests/configured_catalog.json @@ -12,6 +12,30 @@ "sync_mode": "full_refresh", "destination_sync_mode": "append" }, + { + "stream": { + "name": "automations", + "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": "triggers", + "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": "group_memberships", diff --git a/airbyte-integrations/connectors/source-zendesk-support/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-zendesk-support/integration_tests/expected_records.jsonl index d663d9ef22c6..a8548e483d42 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-zendesk-support/integration_tests/expected_records.jsonl @@ -71,3 +71,5 @@ {"stream": "attribute_definitions", "data": {"title": "Brand", "subject": "brand_id", "type": "list", "group": "ticket", "nullable": false, "repeatable": false, "operators": [{"value": "is", "title": "Is", "terminal": false}, {"value": "is_not", "title": "Is not", "terminal": false}], "values": [{"value": "360000358316", "title": "Airbyte", "enabled": true}], "condition": "all"}, "emitted_at": 1720179652468} {"stream": "attribute_definitions", "data": {"title": "Form", "subject": "ticket_form_id", "type": "list", "group": "ticket", "nullable": false, "repeatable": false, "operators": [{"value": "is", "title": "Is", "terminal": false}, {"value": "is_not", "title": "Is not", "terminal": false}], "values": [{"value": "360000084116", "title": "Default Ticket Form", "enabled": true}], "condition": "all"}, "emitted_at": 1720179652472} {"stream": "ticket_forms", "data": {"id": 360000084116, "raw_name": "Default Ticket Form", "raw_display_name": "Default Ticket Form", "end_user_visible": true, "position": 1, "ticket_field_ids": [360002833076, 360002833096, 360002833116, 360002833136, 360002833156, 360002833176, 360002833196], "active": true, "default": true, "in_all_brands": true, "restricted_brand_ids": [], "end_user_conditions": [], "agent_conditions": [], "url": "https://d3v-airbyte.zendesk.com/api/v2/ticket_forms/360000084116.json", "name": "Default Ticket Form", "display_name": "Default Ticket Form", "created_at": "2020-12-11T18:34:37Z", "updated_at": "2020-12-11T18:34:37Z"}, "emitted_at": 1720179653174} +{"stream":"automations","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/automations/6241378811151.json","id":6241378811151,"title":"Close ticket 4 days after status is set to solved","active":true,"updated_at":"2023-01-19T00:26:48Z","created_at":"2023-01-19T00:26:48Z","default":true,"actions":[{"field":"status","value":"closed"}],"conditions":{"all":[{"field":"status","operator":"is","value":"solved"},{"field":"SOLVED","operator":"greater_than","value":"480"}],"any":[]},"position":0,"raw_title":"Close ticket 4 days after status is set to solved"},"emitted_at":1725816608179} +{"stream":"triggers","data":{"url":"https://d3v-airbyte.zendesk.com/api/v2/triggers/7282769224079.json","id":7282769224079,"title":"Request customer satisfaction rating (social messaging)","active":true,"updated_at":"2023-06-26T10:48:19Z","created_at":"2023-06-26T10:48:19Z","default":false,"actions":[{"field":"notification_messaging_csat","value":"requester_id"}],"conditions":{"all":[{"field":"status","operator":"value","value":"solved"}],"any":[{"field":"via_id","operator":"is","value":"73"},{"field":"via_id","operator":"is","value":"72"},{"field":"via_id","operator":"is","value":"74"},{"field":"via_id","operator":"is","value":"78"},{"field":"via_id","operator":"is","value":"88"}]},"description":"Asks customer for a rating after the conversation is over. This trigger is created by the system.","position":8,"raw_title":"Request customer satisfaction rating (social messaging)","category_id":"1276235"},"emitted_at":1725816657977} diff --git a/airbyte-integrations/connectors/source-zendesk-support/metadata.yaml b/airbyte-integrations/connectors/source-zendesk-support/metadata.yaml index d66aa67bf5eb..128787d37e2c 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/metadata.yaml +++ b/airbyte-integrations/connectors/source-zendesk-support/metadata.yaml @@ -11,7 +11,7 @@ data: connectorSubtype: api connectorType: source definitionId: 79c1aa37-dae3-42ae-b333-d1c105477715 - dockerImageTag: 4.1.1 + dockerImageTag: 4.2.0 dockerRepository: airbyte/source-zendesk-support documentationUrl: https://docs.airbyte.com/integrations/sources/zendesk-support githubIssueLabel: source-zendesk-support diff --git a/airbyte-integrations/connectors/source-zendesk-support/pyproject.toml b/airbyte-integrations/connectors/source-zendesk-support/pyproject.toml index 4bce08ed55c2..cee0c2231291 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/pyproject.toml +++ b/airbyte-integrations/connectors/source-zendesk-support/pyproject.toml @@ -3,7 +3,7 @@ requires = [ "poetry-core>=1.0.0",] build-backend = "poetry.core.masonry.api" [tool.poetry] -version = "4.1.1" +version = "4.2.0" name = "source-zendesk-support" description = "Source implementation for Zendesk Support." authors = [ "Airbyte ",] diff --git a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/manifest.yaml b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/manifest.yaml index b37fbc297c80..3a12f65c0549 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/manifest.yaml +++ b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/manifest.yaml @@ -199,6 +199,17 @@ definitions: path: "tags" primary_key: "name" + automations_stream: + $ref: "#/definitions/base_stream" + retriever: + $ref: "#/definitions/retriever" + paginator: + $ref: "#/definitions/links_next_paginator" + $parameters: + name: "automations" + path: "automations" + primary_key: "id" + # Incremental cursor-based streams audit_logs_stream: $ref: "#/definitions/base_incremental_stream" @@ -554,6 +565,14 @@ definitions: cursor_field: "updated_at" primary_key: "id" + triggers_stream: + $ref: "#/definitions/semi_incremental_stream" + $parameters: + name: "triggers" + path: "triggers" + cursor_field: "updated_at" + primary_key: "id" + users_stream: $ref: "#/definitions/base_incremental_stream" retriever: @@ -581,6 +600,7 @@ streams: - $ref: "#/definitions/ticket_forms_stream" - $ref: "#/definitions/topics_stream" - $ref: "#/definitions/user_fields_stream" + - $ref: "#/definitions/automations_stream" # Incremental streams - $ref: "#/definitions/audit_logs_stream" - $ref: "#/definitions/groups_stream" @@ -595,4 +615,5 @@ streams: - $ref: "#/definitions/ticket_comments_stream" - $ref: "#/definitions/ticket_metric_events_stream" - $ref: "#/definitions/ticket_skips_stream" + - $ref: "#/definitions/triggers_stream" - $ref: "#/definitions/users_stream" diff --git a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/schemas/automations.json b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/schemas/automations.json new file mode 100644 index 000000000000..e245a8681778 --- /dev/null +++ b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/schemas/automations.json @@ -0,0 +1,93 @@ +{ + "$schema": "https://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "actions": { + "type": "array", + "description": "An object describing what the automation will do", + "items": { + "type": ["object", "null"], + "properties": { + "field": { + "type": ["string", "null"] + }, + "value": { + "type": ["string", "null"] + } + } + } + }, + "active": { + "type": ["boolean", "null"], + "description": "Whether the automation is active" + }, + "conditions": { + "type": "object", + "description": "An object that describes the conditions under which the automation will execute", + "properties": { + "all": { + "type": "array", + "items": { + "type": ["object", "null"], + "properties": { + "field": { + "type": ["string", "null"] + }, + "operator": { + "type": ["string", "null"] + }, + "value": { + "type": ["string", "null"] + } + } + } + }, + "any": { + "type": "array", + "items": { + "type": ["object", "null"], + "properties": { + "field": { + "type": ["string", "null"] + }, + "operator": { + "type": ["string", "null"] + }, + "value": { + "type": ["string", "null"] + } + } + } + } + } + }, + "created_at": { + "description": "The time the automation was created", + "type": ["string", "null"] + }, + "default": { + "type": ["boolean", "null"], + "description": "If true, the automation is a default automation" + }, + "id": { + "type": ["integer", "null"], + "description": "Automatically assigned when created" + }, + "position": { + "type": ["integer", "null"], + "description": "The position of the automation which specifies the order it will be executed" + }, + "raw_title": { + "type": ["string", "null"], + "description": "The raw title of the automation" + }, + "title": { + "type": ["string", "null"], + "description": "The title of the automation" + }, + "updated_at": { + "description": "The time of the last update of the automation", + "type": ["string", "null"] + } + } +} diff --git a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/schemas/triggers.json b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/schemas/triggers.json new file mode 100644 index 000000000000..27cad0b6456d --- /dev/null +++ b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/schemas/triggers.json @@ -0,0 +1,105 @@ +{ + "$schema": "https://json-schema.org/draft-07/schema#", + "type": ["null", "object"], + "properties": { + "actions": { + "type": ["array", "null"], + "description": "An array of actions describing what the ticket trigger will do", + "items": { + "type": "object", + "properties": { + "field": { + "type": ["string", "null"] + }, + "value": { + "type": ["string", "null"] + } + } + } + }, + "active": { + "description": "Whether the ticket trigger is active", + "type": "boolean" + }, + "category_id": { + "description": "The ID of the category the ticket trigger belongs to", + "type": ["string", "null"] + }, + "conditions": { + "description": "An object that describes the circumstances under which the trigger performs its actions", + "type": "object", + "properties": { + "all": { + "type": ["array", "null"], + "items": { + "type": "object", + "properties": { + "field": { + "type": ["string", "null"] + }, + "operator": { + "type": ["string", "null"] + }, + "value": { + "type": ["string", "null"] + } + } + } + }, + "any": { + "type": ["array", "null"], + "items": { + "type": "object", + "properties": { + "field": { + "type": ["string", "null"] + }, + "operator": { + "type": ["string", "null"] + }, + "value": { + "type": ["string", "null"] + } + } + } + } + } + }, + "created_at": { + "description": "The time the ticket trigger was created", + "type": ["string", "null"] + }, + "default": { + "description": "If true, the ticket trigger is a standard trigger", + "type": "boolean" + }, + "description": { + "description": "The description of the ticket trigger", + "type": ["string", "null"] + }, + "id": { + "description": "Automatically assigned when created", + "type": "integer" + }, + "position": { + "description": "Position of the ticket trigger, determines the order they will execute in", + "type": "integer" + }, + "raw_title": { + "description": "The raw format of the title of the ticket trigger", + "type": ["string", "null"] + }, + "title": { + "description": "The title of the ticket trigger", + "type": ["string", "null"] + }, + "updated_at": { + "description": "The time of the last update of the ticket trigger", + "type": ["string", "null"] + }, + "url": { + "description": "The url of the ticket trigger", + "type": ["string", "null"] + } + } +} diff --git a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/streams.py b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/streams.py index f1887a03442e..4095b6c50a5a 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/streams.py +++ b/airbyte-integrations/connectors/source-zendesk-support/source_zendesk_support/streams.py @@ -431,6 +431,10 @@ class AuditLogs(CursorPaginationZendeskSupportStream): cursor_field = "created_at" +class Automations(FullRefreshZendeskSupportStream): + """Automations stream: https://developer.zendesk.com/api-reference/ticketing/business-rules/automations/#list-automations""" + + class Users(SourceZendeskIncrementalExportStream): """Users stream: https://developer.zendesk.com/api-reference/ticketing/ticket-management/incremental_exports/#incremental-user-export""" @@ -779,6 +783,10 @@ def path(self, **kwargs): return "community/topics" +class Triggers(CursorPaginationZendeskSupportStream): + """Triggers stream: https://developer.zendesk.com/api-reference/ticketing/business-rules/triggers/#list-ticket-triggers""" + + class SlaPolicies(IncrementalZendeskSupportStream): """SlaPolicies stream: https://developer.zendesk.com/api-reference/ticketing/business-rules/sla_policies/""" diff --git a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/unit_test.py b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/unit_test.py index 9a33e3802b34..f51adae5ccab 100644 --- a/airbyte-integrations/connectors/source-zendesk-support/unit_tests/unit_test.py +++ b/airbyte-integrations/connectors/source-zendesk-support/unit_tests/unit_test.py @@ -185,11 +185,11 @@ def test_check(response, start_date, check_passed): @pytest.mark.parametrize( "ticket_forms_response, status_code, expected_n_streams, expected_warnings, reason", [ - ('{"ticket_forms": [{"id": 1, "updated_at": "2021-07-08T00:05:45Z"}]}', 200, 35, [], None), + ('{"ticket_forms": [{"id": 1, "updated_at": "2021-07-08T00:05:45Z"}]}', 200, 37, [], None), ( '{"error": "Not sufficient permissions"}', 403, - 32, + 34, [ "An exception occurred while trying to access TicketForms stream: Forbidden. You don't have permission to access this resource.. Skipping this stream." ], @@ -198,7 +198,7 @@ def test_check(response, start_date, check_passed): ( "", 404, - 32, + 34, [ "An exception occurred while trying to access TicketForms stream: Not found. The requested resource was not found on the server.. Skipping this stream." ], diff --git a/docs/integrations/sources/zendesk-support.md b/docs/integrations/sources/zendesk-support.md index b6aa46fd52ae..55ee7060363c 100644 --- a/docs/integrations/sources/zendesk-support.md +++ b/docs/integrations/sources/zendesk-support.md @@ -114,6 +114,7 @@ The Zendesk Support source connector supports the following streams: - [Article Comment Votes](https://developer.zendesk.com/api-reference/help_center/help-center-api/votes/#list-votes) \(Incremental\) - [Attribute Definitions](https://developer.zendesk.com/api-reference/ticketing/ticket-management/skill_based_routing/#list-routing-attribute-definitions) - [Audit Logs](https://developer.zendesk.com/api-reference/ticketing/account-configuration/audit_logs/#list-audit-logs)\(Incremental\) (Only available for enterprise accounts) +- [Automations](https://developer.zendesk.com/api-reference/ticketing/business-rules/automations/#list-automations) - [Brands](https://developer.zendesk.com/api-reference/ticketing/account-configuration/brands/#list-brands) - [Custom Roles](https://developer.zendesk.com/api-reference/ticketing/account-configuration/custom_roles/#list-custom-roles) \(Incremental\) - [Groups](https://developer.zendesk.com/rest_api/docs/support/groups) \(Incremental\) @@ -138,6 +139,7 @@ The Zendesk Support source connector supports the following streams: - [Ticket Metrics](https://developer.zendesk.com/rest_api/docs/support/ticket_metrics) \(Incremental\) - [Ticket Metric Events](https://developer.zendesk.com/api-reference/ticketing/tickets/ticket_metric_events/) \(Incremental\) - [Topics](https://developer.zendesk.com/api-reference/help_center/help-center-api/topics/#list-topics) \(Incremental\) +- [Triggers](https://developer.zendesk.com/api-reference/ticketing/business-rules/triggers/#list-ticket-triggers) \(Incremental\) - [Ticket Skips](https://developer.zendesk.com/api-reference/ticketing/tickets/ticket_skips/) \(Incremental\) - [Users](https://developer.zendesk.com/api-reference/ticketing/ticket-management/incremental_exports/#incremental-user-export) \(Incremental\) - [UserFields](https://developer.zendesk.com/api-reference/ticketing/users/user_fields/#list-user-fields) @@ -182,6 +184,7 @@ The Zendesk connector ideally should not run into Zendesk API limitations under | Version | Date | Pull Request | Subject | |:--------|:-----------|:---------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 4.2.0 | 2024-09-10 | [44610](https://github.com/airbytehq/airbyte/pull/44610) | Add `Automations` and `Triggers` stream | | 4.1.1 | 2024-09-07 | [45215](https://github.com/airbytehq/airbyte/pull/45215) | Update dependencies | | 4.1.0 | 2024-09-06 | [45187](https://github.com/airbytehq/airbyte/pull/45187) | Migrate to CDK v5 | | 4.0.2 | 2024-08-31 | [44965](https://github.com/airbytehq/airbyte/pull/44965) | Update dependencies |