diff --git a/airbyte-integrations/connectors/source-intercom/acceptance-test-config.yml b/airbyte-integrations/connectors/source-intercom/acceptance-test-config.yml index 6f300242c7e6c..2b3638d81d6f6 100644 --- a/airbyte-integrations/connectors/source-intercom/acceptance-test-config.yml +++ b/airbyte-integrations/connectors/source-intercom/acceptance-test-config.yml @@ -10,6 +10,8 @@ acceptance_tests: tests: - config_path: "secrets/config.json" status: "succeed" + - config_path: "secrets/config_sandbox.json" + status: "succeed" - config_path: "integration_tests/invalid_config.json" status: "failed" discovery: @@ -17,7 +19,7 @@ acceptance_tests: - config_path: "secrets/config.json" basic_read: tests: - - config_path: "secrets/config.json" + - config_path: "secrets/config_sandbox.json" expect_records: path: "integration_tests/expected_records.jsonl" empty_streams: [] diff --git a/airbyte-integrations/connectors/source-intercom/integration_tests/configured_catalog.json b/airbyte-integrations/connectors/source-intercom/integration_tests/configured_catalog.json index 66ccdc871d869..16c16c234d012 100644 --- a/airbyte-integrations/connectors/source-intercom/integration_tests/configured_catalog.json +++ b/airbyte-integrations/connectors/source-intercom/integration_tests/configured_catalog.json @@ -152,6 +152,20 @@ "sync_mode": "full_refresh", "primary_key": [["name"]], "destination_sync_mode": "append" + }, + { + "stream": { + "name": "tickets", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["updated_at"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["updated_at"], + "primary_key": [["id"]], + "destination_sync_mode": "append" } ] } diff --git a/airbyte-integrations/connectors/source-intercom/integration_tests/expected_records.jsonl b/airbyte-integrations/connectors/source-intercom/integration_tests/expected_records.jsonl index 7e61c0ad3cf6b..6c34811b40356 100644 --- a/airbyte-integrations/connectors/source-intercom/integration_tests/expected_records.jsonl +++ b/airbyte-integrations/connectors/source-intercom/integration_tests/expected_records.jsonl @@ -34,3 +34,5 @@ {"stream":"conversation_parts","data":{"type":"conversation_part","id":"7288120839","part_type":"comment","body":"
is this showing up
","created_at":1607553246,"updated_at":1607553246,"notified_at":1607553246,"author":{"id":"5fd150d50697b6d0bbc4a2c2","type":"user","name":null,"email":""},"attachments":[],"redacted":false,"conversation_id":1},"emitted_at":1736209152327} {"stream":"conversation_parts","data":{"type":"conversation_part","id":"7288121348","part_type":"comment","body":"Airbyte [DEV] will reply as soon as they can.
","created_at":1607553249,"updated_at":1607553249,"notified_at":1607553249,"author":{"id":"4423434","type":"bot","name":"Operator","email":"operator+wjw5eps7@intercom.io"},"attachments":[],"redacted":false,"conversation_id":1},"emitted_at":1736209152327} {"stream":"conversation_parts","data":{"type":"conversation_part","id":"7288121392","part_type":"comment","body":"Give the team a way to reach you:
","created_at":1607553250,"updated_at":1607553250,"notified_at":1607553250,"author":{"id":"4423434","type":"bot","name":"Operator","email":"operator+wjw5eps7@intercom.io"},"attachments":[],"redacted":false,"conversation_id":1},"emitted_at":1736209152327} +{"stream":"tickets","data":{"type":"ticket","id":"70","ticket_id":"1","ticket_attributes":{"_default_title_":"Test ticket","_default_description_":"there is a problem"},"ticket_state":"submitted","ticket_type":{"type":"ticket_type","id":"1","name":"Test Ticket Type 1","description":"Test Ticket Type 1","icon":"🏭","workspace_id":"wjw5eps7","archived":false,"created_at":1738326590,"updated_at":1738326590,"is_internal":true,"ticket_type_attributes":{"type":"list","data":[{"type":"ticket_type_attribute","id":"6594164","workspace_id":"wjw5eps7","name":"_default_title_","description":"","data_type":"string","input_options":{"multiline":false},"order":0,"required_to_create":false,"required_to_create_for_contacts":false,"visible_on_create":true,"visible_to_contacts":false,"default":true,"ticket_type_id":1,"archived":false,"created_at":1738326590,"updated_at":1738326590},{"type":"ticket_type_attribute","id":"6594165","workspace_id":"wjw5eps7","name":"_default_description_","description":"","data_type":"string","input_options":{"multiline":true},"order":1,"required_to_create":false,"required_to_create_for_contacts":false,"visible_on_create":true,"visible_to_contacts":false,"default":true,"ticket_type_id":1,"archived":false,"created_at":1738326590,"updated_at":1738326590}]},"category":"Tracker"},"contacts":{"type":"contact.list","contacts":[]},"admin_assignee_id":"0","team_assignee_id":"0","created_at":1738329209,"updated_at":1738329211,"ticket_parts":{"type":"ticket_part.list","ticket_parts":[{"type":"ticket_part","id":"19760294812","part_type":"ticket_state_updated_by_admin","ticket_state":"submitted","previous_ticket_state":"submitted","created_at":1738329210,"updated_at":1738329210,"author":{"id":"4423434","type":"bot","name":"Fin","email":"operator+wjw5eps7@intercom.io"},"attachments":[],"redacted":false}],"total_count":1},"open":true,"linked_objects":{"type":"list","data":[],"total_count":0,"has_more":false},"category":"Tracker","is_shared":false,"ticket_state_internal_label":"Submitted","ticket_state_external_label":"Submitted"},"emitted_at":1738599593257} +{"stream":"tickets","data":{"type":"ticket","id":"71","ticket_id":"2","ticket_attributes":{"_default_title_":"Test ticket","_default_description_":"there is a problem"},"ticket_state":"submitted","ticket_type":{"type":"ticket_type","id":"1","name":"Test Ticket Type 1","description":"Test Ticket Type 1","icon":"🏭","workspace_id":"wjw5eps7","archived":false,"created_at":1738326590,"updated_at":1738326590,"is_internal":true,"ticket_type_attributes":{"type":"list","data":[{"type":"ticket_type_attribute","id":"6594164","workspace_id":"wjw5eps7","name":"_default_title_","description":"","data_type":"string","input_options":{"multiline":false},"order":0,"required_to_create":false,"required_to_create_for_contacts":false,"visible_on_create":true,"visible_to_contacts":false,"default":true,"ticket_type_id":1,"archived":false,"created_at":1738326590,"updated_at":1738326590},{"type":"ticket_type_attribute","id":"6594165","workspace_id":"wjw5eps7","name":"_default_description_","description":"","data_type":"string","input_options":{"multiline":true},"order":1,"required_to_create":false,"required_to_create_for_contacts":false,"visible_on_create":true,"visible_to_contacts":false,"default":true,"ticket_type_id":1,"archived":false,"created_at":1738326590,"updated_at":1738326590}]},"category":"Tracker"},"contacts":{"type":"contact.list","contacts":[]},"admin_assignee_id":"0","team_assignee_id":"0","created_at":1738329331,"updated_at":1738329332,"ticket_parts":{"type":"ticket_part.list","ticket_parts":[{"type":"ticket_part","id":"19760294813","part_type":"ticket_state_updated_by_admin","ticket_state":"submitted","previous_ticket_state":"submitted","created_at":1738329331,"updated_at":1738329331,"author":{"id":"4423434","type":"bot","name":"Fin","email":"operator+wjw5eps7@intercom.io"},"attachments":[],"redacted":false}],"total_count":1},"open":true,"linked_objects":{"type":"list","data":[],"total_count":0,"has_more":false},"category":"Tracker","is_shared":false,"ticket_state_internal_label":"Submitted","ticket_state_external_label":"Submitted"},"emitted_at":1738599593257} diff --git a/airbyte-integrations/connectors/source-intercom/integration_tests/sample_state.json b/airbyte-integrations/connectors/source-intercom/integration_tests/sample_state.json index 6745627f060de..cdf424c533094 100755 --- a/airbyte-integrations/connectors/source-intercom/integration_tests/sample_state.json +++ b/airbyte-integrations/connectors/source-intercom/integration_tests/sample_state.json @@ -70,5 +70,16 @@ "updated_at": 1676462031 } } + }, + { + "type": "STREAM", + "stream": { + "stream_descriptor": { + "name": "tickets" + }, + "stream_state": { + "updated_at": 1676462031 + } + } } ] diff --git a/airbyte-integrations/connectors/source-intercom/manifest.yaml b/airbyte-integrations/connectors/source-intercom/manifest.yaml index 382c5f4392f5f..c2a654b4d0b41 100644 --- a/airbyte-integrations/connectors/source-intercom/manifest.yaml +++ b/airbyte-integrations/connectors/source-intercom/manifest.yaml @@ -2469,6 +2469,544 @@ definitions: type: - "null" - integer + tickets: + $ref: "#/definitions/stream_full_refresh" + primary_key: id + $parameters: + name: "tickets" + path: "tickets/search" + data_field: "tickets" + page_size: 150 + retriever: + $ref: "#/definitions/retriever" + requester: + $ref: "#/definitions/retriever/requester" + http_method: "POST" + request_body_json: + query: >- + {"operator" : "AND", "value" : [ + {"operator" : "OR", "value" : [ + {"field" : "updated_at", "operator" : ">", "value" : {{ stream_interval['start_time'] }} }, + {"field" : "updated_at", "operator" : "=", "value" : {{ stream_interval['start_time'] }} }]}, + {"field" : "updated_at", "operator" : "<", "value" : {{ stream_interval['end_time'] }} } + ]} + sort: >- + {"field": "updated_at", "order": "ascending"} + pagination: >- + {{ {"per_page": parameters['page_size']} if not next_page_token else {"per_page": parameters['page_size'], + "starting_after": next_page_token["next_page_token"]} }} + test: + paginator: + type: "DefaultPaginator" + url_base: "#/definitions/requester/url_base" + pagination_strategy: + type: "CursorPagination" + cursor_value: "{{ response.get('pages', {}).get('next', {}).get('starting_after') }}" + stop_condition: "{{ not response.get('pages', {}).get('next', {}).get('starting_after') }}" + incremental_sync: + type: DatetimeBasedCursor + cursor_field: updated_at + cursor_datetime_formats: + - "%s" + datetime_format: "%s" + start_datetime: + type: MinMaxDatetime + datetime: "{{ config['start_date'] }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + end_datetime: + type: MinMaxDatetime + datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}" + datetime_format: "%Y-%m-%dT%H:%M:%SZ" + + schema_loader: + type: InlineSchemaLoader + schema: + type: object + additionalProperties: true + properties: + type: + description: Always ticket. + type: + - string + - "null" + id: + description: The unique identifier for the ticket which is given by Intercom. + type: + - string + - "null" + ticket_id: + description: The ID of the Ticket used in the Intercom Inbox and Messenger. Do not use ticket_id for API queries. + type: + - string + - "null" + category: + description: Category of the Ticket. + type: + - string + - "null" + ticket_attributes: + description: An object containing the different attributes associated to the ticket as key-value pairs. + type: + - object + - "null" + additionalProperties: true + ticket_state: + description: The state the ticket is currently in. + type: + - string + - "null" + ticket_type: + description: he state the ticket is currently in. + type: + - object + - "null" + properties: + type: + description: String representing the object's type. Always has the value ticket_type. + type: + - string + - "null" + id: + description: The id representing the ticket type. + type: + - string + - "null" + category: + description: Category of the Ticket Type. + type: + - string + - "null" + name: + description: The name of the ticket type. + type: + - string + - "null" + description: + description: The description of the ticket type. + type: + - string + - "null" + icon: + description: The icon of the ticket type. + type: + - string + - "null" + workspace_id: + description: The id of the workspace that the ticket type belongs to. + type: + - string + - "null" + ticket_type_attributes: + description: A list of attributes associated with a given ticket type. + type: + - object + - "null" + properties: + type: + description: String representing the object's type. Always has the value ticket_type_attributes.list. + type: + - string + - "null" + ticket_type_attributes: + description: A list of ticket type attributes associated with a given ticket type. + type: + - array + - "null" + properties: + type: + description: String representing the object's type. Always has the value ticket_type_attribute. + type: + - string + - "null" + id: + description: The id representing the ticket type attribute. + type: + - string + - "null" + workspace_id: + description: The id of the workspace that the ticket type attribute belongs to. + type: + - string + - "null" + name: + description: The name of the ticket type attribute. + type: + - string + - "null" + description: + description: The description of the ticket type attribute. + type: + - string + - "null" + data_type: + description: The type of the data attribute. + type: + - string + - "null" + input_options: + description: Input options for the attribute. + type: + - object + - "null" + additionalProperties: true + order: + description: The order of the attribute against other attributes. + type: + - integer + - "null" + required_to_create: + description: Whether the attribute is required or not for teammates. + type: + - boolean + - "null" + required_to_create_for_contacts: + description: Whether the attribute is required or not for contacts. + type: + - boolean + - "null" + visible_on_create: + description: Whether the attribute is visible or not to teammates. + type: + - boolean + - "null" + visible_to_contacts: + description: Whether the attribute is visible or not to contacts. + type: + - boolean + - "null" + default: + description: Whether the attribute is built in or not. + type: + - boolean + - "null" + ticket_type_id: + description: The id of the ticket type that the attribute belongs to. + type: + - integer + - "null" + archived: + description: Whether the ticket type attribute is archived or not. + type: + - boolean + - "null" + created_at: + description: The date and time the ticket type attribute was created. + type: + - integer + - "null" + updated_at: + description: The date and time the ticket type attribute was last updated. + type: + - integer + - "null" + archived: + description: Whether the ticket type is archived or not. + type: + - boolean + - "null" + created_at: + description: The date and time the ticket type was created. + type: + - integer + - "null" + updated_at: + description: The date and time the ticket type was last updated. + type: + - integer + - "null" + contacts: + description: The list of contacts affected by a ticket. + type: + - object + - "null" + properties: + type: + description: Always contact.list. + type: + - string + - "null" + contacts: + description: The list of contacts affected by this ticket. + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + description: Always contact. + type: + - string + - "null" + id: + description: The unique identifier for the contact which is given by Intercom. + type: + - string + - "null" + external_id: + description: The unique identifier for the contact which is provided by the Client. + type: + - string + - "null" + admin_assignee_id: + description: The id representing the admin assigned to the ticket. + type: + - string + - "null" + team_assignee_id: + description: The id representing the team assigned to the ticket. + type: + - string + - "null" + created_at: + description: The time the ticket was created as a UTC Unix timestamp. + type: + - integer + - "null" + updated_at: + description: The last time the ticket was updated as a UTC Unix timestamp. + type: + - integer + - "null" + open: + description: Whether or not the ticket is open. If false, the ticket is closed. + type: + - boolean + - "null" + snoozed_until: + description: The time the ticket will be snoozed until as a UTC Unix timestamp. If null, the ticket is not currently snoozed. + type: + - integer + - "null" + linked_objects: + description: An object containing metadata about linked conversations and linked tickets. + type: + - object + - "null" + properties: + type: + description: Always list. + type: + - string + - "null" + total_count: + description: The total number of linked objects. + type: + - integer + - "null" + has_more: + description: Whether or not there are more linked objects than returned. + type: + - boolean + - "null" + data: + description: An array containing the linked conversations and linked tickets. + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + description: Ticket or conversation. + type: + - string + - "null" + id: + description: The ID of the linked object. + type: + - string + - "null" + category: + description: Category of the Linked Ticket Object.. + type: + - string + - "null" + ticket_parts: + description: A list of Ticket Part objects for each note and event in the ticket. + type: + - object + - "null" + properties: + type: + description: Value ticket_part.list. + type: + - string + - "null" + ticket_parts: + description: A list of Ticket Part objects for each ticket. + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + description: Always ticket_part. + type: + - string + - "null" + id: + description: The id representing the ticket part. + type: + - string + - "null" + part_type: + description: The type of ticket part. + type: + - string + - "null" + body: + description: The message body, which may contain HTML. + type: + - string + - "null" + previous_ticket_state: + description: The previous state of the ticket. + type: + - string + - "null" + ticket_state: + description: The state of the ticket. + type: + - string + - "null" + created_at: + description: The time the ticket part was created. + type: + - integer + - "null" + updated_at: + description: The last time the ticket part was updated. + type: + - integer + - "null" + assigned_to: + description: Teference to another object. + type: + - object + - "null" + properties: + type: + description: Example - contact. + type: + - string + - "null" + id: + description: Example - 1a2b3c. + type: + - string + - "null" + author: + description: The author that wrote or triggered the part. Can be a bot, admin, team or user. + type: + - object + - "null" + properties: + type: + description: The type of the author. + type: + - string + - "null" + id: + description: The id of the author. + type: + - string + - "null" + name: + description: The name of the author. + type: + - string + - "null" + email: + description: The email of the author. + type: + - string + - "null" + attachments: + description: A list of attachments for the part. + type: + - array + - "null" + items: + type: + - object + - "null" + properties: + type: + description: The type of attachment + type: + - string + - "null" + name: + description: The name of attachment + type: + - string + - "null" + url: + description: The url of attachment + type: + - string + - "null" + content_type: + description: The content type of attachment + type: + - string + - "null" + filesize: + description: The file size of attachment + type: + - integer + - "null" + width: + description: The width of attachment + type: + - integer + - "null" + height: + description: The height of attachment + type: + - integer + - "null" + external_id: + description: The external id of the ticket part. + type: + - string + - "null" + redacted: + description: Whether or not the ticket part has been redacted. + type: + - boolean + - "null" + total_count: + description: Total count of ticket parts. + type: + - integer + - "null" + is_shared: + description: Whether or not the ticket is shared with the customer. + type: + - boolean + - "null" + ticket_state_internal_label: + description: The state the ticket is currently in, in a human readable form - visible in Intercom. + type: + - string + - "null" + ticket_state_external_label: + description: The state the ticket is currently in, in a human readable form - visible to customers, in the messenger, email and tickets portal. + type: + - string + - "null" + + + streams: - "#/definitions/activity_logs" - "#/definitions/admins" @@ -2482,6 +3020,7 @@ streams: - "#/definitions/conversations" - "#/definitions/conversation_parts" - "#/definitions/company_segments" + - "#/definitions/tickets" check: stream_names: diff --git a/airbyte-integrations/connectors/source-intercom/metadata.yaml b/airbyte-integrations/connectors/source-intercom/metadata.yaml index 6152c8f08dc9c..5c89a7649e8f3 100644 --- a/airbyte-integrations/connectors/source-intercom/metadata.yaml +++ b/airbyte-integrations/connectors/source-intercom/metadata.yaml @@ -10,7 +10,7 @@ data: connectorSubtype: api connectorType: source definitionId: d8313939-3782-41b0-be29-b3ca20d8dd3a - dockerImageTag: 0.11.0 + dockerImageTag: 0.12.0 dockerRepository: airbyte/source-intercom documentationUrl: https://docs.airbyte.com/integrations/sources/intercom githubIssueLabel: source-intercom @@ -74,4 +74,9 @@ data: secretStore: type: GSM alias: airbyte-connector-testing-secret-store + - name: SECRET_SOURCE-INTERCOM_SANDBOX__CREDS + fileName: config_sandbox.json + secretStore: + type: GSM + alias: airbyte-connector-testing-secret-store metadataSpecVersion: "1.0" diff --git a/docs/integrations/sources/intercom.md b/docs/integrations/sources/intercom.md index ccdd7021862aa..b258ee6a6fcab 100644 --- a/docs/integrations/sources/intercom.md +++ b/docs/integrations/sources/intercom.md @@ -96,6 +96,7 @@ The Intercom connector should not run into Intercom API limitations under normal | Version | Date | Pull Request | Subject | |:-----------|:-----------|:---------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------| +| 0.12.0 | 2025-02-03 | [52687](https://github.com/airbytehq/airbyte/pull/52687) | New stream Tickets | | 0.11.0 | 2025-02-03 | [51619](https://github.com/airbytehq/airbyte/pull/51619) | Upgrade API version to 2.11, add ai_agent_participated and ai_agent fields conversations stream schema | | 0.10.1 | 2025-02-01 | [49212](https://github.com/airbytehq/airbyte/pull/49212) | Update dependencies | | 0.10.0 | 2025-01-24 | [52132](https://github.com/airbytehq/airbyte/pull/52132) | Fix incremental sync |