Skip to content

Commit

Permalink
Source Retently - Add Feedback, NPS Score, Campaigns streams (#19381)
Browse files Browse the repository at this point in the history
* add sources

* add campaigns

* change parse_response

* spec.json

* schema and spec

* feedback schema

* docker file version
  • Loading branch information
schlattk authored Dec 16, 2022
1 parent 86b32db commit 8dfc53d
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 22 deletions.
2 changes: 1 addition & 1 deletion airbyte-integrations/connectors/source-retently/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,5 @@ COPY source_retently ./source_retently
ENV AIRBYTE_ENTRYPOINT "python /airbyte/integration_code/main.py"
ENTRYPOINT ["python", "/airbyte/integration_code/main.py"]

LABEL io.airbyte.version=0.1.2
LABEL io.airbyte.version=0.1.3
LABEL io.airbyte.name=airbyte/source-retently
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
{
"stream": {
"name": "companies",
"name": "reports",
"json_schema": {
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object"
Expand All @@ -26,7 +26,43 @@
},
{
"stream": {
"name": "reports",
"name": "nps",
"json_schema": {
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object"
},
"supported_sync_modes": ["full_refresh"]
},
"sync_mode": "full_refresh",
"destination_sync_mode": "overwrite"
},
{
"stream": {
"name": "feedback",
"json_schema": {
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object"
},
"supported_sync_modes": ["full_refresh"]
},
"sync_mode": "full_refresh",
"destination_sync_mode": "overwrite"
},
{
"stream": {
"name": "campaigns",
"json_schema": {
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object"
},
"supported_sync_modes": ["full_refresh"]
},
"sync_mode": "full_refresh",
"destination_sync_mode": "overwrite"
},
{
"stream": {
"name": "companies",
"json_schema": {
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"type": "object",
"properties":
{
"id": { "type": "string" },
"name": { "type": "string" },
"isActive": { "type": "boolean" },
"templateId": { "type": "string" },
"metric": { "type": "string" },
"type": { "type": "string" },
"channel": { "type": "string" }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"type": "object",
"properties": {
"id": { "type": "string" },
"customerId": { "type": "string" },
"email": { "type": "string" },
"firstName": { "type": "string" },
"lastName": { "type": "string" },
"companyName": { "type": "string" },
"jobTitle": { "type": "string" },
"country": { "type": "string" },
"state": { "type": "string" },
"city": { "type": "string" },
"tags": {
"type": "array",
"items": { "type": "string" }
},
"customProps": {
"type": "array",
"items": { "type": "object" }
},
"campaignId": { "type": "string" },
"campaignName": { "type": "string" },
"createdDate": { "type": "string" },
"score": { "type": "number" },
"comment": { "type": "string" },
"checkbox": { "type": "boolean" },
"additionalQuestions": {
"type": "array",
"items": { "type": "object" }
},
"feedbackTags": {
"type": "array",
"items": { "type": "string" }
},
"notes": {
"type": "array",
"items": { "type": "object" }
},
"status": { "type": "string" },
"assigned": { "type": "string" },
"ratingCategory": { "type": "string" },
"resolved": { "type": "boolean" },
"channel": { "type": "string" },
"metricsType": { "type": "string" },
"isBogus": { "type": "boolean" }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"score": { "type": "integer" },
"scoreSum": { "type": "integer" },
"metricsType": { "type": "string" },
"promoters": { "type": "integer" },
"passives": { "type": "integer" },
"detractors": { "type": "integer" },
"promotersCount": { "type": "integer" },
"passivesCount": { "type": "integer" },
"detractorsCount": { "type": "integer" },
"totalResponses": { "type": "integer" }
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def get_authenticator(config):
def check_connection(self, logger, config) -> Tuple[bool, any]:
try:
auth = self.get_authenticator(config)
stream = Companies(auth)
stream = Customers(auth)
records = stream.read_records(sync_mode=SyncMode.full_refresh)
next(records)
return True, None
Expand All @@ -44,7 +44,7 @@ def check_connection(self, logger, config) -> Tuple[bool, any]:

def streams(self, config: Mapping[str, Any]) -> List[Stream]:
auth = self.get_authenticator(config)
return [Customers(auth), Companies(auth), Reports(auth)]
return [Customers(auth), Companies(auth), Reports(auth), Nps(auth), Campaigns(auth), Feedback(auth)]


class RetentlyStream(HttpStream):
Expand All @@ -67,11 +67,9 @@ def parse_response(
next_page_token: Mapping[str, Any] = None,
) -> Iterable[Mapping]:
data = response.json().get("data")
if data:
stream_data = data.get(self.json_path) if self.json_path else data
if stream_data:
for d in stream_data:
yield d
stream_data = data.get(self.json_path) if self.json_path else data
for d in stream_data:
yield d

def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]:
json = response.json().get("data", dict())
Expand Down Expand Up @@ -118,7 +116,56 @@ def path(
self, stream_state: Mapping[str, Any] = None, stream_slice: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None
) -> str:
return "reports"
# does not support pagination
def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]:
return None

class Nps(RetentlyStream):
json_path = None

def path(
self, stream_state: Mapping[str, Any] = None, stream_slice: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None
) -> str:
return "nps/score"

# does not support pagination
def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]:
return None

def parse_response(
self,
response: requests.Response,
stream_state: Mapping[str, Any],
stream_slice: Mapping[str, Any] = None,
next_page_token: Mapping[str, Any] = None,
) -> Iterable[Mapping]:
data = response.json().get("data")
yield data

class Campaigns(RetentlyStream):
json_path = "campaigns"

def path(
self, stream_state: Mapping[str, Any] = None, stream_slice: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None
) -> str:
return "campaigns"

def parse_response(
self,
response: requests.Response,
stream_state: Mapping[str, Any],
stream_slice: Mapping[str, Any] = None,
next_page_token: Mapping[str, Any] = None,
) -> Iterable[Mapping]:
data = response.json()
stream_data = data.get(self.json_path) if self.json_path else data
for d in stream_data:
yield d

class Feedback(RetentlyStream):
json_path = "responses"

def path(
self, stream_state: Mapping[str, Any] = None, stream_slice: Mapping[str, Any] = None, next_page_token: Mapping[str, Any] = None
) -> str:
return "feedback"
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,11 @@
"type": "object",
"title": "Authenticate via Retently (OAuth)",
"required": ["client_id", "client_secret", "refresh_token"],
"additionalProperties": false,
"additionalProperties": true,
"properties": {
"auth_type": {
"type": "string",
"const": "Client",
"enum": ["Client"],
"default": "Client",
"order": 0
},
"client_id": {
Expand All @@ -47,13 +45,11 @@
"type": "object",
"title": "Authenticate with API Token",
"required": ["api_key"],
"additionalProperties": false,
"additionalProperties": true,
"properties": {
"auth_type": {
"type": "string",
"const": "Token",
"enum": ["Token"],
"default": "Token",
"order": 0
},
"api_key": {
Expand All @@ -75,7 +71,7 @@
"oauth_config_specification": {
"complete_oauth_output_specification": {
"type": "object",
"additionalProperties": false,
"additionalProperties": true,
"properties": {
"refresh_token": {
"type": "string",
Expand All @@ -85,7 +81,7 @@
},
"complete_oauth_server_input_specification": {
"type": "object",
"additionalProperties": false,
"additionalProperties": true,
"properties": {
"client_id": {
"type": "string"
Expand All @@ -97,7 +93,7 @@
},
"complete_oauth_server_output_specification": {
"type": "object",
"additionalProperties": false,
"additionalProperties": true,
"properties": {
"client_id": {
"type": "string",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
def setup_responses():
responses.add(
responses.GET,
"https://app.retently.com/api/v2/companies",
json={"data": {"companies": [{}]}},
"https://app.retently.com/api/v2/nps/customers",
json={"data": {"subscribers": [{}]}},
)


Expand All @@ -28,5 +28,5 @@ def test_streams(mocker):
source = SourceRetently()
config_mock = MagicMock()
streams = source.streams(config_mock)
expected_streams_number = 3
expected_streams_number = 6
assert len(streams) == expected_streams_number

0 comments on commit 8dfc53d

Please sign in to comment.