class ExternalUsersStream(BaseStream): API_PATH = '/api/v2/admin/external_users' TABLE = 'external_users' SCHEMA = with_properties(merge( DEFAULT_DATE_FIELDS, make_date_field("external_created_at"), make_date_field("last_seen_at"), { "email": {"type": ["string", "null"]}, "external_id": {"type": ["string", "null"]}, "id": {"type": ["integer", "null"]}, "ip": {"type": ["string", "null"]}, "links": { "type": "object", "properties": { "external_accounts": {"type": ["integer", "null"]}, "external_users": {"type": ["integer", "null"]}, }, }, "name": {"type": ["string", "null"]}, "seen_days": {"type": ["integer", "null"]}, "type": {"type": ["string", "null"]}, }), additional=True) def get_stream_data(self, result): return result.get('external_users')
class ProductAreasStream(BaseStream): API_PATH = '/api/v2/admin/product_areas' TABLE = 'product_areas' SCHEMA = with_properties( merge( DEFAULT_DATE_FIELDS, { "id": { "type": ["integer", "null"] }, "name": { "type": ["string", "null"] }, "links": { "type": "object", "properties": { "updated_by": { "type": ["integer", "null"] }, "created_by": { "type": ["integer", "null"] } } } })) def get_stream_data(self, result): return result.get('product_areas')
class StatusesStream(BaseStream): API_PATH = '/api/v2/admin/statuses' TABLE = 'statuses' SCHEMA = with_properties( merge( DEFAULT_DATE_FIELDS, { "id": { "type": "integer" }, "name": { "type": ["null", "string"] }, "is_open": { "type": ["boolean", "null"] }, "hex_color": { "type": ["string", "null"] }, "position": { "type": ["integer", "null"] }, "allow_comments": { "type": ["boolean", "null"] }, })) def get_stream_data(self, result): return result.get('statuses')
class CategoriesStream(BaseStream): API_PATH = '/api/v2/admin/categories' TABLE = 'categories' SCHEMA = with_properties( merge( DEFAULT_DATE_FIELDS, { "id": { "type": "integer" }, "name": { "type": "string" }, "suggestions_count": { "type": "integer", }, "open_suggestions_count": { "type": "integer", }, "links": { "type": "object", "properties": { "forum": { "type": "integer" } } } })) def get_stream_data(self, result): return result.get('categories')
class LabelsStream(BaseStream): API_PATH = '/api/v2/admin/labels' TABLE = 'labels' SCHEMA = with_properties( merge( DEFAULT_DATE_FIELDS, { "id": { "type": ["integer", "null"] }, "name": { "type": ["string", "null"] }, "full_name": { "type": ["string", "null"] }, "level": { "type": ["integer", "null"] }, "open_suggestions_count": { "type": ["integer", "null"] }, "links": { "type": "object", "properties": { "parent": { "type": ["integer", "null"] } } } })) def get_stream_data(self, result): return result.get('labels')
class CommentsStream(BaseStream): API_PATH = '/api/v2/admin/comments' TABLE = 'comments' SCHEMA = with_properties(merge( DEFAULT_DATE_FIELDS, { "id": {"type": "integer"}, "body": {"type": "string"}, "body_mime_type": {"type": "string"}, "state": {"type": "string"}, "inappropriate_flags_count": {"type": "integer"}, "is_admin_comment": {"type": "boolean"}, "channel": {"type": "string"}, "links": { "type": "object", "properties": { "suggestion": {"type": "integer"}, "created_by": {"type": "integer"} } } })) def get_stream_data(self, result): return result.get('comments')
class FeaturesStream(BaseStream): API_PATH = '/api/v2/admin/features' TABLE = 'features' SCHEMA = with_properties(merge( DEFAULT_DATE_FIELDS, { "id": { "type": ["integer", "null"] }, "description": { "type": ["string", "null"] }, "is_blocker": { "type": ["boolean", "null"] }, "links": { "type": "object", "properties": { "created_by": { "type": ["integer", "null"] }, "feature_status": { "type": ["integer", "null"] }, "product_area": { "type": ["integer", "null"] }, "updated_by": { "type": ["integer", "null"] } }, "additionalProperties": True }, "name": { "type": ["string", "null"] }, "suggestions_count": { "type": ["integer", "null"] }, "supporter_mrr_cents": { "type": ["integer", "null"] }, "supporting_accounts_count": { "type": ["integer", "null"] }, "supporting_users_count": { "type": ["integer", "null"] }, }), additional=True) def get_stream_data(self, result): return result.get('features')
class ExternalAccountsStream(BaseStream): API_PATH = '/api/v2/admin/external_accounts' TABLE = 'external_accounts' SCHEMA = with_properties(merge( DEFAULT_DATE_FIELDS, make_date_field('external_created_at'), make_date_field('last_active_at'), { "external_id": { "type": ["string", "null"] }, "id": { "type": ["integer", "null"] }, "is_blocker": { "type": ["boolean", "null"] }, "ltv": { "type": ["number", "null"] }, "ltv_cents": { "type": ["integer", "null"] }, "mrr": { "type": ["number", "null"] }, "mrr_cents": { "type": ["integer", "null"] }, "name": { "type": ["string", "null"] }, "nps": { "type": ["number", "null"] }, "plan": { "type": ["string", "null"] }, "requests_count": { "type": ["integer", "null"] }, "supported_ideas_count": { "type": ["integer", "null"] }, "users_count": { "type": ["integer", "null"] }, }), additional=True) def get_stream_data(self, result): return result.get('external_accounts')
class StatusUpdatesStream(BaseStream): API_PATH = '/api/v2/admin/status_updates' TABLE = 'status_updates' SCHEMA = with_properties( merge( DEFAULT_DATE_FIELDS, { "id": { "type": ["integer", "null"] }, "body": { "type": ["string", "null"] }, "supporters_notified": { "type": ["boolean", "null"] }, "notification_email_address": { "type": ["string", "null"] }, "mail_sent_count": { "type": ["integer", "null"] }, "mail_opened_count": { "type": ["integer", "null"] }, "mail_clicked_count": { "type": ["integer", "null"] }, "links": { "type": "object", "properties": { "suggestion": { "type": ["integer", "null"] }, "user": { "type": ["integer", "null"] }, "new_status": { "type": ["integer", "null"] }, "old_status": { "type": ["integer", "null"] } } } })) def get_stream_data(self, result): return result.get('status_updates')
class SupportersStream(BaseStream): API_PATH = '/api/v2/admin/supporters' TABLE = 'supporters' SCHEMA = with_properties( merge( DEFAULT_DATE_FIELDS, { "id": { "type": "integer" }, "is_subscribed": { "type": "boolean" }, "how": { "type": "string" }, "channel": { "type": "string" }, "requests_count": { "type": "integer" }, "comments_count": { "type": "integer" }, "links": { "type": "object", "properties": { "suggestion": { "type": "integer" }, "user": { "type": "integer" }, "created_by": { "type": "integer" }, "updated_by": { "type": "integer" }, } } })) def get_stream_data(self, result): return result.get('supporters')
class TeamsStream(BaseStream): API_PATH = '/api/v2/admin/teams' TABLE = 'teams' SCHEMA = with_properties({ "id": { "type": "integer" }, "name": { "type": "string" }, "members_count": { "type": "integer" }, }) def get_stream_data(self, result): return result.get('teams')
class SegmentedValuesStream(BaseStream): API_PATH = '/api/v2/admin/segmented_values' TABLE = 'segmented_values' SCHEMA = with_properties( merge( DEFAULT_DATE_FIELDS, { "id": { "type": ["integer", "null"] }, "name": { "type": ["string", "null"] }, "key": { "type": ["string", "null"] }, "object_type": { "type": ["string", "null"] }, "column_type": { "type": ["string", "null"] }, "links": { "type": "object", "properties": { "updated_by": { "type": ["integer", "null"] }, "created_by": { "type": ["integer", "null"] }, "segment": { "type": ["integer", "null"] } } } })) def get_stream_data(self, result): return result.get('segmented_values')
class SegmentsStream(BaseStream): API_PATH = '/api/v2/admin/segments' TABLE = 'segments' SCHEMA = with_properties( merge( DEFAULT_DATE_FIELDS, { "id": { "type": ["integer", "null"] }, "key": { "type": ["string", "null"] }, "name": { "type": ["string", "null"] }, "filters": { "type": "object", "additionalProperties": True } })) def get_stream_data(self, result): return result.get('segments')
class RequestsStream(BaseStream): API_PATH = '/api/v2/admin/requests' TABLE = 'requests' SCHEMA = with_properties( merge( DEFAULT_DATE_FIELDS, { "id": { "type": ["integer", "null"] }, "body": { "type": ["string", "null"] }, "body_mime_type": { "type": ["string", "null"] }, "source_url": { "type": ["string", "null"] }, "source_type": { "type": ["string", "null"] }, "source_guid": { "type": ["string", "null"] }, "channel": { "type": ["string", "null"] }, "severity": { "type": ["integer", "null"] }, "links": { "type": "object", "properties": { "suggestion": { "type": ["integer", "null"] }, "user": { "type": ["integer", "null"] }, "ticket": { "type": ["integer", "null"] }, "created_by": { "type": ["integer", "null"] }, "updated_by": { "type": ["integer", "null"] }, "supporter": { "type": ["integer", "null"] }, "sfdc_opportunity": { "type": ["integer", "null"] } } } })) def get_stream_data(self, result): return result.get('requests')
class UsersStream(BaseStream): API_PATH = '/api/v2/admin/users' TABLE = 'users' SCHEMA = with_properties( merge( DEFAULT_DATE_FIELDS, make_date_field('last_login'), { "id": { "type": "integer" }, "guid": { "type": ["string", "null"] }, "name": { "type": ["string", "null"] }, "email_address": { "type": ["string", "null"] }, "job_title": { "type": ["string", "null"] }, "avatar_url": { "type": ["string", "null"] }, "last_ip": { "type": ["string", "null"] }, "country": { "type": ["string", "null"] }, "region": { "type": ["string", "null"] }, "city": { "type": ["string", "null"] }, "satisfaction_score": { "type": ["integer", "null"] }, "allowed_state": { "type": ["string", "null"] }, "state": { "type": ["string", "null"] }, "supported_suggestions_count": { "type": "integer" }, "is_admin": { "type": "boolean" }, "is_owner": { "type": "boolean" }, "email_confirmed": { "type": "boolean" }, "status_notifications": { "type": "boolean" }, "comment_notifications": { "type": "boolean" }, "links": { "type": "object", "properties": { # todo: check these "teams": { "type": ["array", "null"] }, "current_nps_rating": { "type": ["integer", "null"] }, "previous_nps_rating": { "type": ["integer", "null"] }, "external_users": { "type": ["array", "null"] } } } })) def get_stream_data(self, result): return result.get('users')
class SuggestionsStream(BaseStream): API_PATH = '/api/v2/admin/suggestions' TABLE = 'suggestions' SCHEMA = with_properties(merge( DEFAULT_DATE_FIELDS, make_date_field('approved_at'), make_date_field('closed_at'), make_date_field('first_support_at'), { "admin_url": { "type": "string" }, "average_engagement": { "type": "number" }, "body": { "type": ["string", "null"] }, "body_mime_type": { "type": "string" }, "channel": { "type": "string" }, "comments_count": { "type": "integer" }, "creator_browser": { "type": ["string", "null"] }, "creator_browser_version": { "type": ["string", "null"] }, "creator_mobile": { "type": ["boolean", "null"] }, "creator_os": { "type": ["string", "null"] }, "creator_referrer": { "type": ["string", "null"] }, "creator_user_agent": { "type": ["string", "null"] }, "engagement_trend": { "type": "number" }, "id": { "type": "integer" }, "inappropriate_flags_count": { "type": "integer" }, "is_blocker": { "type": ["boolean", "null"] }, "notes_count": { "type": "integer" }, "portal_url": { "type": "string" }, "recent_engagement": { "type": "integer" }, "requests_count": { "type": "integer" }, "satisfaction_detractor_count": { "type": "integer" }, "satisfaction_neutral_count": { "type": "integer" }, "satisfaction_promoter_count": { "type": "integer" }, "state": { "type": "string" }, "supporter_mrr": { "type": "number" }, "supporter_satisfaction_score": { "type": "number" }, "supporters_count": { "type": "integer" }, "supporting_accounts_count": { "type": "integer" }, "title": { "type": "string" }, "votes_count": { "type": "integer" }, "links": { "type": "object", "additionalProperties": True, "properties": { "category": { "type": ["integer", "null"] }, "created_by": { "type": ["integer", "null"] }, "forum": { "type": ["integer", "null"] }, "labels": { "type": ["array", "null"], "items": { "type": ["integer", "null"] } }, "last_status_update": { "type": ["integer", "null"] }, "parent_suggestion": { "type": ["integer", "null"] }, "parent_suggestions": { "type": ["array", "null"], "items": { "type": ["integer", "null"] } }, "status": { "type": ["integer", "null"] }, "ticket": { "type": ["integer", "null"] } } } }), additional=True) def get_stream_data(self, result): return result.get('suggestions')