From 56c5476a9ca4fd8e3ff616e7b3bf71a4137bb449 Mon Sep 17 00:00:00 2001 From: Luishfs Date: Thu, 25 Apr 2024 23:28:58 -0300 Subject: [PATCH 1/5] Adding initial snapshots --- source-mailchimp/acmeCo/campaigns.schema.yaml | 2009 +++++++++ .../acmeCo/email_activity.schema.yaml | 56 + source-mailchimp/acmeCo/flow.yaml | 20 + source-mailchimp/acmeCo/lists.schema.yaml | 246 ++ source-mailchimp/acmeCo/reports.schema.yaml | 444 ++ source-mailchimp/config.yaml | 17 + source-mailchimp/test.flow.yaml | 34 + source-mailchimp/tests/__init__.py | 0 .../snapshots__capture__capture.stdout.json | 159 + .../snapshots__discover__capture.stdout.json | 3605 +++++++++++++++++ .../snapshots__spec__capture.stdout.json | 135 + source-mailchimp/tests/test_snapshots.py | 73 + 12 files changed, 6798 insertions(+) create mode 100644 source-mailchimp/acmeCo/campaigns.schema.yaml create mode 100644 source-mailchimp/acmeCo/email_activity.schema.yaml create mode 100644 source-mailchimp/acmeCo/flow.yaml create mode 100644 source-mailchimp/acmeCo/lists.schema.yaml create mode 100644 source-mailchimp/acmeCo/reports.schema.yaml create mode 100644 source-mailchimp/config.yaml create mode 100644 source-mailchimp/test.flow.yaml create mode 100644 source-mailchimp/tests/__init__.py create mode 100644 source-mailchimp/tests/snapshots/snapshots__capture__capture.stdout.json create mode 100644 source-mailchimp/tests/snapshots/snapshots__discover__capture.stdout.json create mode 100644 source-mailchimp/tests/snapshots/snapshots__spec__capture.stdout.json create mode 100644 source-mailchimp/tests/test_snapshots.py diff --git a/source-mailchimp/acmeCo/campaigns.schema.yaml b/source-mailchimp/acmeCo/campaigns.schema.yaml new file mode 100644 index 0000000000..0f76d0092f --- /dev/null +++ b/source-mailchimp/acmeCo/campaigns.schema.yaml @@ -0,0 +1,2009 @@ +--- +description: "A summary of an individual campaign's settings and content." +properties: + ab_split_opts: + description: "[A/B Testing](https://mailchimp.com/help/about-ab-testing-campaigns/) options for a campaign." + properties: + from_name_a: + description: "For campaigns split on 'From Name', the name for Group A." + title: From Name Group A + type: string + from_name_b: + description: "For campaigns split on 'From Name', the name for Group B." + title: From Name Group B + type: string + pick_winner: + description: "How we should evaluate a winner. Based on 'opens', 'clicks', or 'manual'." + title: Pick Winner + type: string + reply_email_a: + description: "For campaigns split on 'From Name', the reply-to address for Group A." + title: Reply Email Group A + type: string + reply_email_b: + description: "For campaigns split on 'From Name', the reply-to address for Group B." + title: Reply Email Group B + type: string + send_time_a: + description: The send time for Group A. + title: Send Time Group A + type: string + send_time_b: + description: The send time for Group B. + title: Send Time Group B + type: string + send_time_winner: + description: The send time for the winning version. + title: Send Time Winner + type: string + split_size: + description: "The size of the split groups. Campaigns split based on 'schedule' are forced to have a 50/50 split. Valid split integers are between 1-50." + maximum: 50 + minimum: 1 + title: Split Size + type: integer + split_test: + description: The type of AB split to run. + title: Split Test + type: string + subject_a: + description: "For campaigns split on 'Subject Line', the subject line for Group A." + title: Subject Line Group A + type: string + subject_b: + description: "For campaigns split on 'Subject Line', the subject line for Group B." + title: Subject Line Group B + type: string + wait_time: + description: The amount of time to wait before picking a winner. This cannot be changed after a campaign is sent. + title: Wait Time + type: integer + wait_units: + description: "How unit of time for measuring the winner ('hours' or 'days'). This cannot be changed after a campaign is sent." + title: Wait Time + type: string + readOnly: true + title: A/B Testing Options + type: object + archive_url: + description: "The link to the campaign's archive version in ISO 8601 format." + readOnly: true + title: Archive URL + type: string + content_type: + description: "How the campaign's content is put together." + title: Content Type + type: string + create_time: + description: The date and time the campaign was created in ISO 8601 format. + readOnly: true + title: Create Time + type: string + delivery_status: + description: Updates on campaigns in the process of sending. + properties: + can_cancel: + description: Whether a campaign send can be canceled. + readOnly: true + title: Campaign Cancelable + type: boolean + emails_canceled: + description: The total number of emails canceled for this campaign. + readOnly: true + title: Emails Canceled + type: integer + emails_sent: + description: The total number of emails confirmed sent for this campaign so far. + readOnly: true + title: Emails Sent + type: integer + enabled: + description: Whether Campaign Delivery Status is enabled for this account and campaign. + readOnly: true + title: Delivery Status Enabled + type: boolean + status: + description: The current state of a campaign delivery. + readOnly: true + title: Campaign Delivery Status + type: string + title: Campaign Delivery Status + type: object + emails_sent: + description: The total number of emails sent for this campaign. + readOnly: true + title: Emails Sent + type: integer + id: + description: A string that uniquely identifies this campaign. + readOnly: true + title: Campaign ID + type: string + long_archive_url: + description: "The original link to the campaign's archive version." + readOnly: true + title: Long Archive URL + type: string + needs_block_refresh: + description: Determines if the campaign needs its blocks refreshed by opening the web-based campaign editor. Deprecated and will always return false. + readOnly: true + title: Needs Block Refresh + type: boolean + parent_campaign_id: + description: "If this campaign is the child of another campaign, this identifies the parent campaign. For Example, for RSS or Automation children." + readOnly: true + title: Parent Campaign ID + type: string + recipients: + description: List settings for the campaign. + properties: + list_id: + description: The unique list id. + title: List ID + type: string + list_is_active: + description: "The status of the list used, namely if it's deleted or disabled." + readOnly: true + title: List Status + type: boolean + list_name: + description: The name of the list. + readOnly: true + title: List Name + type: string + recipient_count: + description: Count of the recipients on the associated list. Formatted as an integer. + readOnly: true + title: Recipient Count + type: integer + segment_opts: + description: "An object representing all segmentation options. This object should contain a `saved_segment_id` to use an existing segment, or you can create a new segment by including both `match` and `conditions` options." + properties: + conditions: + description: "Segment match conditions. There are multiple possible types, see the [condition types documentation](https://mailchimp.com/developer/marketing/docs/alternative-schemas/#segment-condition-schemas)." + items: + oneOf: + - description: Segment by interaction with a specific campaign. + properties: + condition_type: + enum: + - Aim + type: string + x-value: Aim + field: + description: Segment by interaction with a specific campaign. + enum: + - aim + example: aim + title: Segment Field + type: string + op: + description: "The status of the member with regard to their campaign interaction. One of the following: opened, clicked, was sent, didn't open, didn't click, or was not sent." + enum: + - open + - click + - sent + - noopen + - noclick + - nosent + example: open + title: Segment Operator + type: string + value: + description: "Either the web id value for a specific campaign or 'any' to account for subscribers who have/have not interacted with any campaigns." + example: any + title: Segment Data + type: string + title: Aim Segment + type: object + - description: Segment by interaction with an Automation workflow. + properties: + condition_type: + enum: + - Automation + type: string + x-value: Automation + field: + description: Segment by interaction with an Automation workflow. + enum: + - automation + example: automation + title: Segment Field + type: string + op: + description: "The status of the member with regard to the automation workflow. One of the following: has started the workflow, has completed the workflow, has not started the workflow, or has not completed the workflow." + enum: + - started + - completed + - not_started + - not_completed + example: started + title: Segment Operator + type: string + value: + description: The web id for the automation workflow to segment against. + example: "2135217" + title: Segment Data + type: string + required: + - field + - op + - value + title: Automation Segment + type: object + - description: Segment by poll activity. + properties: + condition_type: + enum: + - CampaignPoll + type: string + x-value: CampaignPoll + field: + description: Segment by poll activity. + enum: + - poll + example: poll + title: Segment Field + type: string + op: + description: Members have/have not interacted with a specific poll in a Mailchimp email. + enum: + - member + - notmember + example: member + title: Segment Operator + type: string + value: + description: The id for the poll. + example: 409 + title: Segment Operator + type: number + required: + - field + - op + - value + title: Poll Activity Segment + type: object + - description: Segment by interaction with a campaign via Conversations. + properties: + condition_type: + enum: + - Conversation + type: string + x-value: Conversation + field: + description: Segment by interaction with a campaign via Conversations. + enum: + - conversation + example: conversation + title: Segment Field + type: string + op: + description: "The status of a member's interaction with a conversation. One of the following: has replied or has not replied." + enum: + - member + - notmember + example: member + title: Segment Operator + type: string + value: + description: "The web id value for a specific campaign or 'any' to account for subscribers who have/have not interacted with any campaigns." + example: any + title: Segment Data + type: string + required: + - field + - op + - value + title: Conversation Segment + type: object + - description: Segment by a specific date field. + properties: + condition_type: + enum: + - Date + type: string + x-value: Date + extra: + description: "When segmenting on 'date' or 'campaign', the date for the segment formatted as YYYY-MM-DD or the web id for the campaign." + example: 2015-01-30 + title: Segment Extra Value + type: string + field: + description: "The type of date field to segment on: The opt-in time for a signup, the date the subscriber was last updated, or the date of their last ecomm purchase." + enum: + - timestamp_opt + - info_changed + - ecomm_date + example: timestamp_opt + title: Segment Field + type: string + op: + description: "When the event took place: Before, after, is a specific date, is not a specific date, is blank, or is not blank." + enum: + - greater + - less + - is + - not + - blank + - blank_not + - within + - notwithin + example: greater + title: Segment Operator + type: string + value: + description: "What type of data to segment on: a specific date, a specific campaign, or the last campaign sent." + example: date + title: Segment Data + type: string + required: + - field + - op + - value + title: Date Segment + type: object + - description: Segment by use of a particular email client. + properties: + condition_type: + enum: + - EmailClient + type: string + x-value: EmailClient + field: + description: Segment by use of a particular email client. + enum: + - email_client + example: email_client + title: Segment Field + type: string + op: + description: "The operation to determine whether we select clients that match the value, or clients that do not match the value." + enum: + - client_is + - client_not + example: client_is + title: Segment Operator + type: string + value: + description: The name of the email client. + example: Gmail + title: Segment Data + type: string + required: + - field + - op + - value + title: Email Client Segment + type: object + - description: Segment by language. + properties: + condition_type: + enum: + - Language + type: string + x-value: Language + field: + description: "Segmenting based off of a subscriber's language." + enum: + - language + example: language + title: Segment Field + type: string + op: + description: "Whether the member's language is or is not set to a specific language." + enum: + - is + - not + example: is + title: Segment Operator + type: string + value: + description: A two-letter language identifier. + example: en + title: Segment Data + type: string + required: + - field + - op + - value + title: Language Segment + type: object + - description: Segment by member rating. + properties: + condition_type: + enum: + - MemberRating + type: string + x-value: MemberRating + field: + description: Segment by member rating. + enum: + - rating + example: rating + title: Segment Field + type: string + op: + description: Members who have have a rating that is/not exactly a given number or members who have a rating greater/less than a given number. + enum: + - is + - not + - greater + - less + example: greater + title: Segment Operator + type: string + value: + description: The star rating number to segment against. + example: 4 + title: Segment Operator + type: number + required: + - field + - op + - value + title: Member Rating Segment + type: object + - description: Segment by signup source. + properties: + condition_type: + enum: + - SignupSource + title: Type + type: string + x-value: SignupSource + field: + enum: + - source + example: source + title: Segment Field + type: string + op: + description: "Whether the member's signup source was/was not a particular value." + enum: + - source_is + - source_not + example: source_is + title: Segment Operator + type: string + value: + description: The signup source. + example: List Import + title: Segment Data + type: string + required: + - field + - condition_type + - op + title: Signup Source Segment + type: object + - description: Segment by interaction with a SurveyMonkey survey. + properties: + condition_type: + enum: + - SurveyMonkey + type: string + x-value: SurveyMonkey + field: + description: Segment by interaction with a SurveyMonkey survey. + enum: + - survey_monkey + example: survey_monkey + title: Segment Field + type: string + op: + description: "The status of the member with regard to the survey. One of the following: has started the survey, has completed the survey, has not started the survey, or has not completed the survey." + enum: + - started + - completed + - not_started + - not_completed + example: started + title: Segment Operator + type: string + value: + description: The unique ID of the SurveyMonkey survey. + example: "32179586" + title: Survey ID + type: string + required: + - field + - op + - value + title: SurveyMonkey Segment + type: object + - description: Segment by VIP status. + properties: + condition_type: + enum: + - VIP + type: string + x-value: VIP + field: + description: Segment by VIP status. + enum: + - gmonkey + example: gmonkey + title: Segment Field + type: string + op: + description: Whether the member is or is not marked as VIP. + enum: + - member + - notmember + example: member + title: Segment Operator + type: string + required: + - field + - op + title: VIP Segment + type: object + - description: Segment by an interest group merge field. + properties: + condition_type: + enum: + - Interests + type: string + x-value: Interests + field: + description: "Segmenting based on interest group information. This should start with 'interests-' followed by the grouping id. Ex. 'interests-123'." + example: interests-123 + title: Segment Field + type: string + op: + description: "Whether the member is a part of one, all, or none of the groups." + enum: + - interestcontains + - interestcontainsall + - interestnotcontains + example: interestcontains + title: Segment Operator + type: string + value: + description: "An array containing strings, each representing a group id." + items: + example: + - "44401" + - "44405" + - "44409" + type: string + title: Segment Value + type: array + title: Interests Segment + type: object + - description: Segment by purchases in specific items or categories. + properties: + condition_type: + enum: + - EcommCategory + type: string + x-value: EcommCategory + field: + description: Segment by purchases in specific items or categories. + enum: + - ecomm_cat + - ecomm_prod + example: ecomm_cat + title: Segment Field + type: string + op: + description: "A member who has purchased from a category/specific item that is/is not a specific name, where the category/item name contains/doesn't contain a specific phrase or string, or a category/item name that starts/ends with a string." + enum: + - is + - not + - contains + - notcontain + - starts + - ends + example: is + title: Segment Operator + type: string + value: + description: The ecommerce category/item information. + example: Product + title: Segment Data + type: string + title: Ecommerce Category Segment + type: object + - description: "Segment by average spent total, number of orders, total number of products purchased, or average number of products per order." + properties: + condition_type: + enum: + - EcommNumber + type: string + x-value: EcommNumber + field: + description: "Segment by average spent total, number of orders, total number of products purchased, or average number of products per order." + enum: + - ecomm_spent_avg + - ecomm_orders + - ecomm_prod_all + - ecomm_avg_ord + example: ecomm_orders + title: Segment Field + type: string + op: + description: "Members who have spent exactly, have not spent exactly, spent more, or spent less than the segment value." + enum: + - is + - not + - greater + - less + example: greater + title: Segment Operator + type: string + value: + description: "Members who have spent exactly, have not spent exactly, spent more, or spent less than this amount." + example: 42 + title: Segment Operator + type: number + required: + - field + - op + - value + title: Ecommerce Number Segment + type: object + - description: Segment by whether someone has purchased anything. + properties: + condition_type: + enum: + - EcommPurchased + type: string + x-value: EcommPurchased + field: + description: Segment by whether someone has purchased anything. + enum: + - ecomm_purchased + example: ecomm_purchased + title: Segment Field + type: string + op: + description: "Members who have have ('member') or have not ('notmember') purchased." + enum: + - member + - notmember + example: member + title: Segment Operator + type: string + title: Ecommerce Purchased Segment + type: object + - description: Segment by amount spent on a single order or across all orders. + properties: + condition_type: + enum: + - EcommSpent + type: string + x-value: EcommSpent + field: + description: Segment by amount spent on a single order or across all orders. + enum: + - ecomm_spent_one + - ecomm_spent_all + example: ecomm_spent_one + title: Segment Field + type: string + op: + description: "Members who have spent 'more' or 'less' than then specified value." + enum: + - greater + - less + example: greater + title: Segment Operator + type: string + value: + description: The total amount a member spent. + example: 42 + title: Segment Data + type: integer + title: Ecommerce Spent Segment + type: object + - description: Segment by purchases from a specific store. + properties: + condition_type: + enum: + - EcommStore + type: string + x-value: EcommStore + field: + description: Segment by purchases from a specific store. + enum: + - ecomm_store + example: ecomm_store + title: Segment Field + type: string + op: + description: Members who have or have not purchased from a specific store. + enum: + - is + - not + example: is + title: Segment Operator + type: string + value: + description: The store id to segment against. + example: "289" + title: Segment Operator + type: string + title: Ecommerce Purchased Store Segment + type: object + - description: Segment by Goal activity. + properties: + condition_type: + enum: + - GoalActivity + type: string + x-value: GoalActivity + field: + description: Segment by Goal activity. + enum: + - goal + example: goal + title: Segment Field + type: string + op: + description: "Whether the website URL is/not exactly, contains/doesn't contain, starts with/ends with a string." + enum: + - is + - goal_not + - contains + - goal_notcontain + - starts + - ends + example: is + title: Segment Operator + type: string + value: + description: The URL to check Goal activity against. + title: Segment Value + type: string + required: + - field + - op + - value + title: Goal Activity Segment + type: object + - description: Segment by most recent interaction with a website. + properties: + condition_type: + enum: + - GoalTimestamp + type: string + x-value: GoalTimestamp + field: + description: Segment by most recent interaction with a website. + enum: + - goal_last_visited + example: goal_last_visited + title: Segment Field + type: string + op: + description: "Whether the website activity happened after, before, or at a given timestamp." + enum: + - greater + - less + - is + example: greater + title: Segment Operator + type: string + value: + description: The date to check Goal activity against. + example: "2015-07-20 19:45:21" + title: Segment Value + type: string + required: + - field + - op + - value + title: Goal Timestamp Segment + type: object + - description: Segment by similar subscribers. + properties: + condition_type: + enum: + - FuzzySegment + type: string + x-value: FuzzySegment + field: + description: Segment by similar subscribers. + enum: + - fuzzy_segment + example: fuzzy_segment + title: Segment Field + type: string + op: + description: "Members who are/are not apart of a 'similar subscribers' segment." + enum: + - fuzzy_is + - fuzzy_not + example: fuzzy_is + title: Segment Operator + type: string + value: + description: "The id for the 'similar subscribers' segment." + example: 48433 + title: Segment Operator + type: number + required: + - field + - op + - value + title: Similar Subscribers Segment Member Segment + type: object + - description: Segment by a given static segment. + properties: + condition_type: + enum: + - StaticSegment + type: string + x-value: StaticSegment + field: + description: Segment by a given static segment. + enum: + - static_segment + example: static_segment + title: Segment Field + type: string + op: + description: Members who are/are not apart of a static segment. + enum: + - static_is + - static_not + example: static_is + title: Segment Operator + type: string + value: + description: The id for the static segment. + example: 48433 + title: Segment Operator + type: number + required: + - field + - op + - value + title: Static Segment Member Segment + type: object + - description: Segment by a specific country or US state. + properties: + condition_type: + enum: + - IPGeoCountryState + type: string + x-value: IPGeoCountryState + field: + description: Segmenting subscribers who are within a specific location. + enum: + - ipgeo + example: ipgeo + title: Segment Field + type: string + op: + description: Segment members who are within a specific country or US state. + enum: + - ipgeocountry + - ipgeonotcountry + - ipgeostate + - ipgeonotstate + example: ipgeocountry + title: Segment Operator + type: string + value: + description: The two-letter country code or US state abbreviation. + example: US + title: Segment Data + type: string + required: + - field + - op + - value + title: Location-Based Segment + type: object + - description: Segment by a specific geographic region. + properties: + addr: + description: The address of the target location. + example: "Atlanta, GA, USA" + title: Segment Location Address + type: string + condition_type: + enum: + - IPGeoIn + type: string + x-value: IPGeoIn + field: + description: Segmenting subscribers who are within a specific location. + enum: + - ipgeo + example: ipgeo + title: Segment Field + type: string + lat: + description: The latitude of the target location. + example: "33.7489954" + title: Segment Location Latitude + type: string + lng: + description: The longitude of the target location. + example: "-84.3879824" + title: Segment Location Longitude + type: string + op: + description: Segment members who are within a specific geographic region. + enum: + - ipgeoin + - ipgeonotin + example: ipgeoin + title: Segment Operator + type: string + value: + description: The radius of the target location. + example: 42 + title: Segment Data + type: integer + required: + - field + - op + - value + - addr + - lat + - lng + title: Geolocation Segment + type: object + - description: Segment by a specific US ZIP code. + properties: + condition_type: + enum: + - IPGeoInZip + type: string + x-value: IPGeoInZip + extra: + description: The zip code to segment against. + example: 30318 + title: Extra Data + type: integer + field: + description: Segmenting subscribers who are within a specific location. + enum: + - ipgeo + example: ipgeo + title: Segment Field + type: string + op: + description: Segment members who are within a specific US zip code. + enum: + - ipgeoinzip + example: ipgeoinzip + title: Segment Operator + type: string + value: + description: The radius of the target location. + example: 25 + title: Segment Data + type: integer + required: + - field + - op + - value + - extra + title: US Zip Code Segment + type: object + - description: Segment members whose location information is unknown. + properties: + condition_type: + enum: + - IPGeoUnknown + type: string + x-value: IPGeoUnknown + field: + description: Segmenting subscribers who are within a specific location. + enum: + - ipgeo + example: ipgeo + title: Segment Field + type: string + op: + description: Segment members for which location information is unknown. + enum: + - ipgeounknown + example: ipgeounknown + title: Segment Operator + type: string + required: + - field + - op + title: Unknown Location-Based Segment + type: object + - description: Segment by a specific US ZIP code. + properties: + condition_type: + enum: + - IPGeoZip + type: string + x-value: IPGeoZip + field: + description: Segmenting subscribers who are within a specific location. + enum: + - ipgeo + example: ipgeo + title: Segment Field + type: string + op: + description: Segment members who are/are not within a specific US zip code. + enum: + - ipgeoiszip + - ipgeonotzip + example: ipgeonotzip + title: Segment Operator + type: string + value: + description: The 5-digit zip code. + example: 30318 + title: Segment Data + type: integer + required: + - field + - op + - value + title: Zip Code Location-Based Segment + type: object + - description: Segment by age ranges in Social Profiles data. + properties: + condition_type: + enum: + - SocialAge + type: string + x-value: SocialAge + field: + description: Segment by age ranges in Social Profiles data. + enum: + - social_age + example: social_age + title: Segment Field + type: string + op: + description: Members who are/not the exact criteria listed. + enum: + - is + - not + example: is + title: Segment Operator + type: string + value: + description: The age range to segment. + enum: + - 18-24 + - 25-34 + - 35-54 + - 55+ + example: 35-54 + title: Segment Operator + type: string + required: + - field + - op + - value + title: Social Profiles Age Segment + type: object + - description: Segment by listed gender in Social Profiles data. + properties: + condition_type: + enum: + - SocialGender + type: string + x-value: SocialGender + field: + description: Segment by listed gender in Social Profiles data. + enum: + - social_gender + example: social_gender + title: Segment Field + type: string + op: + description: Members who are/not the exact criteria listed. + enum: + - is + - not + example: is + title: Segment Operator + type: string + value: + description: The Social Profiles gender to segment. + enum: + - male + - female + example: female + title: Segment Operator + type: string + required: + - field + - op + - value + title: Social Profiles Gender Segment + type: object + - description: Segment by influence rating in Social Profiles data. + properties: + condition_type: + enum: + - SocialInfluence + type: string + x-value: SocialInfluence + field: + description: Segment by influence rating in Social Profiles data. + enum: + - social_influence + example: social_influence + title: Segment Field + type: string + op: + description: Members who have a rating that is/not or greater/less than the rating provided. + enum: + - is + - not + - greater + - less + example: greater + title: Segment Operator + type: string + value: + description: The Social Profiles influence rating to segment. + example: 2 + title: Segment Operator + type: number + required: + - field + - op + - value + title: Social Profiles Influence Segment + type: object + - description: Segment by social network in Social Profiles data. + properties: + condition_type: + enum: + - SocialNetworkMember + type: string + x-value: SocialNetworkMember + field: + description: Segment by social network in Social Profiles data. + enum: + - social_network + example: social_network + title: Segment Field + type: string + op: + description: Members who are/not on a given social network. + enum: + - member + - notmember + example: member + title: Segment Operator + type: string + value: + description: The social network to segment against. + enum: + - twitter + - facebook + - linkedin + - flickr + - foursquare + - lastfm + - myspace + - quora + - vimeo + - yelp + - youtube + example: twitter + title: Segment Operator + type: string + required: + - field + - op + - value + title: Social Profiles Social Network Segment + type: object + - description: Segment by social network in Social Profiles data. + properties: + condition_type: + enum: + - SocialNetworkFollow + type: string + x-value: SocialNetworkFollow + field: + description: Segment by social network in Social Profiles data. + enum: + - social_network + example: social_network + title: Segment Field + type: string + op: + description: Members who are/not following a linked account on a given social network. + enum: + - follow + - notfollow + example: follow + title: Segment Operator + type: string + value: + description: The social network to segment against. + enum: + - twitter_follow + example: twitter_follow + title: Segment Operator + type: string + required: + - field + - op + - value + title: Social Profiles Social Network Follow Segment + type: object + - description: Segment by an address-type merge field. + properties: + condition_type: + enum: + - AddressMerge + type: string + x-value: AddressMerge + field: + description: An address-type merge field to segment. + example: MMERGE3 + title: Segment Field + type: string + op: + description: "Whether the member's address merge field contains/does not contain a value or is/is not blank." + enum: + - contains + - notcontain + - blank + - blank_not + example: contains + title: Segment Operator + type: string + value: + description: The value to segment a text merge field with. + example: Atlanta + title: Segment Value + type: string + required: + - field + - op + title: Address Merge Field Segment + type: object + - description: Segment by an address-type merge field within a given distance. + properties: + condition_type: + enum: + - ZipMerge + type: string + x-value: ZipMerge + extra: + description: The city or the zip being used to segment against. + example: "30318" + title: Segment Extra + type: string + field: + description: An address or zip-type merge field to segment. + example: MMERGE2 + title: Segment Field + type: string + op: + description: "Whether the member's address merge field is within a given distance from a city or zip." + enum: + - geoin + example: geoin + title: Segment Operator + type: string + value: + description: The distance from the city/zip. + example: "25" + title: Segment Value + type: string + required: + - field + - op + - value + - extra + title: Address/Zip Merge Field Segment + type: object + - description: "Segment by a contact's birthday." + properties: + condition_type: + enum: + - BirthdayMerge + type: string + x-value: BirthdayMerge + field: + description: A date merge field to segment. + example: MMERGE4 + title: Segment Field + type: string + op: + description: "Whether the member's birthday merge information is/is not a certain date or is/is not blank." + enum: + - is + - not + - blank + - blank_not + example: is + title: Segment Operator + type: string + value: + description: A date to segment against (mm/dd). + example: 01/30 + title: Segment Value + type: string + required: + - field + - op + title: Birthday Merge Field Segment + type: object + - description: Segment by a given date merge field. + properties: + condition_type: + enum: + - DateMerge + type: string + x-value: DateMerge + field: + description: A date merge field to segment. + example: MMERGE5 + title: Segment Field + type: string + op: + description: "Whether the member's merge information is/is not, is greater/less than a value or is/is not blank." + enum: + - is + - not + - less + - blank + - blank_not + - greater + example: is + title: Segment Operator + type: string + value: + description: A date to segment against. + example: 01/30/2015 + title: Segment Value + type: string + required: + - field + - op + title: Date Merge Field Segment + type: object + - description: An individual segment condition + properties: + condition_type: + enum: + - SelectMerge + type: string + x-value: SelectMerge + field: + description: A merge field to segment. + example: MMERGE6 + title: Segment Field + type: string + op: + description: "Whether the member's merge information is/is not a value or is/is not blank." + enum: + - is + - not + - blank + - blank_not + - notcontain + - contains + example: is + title: Segment Operator + type: string + value: + description: The value to segment a text merge field with. + example: Second Choice + title: Segment Value + type: string + required: + - field + - op + title: Dropdown/Radio Merge Field Segment + type: object + - description: Segment by a given text or number merge field. + properties: + condition_type: + enum: + - TextMerge + type: string + x-value: TextMerge + field: + description: A text or number merge field to segment. + example: MMERGE7 + title: Segment Field + type: string + op: + description: "Whether the member's merge information is/is not, contains/does not contain, starts/ends with, or is greater/less than a value" + enum: + - is + - not + - contains + - notcontain + - starts + - ends + - greater + - less + - blank + - blank_not + example: contains + title: Segment Operator + type: string + value: + description: The value to segment a text or number merge field with. + example: "Freddie's Jokes" + title: Segment Value + type: string + required: + - field + - op + title: Text or Number Merge Field Segment + type: object + - description: Segment by email address. + properties: + condition_type: + enum: + - EmailAddress + type: string + x-value: EmailAddress + field: + description: "Segmenting based off of a subscriber's email address." + enum: + - merge0 + - EMAIL + example: EMAIL + title: Segment Field + type: string + op: + description: "Whether the email address is/not exactly, contains/doesn't contain, starts/ends with a string." + enum: + - is + - not + - contains + - notcontain + - starts + - ends + - greater + - less + title: Segment Operator + type: string + value: + description: The value to compare the email against. + example: urist.mcvankab@freddiesjokes.com + title: Segment Value + type: string + required: + - field + - op + title: Email Segment + type: object + - description: Segment by predicted gender. + properties: + condition_type: + enum: + - PredictedGender + type: string + x-value: PredictedGender + field: + description: Segment by predicted gender. + enum: + - predicted_gender + title: Segment Field + type: string + op: + description: Members who are/not the exact criteria listed. + enum: + - is + - not + example: is + title: Segment Operator + type: string + value: + description: The predicted gender to segment. + enum: + - male + - female + example: female + title: Segment Operator + type: string + required: + - field + - op + - value + title: Predicted Gender Segment + type: object + - description: Segment by predicted age. + properties: + condition_type: + enum: + - PredictedAge + type: string + x-value: PredictedAge + field: + description: Segment by predicted age. + enum: + - predicted_age_range + title: Segment Field + type: string + op: + description: Members who are/not the exact criteria listed. + enum: + - is + example: is + title: Segment Operator + type: string + value: + description: The predicted age to segment. + enum: + - 18-24 + - 25-34 + - 35-44 + - 45-54 + - 55-64 + - 65+ + example: female + title: Segment Operator + type: string + required: + - field + - op + - value + title: Predicted Age Segment + type: object + - description: Segment by when people subscribed. + properties: + condition_type: + enum: + - NewSubscribers + type: string + x-value: NewSubscribers + field: + description: Segment by when people subscribed. + enum: + - timestamp_opt + title: Segment Field + type: string + op: + description: "Whe the event took place, namely within a time frame." + enum: + - date_within + title: Segment Operator + type: string + value: + description: "What type of data to segment on: a specific date, a specific campaign, or the last campaign sent." + title: Segment Data + type: string + title: New Subscribers Prebuilt Segment + type: object + x-discriminator: + propertyName: condition_type + title: Segment Type + type: array + match: + description: Segment match type. + title: Match Type + type: string + prebuilt_segment_id: + description: "The prebuilt segment id, if a prebuilt segment has been designated for this campaign." + example: subscribers-female + title: Prebuilt Segment Id + type: string + saved_segment_id: + description: The id for an existing saved segment. + title: Saved Segment ID + type: integer + title: Segment Options + type: object + segment_text: + description: "A description of the [segment](https://mailchimp.com/help/create-and-send-to-a-segment/) used for the campaign. Formatted as a string marked up with HTML." + readOnly: true + title: Segment Text + type: string + title: List + type: object + report_summary: + description: "For sent campaigns, a summary of opens, clicks, and e-commerce data." + properties: + click_rate: + description: The number of unique clicks divided by the total number of successful deliveries. + readOnly: true + title: Click Rate + type: number + clicks: + description: The total number of clicks for an campaign. + readOnly: true + title: Total Clicks + type: integer + ecommerce: + description: E-Commerce stats for a campaign. + properties: + total_orders: + description: The total orders for a campaign. + readOnly: true + title: Total Orders + type: integer + total_revenue: + description: The total revenue for a campaign. Calculated as the sum of all order totals minus shipping and tax totals. + readOnly: true + title: Total Revenue + type: number + total_spent: + description: The total spent for a campaign. Calculated as the sum of all order totals with no deductions. + readOnly: true + title: Total Spent + type: number + title: E-Commerce Report + type: object + open_rate: + description: The number of unique opens divided by the total number of successful deliveries. + readOnly: true + title: Open Rate + type: number + opens: + description: The total number of opens for a campaign. + readOnly: true + title: Automation Opens + type: integer + subscriber_clicks: + description: The number of unique clicks. + readOnly: true + title: Unique Subscriber Clicks + type: integer + unique_opens: + description: The number of unique opens. + readOnly: true + title: Unique Opens + type: integer + title: Campaign Report Summary + type: object + resendable: + description: Determines if the campaign qualifies to be resent to non-openers. + readOnly: true + title: Resendable + type: boolean + rss_opts: + description: "[RSS](https://mailchimp.com/help/share-your-blog-posts-with-mailchimp/) options for a campaign." + properties: + constrain_rss_img: + description: Whether to add CSS to images in the RSS feed to constrain their width in campaigns. + title: Constrain RSS Images + type: boolean + feed_url: + description: The URL for the RSS feed. + format: uri + title: Feed URL + type: string + frequency: + description: The frequency of the RSS Campaign. + title: Frequency + type: string + last_sent: + description: The date the campaign was last sent. + readOnly: true + title: Last Sent + type: string + schedule: + description: The schedule for sending the RSS Campaign. + properties: + daily_send: + description: The days of the week to send a daily RSS Campaign. + properties: + friday: + description: Sends the daily RSS Campaign on Fridays. + title: Friday + type: boolean + monday: + description: Sends the daily RSS Campaign on Mondays. + title: Monday + type: boolean + saturday: + description: Sends the daily RSS Campaign on Saturdays. + title: Saturday + type: boolean + sunday: + description: Sends the daily RSS Campaign on Sundays. + title: Sunday + type: boolean + thursday: + description: Sends the daily RSS Campaign on Thursdays. + title: Thursday + type: boolean + tuesday: + description: Sends the daily RSS Campaign on Tuesdays. + title: tuesday + type: boolean + wednesday: + description: Sends the daily RSS Campaign on Wednesdays. + title: Monday + type: boolean + title: Daily Sending Days + type: object + hour: + description: "The hour to send the campaign in local time. Acceptable hours are 0-23. For example, '4' would be 4am in [your account's default time zone](https://mailchimp.com/help/set-account-defaults/)." + maximum: 23 + minimum: 0 + title: Sending Hour + type: integer + monthly_send_date: + description: "The day of the month to send a monthly RSS Campaign. Acceptable days are 0-31, where '0' is always the last day of a month. Months with fewer than the selected number of days will not have an RSS campaign sent out that day. For example, RSS Campaigns set to send on the 30th will not go out in February." + maximum: 31 + minimum: 0 + title: Monthly Sending Day + type: number + weekly_send_day: + description: The day of the week to send a weekly RSS Campaign. + title: Weekly Sending Day + type: string + title: Sending Schedule + type: object + title: RSS Options + type: object + send_time: + description: The date and time a campaign was sent. + readOnly: true + title: Send Time + type: string + settings: + description: "The settings for your campaign, including subject, from name, reply-to address, and more." + properties: + authenticate: + description: "Whether Mailchimp [authenticated](https://mailchimp.com/help/about-email-authentication/) the campaign. Defaults to `true`." + title: Authentication + type: boolean + auto_fb_post: + description: "An array of [Facebook](https://mailchimp.com/help/connect-or-disconnect-the-facebook-integration/) page ids to auto-post to." + items: + type: string + title: Auto Post to Facebook + type: array + auto_footer: + description: "Automatically append Mailchimp's [default footer](https://mailchimp.com/help/about-campaign-footers/) to the campaign." + title: Auto-Footer + type: boolean + auto_tweet: + description: "Automatically tweet a link to the [campaign archive](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) page when the campaign is sent." + title: Auto-Tweet + type: boolean + drag_and_drop: + description: Whether the campaign uses the drag-and-drop editor. + readOnly: true + title: Drag And Drop Campaign + type: boolean + fb_comments: + description: "Allows Facebook comments on the campaign (also force-enables the Campaign Archive toolbar). Defaults to `true`." + title: Facebook Comments + type: boolean + folder_id: + description: "If the campaign is listed in a folder, the id for that folder." + title: Folder ID + type: string + from_name: + description: "The 'from' name on the campaign (not an email address)." + title: From Name + type: string + inline_css: + description: Automatically inline the CSS included with the campaign content. + title: Inline CSS + type: boolean + preview_text: + description: The preview text for the campaign. + title: Campaign Preview Text + type: string + reply_to: + description: The reply-to email address for the campaign. + title: Reply To Address + type: string + subject_line: + description: The subject line for the campaign. + title: Campaign Subject Line + type: string + template_id: + description: The id for the template used in this campaign. + readOnly: false + title: Template ID + type: integer + timewarp: + description: "Send this campaign using [Timewarp](https://mailchimp.com/help/use-timewarp/)." + readOnly: true + title: Timewarp Send + type: boolean + title: + description: The title of the campaign. + title: Campaign Title + type: string + to_name: + description: "The campaign's custom 'To' name. Typically the first name [merge field](https://mailchimp.com/help/getting-started-with-merge-tags/)." + title: To Name + type: string + use_conversation: + description: Use Mailchimp Conversation feature to manage out-of-office replies. + title: Conversation + type: boolean + title: Campaign Settings + type: object + social_card: + description: "The preview for the campaign, rendered by social networks like Facebook and Twitter. [Learn more](https://mailchimp.com/help/enable-and-customize-social-cards/)." + properties: + description: + description: A short summary of the campaign to display. + title: Campaign Description + type: string + image_url: + description: The url for the header image for the card. + title: Image URL + type: string + title: + description: The title for the card. Typically the subject line of the campaign. + title: Title + type: string + title: Campaign Social Card + type: object + status: + description: The current status of the campaign. + readOnly: true + title: Campaign Status + type: string + tracking: + description: The tracking options for a campaign. + properties: + capsule: + description: "Capsule tracking options for a campaign. Must be using Mailchimp's built-in Capsule integration." + properties: + notes: + description: Update contact notes for a campaign based on subscriber email addresses. + title: Capsule Note + type: boolean + title: Capsule CRM Tracking + type: object + clicktale: + description: "The custom slug for [ClickTale](https://mailchimp.com/help/additional-tracking-options-for-campaigns/) tracking (max of 50 bytes)." + title: ClickTale Analytics Tracking + type: string + ecomm360: + description: "Whether to enable [eCommerce360](https://mailchimp.com/help/connect-your-online-store-to-mailchimp/) tracking." + title: E-commerce Tracking + type: boolean + goal_tracking: + description: "Whether to enable [Goal](https://mailchimp.com/help/about-connected-sites/) tracking." + title: Mailchimp Goal Tracking + type: boolean + google_analytics: + description: "The custom slug for [Google Analytics](https://mailchimp.com/help/integrate-google-analytics-with-mailchimp/) tracking (max of 50 bytes)." + title: Google Analytics Tracking + type: string + html_clicks: + description: "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the HTML version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns." + title: HTML Click Tracking + type: boolean + opens: + description: "Whether to [track opens](https://mailchimp.com/help/about-open-tracking/). Defaults to `true`. Cannot be set to false for variate campaigns." + title: Opens + type: boolean + salesforce: + description: "Salesforce tracking options for a campaign. Must be using Mailchimp's built-in [Salesforce integration](https://mailchimp.com/help/integrate-salesforce-with-mailchimp/)." + properties: + campaign: + description: Create a campaign in a connected Salesforce account. + title: Salesforce Campaign + type: boolean + notes: + description: Update contact notes for a campaign based on subscriber email addresses. + title: Salesforce Note + type: boolean + title: Salesforce CRM Tracking + type: object + text_clicks: + description: "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the plain-text version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns." + title: Plain-Text Click Tracking + type: boolean + title: Campaign Tracking Options + type: object + type: + description: "There are four types of [campaigns](https://mailchimp.com/help/getting-started-with-campaigns/) you can create in Mailchimp. A/B Split campaigns have been deprecated and variate campaigns should be used instead." + title: Campaign Type + type: string + variate_settings: + description: The settings specific to A/B test campaigns. + properties: + combinations: + description: Combinations of possible variables used to build emails. + items: + properties: + content_description: + description: "The index of `variate_settings.contents` used." + title: Content Description + type: integer + from_name: + description: "The index of `variate_settings.from_names` used." + title: From Name + type: integer + id: + description: Unique ID for the combination. + title: ID + type: string + recipients: + description: The number of recipients for this combination. + title: Recipients + type: integer + reply_to: + description: "The index of `variate_settings.reply_to_addresses` used." + title: Reply To + type: integer + send_time: + description: "The index of `variate_settings.send_times` used." + title: Send Time + type: integer + subject_line: + description: "The index of `variate_settings.subject_lines` used." + title: Subject Line + type: integer + type: object + readOnly: true + title: Combinations + type: array + contents: + description: "Descriptions of possible email contents. To set campaign contents, make a PUT request to /campaigns/{campaign_id}/content with the field 'variate_contents'." + items: + type: string + readOnly: true + title: Content Descriptions + type: array + from_names: + description: "The possible from names. The number of from_names provided must match the number of reply_to_addresses. If no from_names are provided, settings.from_name will be used." + items: + type: string + title: From Names + type: array + reply_to_addresses: + description: "The possible reply-to addresses. The number of reply_to_addresses provided must match the number of from_names. If no reply_to_addresses are provided, settings.reply_to will be used." + items: + type: string + title: Reply To Addresses + type: array + send_times: + description: "The possible send times to test. The times provided should be in the format YYYY-MM-DD HH:MM:SS. If send_times are provided to test, the test_size will be set to 100% and winner_criteria will be ignored." + items: + type: string + title: Send Times + type: array + subject_lines: + description: "The possible subject lines to test. If no subject lines are provided, settings.subject_line will be used." + items: + type: string + title: Subject Lines + type: array + test_size: + description: "The percentage of recipients to send the test combinations to, must be a value between 10 and 100." + title: Test Size + type: integer + wait_time: + description: "The number of minutes to wait before choosing the winning campaign. The value of wait_time must be greater than 0 and in whole hours, specified in minutes." + title: Wait Time + type: integer + winner_criteria: + description: "The combination that performs the best. This may be determined automatically by click rate, open rate, or total revenue -- or you may choose manually based on the reporting data you find the most valuable. For Multivariate Campaigns testing send_time, winner_criteria is ignored. For Multivariate Campaigns with 'manual' as the winner_criteria, the winner must be chosen in the Mailchimp web application." + title: Winning Criteria + type: string + winning_campaign_id: + description: ID of the campaign that was sent to the remaining recipients based on the winning combination. + readOnly: true + title: Winning Campaign ID + type: string + winning_combination_id: + description: ID for the winning combination. + readOnly: true + title: Winning Combination ID + type: string + title: A/B Test Options + type: object + web_id: + description: "The ID used in the Mailchimp web application. View this campaign in your Mailchimp account at `https://{dc}.admin.mailchimp.com/campaigns/show/?id={web_id}`." + readOnly: true + title: Campaign Web ID + type: integer +required: + - id +title: Campaign +type: object diff --git a/source-mailchimp/acmeCo/email_activity.schema.yaml b/source-mailchimp/acmeCo/email_activity.schema.yaml new file mode 100644 index 0000000000..745521e673 --- /dev/null +++ b/source-mailchimp/acmeCo/email_activity.schema.yaml @@ -0,0 +1,56 @@ +--- +description: "A list of member's subscriber activity in a specific campaign." +properties: + action: + description: "One of the following actions: 'open', 'click', or 'bounce'" + title: action + type: string + campaign_id: + description: The unique id for the campaign. + title: The unique id for the campaign. + type: string + email_address: + description: Email address for a subscriber. + title: Email address for a subscriber. + type: string + email_id: + description: "The MD5 hash of the lowercase version of the list member's email address." + title: email MD5 hash. + type: string + ip: + description: The IP address recorded for the action. + title: Action ip address + type: + - string + - "null" + list_id: + description: The unique id for the list. + title: The unique id for the list. + type: string + list_is_active: + description: "The status of the list used, namely if it's deleted or disabled." + title: The status of the list used. + type: boolean + timestamp: + description: The date and time recorded for the action in ISO 8601 format. + format: date-time + title: Action date and time + type: string + type: + description: "If the action is a 'bounce', the type of bounce received: 'hard', 'soft'." + title: Type + type: + - string + - "null" + url: + description: "If the action is a 'click', the URL on which the member clicked." + title: Click url + type: + - string + - "null" +required: + - timestamp + - email_id + - action +title: Email Activity +type: object diff --git a/source-mailchimp/acmeCo/flow.yaml b/source-mailchimp/acmeCo/flow.yaml new file mode 100644 index 0000000000..83fcaf0811 --- /dev/null +++ b/source-mailchimp/acmeCo/flow.yaml @@ -0,0 +1,20 @@ +--- +collections: + acmeCo/campaigns: + schema: campaigns.schema.yaml + key: + - /id + acmeCo/email_activity: + schema: email_activity.schema.yaml + key: + - /timestamp + - /email_id + - /action + acmeCo/lists: + schema: lists.schema.yaml + key: + - /id + acmeCo/reports: + schema: reports.schema.yaml + key: + - /id diff --git a/source-mailchimp/acmeCo/lists.schema.yaml b/source-mailchimp/acmeCo/lists.schema.yaml new file mode 100644 index 0000000000..03f1e089c9 --- /dev/null +++ b/source-mailchimp/acmeCo/lists.schema.yaml @@ -0,0 +1,246 @@ +--- +description: Information about a specific list. +properties: + beamer_address: + description: "The list's [Email Beamer](https://mailchimp.com/help/use-email-beamer-to-create-a-campaign/) address." + readOnly: true + title: Beamer Address + type: string + campaign_defaults: + description: "[Default values for campaigns](https://mailchimp.com/help/edit-your-emails-subject-preview-text-from-name-or-from-email-address/) created for this list." + properties: + from_email: + description: The default from email for campaigns sent to this list. + title: "Sender's Email Address" + type: string + from_name: + description: The default from name for campaigns sent to this list. + title: "Sender's Name" + type: string + language: + description: "The default language for this lists's forms." + title: Language + type: string + subject: + description: The default subject line for campaigns sent to this list. + title: Subject + type: string + title: Campaign Defaults + type: object + contact: + description: "[Contact information displayed in campaign footers](https://mailchimp.com/help/about-campaign-footers/) to comply with international spam laws." + properties: + address1: + description: The street address for the list contact. + title: Address + type: string + address2: + description: The street address for the list contact. + title: Address + type: string + city: + description: The city for the list contact. + title: City + type: string + company: + description: The company name for the list. + title: Company Name + type: string + country: + description: A two-character ISO3166 country code. Defaults to US if invalid. + title: Country Code + type: string + phone: + description: The phone number for the list contact. + title: Phone Number + type: string + state: + description: The state for the list contact. + title: State + type: string + zip: + description: The postal or zip code for the list contact. + title: Postal Code + type: string + title: List Contact + type: object + date_created: + description: The date and time that this list was created in ISO 8601 format. + format: date-time + readOnly: true + title: Creation Date + type: string + double_optin: + default: false + description: Whether or not to require the subscriber to confirm subscription via email. + title: Double Opt In + type: boolean + email_type_option: + description: "Whether the list supports [multiple formats for emails](https://mailchimp.com/help/change-list-name-and-defaults/). When set to `true`, subscribers can choose whether they want to receive HTML or plain-text emails. When set to `false`, subscribers will receive HTML emails, with a plain-text alternative backup." + title: Email Type Option + type: boolean + has_welcome: + default: false + description: "Whether or not this list has a welcome automation connected. Welcome Automations: welcomeSeries, singleWelcome, emailFollowup." + example: false + title: Has Welcome + type: boolean + id: + description: A string that uniquely identifies this list. + readOnly: true + title: List ID + type: string + list_rating: + description: An auto-generated activity score for the list (0-5). + readOnly: true + title: List Rating + type: integer + marketing_permissions: + default: false + description: Whether or not the list has marketing permissions (eg. GDPR) enabled. + title: Marketing Permissions + type: boolean + modules: + description: Any list-specific modules installed for this list. + items: + type: string + readOnly: true + title: Modules + type: array + name: + description: The name of the list. + title: List Name + type: string + notify_on_subscribe: + default: "false" + description: "The email address to send [subscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to." + title: Notify on Subscribe + type: string + notify_on_unsubscribe: + default: "false" + description: "The email address to send [unsubscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to." + title: Notify on Unsubscribe + type: string + permission_reminder: + description: "The [permission reminder](https://mailchimp.com/help/edit-the-permission-reminder/) for the list." + title: Permission Reminder + type: string + stats: + description: Stats for the list. Many of these are cached for at least five minutes. + properties: + avg_sub_rate: + description: "The average number of subscriptions per month for the list (not returned if we haven't calculated it yet)." + readOnly: true + title: Average Subscription Rate + type: number + avg_unsub_rate: + description: "The average number of unsubscriptions per month for the list (not returned if we haven't calculated it yet)." + readOnly: true + title: Average Unsubscription Rate + type: number + campaign_count: + description: The number of campaigns in any status that use this list. + readOnly: true + title: Campaign Count + type: integer + campaign_last_sent: + description: The date and time the last campaign was sent to this list in ISO 8601 format. This is updated when a campaign is sent to 10 or more recipients. + readOnly: true + title: Campaign Last Sent + type: string + cleaned_count: + description: The number of members cleaned from the list. + readOnly: true + title: Cleaned Count + type: integer + cleaned_count_since_send: + description: The number of members cleaned from the list since the last campaign was sent. + readOnly: true + title: Cleaned Count Since Send + type: integer + click_rate: + description: "The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet)." + readOnly: true + title: Click Rate + type: number + last_sub_date: + description: The date and time of the last time someone subscribed to this list in ISO 8601 format. + readOnly: true + title: Date of Last List Subscribe + type: string + last_unsub_date: + description: The date and time of the last time someone unsubscribed from this list in ISO 8601 format. + readOnly: true + title: Date of Last List Unsubscribe + type: string + member_count: + description: The number of active members in the list. + readOnly: true + title: Member Count + type: integer + member_count_since_send: + description: The number of active members in the list since the last campaign was sent. + readOnly: true + title: Member Count Since Send + type: integer + merge_field_count: + description: "The number of merge vars for this list (not EMAIL, which is required)." + readOnly: true + title: Merge Var Count + type: integer + open_rate: + description: "The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet)." + readOnly: true + title: Open Rate + type: number + target_sub_rate: + description: "The target number of subscriptions per month for the list to keep it growing (not returned if we haven't calculated it yet)." + readOnly: true + title: Average Subscription Rate + type: number + total_contacts: + description: "The number of contacts in the list, including subscribed, unsubscribed, pending, cleaned, deleted, transactional, and those that need to be reconfirmed." + readOnly: true + title: Total Contacts + type: integer + unsubscribe_count: + description: The number of members who have unsubscribed from the list. + readOnly: true + title: Unsubscribe Count + type: integer + unsubscribe_count_since_send: + description: The number of members who have unsubscribed since the last campaign was sent. + readOnly: true + title: Unsubscribe Count Since Send + type: integer + readOnly: true + title: Statistics + type: object + subscribe_url_long: + description: "The full version of this list's subscribe form (host will vary)." + readOnly: true + title: Subscribe URL Long + type: string + subscribe_url_short: + description: "Our [EepURL shortened](https://mailchimp.com/help/share-your-signup-form/) version of this list's subscribe form." + readOnly: true + title: Subscribe URL Short + type: string + use_archive_bar: + default: false + description: "Whether campaigns for this list use the [Archive Bar](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) in archives by default." + title: Use Archive Bar + type: boolean + visibility: + description: "Whether this list is [public or private](https://mailchimp.com/help/about-list-publicity/)." + title: Visibility + type: string + web_id: + description: "The ID used in the Mailchimp web application. View this list in your Mailchimp account at `https://{dc}.admin.mailchimp.com/lists/members/?id={web_id}`." + readOnly: true + title: List Web ID + type: integer +required: + - id +title: Subscriber List +type: object diff --git a/source-mailchimp/acmeCo/reports.schema.yaml b/source-mailchimp/acmeCo/reports.schema.yaml new file mode 100644 index 0000000000..e6cd4a6dd1 --- /dev/null +++ b/source-mailchimp/acmeCo/reports.schema.yaml @@ -0,0 +1,444 @@ +--- +description: A list of reports containing campaigns marked as Sent. +properties: + ab_split: + description: General stats about different groups of an A/B Split campaign. Does not return information about Multivariate Campaigns. + properties: + a: + description: Stats for Campaign A. + properties: + abuse_reports: + description: Abuse reports for Campaign A. + title: Abuse Reports + type: integer + bounces: + description: Bounces for Campaign A. + title: Bounces + type: integer + forwards: + description: Forwards for Campaign A. + title: Forwards + type: integer + forwards_opens: + description: Opens from forwards for Campaign A. + title: Forward Opens + type: integer + last_open: + description: The last open for Campaign A. + title: Last Open + type: string + opens: + description: Opens for Campaign A. + title: Opens + type: integer + recipient_clicks: + description: Recipient Clicks for Campaign A. + title: Recipient Clicks + type: integer + unique_opens: + description: Unique opens for Campaign A. + title: Unique Opens + type: integer + unsubs: + description: Unsubscribes for Campaign A. + title: Unsubscribes + type: integer + title: Campaign A + type: object + b: + description: Stats for Campaign B. + properties: + abuse_reports: + description: Abuse reports for Campaign B. + title: Abuse Reports + type: integer + bounces: + description: Bounces for Campaign B. + title: Bounces + type: integer + forwards: + description: Forwards for Campaign B. + title: Forwards + type: integer + forwards_opens: + description: Opens for forwards from Campaign B. + title: Forward Opens + type: integer + last_open: + description: The last open for Campaign B. + title: Last Open + type: string + opens: + description: Opens for Campaign B. + title: Opens + type: integer + recipient_clicks: + description: Recipients clicks for Campaign B. + title: Recipient Clicks + type: integer + unique_opens: + description: Unique opens for Campaign B. + title: Unique Opens + type: integer + unsubs: + description: Unsubscribes for Campaign B. + title: Unsubscribes + type: integer + title: Campaign B + type: object + title: A/B Split Stats + type: object + abuse_reports: + description: The number of abuse reports generated for this campaign. + title: Abuse Reports + type: integer + bounces: + description: An object describing the bounce summary for the campaign. + properties: + hard_bounces: + description: The total number of hard bounced email addresses. + title: Hard Bounces + type: integer + soft_bounces: + description: The total number of soft bounced email addresses. + title: Soft Bounces + type: integer + syntax_errors: + description: The total number of addresses that were syntax-related bounces. + title: Syntax Errors + type: integer + title: Bounces + type: object + campaign_title: + description: The title of the campaign. + readOnly: true + title: Campaign Title + type: string + clicks: + description: An object describing the click activity for the campaign. + properties: + click_rate: + description: The number of unique clicks divided by the total number of successful deliveries. + title: Click Rate + type: number + clicks_total: + description: The total number of clicks for the campaign. + title: Total Clicks + type: integer + last_click: + description: The date and time of the last recorded click for the campaign in ISO 8601 format. + format: date-time + title: Last Click + type: string + unique_clicks: + description: The total number of unique clicks for links across a campaign. + title: Unique Clicks + type: integer + unique_subscriber_clicks: + description: The total number of subscribers who clicked on a campaign. + title: Unique Subscriber Clicks + type: integer + title: Clicks + type: object + delivery_status: + description: Updates on campaigns in the process of sending. + properties: + can_cancel: + description: Whether a campaign send can be canceled. + readOnly: true + title: Campaign Cancelable + type: boolean + emails_canceled: + description: The total number of emails canceled for this campaign. + readOnly: true + title: Emails Canceled + type: integer + emails_sent: + description: The total number of emails confirmed sent for this campaign so far. + readOnly: true + title: Emails Sent + type: integer + enabled: + description: Whether Campaign Delivery Status is enabled for this account and campaign. + readOnly: true + title: Delivery Status Enabled + type: boolean + status: + description: The current state of a campaign delivery. + readOnly: true + title: Campaign Delivery Status + type: string + title: Campaign Delivery Status + type: object + ecommerce: + description: E-Commerce stats for a campaign. + properties: + currency_code: + example: USD + readOnly: true + title: Three letter currency code for this user + type: string + total_orders: + description: The total orders for a campaign. + readOnly: true + title: Total Orders + type: integer + total_revenue: + description: The total revenue for a campaign. Calculated as the sum of all order totals minus shipping and tax totals. + readOnly: true + title: Total Revenue + type: number + total_spent: + description: The total spent for a campaign. Calculated as the sum of all order totals with no deductions. + readOnly: true + title: Total Spent + type: number + title: E-Commerce Report + type: object + emails_sent: + description: The total number of emails sent for this campaign. + title: Emails Sent + type: integer + facebook_likes: + description: An object describing campaign engagement on Facebook. + properties: + facebook_likes: + description: The number of Facebook likes for the campaign. + title: Facebook Likes + type: integer + recipient_likes: + description: The number of recipients who liked the campaign on Facebook. + title: Recipient Likes + type: integer + unique_likes: + description: The number of unique likes. + title: Unique Likes + type: integer + title: Facebook Likes + type: object + forwards: + description: An object describing the forwards and forward activity for the campaign. + properties: + forwards_count: + description: How many times the campaign has been forwarded. + title: Total Forwards + type: integer + forwards_opens: + description: How many times the forwarded campaign has been opened. + title: Forward Opens + type: integer + title: Forwards + type: object + id: + description: A string that uniquely identifies this campaign. + title: Campaign ID + type: string + industry_stats: + description: The average campaign statistics for your industry. + properties: + abuse_rate: + description: The industry abuse rate. + title: Abuse Rate + type: number + bounce_rate: + description: The industry bounce rate. + title: Bounce Rate + type: number + click_rate: + description: The industry click rate. + title: Click Rate + type: number + open_rate: + description: The industry open rate. + title: Open Rate + type: number + type: + description: "The type of business industry associated with your account. For example: retail, education, etc." + title: Industry Type + type: string + unopen_rate: + description: The industry unopened rate. + title: Unopened Rate + type: number + unsub_rate: + description: The industry unsubscribe rate. + title: Unsubscribe Rate + type: number + title: Industry Stats + type: object + list_id: + description: The unique list id. + readOnly: true + title: List ID + type: string + list_is_active: + description: "The status of the list used, namely if it's deleted or disabled." + readOnly: true + title: List Status + type: boolean + list_name: + description: The name of the list. + readOnly: true + title: List Name + type: string + list_stats: + description: "The average campaign statistics for your list. This won't be present if we haven't calculated it yet for this list." + properties: + click_rate: + description: The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list. + readOnly: true + title: Click Rate + type: number + open_rate: + description: The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list. + readOnly: true + title: Open Rate + type: number + sub_rate: + description: The average number of subscriptions per month for the list. + readOnly: true + title: Average Subscription Rate + type: number + unsub_rate: + description: The average number of unsubscriptions per month for the list. + readOnly: true + title: Average Unsubscription Rate + type: number + title: List Stats + type: object + opens: + description: An object describing the open activity for the campaign. + properties: + last_open: + description: The date and time of the last recorded open in ISO 8601 format. + format: date-time + title: Last Open + type: string + open_rate: + description: The number of unique opens divided by the total number of successful deliveries. + title: Open Rate + type: number + opens_total: + description: The total number of opens for a campaign. + title: Total Opens + type: integer + unique_opens: + description: The total number of unique opens. + title: Unique Opens + type: integer + title: Opens + type: object + preview_text: + description: The preview text for the campaign. + title: Campaign Preview Text + type: string + rss_last_send: + description: "For RSS campaigns, the date and time of the last send in ISO 8601 format." + format: date-time + readOnly: true + title: RSS Last Send + type: string + send_time: + description: The date and time a campaign was sent in ISO 8601 format. + format: date-time + readOnly: true + title: Send Time + type: string + share_report: + description: "The url and password for the [VIP report](https://mailchimp.com/help/share-a-campaign-report/)." + properties: + share_password: + description: "If password protected, the password for the VIP report." + readOnly: true + title: Report Password + type: string + share_url: + description: The URL for the VIP report. + readOnly: true + title: Report URL + type: string + title: Share Report + type: object + subject_line: + description: The subject line for the campaign. + readOnly: true + title: Campaign Subject Line + type: string + timeseries: + description: An hourly breakdown of the performance of the campaign over the first 24 hours. + items: + properties: + emails_sent: + description: The number of emails sent in the timeseries. + title: Emails Sent + type: integer + recipients_clicks: + description: The number of clicks in the timeseries. + title: Recipient Clicks + type: integer + timestamp: + description: The date and time for the series in ISO 8601 format. + format: date-time + title: Timestamp + type: string + unique_opens: + description: The number of unique opens in the timeseries. + title: Unique Opens + type: integer + type: object + title: Timeseries + type: array + timewarp: + description: "An hourly breakdown of sends, opens, and clicks if a campaign is sent using timewarp." + items: + properties: + bounces: + description: The number of bounces. + title: Bounces + type: integer + clicks: + description: The number of clicks. + title: Clicks + type: integer + gmt_offset: + description: "For campaigns sent with timewarp, the time zone group the member is apart of." + title: GMT Offset + type: integer + last_click: + description: The date and time of the last click in ISO 8601 format. + format: date-time + title: Last Click + type: string + last_open: + description: The date and time of the last open in ISO 8601 format. + format: date-time + title: Last Open + type: string + opens: + description: The number of opens. + title: Opens + type: integer + unique_clicks: + description: The number of unique clicks. + title: Unique Clicks + type: integer + unique_opens: + description: The number of unique opens. + title: Unique Opens + type: integer + type: object + title: Timewarp Stats + type: array + type: + description: "The type of campaign (regular, plain-text, ab_split, rss, automation, variate, or auto)." + title: Campaign Type + type: string + unsubscribed: + description: The total number of unsubscribed members for this campaign. + readOnly: true + title: Unsubscribe Count + type: integer +required: + - id +title: Campaign Reports +type: object diff --git a/source-mailchimp/config.yaml b/source-mailchimp/config.yaml new file mode 100644 index 0000000000..5eaebc7894 --- /dev/null +++ b/source-mailchimp/config.yaml @@ -0,0 +1,17 @@ +credentials: + auth_type: apikey + apikey_sops: ENC[AES256_GCM,data:4B/VTwYCkB2uc3QM0DBRk757/eqaJ1FzAdwbwbgkVzpCtgv3tQ==,iv:CleHnlAI6iCB6oRxIoYVJ4Oaw6QBOBlB8RgwDrDzeSU=,tag:+pdWVoiHyOHh1uczEMGJxg==,type:str] +sops: + kms: [] + gcp_kms: + - resource_id: projects/estuary-theatre/locations/us-central1/keyRings/connector-keyring/cryptoKeys/connector-repository + created_at: "2024-04-26T02:11:51Z" + enc: CiQAdmEdwpe7go7loWHFoP1QD0mqsGfqLq1/3jJuZSlmkJmPhmASSQCSobQjpuhj0SICJqn2EBxhNXDcndy4FOOhsMoxDwj7BbazTokCBtTFI1AA2jjllh0LxVoOa8+C2KJpQxGAQayZ2kq2XIzldCI= + azure_kv: [] + hc_vault: [] + age: [] + lastmodified: "2024-04-26T02:11:52Z" + mac: ENC[AES256_GCM,data:l2QNjQI5oHC4T93MqB9LQCPkInF4sf2X1CjYTbmIcUgQnniHHNFAHMwT0SbYg0IcQwMJEJoItEoVqhA1dpc9M4n9TbIios2PFPUvdYPeiJb1B9NXGaMQDZ25H7GSG1SQ12Dw4fjGjyGYvyuAgo5Ok/kXuhTsQYE0VWY8vd0gBmM=,iv:y0JMPEGuUcyRS99GSK2qfAwFNCXGdm22xUcplyaLMoY=,tag:L1Gby/By5gJ1DluYUNOg5g==,type:str] + pgp: [] + encrypted_suffix: _sops + version: 3.8.1 diff --git a/source-mailchimp/test.flow.yaml b/source-mailchimp/test.flow.yaml new file mode 100644 index 0000000000..0be6c0a374 --- /dev/null +++ b/source-mailchimp/test.flow.yaml @@ -0,0 +1,34 @@ +--- +import: + - acmeCo/flow.yaml +captures: + acmeCo/source-mailchimp: + endpoint: + connector: + image: "ghcr.io/estuary/source-mailchimp:v2" + config: config.yaml + bindings: + - resource: + stream: lists + syncMode: incremental + cursorField: + - date_created + target: acmeCo/lists + - resource: + stream: campaigns + syncMode: incremental + cursorField: + - create_time + target: acmeCo/campaigns + - resource: + stream: email_activity + syncMode: incremental + cursorField: + - timestamp + target: acmeCo/email_activity + - resource: + stream: reports + syncMode: incremental + cursorField: + - send_time + target: acmeCo/reports diff --git a/source-mailchimp/tests/__init__.py b/source-mailchimp/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/source-mailchimp/tests/snapshots/snapshots__capture__capture.stdout.json b/source-mailchimp/tests/snapshots/snapshots__capture__capture.stdout.json new file mode 100644 index 0000000000..2bed8b8b8d --- /dev/null +++ b/source-mailchimp/tests/snapshots/snapshots__capture__capture.stdout.json @@ -0,0 +1,159 @@ +[ + [ + "acmeCo/lists", + { + "_links": [ + { + "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72", + "method": "GET", + "rel": "self", + "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Response.json" + }, + { + "href": "https://us22.api.mailchimp.com/3.0/lists", + "method": "GET", + "rel": "parent", + "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/Collection.json", + "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/CollectionResponse.json" + }, + { + "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72", + "method": "PATCH", + "rel": "update", + "schema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/PATCH.json", + "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Response.json" + }, + { + "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72", + "method": "POST", + "rel": "batch-sub-unsub-members", + "schema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/BatchPOST.json", + "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/BatchPOST-Response.json" + }, + { + "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72", + "method": "DELETE", + "rel": "delete" + }, + { + "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/abuse-reports", + "method": "GET", + "rel": "abuse-reports", + "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/Abuse/Collection.json", + "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Abuse/CollectionResponse.json" + }, + { + "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/activity", + "method": "GET", + "rel": "activity", + "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Activity/Response.json" + }, + { + "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/clients", + "method": "GET", + "rel": "clients", + "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Clients/Response.json" + }, + { + "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/growth-history", + "method": "GET", + "rel": "growth-history", + "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/Growth/Collection.json", + "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Growth/CollectionResponse.json" + }, + { + "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/interest-categories", + "method": "GET", + "rel": "interest-categories", + "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/InterestCategories/Collection.json", + "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/InterestCategories/CollectionResponse.json" + }, + { + "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/members", + "method": "GET", + "rel": "members", + "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/Members/Collection.json", + "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Members/CollectionResponse.json" + }, + { + "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/merge-fields", + "method": "GET", + "rel": "merge-fields", + "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/MergeFields/Collection.json", + "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/MergeFields/CollectionResponse.json" + }, + { + "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/segments", + "method": "GET", + "rel": "segments", + "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/Segments/Collection.json", + "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Segments/CollectionResponse.json" + }, + { + "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/webhooks", + "method": "GET", + "rel": "webhooks", + "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/Webhooks/Collection.json", + "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Webhooks/CollectionResponse.json" + }, + { + "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/signup-forms", + "method": "GET", + "rel": "signup-forms", + "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/SignupForms/Collection.json", + "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/SignupForms/CollectionResponse.json" + }, + { + "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/locations", + "method": "GET", + "rel": "locations", + "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/Locations/Collection.json", + "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Locations/CollectionResponse.json" + } + ], + "beamer_address": "us22-eb203924dd-18076968e2@inbound.mailchimp.com", + "campaign_defaults": { + "from_email": "leofs123@gmail.com", + "from_name": "Estu", + "language": "en", + "subject": "" + }, + "contact": "redacted", + "date_created": "2024-03-22T20:01:48+00:00", + "double_optin": false, + "email_type_option": false, + "has_welcome": false, + "id": "7a1cbe4b72", + "list_rating": 0, + "marketing_permissions": false, + "modules": [], + "name": "Penguins", + "notify_on_subscribe": "", + "notify_on_unsubscribe": "", + "permission_reminder": "Voc\u00ea est\u00e1 recebendo este e-mail porque se inscreveu em nosso site.", + "stats": { + "avg_sub_rate": 0, + "avg_unsub_rate": 0, + "campaign_count": 0, + "campaign_last_sent": "", + "cleaned_count": 0, + "cleaned_count_since_send": 0, + "click_rate": 0, + "last_sub_date": "redacted", + "last_unsub_date": "", + "member_count": 2, + "member_count_since_send": 2, + "merge_field_count": 5, + "open_rate": 0, + "target_sub_rate": 0, + "unsubscribe_count": 0, + "unsubscribe_count_since_send": 0 + }, + "subscribe_url_long": "https://gmail.us22.list-manage.com/subscribe?u=ae90d8c414dc11cf841a0c191&id=7a1cbe4b72", + "subscribe_url_short": "http://eepurl.com/iOREaU", + "use_archive_bar": true, + "visibility": "prv", + "web_id": 1174 + } + ] +] diff --git a/source-mailchimp/tests/snapshots/snapshots__discover__capture.stdout.json b/source-mailchimp/tests/snapshots/snapshots__discover__capture.stdout.json new file mode 100644 index 0000000000..6709ff686f --- /dev/null +++ b/source-mailchimp/tests/snapshots/snapshots__discover__capture.stdout.json @@ -0,0 +1,3605 @@ +[ + { + "documentSchema": { + "description": "Information about a specific list.", + "properties": { + "beamer_address": { + "description": "The list's [Email Beamer](https://mailchimp.com/help/use-email-beamer-to-create-a-campaign/) address.", + "readOnly": true, + "title": "Beamer Address", + "type": "string" + }, + "campaign_defaults": { + "description": "[Default values for campaigns](https://mailchimp.com/help/edit-your-emails-subject-preview-text-from-name-or-from-email-address/) created for this list.", + "properties": { + "from_email": { + "description": "The default from email for campaigns sent to this list.", + "title": "Sender's Email Address", + "type": "string" + }, + "from_name": { + "description": "The default from name for campaigns sent to this list.", + "title": "Sender's Name", + "type": "string" + }, + "language": { + "description": "The default language for this lists's forms.", + "title": "Language", + "type": "string" + }, + "subject": { + "description": "The default subject line for campaigns sent to this list.", + "title": "Subject", + "type": "string" + } + }, + "title": "Campaign Defaults", + "type": "object" + }, + "contact": { + "description": "[Contact information displayed in campaign footers](https://mailchimp.com/help/about-campaign-footers/) to comply with international spam laws.", + "properties": { + "address1": { + "description": "The street address for the list contact.", + "title": "Address", + "type": "string" + }, + "address2": { + "description": "The street address for the list contact.", + "title": "Address", + "type": "string" + }, + "city": { + "description": "The city for the list contact.", + "title": "City", + "type": "string" + }, + "company": { + "description": "The company name for the list.", + "title": "Company Name", + "type": "string" + }, + "country": { + "description": "A two-character ISO3166 country code. Defaults to US if invalid.", + "title": "Country Code", + "type": "string" + }, + "phone": { + "description": "The phone number for the list contact.", + "title": "Phone Number", + "type": "string" + }, + "state": { + "description": "The state for the list contact.", + "title": "State", + "type": "string" + }, + "zip": { + "description": "The postal or zip code for the list contact.", + "title": "Postal Code", + "type": "string" + } + }, + "title": "List Contact", + "type": "object" + }, + "date_created": { + "description": "The date and time that this list was created in ISO 8601 format.", + "format": "date-time", + "readOnly": true, + "title": "Creation Date", + "type": "string" + }, + "double_optin": { + "default": false, + "description": "Whether or not to require the subscriber to confirm subscription via email.", + "title": "Double Opt In", + "type": "boolean" + }, + "email_type_option": { + "description": "Whether the list supports [multiple formats for emails](https://mailchimp.com/help/change-list-name-and-defaults/). When set to `true`, subscribers can choose whether they want to receive HTML or plain-text emails. When set to `false`, subscribers will receive HTML emails, with a plain-text alternative backup.", + "title": "Email Type Option", + "type": "boolean" + }, + "has_welcome": { + "default": false, + "description": "Whether or not this list has a welcome automation connected. Welcome Automations: welcomeSeries, singleWelcome, emailFollowup.", + "example": false, + "title": "Has Welcome", + "type": "boolean" + }, + "id": { + "description": "A string that uniquely identifies this list.", + "readOnly": true, + "title": "List ID", + "type": "string" + }, + "list_rating": { + "description": "An auto-generated activity score for the list (0-5).", + "readOnly": true, + "title": "List Rating", + "type": "integer" + }, + "marketing_permissions": { + "default": false, + "description": "Whether or not the list has marketing permissions (eg. GDPR) enabled.", + "title": "Marketing Permissions", + "type": "boolean" + }, + "modules": { + "description": "Any list-specific modules installed for this list.", + "items": { + "type": "string" + }, + "readOnly": true, + "title": "Modules", + "type": "array" + }, + "name": { + "description": "The name of the list.", + "title": "List Name", + "type": "string" + }, + "notify_on_subscribe": { + "default": "false", + "description": "The email address to send [subscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", + "title": "Notify on Subscribe", + "type": "string" + }, + "notify_on_unsubscribe": { + "default": "false", + "description": "The email address to send [unsubscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", + "title": "Notify on Unsubscribe", + "type": "string" + }, + "permission_reminder": { + "description": "The [permission reminder](https://mailchimp.com/help/edit-the-permission-reminder/) for the list.", + "title": "Permission Reminder", + "type": "string" + }, + "stats": { + "description": "Stats for the list. Many of these are cached for at least five minutes.", + "properties": { + "avg_sub_rate": { + "description": "The average number of subscriptions per month for the list (not returned if we haven't calculated it yet).", + "readOnly": true, + "title": "Average Subscription Rate", + "type": "number" + }, + "avg_unsub_rate": { + "description": "The average number of unsubscriptions per month for the list (not returned if we haven't calculated it yet).", + "readOnly": true, + "title": "Average Unsubscription Rate", + "type": "number" + }, + "campaign_count": { + "description": "The number of campaigns in any status that use this list.", + "readOnly": true, + "title": "Campaign Count", + "type": "integer" + }, + "campaign_last_sent": { + "description": "The date and time the last campaign was sent to this list in ISO 8601 format. This is updated when a campaign is sent to 10 or more recipients.", + "readOnly": true, + "title": "Campaign Last Sent", + "type": "string" + }, + "cleaned_count": { + "description": "The number of members cleaned from the list.", + "readOnly": true, + "title": "Cleaned Count", + "type": "integer" + }, + "cleaned_count_since_send": { + "description": "The number of members cleaned from the list since the last campaign was sent.", + "readOnly": true, + "title": "Cleaned Count Since Send", + "type": "integer" + }, + "click_rate": { + "description": "The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet).", + "readOnly": true, + "title": "Click Rate", + "type": "number" + }, + "last_sub_date": { + "description": "The date and time of the last time someone subscribed to this list in ISO 8601 format.", + "readOnly": true, + "title": "Date of Last List Subscribe", + "type": "string" + }, + "last_unsub_date": { + "description": "The date and time of the last time someone unsubscribed from this list in ISO 8601 format.", + "readOnly": true, + "title": "Date of Last List Unsubscribe", + "type": "string" + }, + "member_count": { + "description": "The number of active members in the list.", + "readOnly": true, + "title": "Member Count", + "type": "integer" + }, + "member_count_since_send": { + "description": "The number of active members in the list since the last campaign was sent.", + "readOnly": true, + "title": "Member Count Since Send", + "type": "integer" + }, + "merge_field_count": { + "description": "The number of merge vars for this list (not EMAIL, which is required).", + "readOnly": true, + "title": "Merge Var Count", + "type": "integer" + }, + "open_rate": { + "description": "The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet).", + "readOnly": true, + "title": "Open Rate", + "type": "number" + }, + "target_sub_rate": { + "description": "The target number of subscriptions per month for the list to keep it growing (not returned if we haven't calculated it yet).", + "readOnly": true, + "title": "Average Subscription Rate", + "type": "number" + }, + "total_contacts": { + "description": "The number of contacts in the list, including subscribed, unsubscribed, pending, cleaned, deleted, transactional, and those that need to be reconfirmed.", + "readOnly": true, + "title": "Total Contacts", + "type": "integer" + }, + "unsubscribe_count": { + "description": "The number of members who have unsubscribed from the list.", + "readOnly": true, + "title": "Unsubscribe Count", + "type": "integer" + }, + "unsubscribe_count_since_send": { + "description": "The number of members who have unsubscribed since the last campaign was sent.", + "readOnly": true, + "title": "Unsubscribe Count Since Send", + "type": "integer" + } + }, + "readOnly": true, + "title": "Statistics", + "type": "object" + }, + "subscribe_url_long": { + "description": "The full version of this list's subscribe form (host will vary).", + "readOnly": true, + "title": "Subscribe URL Long", + "type": "string" + }, + "subscribe_url_short": { + "description": "Our [EepURL shortened](https://mailchimp.com/help/share-your-signup-form/) version of this list's subscribe form.", + "readOnly": true, + "title": "Subscribe URL Short", + "type": "string" + }, + "use_archive_bar": { + "default": false, + "description": "Whether campaigns for this list use the [Archive Bar](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) in archives by default.", + "title": "Use Archive Bar", + "type": "boolean" + }, + "visibility": { + "description": "Whether this list is [public or private](https://mailchimp.com/help/about-list-publicity/).", + "title": "Visibility", + "type": "string" + }, + "web_id": { + "description": "The ID used in the Mailchimp web application. View this list in your Mailchimp account at `https://{dc}.admin.mailchimp.com/lists/members/?id={web_id}`.", + "readOnly": true, + "title": "List Web ID", + "type": "integer" + } + }, + "required": [ + "id" + ], + "title": "Subscriber List", + "type": "object" + }, + "key": [ + "/id" + ], + "recommendedName": "lists", + "resourceConfig": { + "cursorField": [ + "date_created" + ], + "stream": "lists", + "syncMode": "incremental" + } + }, + { + "documentSchema": { + "description": "A summary of an individual campaign's settings and content.", + "properties": { + "ab_split_opts": { + "description": "[A/B Testing](https://mailchimp.com/help/about-ab-testing-campaigns/) options for a campaign.", + "properties": { + "from_name_a": { + "description": "For campaigns split on 'From Name', the name for Group A.", + "title": "From Name Group A", + "type": "string" + }, + "from_name_b": { + "description": "For campaigns split on 'From Name', the name for Group B.", + "title": "From Name Group B", + "type": "string" + }, + "pick_winner": { + "description": "How we should evaluate a winner. Based on 'opens', 'clicks', or 'manual'.", + "title": "Pick Winner", + "type": "string" + }, + "reply_email_a": { + "description": "For campaigns split on 'From Name', the reply-to address for Group A.", + "title": "Reply Email Group A", + "type": "string" + }, + "reply_email_b": { + "description": "For campaigns split on 'From Name', the reply-to address for Group B.", + "title": "Reply Email Group B", + "type": "string" + }, + "send_time_a": { + "description": "The send time for Group A.", + "title": "Send Time Group A", + "type": "string" + }, + "send_time_b": { + "description": "The send time for Group B.", + "title": "Send Time Group B", + "type": "string" + }, + "send_time_winner": { + "description": "The send time for the winning version.", + "title": "Send Time Winner", + "type": "string" + }, + "split_size": { + "description": "The size of the split groups. Campaigns split based on 'schedule' are forced to have a 50/50 split. Valid split integers are between 1-50.", + "maximum": 50, + "minimum": 1, + "title": "Split Size", + "type": "integer" + }, + "split_test": { + "description": "The type of AB split to run.", + "title": "Split Test", + "type": "string" + }, + "subject_a": { + "description": "For campaigns split on 'Subject Line', the subject line for Group A.", + "title": "Subject Line Group A", + "type": "string" + }, + "subject_b": { + "description": "For campaigns split on 'Subject Line', the subject line for Group B.", + "title": "Subject Line Group B", + "type": "string" + }, + "wait_time": { + "description": "The amount of time to wait before picking a winner. This cannot be changed after a campaign is sent.", + "title": "Wait Time", + "type": "integer" + }, + "wait_units": { + "description": "How unit of time for measuring the winner ('hours' or 'days'). This cannot be changed after a campaign is sent.", + "title": "Wait Time", + "type": "string" + } + }, + "readOnly": true, + "title": "A/B Testing Options", + "type": "object" + }, + "archive_url": { + "description": "The link to the campaign's archive version in ISO 8601 format.", + "readOnly": true, + "title": "Archive URL", + "type": "string" + }, + "content_type": { + "description": "How the campaign's content is put together.", + "title": "Content Type", + "type": "string" + }, + "create_time": { + "description": "The date and time the campaign was created in ISO 8601 format.", + "readOnly": true, + "title": "Create Time", + "type": "string" + }, + "delivery_status": { + "description": "Updates on campaigns in the process of sending.", + "properties": { + "can_cancel": { + "description": "Whether a campaign send can be canceled.", + "readOnly": true, + "title": "Campaign Cancelable", + "type": "boolean" + }, + "emails_canceled": { + "description": "The total number of emails canceled for this campaign.", + "readOnly": true, + "title": "Emails Canceled", + "type": "integer" + }, + "emails_sent": { + "description": "The total number of emails confirmed sent for this campaign so far.", + "readOnly": true, + "title": "Emails Sent", + "type": "integer" + }, + "enabled": { + "description": "Whether Campaign Delivery Status is enabled for this account and campaign.", + "readOnly": true, + "title": "Delivery Status Enabled", + "type": "boolean" + }, + "status": { + "description": "The current state of a campaign delivery.", + "readOnly": true, + "title": "Campaign Delivery Status", + "type": "string" + } + }, + "title": "Campaign Delivery Status", + "type": "object" + }, + "emails_sent": { + "description": "The total number of emails sent for this campaign.", + "readOnly": true, + "title": "Emails Sent", + "type": "integer" + }, + "id": { + "description": "A string that uniquely identifies this campaign.", + "readOnly": true, + "title": "Campaign ID", + "type": "string" + }, + "long_archive_url": { + "description": "The original link to the campaign's archive version.", + "readOnly": true, + "title": "Long Archive URL", + "type": "string" + }, + "needs_block_refresh": { + "description": "Determines if the campaign needs its blocks refreshed by opening the web-based campaign editor. Deprecated and will always return false.", + "readOnly": true, + "title": "Needs Block Refresh", + "type": "boolean" + }, + "parent_campaign_id": { + "description": "If this campaign is the child of another campaign, this identifies the parent campaign. For Example, for RSS or Automation children.", + "readOnly": true, + "title": "Parent Campaign ID", + "type": "string" + }, + "recipients": { + "description": "List settings for the campaign.", + "properties": { + "list_id": { + "description": "The unique list id.", + "title": "List ID", + "type": "string" + }, + "list_is_active": { + "description": "The status of the list used, namely if it's deleted or disabled.", + "readOnly": true, + "title": "List Status", + "type": "boolean" + }, + "list_name": { + "description": "The name of the list.", + "readOnly": true, + "title": "List Name", + "type": "string" + }, + "recipient_count": { + "description": "Count of the recipients on the associated list. Formatted as an integer.", + "readOnly": true, + "title": "Recipient Count", + "type": "integer" + }, + "segment_opts": { + "description": "An object representing all segmentation options. This object should contain a `saved_segment_id` to use an existing segment, or you can create a new segment by including both `match` and `conditions` options.", + "properties": { + "conditions": { + "description": "Segment match conditions. There are multiple possible types, see the [condition types documentation](https://mailchimp.com/developer/marketing/docs/alternative-schemas/#segment-condition-schemas).", + "items": { + "oneOf": [ + { + "description": "Segment by interaction with a specific campaign.", + "properties": { + "condition_type": { + "enum": [ + "Aim" + ], + "type": "string", + "x-value": "Aim" + }, + "field": { + "description": "Segment by interaction with a specific campaign.", + "enum": [ + "aim" + ], + "example": "aim", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "The status of the member with regard to their campaign interaction. One of the following: opened, clicked, was sent, didn't open, didn't click, or was not sent.", + "enum": [ + "open", + "click", + "sent", + "noopen", + "noclick", + "nosent" + ], + "example": "open", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "Either the web id value for a specific campaign or 'any' to account for subscribers who have/have not interacted with any campaigns.", + "example": "any", + "title": "Segment Data", + "type": "string" + } + }, + "title": "Aim Segment", + "type": "object" + }, + { + "description": "Segment by interaction with an Automation workflow.", + "properties": { + "condition_type": { + "enum": [ + "Automation" + ], + "type": "string", + "x-value": "Automation" + }, + "field": { + "description": "Segment by interaction with an Automation workflow.", + "enum": [ + "automation" + ], + "example": "automation", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "The status of the member with regard to the automation workflow. One of the following: has started the workflow, has completed the workflow, has not started the workflow, or has not completed the workflow.", + "enum": [ + "started", + "completed", + "not_started", + "not_completed" + ], + "example": "started", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The web id for the automation workflow to segment against.", + "example": "2135217", + "title": "Segment Data", + "type": "string" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Automation Segment", + "type": "object" + }, + { + "description": "Segment by poll activity.", + "properties": { + "condition_type": { + "enum": [ + "CampaignPoll" + ], + "type": "string", + "x-value": "CampaignPoll" + }, + "field": { + "description": "Segment by poll activity.", + "enum": [ + "poll" + ], + "example": "poll", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Members have/have not interacted with a specific poll in a Mailchimp email.", + "enum": [ + "member", + "notmember" + ], + "example": "member", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The id for the poll.", + "example": 409, + "title": "Segment Operator", + "type": "number" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Poll Activity Segment", + "type": "object" + }, + { + "description": "Segment by interaction with a campaign via Conversations.", + "properties": { + "condition_type": { + "enum": [ + "Conversation" + ], + "type": "string", + "x-value": "Conversation" + }, + "field": { + "description": "Segment by interaction with a campaign via Conversations.", + "enum": [ + "conversation" + ], + "example": "conversation", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "The status of a member's interaction with a conversation. One of the following: has replied or has not replied.", + "enum": [ + "member", + "notmember" + ], + "example": "member", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The web id value for a specific campaign or 'any' to account for subscribers who have/have not interacted with any campaigns.", + "example": "any", + "title": "Segment Data", + "type": "string" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Conversation Segment", + "type": "object" + }, + { + "description": "Segment by a specific date field.", + "properties": { + "condition_type": { + "enum": [ + "Date" + ], + "type": "string", + "x-value": "Date" + }, + "extra": { + "description": "When segmenting on 'date' or 'campaign', the date for the segment formatted as YYYY-MM-DD or the web id for the campaign.", + "example": "2015-01-30", + "title": "Segment Extra Value", + "type": "string" + }, + "field": { + "description": "The type of date field to segment on: The opt-in time for a signup, the date the subscriber was last updated, or the date of their last ecomm purchase.", + "enum": [ + "timestamp_opt", + "info_changed", + "ecomm_date" + ], + "example": "timestamp_opt", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "When the event took place: Before, after, is a specific date, is not a specific date, is blank, or is not blank.", + "enum": [ + "greater", + "less", + "is", + "not", + "blank", + "blank_not", + "within", + "notwithin" + ], + "example": "greater", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "What type of data to segment on: a specific date, a specific campaign, or the last campaign sent.", + "example": "date", + "title": "Segment Data", + "type": "string" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Date Segment", + "type": "object" + }, + { + "description": "Segment by use of a particular email client.", + "properties": { + "condition_type": { + "enum": [ + "EmailClient" + ], + "type": "string", + "x-value": "EmailClient" + }, + "field": { + "description": "Segment by use of a particular email client.", + "enum": [ + "email_client" + ], + "example": "email_client", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "The operation to determine whether we select clients that match the value, or clients that do not match the value.", + "enum": [ + "client_is", + "client_not" + ], + "example": "client_is", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The name of the email client.", + "example": "Gmail", + "title": "Segment Data", + "type": "string" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Email Client Segment", + "type": "object" + }, + { + "description": "Segment by language.", + "properties": { + "condition_type": { + "enum": [ + "Language" + ], + "type": "string", + "x-value": "Language" + }, + "field": { + "description": "Segmenting based off of a subscriber's language.", + "enum": [ + "language" + ], + "example": "language", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Whether the member's language is or is not set to a specific language.", + "enum": [ + "is", + "not" + ], + "example": "is", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "A two-letter language identifier.", + "example": "en", + "title": "Segment Data", + "type": "string" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Language Segment", + "type": "object" + }, + { + "description": "Segment by member rating.", + "properties": { + "condition_type": { + "enum": [ + "MemberRating" + ], + "type": "string", + "x-value": "MemberRating" + }, + "field": { + "description": "Segment by member rating.", + "enum": [ + "rating" + ], + "example": "rating", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Members who have have a rating that is/not exactly a given number or members who have a rating greater/less than a given number.", + "enum": [ + "is", + "not", + "greater", + "less" + ], + "example": "greater", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The star rating number to segment against.", + "example": 4, + "title": "Segment Operator", + "type": "number" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Member Rating Segment", + "type": "object" + }, + { + "description": "Segment by signup source.", + "properties": { + "condition_type": { + "enum": [ + "SignupSource" + ], + "title": "Type", + "type": "string", + "x-value": "SignupSource" + }, + "field": { + "enum": [ + "source" + ], + "example": "source", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Whether the member's signup source was/was not a particular value.", + "enum": [ + "source_is", + "source_not" + ], + "example": "source_is", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The signup source.", + "example": "List Import", + "title": "Segment Data", + "type": "string" + } + }, + "required": [ + "field", + "condition_type", + "op" + ], + "title": "Signup Source Segment", + "type": "object" + }, + { + "description": "Segment by interaction with a SurveyMonkey survey.", + "properties": { + "condition_type": { + "enum": [ + "SurveyMonkey" + ], + "type": "string", + "x-value": "SurveyMonkey" + }, + "field": { + "description": "Segment by interaction with a SurveyMonkey survey.", + "enum": [ + "survey_monkey" + ], + "example": "survey_monkey", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "The status of the member with regard to the survey. One of the following: has started the survey, has completed the survey, has not started the survey, or has not completed the survey.", + "enum": [ + "started", + "completed", + "not_started", + "not_completed" + ], + "example": "started", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The unique ID of the SurveyMonkey survey.", + "example": "32179586", + "title": "Survey ID", + "type": "string" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "SurveyMonkey Segment", + "type": "object" + }, + { + "description": "Segment by VIP status.", + "properties": { + "condition_type": { + "enum": [ + "VIP" + ], + "type": "string", + "x-value": "VIP" + }, + "field": { + "description": "Segment by VIP status.", + "enum": [ + "gmonkey" + ], + "example": "gmonkey", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Whether the member is or is not marked as VIP.", + "enum": [ + "member", + "notmember" + ], + "example": "member", + "title": "Segment Operator", + "type": "string" + } + }, + "required": [ + "field", + "op" + ], + "title": "VIP Segment", + "type": "object" + }, + { + "description": "Segment by an interest group merge field.", + "properties": { + "condition_type": { + "enum": [ + "Interests" + ], + "type": "string", + "x-value": "Interests" + }, + "field": { + "description": "Segmenting based on interest group information. This should start with 'interests-' followed by the grouping id. Ex. 'interests-123'.", + "example": "interests-123", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Whether the member is a part of one, all, or none of the groups.", + "enum": [ + "interestcontains", + "interestcontainsall", + "interestnotcontains" + ], + "example": "interestcontains", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "An array containing strings, each representing a group id.", + "items": { + "example": [ + "44401", + "44405", + "44409" + ], + "type": "string" + }, + "title": "Segment Value", + "type": "array" + } + }, + "title": "Interests Segment", + "type": "object" + }, + { + "description": "Segment by purchases in specific items or categories.", + "properties": { + "condition_type": { + "enum": [ + "EcommCategory" + ], + "type": "string", + "x-value": "EcommCategory" + }, + "field": { + "description": "Segment by purchases in specific items or categories.", + "enum": [ + "ecomm_cat", + "ecomm_prod" + ], + "example": "ecomm_cat", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "A member who has purchased from a category/specific item that is/is not a specific name, where the category/item name contains/doesn't contain a specific phrase or string, or a category/item name that starts/ends with a string.", + "enum": [ + "is", + "not", + "contains", + "notcontain", + "starts", + "ends" + ], + "example": "is", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The ecommerce category/item information.", + "example": "Product", + "title": "Segment Data", + "type": "string" + } + }, + "title": "Ecommerce Category Segment", + "type": "object" + }, + { + "description": "Segment by average spent total, number of orders, total number of products purchased, or average number of products per order.", + "properties": { + "condition_type": { + "enum": [ + "EcommNumber" + ], + "type": "string", + "x-value": "EcommNumber" + }, + "field": { + "description": "Segment by average spent total, number of orders, total number of products purchased, or average number of products per order.", + "enum": [ + "ecomm_spent_avg", + "ecomm_orders", + "ecomm_prod_all", + "ecomm_avg_ord" + ], + "example": "ecomm_orders", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Members who have spent exactly, have not spent exactly, spent more, or spent less than the segment value.", + "enum": [ + "is", + "not", + "greater", + "less" + ], + "example": "greater", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "Members who have spent exactly, have not spent exactly, spent more, or spent less than this amount.", + "example": 42, + "title": "Segment Operator", + "type": "number" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Ecommerce Number Segment", + "type": "object" + }, + { + "description": "Segment by whether someone has purchased anything.", + "properties": { + "condition_type": { + "enum": [ + "EcommPurchased" + ], + "type": "string", + "x-value": "EcommPurchased" + }, + "field": { + "description": "Segment by whether someone has purchased anything.", + "enum": [ + "ecomm_purchased" + ], + "example": "ecomm_purchased", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Members who have have ('member') or have not ('notmember') purchased.", + "enum": [ + "member", + "notmember" + ], + "example": "member", + "title": "Segment Operator", + "type": "string" + } + }, + "title": "Ecommerce Purchased Segment", + "type": "object" + }, + { + "description": "Segment by amount spent on a single order or across all orders.", + "properties": { + "condition_type": { + "enum": [ + "EcommSpent" + ], + "type": "string", + "x-value": "EcommSpent" + }, + "field": { + "description": "Segment by amount spent on a single order or across all orders.", + "enum": [ + "ecomm_spent_one", + "ecomm_spent_all" + ], + "example": "ecomm_spent_one", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Members who have spent 'more' or 'less' than then specified value.", + "enum": [ + "greater", + "less" + ], + "example": "greater", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The total amount a member spent.", + "example": 42, + "title": "Segment Data", + "type": "integer" + } + }, + "title": "Ecommerce Spent Segment", + "type": "object" + }, + { + "description": "Segment by purchases from a specific store.", + "properties": { + "condition_type": { + "enum": [ + "EcommStore" + ], + "type": "string", + "x-value": "EcommStore" + }, + "field": { + "description": "Segment by purchases from a specific store.", + "enum": [ + "ecomm_store" + ], + "example": "ecomm_store", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Members who have or have not purchased from a specific store.", + "enum": [ + "is", + "not" + ], + "example": "is", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The store id to segment against.", + "example": "289", + "title": "Segment Operator", + "type": "string" + } + }, + "title": "Ecommerce Purchased Store Segment", + "type": "object" + }, + { + "description": "Segment by Goal activity.", + "properties": { + "condition_type": { + "enum": [ + "GoalActivity" + ], + "type": "string", + "x-value": "GoalActivity" + }, + "field": { + "description": "Segment by Goal activity.", + "enum": [ + "goal" + ], + "example": "goal", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Whether the website URL is/not exactly, contains/doesn't contain, starts with/ends with a string.", + "enum": [ + "is", + "goal_not", + "contains", + "goal_notcontain", + "starts", + "ends" + ], + "example": "is", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The URL to check Goal activity against.", + "title": "Segment Value", + "type": "string" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Goal Activity Segment", + "type": "object" + }, + { + "description": "Segment by most recent interaction with a website.", + "properties": { + "condition_type": { + "enum": [ + "GoalTimestamp" + ], + "type": "string", + "x-value": "GoalTimestamp" + }, + "field": { + "description": "Segment by most recent interaction with a website.", + "enum": [ + "goal_last_visited" + ], + "example": "goal_last_visited", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Whether the website activity happened after, before, or at a given timestamp.", + "enum": [ + "greater", + "less", + "is" + ], + "example": "greater", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The date to check Goal activity against.", + "example": "2015-07-20 19:45:21", + "title": "Segment Value", + "type": "string" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Goal Timestamp Segment", + "type": "object" + }, + { + "description": "Segment by similar subscribers.", + "properties": { + "condition_type": { + "enum": [ + "FuzzySegment" + ], + "type": "string", + "x-value": "FuzzySegment" + }, + "field": { + "description": "Segment by similar subscribers.", + "enum": [ + "fuzzy_segment" + ], + "example": "fuzzy_segment", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Members who are/are not apart of a 'similar subscribers' segment.", + "enum": [ + "fuzzy_is", + "fuzzy_not" + ], + "example": "fuzzy_is", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The id for the 'similar subscribers' segment.", + "example": 48433, + "title": "Segment Operator", + "type": "number" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Similar Subscribers Segment Member Segment", + "type": "object" + }, + { + "description": "Segment by a given static segment.", + "properties": { + "condition_type": { + "enum": [ + "StaticSegment" + ], + "type": "string", + "x-value": "StaticSegment" + }, + "field": { + "description": "Segment by a given static segment.", + "enum": [ + "static_segment" + ], + "example": "static_segment", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Members who are/are not apart of a static segment.", + "enum": [ + "static_is", + "static_not" + ], + "example": "static_is", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The id for the static segment.", + "example": 48433, + "title": "Segment Operator", + "type": "number" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Static Segment Member Segment", + "type": "object" + }, + { + "description": "Segment by a specific country or US state.", + "properties": { + "condition_type": { + "enum": [ + "IPGeoCountryState" + ], + "type": "string", + "x-value": "IPGeoCountryState" + }, + "field": { + "description": "Segmenting subscribers who are within a specific location.", + "enum": [ + "ipgeo" + ], + "example": "ipgeo", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Segment members who are within a specific country or US state.", + "enum": [ + "ipgeocountry", + "ipgeonotcountry", + "ipgeostate", + "ipgeonotstate" + ], + "example": "ipgeocountry", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The two-letter country code or US state abbreviation.", + "example": "US", + "title": "Segment Data", + "type": "string" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Location-Based Segment", + "type": "object" + }, + { + "description": "Segment by a specific geographic region.", + "properties": { + "addr": { + "description": "The address of the target location.", + "example": "Atlanta, GA, USA", + "title": "Segment Location Address", + "type": "string" + }, + "condition_type": { + "enum": [ + "IPGeoIn" + ], + "type": "string", + "x-value": "IPGeoIn" + }, + "field": { + "description": "Segmenting subscribers who are within a specific location.", + "enum": [ + "ipgeo" + ], + "example": "ipgeo", + "title": "Segment Field", + "type": "string" + }, + "lat": { + "description": "The latitude of the target location.", + "example": "33.7489954", + "title": "Segment Location Latitude", + "type": "string" + }, + "lng": { + "description": "The longitude of the target location.", + "example": "-84.3879824", + "title": "Segment Location Longitude", + "type": "string" + }, + "op": { + "description": "Segment members who are within a specific geographic region.", + "enum": [ + "ipgeoin", + "ipgeonotin" + ], + "example": "ipgeoin", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The radius of the target location.", + "example": 42, + "title": "Segment Data", + "type": "integer" + } + }, + "required": [ + "field", + "op", + "value", + "addr", + "lat", + "lng" + ], + "title": "Geolocation Segment", + "type": "object" + }, + { + "description": "Segment by a specific US ZIP code.", + "properties": { + "condition_type": { + "enum": [ + "IPGeoInZip" + ], + "type": "string", + "x-value": "IPGeoInZip" + }, + "extra": { + "description": "The zip code to segment against.", + "example": 30318, + "title": "Extra Data", + "type": "integer" + }, + "field": { + "description": "Segmenting subscribers who are within a specific location.", + "enum": [ + "ipgeo" + ], + "example": "ipgeo", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Segment members who are within a specific US zip code.", + "enum": [ + "ipgeoinzip" + ], + "example": "ipgeoinzip", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The radius of the target location.", + "example": 25, + "title": "Segment Data", + "type": "integer" + } + }, + "required": [ + "field", + "op", + "value", + "extra" + ], + "title": "US Zip Code Segment", + "type": "object" + }, + { + "description": "Segment members whose location information is unknown.", + "properties": { + "condition_type": { + "enum": [ + "IPGeoUnknown" + ], + "type": "string", + "x-value": "IPGeoUnknown" + }, + "field": { + "description": "Segmenting subscribers who are within a specific location.", + "enum": [ + "ipgeo" + ], + "example": "ipgeo", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Segment members for which location information is unknown.", + "enum": [ + "ipgeounknown" + ], + "example": "ipgeounknown", + "title": "Segment Operator", + "type": "string" + } + }, + "required": [ + "field", + "op" + ], + "title": "Unknown Location-Based Segment", + "type": "object" + }, + { + "description": "Segment by a specific US ZIP code.", + "properties": { + "condition_type": { + "enum": [ + "IPGeoZip" + ], + "type": "string", + "x-value": "IPGeoZip" + }, + "field": { + "description": "Segmenting subscribers who are within a specific location.", + "enum": [ + "ipgeo" + ], + "example": "ipgeo", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Segment members who are/are not within a specific US zip code.", + "enum": [ + "ipgeoiszip", + "ipgeonotzip" + ], + "example": "ipgeonotzip", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The 5-digit zip code.", + "example": 30318, + "title": "Segment Data", + "type": "integer" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Zip Code Location-Based Segment", + "type": "object" + }, + { + "description": "Segment by age ranges in Social Profiles data.", + "properties": { + "condition_type": { + "enum": [ + "SocialAge" + ], + "type": "string", + "x-value": "SocialAge" + }, + "field": { + "description": "Segment by age ranges in Social Profiles data.", + "enum": [ + "social_age" + ], + "example": "social_age", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Members who are/not the exact criteria listed.", + "enum": [ + "is", + "not" + ], + "example": "is", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The age range to segment.", + "enum": [ + "18-24", + "25-34", + "35-54", + "55+" + ], + "example": "35-54", + "title": "Segment Operator", + "type": "string" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Social Profiles Age Segment", + "type": "object" + }, + { + "description": "Segment by listed gender in Social Profiles data.", + "properties": { + "condition_type": { + "enum": [ + "SocialGender" + ], + "type": "string", + "x-value": "SocialGender" + }, + "field": { + "description": "Segment by listed gender in Social Profiles data.", + "enum": [ + "social_gender" + ], + "example": "social_gender", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Members who are/not the exact criteria listed.", + "enum": [ + "is", + "not" + ], + "example": "is", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The Social Profiles gender to segment.", + "enum": [ + "male", + "female" + ], + "example": "female", + "title": "Segment Operator", + "type": "string" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Social Profiles Gender Segment", + "type": "object" + }, + { + "description": "Segment by influence rating in Social Profiles data.", + "properties": { + "condition_type": { + "enum": [ + "SocialInfluence" + ], + "type": "string", + "x-value": "SocialInfluence" + }, + "field": { + "description": "Segment by influence rating in Social Profiles data.", + "enum": [ + "social_influence" + ], + "example": "social_influence", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Members who have a rating that is/not or greater/less than the rating provided.", + "enum": [ + "is", + "not", + "greater", + "less" + ], + "example": "greater", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The Social Profiles influence rating to segment.", + "example": 2, + "title": "Segment Operator", + "type": "number" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Social Profiles Influence Segment", + "type": "object" + }, + { + "description": "Segment by social network in Social Profiles data.", + "properties": { + "condition_type": { + "enum": [ + "SocialNetworkMember" + ], + "type": "string", + "x-value": "SocialNetworkMember" + }, + "field": { + "description": "Segment by social network in Social Profiles data.", + "enum": [ + "social_network" + ], + "example": "social_network", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Members who are/not on a given social network.", + "enum": [ + "member", + "notmember" + ], + "example": "member", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The social network to segment against.", + "enum": [ + "twitter", + "facebook", + "linkedin", + "flickr", + "foursquare", + "lastfm", + "myspace", + "quora", + "vimeo", + "yelp", + "youtube" + ], + "example": "twitter", + "title": "Segment Operator", + "type": "string" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Social Profiles Social Network Segment", + "type": "object" + }, + { + "description": "Segment by social network in Social Profiles data.", + "properties": { + "condition_type": { + "enum": [ + "SocialNetworkFollow" + ], + "type": "string", + "x-value": "SocialNetworkFollow" + }, + "field": { + "description": "Segment by social network in Social Profiles data.", + "enum": [ + "social_network" + ], + "example": "social_network", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Members who are/not following a linked account on a given social network.", + "enum": [ + "follow", + "notfollow" + ], + "example": "follow", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The social network to segment against.", + "enum": [ + "twitter_follow" + ], + "example": "twitter_follow", + "title": "Segment Operator", + "type": "string" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Social Profiles Social Network Follow Segment", + "type": "object" + }, + { + "description": "Segment by an address-type merge field.", + "properties": { + "condition_type": { + "enum": [ + "AddressMerge" + ], + "type": "string", + "x-value": "AddressMerge" + }, + "field": { + "description": "An address-type merge field to segment.", + "example": "MMERGE3", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Whether the member's address merge field contains/does not contain a value or is/is not blank.", + "enum": [ + "contains", + "notcontain", + "blank", + "blank_not" + ], + "example": "contains", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The value to segment a text merge field with.", + "example": "Atlanta", + "title": "Segment Value", + "type": "string" + } + }, + "required": [ + "field", + "op" + ], + "title": "Address Merge Field Segment", + "type": "object" + }, + { + "description": "Segment by an address-type merge field within a given distance.", + "properties": { + "condition_type": { + "enum": [ + "ZipMerge" + ], + "type": "string", + "x-value": "ZipMerge" + }, + "extra": { + "description": "The city or the zip being used to segment against.", + "example": "30318", + "title": "Segment Extra", + "type": "string" + }, + "field": { + "description": "An address or zip-type merge field to segment.", + "example": "MMERGE2", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Whether the member's address merge field is within a given distance from a city or zip.", + "enum": [ + "geoin" + ], + "example": "geoin", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The distance from the city/zip.", + "example": "25", + "title": "Segment Value", + "type": "string" + } + }, + "required": [ + "field", + "op", + "value", + "extra" + ], + "title": "Address/Zip Merge Field Segment", + "type": "object" + }, + { + "description": "Segment by a contact's birthday.", + "properties": { + "condition_type": { + "enum": [ + "BirthdayMerge" + ], + "type": "string", + "x-value": "BirthdayMerge" + }, + "field": { + "description": "A date merge field to segment.", + "example": "MMERGE4", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Whether the member's birthday merge information is/is not a certain date or is/is not blank.", + "enum": [ + "is", + "not", + "blank", + "blank_not" + ], + "example": "is", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "A date to segment against (mm/dd).", + "example": "01/30", + "title": "Segment Value", + "type": "string" + } + }, + "required": [ + "field", + "op" + ], + "title": "Birthday Merge Field Segment", + "type": "object" + }, + { + "description": "Segment by a given date merge field.", + "properties": { + "condition_type": { + "enum": [ + "DateMerge" + ], + "type": "string", + "x-value": "DateMerge" + }, + "field": { + "description": "A date merge field to segment.", + "example": "MMERGE5", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Whether the member's merge information is/is not, is greater/less than a value or is/is not blank.", + "enum": [ + "is", + "not", + "less", + "blank", + "blank_not", + "greater" + ], + "example": "is", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "A date to segment against.", + "example": "01/30/2015", + "title": "Segment Value", + "type": "string" + } + }, + "required": [ + "field", + "op" + ], + "title": "Date Merge Field Segment", + "type": "object" + }, + { + "description": "An individual segment condition", + "properties": { + "condition_type": { + "enum": [ + "SelectMerge" + ], + "type": "string", + "x-value": "SelectMerge" + }, + "field": { + "description": "A merge field to segment.", + "example": "MMERGE6", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Whether the member's merge information is/is not a value or is/is not blank.", + "enum": [ + "is", + "not", + "blank", + "blank_not", + "notcontain", + "contains" + ], + "example": "is", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The value to segment a text merge field with.", + "example": "Second Choice", + "title": "Segment Value", + "type": "string" + } + }, + "required": [ + "field", + "op" + ], + "title": "Dropdown/Radio Merge Field Segment", + "type": "object" + }, + { + "description": "Segment by a given text or number merge field.", + "properties": { + "condition_type": { + "enum": [ + "TextMerge" + ], + "type": "string", + "x-value": "TextMerge" + }, + "field": { + "description": "A text or number merge field to segment.", + "example": "MMERGE7", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Whether the member's merge information is/is not, contains/does not contain, starts/ends with, or is greater/less than a value", + "enum": [ + "is", + "not", + "contains", + "notcontain", + "starts", + "ends", + "greater", + "less", + "blank", + "blank_not" + ], + "example": "contains", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The value to segment a text or number merge field with.", + "example": "Freddie's Jokes", + "title": "Segment Value", + "type": "string" + } + }, + "required": [ + "field", + "op" + ], + "title": "Text or Number Merge Field Segment", + "type": "object" + }, + { + "description": "Segment by email address.", + "properties": { + "condition_type": { + "enum": [ + "EmailAddress" + ], + "type": "string", + "x-value": "EmailAddress" + }, + "field": { + "description": "Segmenting based off of a subscriber's email address.", + "enum": [ + "merge0", + "EMAIL" + ], + "example": "EMAIL", + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Whether the email address is/not exactly, contains/doesn't contain, starts/ends with a string.", + "enum": [ + "is", + "not", + "contains", + "notcontain", + "starts", + "ends", + "greater", + "less" + ], + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The value to compare the email against.", + "example": "urist.mcvankab@freddiesjokes.com", + "title": "Segment Value", + "type": "string" + } + }, + "required": [ + "field", + "op" + ], + "title": "Email Segment", + "type": "object" + }, + { + "description": "Segment by predicted gender.", + "properties": { + "condition_type": { + "enum": [ + "PredictedGender" + ], + "type": "string", + "x-value": "PredictedGender" + }, + "field": { + "description": "Segment by predicted gender.", + "enum": [ + "predicted_gender" + ], + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Members who are/not the exact criteria listed.", + "enum": [ + "is", + "not" + ], + "example": "is", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The predicted gender to segment.", + "enum": [ + "male", + "female" + ], + "example": "female", + "title": "Segment Operator", + "type": "string" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Predicted Gender Segment", + "type": "object" + }, + { + "description": "Segment by predicted age.", + "properties": { + "condition_type": { + "enum": [ + "PredictedAge" + ], + "type": "string", + "x-value": "PredictedAge" + }, + "field": { + "description": "Segment by predicted age.", + "enum": [ + "predicted_age_range" + ], + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Members who are/not the exact criteria listed.", + "enum": [ + "is" + ], + "example": "is", + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "The predicted age to segment.", + "enum": [ + "18-24", + "25-34", + "35-44", + "45-54", + "55-64", + "65+" + ], + "example": "female", + "title": "Segment Operator", + "type": "string" + } + }, + "required": [ + "field", + "op", + "value" + ], + "title": "Predicted Age Segment", + "type": "object" + }, + { + "description": "Segment by when people subscribed.", + "properties": { + "condition_type": { + "enum": [ + "NewSubscribers" + ], + "type": "string", + "x-value": "NewSubscribers" + }, + "field": { + "description": "Segment by when people subscribed.", + "enum": [ + "timestamp_opt" + ], + "title": "Segment Field", + "type": "string" + }, + "op": { + "description": "Whe the event took place, namely within a time frame.", + "enum": [ + "date_within" + ], + "title": "Segment Operator", + "type": "string" + }, + "value": { + "description": "What type of data to segment on: a specific date, a specific campaign, or the last campaign sent.", + "title": "Segment Data", + "type": "string" + } + }, + "title": "New Subscribers Prebuilt Segment", + "type": "object" + } + ], + "x-discriminator": { + "propertyName": "condition_type" + } + }, + "title": "Segment Type", + "type": "array" + }, + "match": { + "description": "Segment match type.", + "title": "Match Type", + "type": "string" + }, + "prebuilt_segment_id": { + "description": "The prebuilt segment id, if a prebuilt segment has been designated for this campaign.", + "example": "subscribers-female", + "title": "Prebuilt Segment Id", + "type": "string" + }, + "saved_segment_id": { + "description": "The id for an existing saved segment.", + "title": "Saved Segment ID", + "type": "integer" + } + }, + "title": "Segment Options", + "type": "object" + }, + "segment_text": { + "description": "A description of the [segment](https://mailchimp.com/help/create-and-send-to-a-segment/) used for the campaign. Formatted as a string marked up with HTML.", + "readOnly": true, + "title": "Segment Text", + "type": "string" + } + }, + "title": "List", + "type": "object" + }, + "report_summary": { + "description": "For sent campaigns, a summary of opens, clicks, and e-commerce data.", + "properties": { + "click_rate": { + "description": "The number of unique clicks divided by the total number of successful deliveries.", + "readOnly": true, + "title": "Click Rate", + "type": "number" + }, + "clicks": { + "description": "The total number of clicks for an campaign.", + "readOnly": true, + "title": "Total Clicks", + "type": "integer" + }, + "ecommerce": { + "description": "E-Commerce stats for a campaign.", + "properties": { + "total_orders": { + "description": "The total orders for a campaign.", + "readOnly": true, + "title": "Total Orders", + "type": "integer" + }, + "total_revenue": { + "description": "The total revenue for a campaign. Calculated as the sum of all order totals minus shipping and tax totals.", + "readOnly": true, + "title": "Total Revenue", + "type": "number" + }, + "total_spent": { + "description": "The total spent for a campaign. Calculated as the sum of all order totals with no deductions.", + "readOnly": true, + "title": "Total Spent", + "type": "number" + } + }, + "title": "E-Commerce Report", + "type": "object" + }, + "open_rate": { + "description": "The number of unique opens divided by the total number of successful deliveries.", + "readOnly": true, + "title": "Open Rate", + "type": "number" + }, + "opens": { + "description": "The total number of opens for a campaign.", + "readOnly": true, + "title": "Automation Opens", + "type": "integer" + }, + "subscriber_clicks": { + "description": "The number of unique clicks.", + "readOnly": true, + "title": "Unique Subscriber Clicks", + "type": "integer" + }, + "unique_opens": { + "description": "The number of unique opens.", + "readOnly": true, + "title": "Unique Opens", + "type": "integer" + } + }, + "title": "Campaign Report Summary", + "type": "object" + }, + "resendable": { + "description": "Determines if the campaign qualifies to be resent to non-openers.", + "readOnly": true, + "title": "Resendable", + "type": "boolean" + }, + "rss_opts": { + "description": "[RSS](https://mailchimp.com/help/share-your-blog-posts-with-mailchimp/) options for a campaign.", + "properties": { + "constrain_rss_img": { + "description": "Whether to add CSS to images in the RSS feed to constrain their width in campaigns.", + "title": "Constrain RSS Images", + "type": "boolean" + }, + "feed_url": { + "description": "The URL for the RSS feed.", + "format": "uri", + "title": "Feed URL", + "type": "string" + }, + "frequency": { + "description": "The frequency of the RSS Campaign.", + "title": "Frequency", + "type": "string" + }, + "last_sent": { + "description": "The date the campaign was last sent.", + "readOnly": true, + "title": "Last Sent", + "type": "string" + }, + "schedule": { + "description": "The schedule for sending the RSS Campaign.", + "properties": { + "daily_send": { + "description": "The days of the week to send a daily RSS Campaign.", + "properties": { + "friday": { + "description": "Sends the daily RSS Campaign on Fridays.", + "title": "Friday", + "type": "boolean" + }, + "monday": { + "description": "Sends the daily RSS Campaign on Mondays.", + "title": "Monday", + "type": "boolean" + }, + "saturday": { + "description": "Sends the daily RSS Campaign on Saturdays.", + "title": "Saturday", + "type": "boolean" + }, + "sunday": { + "description": "Sends the daily RSS Campaign on Sundays.", + "title": "Sunday", + "type": "boolean" + }, + "thursday": { + "description": "Sends the daily RSS Campaign on Thursdays.", + "title": "Thursday", + "type": "boolean" + }, + "tuesday": { + "description": "Sends the daily RSS Campaign on Tuesdays.", + "title": "tuesday", + "type": "boolean" + }, + "wednesday": { + "description": "Sends the daily RSS Campaign on Wednesdays.", + "title": "Monday", + "type": "boolean" + } + }, + "title": "Daily Sending Days", + "type": "object" + }, + "hour": { + "description": "The hour to send the campaign in local time. Acceptable hours are 0-23. For example, '4' would be 4am in [your account's default time zone](https://mailchimp.com/help/set-account-defaults/).", + "maximum": 23, + "minimum": 0, + "title": "Sending Hour", + "type": "integer" + }, + "monthly_send_date": { + "description": "The day of the month to send a monthly RSS Campaign. Acceptable days are 0-31, where '0' is always the last day of a month. Months with fewer than the selected number of days will not have an RSS campaign sent out that day. For example, RSS Campaigns set to send on the 30th will not go out in February.", + "maximum": 31, + "minimum": 0, + "title": "Monthly Sending Day", + "type": "number" + }, + "weekly_send_day": { + "description": "The day of the week to send a weekly RSS Campaign.", + "title": "Weekly Sending Day", + "type": "string" + } + }, + "title": "Sending Schedule", + "type": "object" + } + }, + "title": "RSS Options", + "type": "object" + }, + "send_time": { + "description": "The date and time a campaign was sent.", + "readOnly": true, + "title": "Send Time", + "type": "string" + }, + "settings": { + "description": "The settings for your campaign, including subject, from name, reply-to address, and more.", + "properties": { + "authenticate": { + "description": "Whether Mailchimp [authenticated](https://mailchimp.com/help/about-email-authentication/) the campaign. Defaults to `true`.", + "title": "Authentication", + "type": "boolean" + }, + "auto_fb_post": { + "description": "An array of [Facebook](https://mailchimp.com/help/connect-or-disconnect-the-facebook-integration/) page ids to auto-post to.", + "items": { + "type": "string" + }, + "title": "Auto Post to Facebook", + "type": "array" + }, + "auto_footer": { + "description": "Automatically append Mailchimp's [default footer](https://mailchimp.com/help/about-campaign-footers/) to the campaign.", + "title": "Auto-Footer", + "type": "boolean" + }, + "auto_tweet": { + "description": "Automatically tweet a link to the [campaign archive](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) page when the campaign is sent.", + "title": "Auto-Tweet", + "type": "boolean" + }, + "drag_and_drop": { + "description": "Whether the campaign uses the drag-and-drop editor.", + "readOnly": true, + "title": "Drag And Drop Campaign", + "type": "boolean" + }, + "fb_comments": { + "description": "Allows Facebook comments on the campaign (also force-enables the Campaign Archive toolbar). Defaults to `true`.", + "title": "Facebook Comments", + "type": "boolean" + }, + "folder_id": { + "description": "If the campaign is listed in a folder, the id for that folder.", + "title": "Folder ID", + "type": "string" + }, + "from_name": { + "description": "The 'from' name on the campaign (not an email address).", + "title": "From Name", + "type": "string" + }, + "inline_css": { + "description": "Automatically inline the CSS included with the campaign content.", + "title": "Inline CSS", + "type": "boolean" + }, + "preview_text": { + "description": "The preview text for the campaign.", + "title": "Campaign Preview Text", + "type": "string" + }, + "reply_to": { + "description": "The reply-to email address for the campaign.", + "title": "Reply To Address", + "type": "string" + }, + "subject_line": { + "description": "The subject line for the campaign.", + "title": "Campaign Subject Line", + "type": "string" + }, + "template_id": { + "description": "The id for the template used in this campaign.", + "readOnly": false, + "title": "Template ID", + "type": "integer" + }, + "timewarp": { + "description": "Send this campaign using [Timewarp](https://mailchimp.com/help/use-timewarp/).", + "readOnly": true, + "title": "Timewarp Send", + "type": "boolean" + }, + "title": { + "description": "The title of the campaign.", + "title": "Campaign Title", + "type": "string" + }, + "to_name": { + "description": "The campaign's custom 'To' name. Typically the first name [merge field](https://mailchimp.com/help/getting-started-with-merge-tags/).", + "title": "To Name", + "type": "string" + }, + "use_conversation": { + "description": "Use Mailchimp Conversation feature to manage out-of-office replies.", + "title": "Conversation", + "type": "boolean" + } + }, + "title": "Campaign Settings", + "type": "object" + }, + "social_card": { + "description": "The preview for the campaign, rendered by social networks like Facebook and Twitter. [Learn more](https://mailchimp.com/help/enable-and-customize-social-cards/).", + "properties": { + "description": { + "description": "A short summary of the campaign to display.", + "title": "Campaign Description", + "type": "string" + }, + "image_url": { + "description": "The url for the header image for the card.", + "title": "Image URL", + "type": "string" + }, + "title": { + "description": "The title for the card. Typically the subject line of the campaign.", + "title": "Title", + "type": "string" + } + }, + "title": "Campaign Social Card", + "type": "object" + }, + "status": { + "description": "The current status of the campaign.", + "readOnly": true, + "title": "Campaign Status", + "type": "string" + }, + "tracking": { + "description": "The tracking options for a campaign.", + "properties": { + "capsule": { + "description": "Capsule tracking options for a campaign. Must be using Mailchimp's built-in Capsule integration.", + "properties": { + "notes": { + "description": "Update contact notes for a campaign based on subscriber email addresses.", + "title": "Capsule Note", + "type": "boolean" + } + }, + "title": "Capsule CRM Tracking", + "type": "object" + }, + "clicktale": { + "description": "The custom slug for [ClickTale](https://mailchimp.com/help/additional-tracking-options-for-campaigns/) tracking (max of 50 bytes).", + "title": "ClickTale Analytics Tracking", + "type": "string" + }, + "ecomm360": { + "description": "Whether to enable [eCommerce360](https://mailchimp.com/help/connect-your-online-store-to-mailchimp/) tracking.", + "title": "E-commerce Tracking", + "type": "boolean" + }, + "goal_tracking": { + "description": "Whether to enable [Goal](https://mailchimp.com/help/about-connected-sites/) tracking.", + "title": "Mailchimp Goal Tracking", + "type": "boolean" + }, + "google_analytics": { + "description": "The custom slug for [Google Analytics](https://mailchimp.com/help/integrate-google-analytics-with-mailchimp/) tracking (max of 50 bytes).", + "title": "Google Analytics Tracking", + "type": "string" + }, + "html_clicks": { + "description": "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the HTML version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns.", + "title": "HTML Click Tracking", + "type": "boolean" + }, + "opens": { + "description": "Whether to [track opens](https://mailchimp.com/help/about-open-tracking/). Defaults to `true`. Cannot be set to false for variate campaigns.", + "title": "Opens", + "type": "boolean" + }, + "salesforce": { + "description": "Salesforce tracking options for a campaign. Must be using Mailchimp's built-in [Salesforce integration](https://mailchimp.com/help/integrate-salesforce-with-mailchimp/).", + "properties": { + "campaign": { + "description": "Create a campaign in a connected Salesforce account.", + "title": "Salesforce Campaign", + "type": "boolean" + }, + "notes": { + "description": "Update contact notes for a campaign based on subscriber email addresses.", + "title": "Salesforce Note", + "type": "boolean" + } + }, + "title": "Salesforce CRM Tracking", + "type": "object" + }, + "text_clicks": { + "description": "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the plain-text version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns.", + "title": "Plain-Text Click Tracking", + "type": "boolean" + } + }, + "title": "Campaign Tracking Options", + "type": "object" + }, + "type": { + "description": "There are four types of [campaigns](https://mailchimp.com/help/getting-started-with-campaigns/) you can create in Mailchimp. A/B Split campaigns have been deprecated and variate campaigns should be used instead.", + "title": "Campaign Type", + "type": "string" + }, + "variate_settings": { + "description": "The settings specific to A/B test campaigns.", + "properties": { + "combinations": { + "description": "Combinations of possible variables used to build emails.", + "items": { + "properties": { + "content_description": { + "description": "The index of `variate_settings.contents` used.", + "title": "Content Description", + "type": "integer" + }, + "from_name": { + "description": "The index of `variate_settings.from_names` used.", + "title": "From Name", + "type": "integer" + }, + "id": { + "description": "Unique ID for the combination.", + "title": "ID", + "type": "string" + }, + "recipients": { + "description": "The number of recipients for this combination.", + "title": "Recipients", + "type": "integer" + }, + "reply_to": { + "description": "The index of `variate_settings.reply_to_addresses` used.", + "title": "Reply To", + "type": "integer" + }, + "send_time": { + "description": "The index of `variate_settings.send_times` used.", + "title": "Send Time", + "type": "integer" + }, + "subject_line": { + "description": "The index of `variate_settings.subject_lines` used.", + "title": "Subject Line", + "type": "integer" + } + }, + "type": "object" + }, + "readOnly": true, + "title": "Combinations", + "type": "array" + }, + "contents": { + "description": "Descriptions of possible email contents. To set campaign contents, make a PUT request to /campaigns/{campaign_id}/content with the field 'variate_contents'.", + "items": { + "type": "string" + }, + "readOnly": true, + "title": "Content Descriptions", + "type": "array" + }, + "from_names": { + "description": "The possible from names. The number of from_names provided must match the number of reply_to_addresses. If no from_names are provided, settings.from_name will be used.", + "items": { + "type": "string" + }, + "title": "From Names", + "type": "array" + }, + "reply_to_addresses": { + "description": "The possible reply-to addresses. The number of reply_to_addresses provided must match the number of from_names. If no reply_to_addresses are provided, settings.reply_to will be used.", + "items": { + "type": "string" + }, + "title": "Reply To Addresses", + "type": "array" + }, + "send_times": { + "description": "The possible send times to test. The times provided should be in the format YYYY-MM-DD HH:MM:SS. If send_times are provided to test, the test_size will be set to 100% and winner_criteria will be ignored.", + "items": { + "type": "string" + }, + "title": "Send Times", + "type": "array" + }, + "subject_lines": { + "description": "The possible subject lines to test. If no subject lines are provided, settings.subject_line will be used.", + "items": { + "type": "string" + }, + "title": "Subject Lines", + "type": "array" + }, + "test_size": { + "description": "The percentage of recipients to send the test combinations to, must be a value between 10 and 100.", + "title": "Test Size", + "type": "integer" + }, + "wait_time": { + "description": "The number of minutes to wait before choosing the winning campaign. The value of wait_time must be greater than 0 and in whole hours, specified in minutes.", + "title": "Wait Time", + "type": "integer" + }, + "winner_criteria": { + "description": "The combination that performs the best. This may be determined automatically by click rate, open rate, or total revenue -- or you may choose manually based on the reporting data you find the most valuable. For Multivariate Campaigns testing send_time, winner_criteria is ignored. For Multivariate Campaigns with 'manual' as the winner_criteria, the winner must be chosen in the Mailchimp web application.", + "title": "Winning Criteria", + "type": "string" + }, + "winning_campaign_id": { + "description": "ID of the campaign that was sent to the remaining recipients based on the winning combination.", + "readOnly": true, + "title": "Winning Campaign ID", + "type": "string" + }, + "winning_combination_id": { + "description": "ID for the winning combination.", + "readOnly": true, + "title": "Winning Combination ID", + "type": "string" + } + }, + "title": "A/B Test Options", + "type": "object" + }, + "web_id": { + "description": "The ID used in the Mailchimp web application. View this campaign in your Mailchimp account at `https://{dc}.admin.mailchimp.com/campaigns/show/?id={web_id}`.", + "readOnly": true, + "title": "Campaign Web ID", + "type": "integer" + } + }, + "required": [ + "id" + ], + "title": "Campaign", + "type": "object" + }, + "key": [ + "/id" + ], + "recommendedName": "campaigns", + "resourceConfig": { + "cursorField": [ + "create_time" + ], + "stream": "campaigns", + "syncMode": "incremental" + } + }, + { + "documentSchema": { + "description": "A list of member's subscriber activity in a specific campaign.", + "properties": { + "action": { + "description": "One of the following actions: 'open', 'click', or 'bounce'", + "title": "action", + "type": "string" + }, + "campaign_id": { + "description": "The unique id for the campaign.", + "title": "The unique id for the campaign.", + "type": "string" + }, + "email_address": { + "description": "Email address for a subscriber.", + "title": "Email address for a subscriber.", + "type": "string" + }, + "email_id": { + "description": "The MD5 hash of the lowercase version of the list member's email address.", + "title": "email MD5 hash.", + "type": "string" + }, + "ip": { + "description": "The IP address recorded for the action.", + "title": "Action ip address", + "type": [ + "string", + "null" + ] + }, + "list_id": { + "description": "The unique id for the list.", + "title": "The unique id for the list.", + "type": "string" + }, + "list_is_active": { + "description": "The status of the list used, namely if it's deleted or disabled.", + "title": "The status of the list used.", + "type": "boolean" + }, + "timestamp": { + "description": "The date and time recorded for the action in ISO 8601 format.", + "format": "date-time", + "title": "Action date and time", + "type": "string" + }, + "type": { + "description": "If the action is a 'bounce', the type of bounce received: 'hard', 'soft'.", + "title": "Type", + "type": [ + "string", + "null" + ] + }, + "url": { + "description": "If the action is a 'click', the URL on which the member clicked.", + "title": "Click url", + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "timestamp", + "email_id", + "action" + ], + "title": "Email Activity", + "type": "object" + }, + "key": [ + "/timestamp", + "/email_id", + "/action" + ], + "recommendedName": "email_activity", + "resourceConfig": { + "cursorField": [ + "timestamp" + ], + "stream": "email_activity", + "syncMode": "incremental" + } + }, + { + "documentSchema": { + "description": "A list of reports containing campaigns marked as Sent.", + "properties": { + "ab_split": { + "description": "General stats about different groups of an A/B Split campaign. Does not return information about Multivariate Campaigns.", + "properties": { + "a": { + "description": "Stats for Campaign A.", + "properties": { + "abuse_reports": { + "description": "Abuse reports for Campaign A.", + "title": "Abuse Reports", + "type": "integer" + }, + "bounces": { + "description": "Bounces for Campaign A.", + "title": "Bounces", + "type": "integer" + }, + "forwards": { + "description": "Forwards for Campaign A.", + "title": "Forwards", + "type": "integer" + }, + "forwards_opens": { + "description": "Opens from forwards for Campaign A.", + "title": "Forward Opens", + "type": "integer" + }, + "last_open": { + "description": "The last open for Campaign A.", + "title": "Last Open", + "type": "string" + }, + "opens": { + "description": "Opens for Campaign A.", + "title": "Opens", + "type": "integer" + }, + "recipient_clicks": { + "description": "Recipient Clicks for Campaign A.", + "title": "Recipient Clicks", + "type": "integer" + }, + "unique_opens": { + "description": "Unique opens for Campaign A.", + "title": "Unique Opens", + "type": "integer" + }, + "unsubs": { + "description": "Unsubscribes for Campaign A.", + "title": "Unsubscribes", + "type": "integer" + } + }, + "title": "Campaign A", + "type": "object" + }, + "b": { + "description": "Stats for Campaign B.", + "properties": { + "abuse_reports": { + "description": "Abuse reports for Campaign B.", + "title": "Abuse Reports", + "type": "integer" + }, + "bounces": { + "description": "Bounces for Campaign B.", + "title": "Bounces", + "type": "integer" + }, + "forwards": { + "description": "Forwards for Campaign B.", + "title": "Forwards", + "type": "integer" + }, + "forwards_opens": { + "description": "Opens for forwards from Campaign B.", + "title": "Forward Opens", + "type": "integer" + }, + "last_open": { + "description": "The last open for Campaign B.", + "title": "Last Open", + "type": "string" + }, + "opens": { + "description": "Opens for Campaign B.", + "title": "Opens", + "type": "integer" + }, + "recipient_clicks": { + "description": "Recipients clicks for Campaign B.", + "title": "Recipient Clicks", + "type": "integer" + }, + "unique_opens": { + "description": "Unique opens for Campaign B.", + "title": "Unique Opens", + "type": "integer" + }, + "unsubs": { + "description": "Unsubscribes for Campaign B.", + "title": "Unsubscribes", + "type": "integer" + } + }, + "title": "Campaign B", + "type": "object" + } + }, + "title": "A/B Split Stats", + "type": "object" + }, + "abuse_reports": { + "description": "The number of abuse reports generated for this campaign.", + "title": "Abuse Reports", + "type": "integer" + }, + "bounces": { + "description": "An object describing the bounce summary for the campaign.", + "properties": { + "hard_bounces": { + "description": "The total number of hard bounced email addresses.", + "title": "Hard Bounces", + "type": "integer" + }, + "soft_bounces": { + "description": "The total number of soft bounced email addresses.", + "title": "Soft Bounces", + "type": "integer" + }, + "syntax_errors": { + "description": "The total number of addresses that were syntax-related bounces.", + "title": "Syntax Errors", + "type": "integer" + } + }, + "title": "Bounces", + "type": "object" + }, + "campaign_title": { + "description": "The title of the campaign.", + "readOnly": true, + "title": "Campaign Title", + "type": "string" + }, + "clicks": { + "description": "An object describing the click activity for the campaign.", + "properties": { + "click_rate": { + "description": "The number of unique clicks divided by the total number of successful deliveries.", + "title": "Click Rate", + "type": "number" + }, + "clicks_total": { + "description": "The total number of clicks for the campaign.", + "title": "Total Clicks", + "type": "integer" + }, + "last_click": { + "description": "The date and time of the last recorded click for the campaign in ISO 8601 format.", + "format": "date-time", + "title": "Last Click", + "type": "string" + }, + "unique_clicks": { + "description": "The total number of unique clicks for links across a campaign.", + "title": "Unique Clicks", + "type": "integer" + }, + "unique_subscriber_clicks": { + "description": "The total number of subscribers who clicked on a campaign.", + "title": "Unique Subscriber Clicks", + "type": "integer" + } + }, + "title": "Clicks", + "type": "object" + }, + "delivery_status": { + "description": "Updates on campaigns in the process of sending.", + "properties": { + "can_cancel": { + "description": "Whether a campaign send can be canceled.", + "readOnly": true, + "title": "Campaign Cancelable", + "type": "boolean" + }, + "emails_canceled": { + "description": "The total number of emails canceled for this campaign.", + "readOnly": true, + "title": "Emails Canceled", + "type": "integer" + }, + "emails_sent": { + "description": "The total number of emails confirmed sent for this campaign so far.", + "readOnly": true, + "title": "Emails Sent", + "type": "integer" + }, + "enabled": { + "description": "Whether Campaign Delivery Status is enabled for this account and campaign.", + "readOnly": true, + "title": "Delivery Status Enabled", + "type": "boolean" + }, + "status": { + "description": "The current state of a campaign delivery.", + "readOnly": true, + "title": "Campaign Delivery Status", + "type": "string" + } + }, + "title": "Campaign Delivery Status", + "type": "object" + }, + "ecommerce": { + "description": "E-Commerce stats for a campaign.", + "properties": { + "currency_code": { + "example": "USD", + "readOnly": true, + "title": "Three letter currency code for this user", + "type": "string" + }, + "total_orders": { + "description": "The total orders for a campaign.", + "readOnly": true, + "title": "Total Orders", + "type": "integer" + }, + "total_revenue": { + "description": "The total revenue for a campaign. Calculated as the sum of all order totals minus shipping and tax totals.", + "readOnly": true, + "title": "Total Revenue", + "type": "number" + }, + "total_spent": { + "description": "The total spent for a campaign. Calculated as the sum of all order totals with no deductions.", + "readOnly": true, + "title": "Total Spent", + "type": "number" + } + }, + "title": "E-Commerce Report", + "type": "object" + }, + "emails_sent": { + "description": "The total number of emails sent for this campaign.", + "title": "Emails Sent", + "type": "integer" + }, + "facebook_likes": { + "description": "An object describing campaign engagement on Facebook.", + "properties": { + "facebook_likes": { + "description": "The number of Facebook likes for the campaign.", + "title": "Facebook Likes", + "type": "integer" + }, + "recipient_likes": { + "description": "The number of recipients who liked the campaign on Facebook.", + "title": "Recipient Likes", + "type": "integer" + }, + "unique_likes": { + "description": "The number of unique likes.", + "title": "Unique Likes", + "type": "integer" + } + }, + "title": "Facebook Likes", + "type": "object" + }, + "forwards": { + "description": "An object describing the forwards and forward activity for the campaign.", + "properties": { + "forwards_count": { + "description": "How many times the campaign has been forwarded.", + "title": "Total Forwards", + "type": "integer" + }, + "forwards_opens": { + "description": "How many times the forwarded campaign has been opened.", + "title": "Forward Opens", + "type": "integer" + } + }, + "title": "Forwards", + "type": "object" + }, + "id": { + "description": "A string that uniquely identifies this campaign.", + "title": "Campaign ID", + "type": "string" + }, + "industry_stats": { + "description": "The average campaign statistics for your industry.", + "properties": { + "abuse_rate": { + "description": "The industry abuse rate.", + "title": "Abuse Rate", + "type": "number" + }, + "bounce_rate": { + "description": "The industry bounce rate.", + "title": "Bounce Rate", + "type": "number" + }, + "click_rate": { + "description": "The industry click rate.", + "title": "Click Rate", + "type": "number" + }, + "open_rate": { + "description": "The industry open rate.", + "title": "Open Rate", + "type": "number" + }, + "type": { + "description": "The type of business industry associated with your account. For example: retail, education, etc.", + "title": "Industry Type", + "type": "string" + }, + "unopen_rate": { + "description": "The industry unopened rate.", + "title": "Unopened Rate", + "type": "number" + }, + "unsub_rate": { + "description": "The industry unsubscribe rate.", + "title": "Unsubscribe Rate", + "type": "number" + } + }, + "title": "Industry Stats", + "type": "object" + }, + "list_id": { + "description": "The unique list id.", + "readOnly": true, + "title": "List ID", + "type": "string" + }, + "list_is_active": { + "description": "The status of the list used, namely if it's deleted or disabled.", + "readOnly": true, + "title": "List Status", + "type": "boolean" + }, + "list_name": { + "description": "The name of the list.", + "readOnly": true, + "title": "List Name", + "type": "string" + }, + "list_stats": { + "description": "The average campaign statistics for your list. This won't be present if we haven't calculated it yet for this list.", + "properties": { + "click_rate": { + "description": "The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list.", + "readOnly": true, + "title": "Click Rate", + "type": "number" + }, + "open_rate": { + "description": "The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list.", + "readOnly": true, + "title": "Open Rate", + "type": "number" + }, + "sub_rate": { + "description": "The average number of subscriptions per month for the list.", + "readOnly": true, + "title": "Average Subscription Rate", + "type": "number" + }, + "unsub_rate": { + "description": "The average number of unsubscriptions per month for the list.", + "readOnly": true, + "title": "Average Unsubscription Rate", + "type": "number" + } + }, + "title": "List Stats", + "type": "object" + }, + "opens": { + "description": "An object describing the open activity for the campaign.", + "properties": { + "last_open": { + "description": "The date and time of the last recorded open in ISO 8601 format.", + "format": "date-time", + "title": "Last Open", + "type": "string" + }, + "open_rate": { + "description": "The number of unique opens divided by the total number of successful deliveries.", + "title": "Open Rate", + "type": "number" + }, + "opens_total": { + "description": "The total number of opens for a campaign.", + "title": "Total Opens", + "type": "integer" + }, + "unique_opens": { + "description": "The total number of unique opens.", + "title": "Unique Opens", + "type": "integer" + } + }, + "title": "Opens", + "type": "object" + }, + "preview_text": { + "description": "The preview text for the campaign.", + "title": "Campaign Preview Text", + "type": "string" + }, + "rss_last_send": { + "description": "For RSS campaigns, the date and time of the last send in ISO 8601 format.", + "format": "date-time", + "readOnly": true, + "title": "RSS Last Send", + "type": "string" + }, + "send_time": { + "description": "The date and time a campaign was sent in ISO 8601 format.", + "format": "date-time", + "readOnly": true, + "title": "Send Time", + "type": "string" + }, + "share_report": { + "description": "The url and password for the [VIP report](https://mailchimp.com/help/share-a-campaign-report/).", + "properties": { + "share_password": { + "description": "If password protected, the password for the VIP report.", + "readOnly": true, + "title": "Report Password", + "type": "string" + }, + "share_url": { + "description": "The URL for the VIP report.", + "readOnly": true, + "title": "Report URL", + "type": "string" + } + }, + "title": "Share Report", + "type": "object" + }, + "subject_line": { + "description": "The subject line for the campaign.", + "readOnly": true, + "title": "Campaign Subject Line", + "type": "string" + }, + "timeseries": { + "description": "An hourly breakdown of the performance of the campaign over the first 24 hours.", + "items": { + "properties": { + "emails_sent": { + "description": "The number of emails sent in the timeseries.", + "title": "Emails Sent", + "type": "integer" + }, + "recipients_clicks": { + "description": "The number of clicks in the timeseries.", + "title": "Recipient Clicks", + "type": "integer" + }, + "timestamp": { + "description": "The date and time for the series in ISO 8601 format.", + "format": "date-time", + "title": "Timestamp", + "type": "string" + }, + "unique_opens": { + "description": "The number of unique opens in the timeseries.", + "title": "Unique Opens", + "type": "integer" + } + }, + "type": "object" + }, + "title": "Timeseries", + "type": "array" + }, + "timewarp": { + "description": "An hourly breakdown of sends, opens, and clicks if a campaign is sent using timewarp.", + "items": { + "properties": { + "bounces": { + "description": "The number of bounces.", + "title": "Bounces", + "type": "integer" + }, + "clicks": { + "description": "The number of clicks.", + "title": "Clicks", + "type": "integer" + }, + "gmt_offset": { + "description": "For campaigns sent with timewarp, the time zone group the member is apart of.", + "title": "GMT Offset", + "type": "integer" + }, + "last_click": { + "description": "The date and time of the last click in ISO 8601 format.", + "format": "date-time", + "title": "Last Click", + "type": "string" + }, + "last_open": { + "description": "The date and time of the last open in ISO 8601 format.", + "format": "date-time", + "title": "Last Open", + "type": "string" + }, + "opens": { + "description": "The number of opens.", + "title": "Opens", + "type": "integer" + }, + "unique_clicks": { + "description": "The number of unique clicks.", + "title": "Unique Clicks", + "type": "integer" + }, + "unique_opens": { + "description": "The number of unique opens.", + "title": "Unique Opens", + "type": "integer" + } + }, + "type": "object" + }, + "title": "Timewarp Stats", + "type": "array" + }, + "type": { + "description": "The type of campaign (regular, plain-text, ab_split, rss, automation, variate, or auto).", + "title": "Campaign Type", + "type": "string" + }, + "unsubscribed": { + "description": "The total number of unsubscribed members for this campaign.", + "readOnly": true, + "title": "Unsubscribe Count", + "type": "integer" + } + }, + "required": [ + "id" + ], + "title": "Campaign Reports", + "type": "object" + }, + "key": [ + "/id" + ], + "recommendedName": "reports", + "resourceConfig": { + "cursorField": [ + "send_time" + ], + "stream": "reports", + "syncMode": "incremental" + } + } +] diff --git a/source-mailchimp/tests/snapshots/snapshots__spec__capture.stdout.json b/source-mailchimp/tests/snapshots/snapshots__spec__capture.stdout.json new file mode 100644 index 0000000000..91a1762cb5 --- /dev/null +++ b/source-mailchimp/tests/snapshots/snapshots__spec__capture.stdout.json @@ -0,0 +1,135 @@ +[ + { + "configSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "credentials": { + "discriminator": { + "propertyName": "auth_type" + }, + "oneOf": [ + { + "properties": { + "access_token": { + "airbyte_secret": true, + "description": "An access token generated using the above client ID and secret.", + "title": "Access Token", + "type": "string" + }, + "auth_type": { + "const": "oauth2.0", + "default": "oauth2.0", + "order": 0, + "type": "string" + }, + "client_id": { + "airbyte_secret": true, + "description": "The Client ID of your OAuth application.", + "title": "Client ID", + "type": "string" + }, + "client_secret": { + "airbyte_secret": true, + "description": "The Client Secret of your OAuth application.", + "title": "Client Secret", + "type": "string" + } + }, + "required": [ + "auth_type", + "access_token" + ], + "title": "OAuth2.0", + "type": "object", + "x-oauth2-provider": "mailchimp" + }, + { + "properties": { + "apikey": { + "airbyte_secret": true, + "description": "Mailchimp API Key. See the docs for more information on how to generate this key: https://go.estuary.dev/tmiNoF", + "title": "API Key", + "type": "string" + }, + "auth_type": { + "const": "apikey", + "default": "apikey", + "order": 1, + "type": "string" + } + }, + "required": [ + "auth_type", + "apikey" + ], + "title": "API Key", + "type": "object" + } + ], + "title": "Authentication", + "type": "object" + } + }, + "required": [ + "credentials" + ], + "title": "Mailchimp Spec", + "type": "object" + }, + "documentationUrl": "https://go.estuary.dev/tmiNoF", + "oauth2": { + "accessTokenBody": "grant_type=authorization_code&client_id={{#urlencode}}{{{ client_id }}}{{/urlencode}}&client_secret={{#urlencode}}{{{ client_secret }}}{{/urlencode}}&redirect_uri={{#urlencode}}{{{ redirect_uri }}}{{/urlencode}}&code={{#urlencode}}{{{ code }}}{{/urlencode}}", + "accessTokenHeaders": { + "content-type": "application/x-www-form-urlencoded" + }, + "accessTokenResponseMap": { + "access_token": "/access_token" + }, + "accessTokenUrlTemplate": "https://login.mailchimp.com/oauth2/token", + "authUrlTemplate": "https://login.mailchimp.com/oauth2/authorize?response_type=code&client_id={{#urlencode}}{{{ client_id }}}{{/urlencode}}&redirect_uri={{#urlencode}}{{{ redirect_uri }}}{{/urlencode}}&state={{#urlencode}}{{{ state }}}{{/urlencode}}", + "provider": "mailchimp" + }, + "protocol": 3032023, + "resourceConfigSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "cursorField": { + "items": { + "type": "string" + }, + "type": [ + "array", + "null" + ] + }, + "namespace": { + "type": [ + "string", + "null" + ] + }, + "stream": { + "type": "string" + }, + "syncMode": { + "enum": [ + "incremental", + "full_refresh" + ], + "type": "string" + } + }, + "required": [ + "stream", + "syncMode" + ], + "title": "ResourceSpec", + "type": "object" + }, + "resourcePathPointers": [ + "/namespace", + "/stream" + ] + } +] diff --git a/source-mailchimp/tests/test_snapshots.py b/source-mailchimp/tests/test_snapshots.py new file mode 100644 index 0000000000..9b9d8ece94 --- /dev/null +++ b/source-mailchimp/tests/test_snapshots.py @@ -0,0 +1,73 @@ +import json +import subprocess + +import pytest_insta.format as insta_format +insta_format.FmtJson.dump = lambda _self, path, value: path.write_text(json.dumps(value, sort_keys=True, indent=2) + "\n", "utf-8") + +def test_capture(request, snapshot): + result = subprocess.run( + [ + "flowctl", + "preview", + "--source", + request.fspath.dirname + "/../test.flow.yaml", + "--sessions", + "1", + "--delay", + "20s", + ], + stdout=subprocess.PIPE, + text=True, + ) + assert result.returncode == 0 + lines = [json.loads(l) for l in result.stdout.splitlines()[:50]] + + for l in lines: + typ, rec = l[0], l[1] + + if typ == "acmeCo/lists": + rec["contact"] = "redacted" # removing address info from tests + rec["stats"]["last_sub_date"] = "redacted" + + elif typ == "acmeCo/segment_members": + rec["ip_opt"] = "redacted" + + assert snapshot("capture.stdout.json") == lines + +def test_discover(request, snapshot): + result = subprocess.run( + [ + "flowctl", + "raw", + "discover", + "--source", + request.config.rootdir + "/source-mailchimp/test.flow.yaml", + "-o", + "json", + "--emit-raw" + ], + stdout=subprocess.PIPE, + text=True, + ) + assert result.returncode == 0 + lines = [json.loads(l) for l in result.stdout.splitlines()] + + assert snapshot("capture.stdout.json") == lines + +def test_spec(request, snapshot): + result = subprocess.run( + [ + "flowctl", + "raw", + "spec", + "--source", + request.config.rootdir + "/source-mailchimp/test.flow.yaml" + ], + stdout=subprocess.PIPE, + text=True, + ) + assert result.returncode == 0 + lines = [json.loads(l) for l in result.stdout.splitlines()] + + assert snapshot("capture.stdout.json") == lines + From 1c3db2aa4ec07f0c83dc1caf96a6d6a1fa4810dd Mon Sep 17 00:00:00 2001 From: Luishfs Date: Fri, 26 Apr 2024 10:21:16 -0300 Subject: [PATCH 2/5] import: source-mailchimp through airbyte @ 45dae2c2485b9c7f90db83a106292a259f4daf43 Remote Repo URL: https://github.com/airbytehq/airbyte.git Source name: 45dae2c2485b9c7f90db83a106292a259f4daf43 Source Commit ID: 45dae2c2485b9c7f90db83a106292a259f4daf43 Source Repo Prefix: airbyte-integrations/connectors/source-mailchimp/ Import Path: source-mailchimp/ License Type: MIT License Path: airbyte-integrations/connectors/source-mailchimp/pyproject.toml git-merge-subpath: 45dae2c2485b9c7f90db83a106292a259f4daf43 airbyte-integrations/connectors/source-mailchimp source-mailchimp --- source-mailchimp/README.md | 91 ++ source-mailchimp/acceptance-test-config.yml | 56 + source-mailchimp/icon.svg | 1 + .../integration_tests/__init__.py | 0 .../integration_tests/acceptance.py | 16 + .../integration_tests/configured_catalog.json | 167 ++ ...ured_catalog_without_email_activities.json | 153 ++ .../integration_tests/expected_records.jsonl | 17 + .../integration_tests/invalid_config.json | 4 + .../invalid_config_apikey.json | 6 + .../invalid_config_oauth.json | 8 + source-mailchimp/integration_tests/state.json | 80 + source-mailchimp/main.py | 8 + source-mailchimp/metadata.yaml | 48 + source-mailchimp/poetry.lock | 1049 +++++++++++++ source-mailchimp/pyproject.toml | 29 + source-mailchimp/sample_files/catalog.json | 1370 ++++++++++++++++ .../sample_files/configured_catalog.json | 1381 +++++++++++++++++ source-mailchimp/sample_files/state.json | 11 + source-mailchimp/source_mailchimp/__init__.py | 3 + source-mailchimp/source_mailchimp/run.py | 14 + .../source_mailchimp/schemas/automations.json | 192 +++ .../source_mailchimp/schemas/campaigns.json | 739 +++++++++ .../schemas/email_activity.json | 61 + .../schemas/interest_categories.json | 21 + .../source_mailchimp/schemas/interests.json | 24 + .../schemas/list_members.json | 185 +++ .../source_mailchimp/schemas/lists.json | 308 ++++ .../source_mailchimp/schemas/reports.json | 570 +++++++ .../schemas/segment_members.json | 122 ++ .../source_mailchimp/schemas/segments.json | 58 + .../schemas/shared/addressMergeSegment.json | 32 + .../shared/addressZipWithinSegment.json | 38 + .../schemas/shared/aimSegment.json | 32 + .../schemas/shared/automationSegment.json | 33 + .../schemas/shared/birthdayMergeSegment.json | 32 + .../schemas/shared/campaignPollSegment.json | 33 + .../schemas/shared/campaignStatus.json | 16 + .../schemas/shared/campaignType.json | 13 + .../schemas/shared/conversationSegment.json | 33 + .../schemas/shared/countryStateSegment.json | 38 + .../schemas/shared/dateMergeSegment.json | 32 + .../schemas/shared/dateSegment.json | 48 + .../shared/dropdownRadioMergeSegment.json | 32 + .../schemas/shared/ecommCategorySegment.json | 32 + .../schemas/shared/ecommNumberSegment.json | 38 + .../schemas/shared/ecommPurchasedSegment.json | 26 + .../schemas/shared/ecommSpentSegment.json | 32 + .../schemas/shared/ecommStoreSegment.json | 32 + .../schemas/shared/emailClientSegment.json | 33 + .../schemas/shared/emailSegment.json | 41 + .../schemas/shared/fuzzySegment.json | 33 + .../schemas/shared/geoInSegment.json | 51 + .../schemas/shared/goalActivitySegment.json | 39 + .../schemas/shared/goalTimestampSegment.json | 33 + .../schemas/shared/interestSegment.json | 38 + .../schemas/shared/ipGeoInZipSegment.json | 39 + .../schemas/shared/languageSegment.json | 33 + .../schemas/shared/memberRatingSegment.json | 33 + .../schemas/shared/newSubscribers.json | 29 + .../schemas/shared/predictedAgeSegment.json | 33 + .../shared/predictedGenderSegment.json | 33 + .../schemas/shared/segmentCondition.json | 135 ++ .../schemas/shared/segmentationOptions.json | 27 + .../schemas/shared/signupSourceSegment.json | 33 + .../schemas/shared/socialAgeSegment.json | 34 + .../schemas/shared/socialGenderSegment.json | 34 + .../shared/socialInfluenceSegment.json | 33 + .../shared/socialNetworkFollowSegment.json | 34 + .../schemas/shared/socialNetworkSegment.json | 46 + .../schemas/shared/staticSegment.json | 33 + .../schemas/shared/surveyMonkeySegment.json | 33 + .../shared/textOrNumberMergeSegment.json | 43 + .../schemas/shared/unknownSegment.json | 27 + .../schemas/shared/vipSegment.json | 27 + .../schemas/shared/zipSegment.json | 33 + .../source_mailchimp/schemas/tags.json | 15 + .../schemas/unsubscribes.json | 37 + source-mailchimp/source_mailchimp/source.py | 149 ++ source-mailchimp/source_mailchimp/spec.json | 123 ++ source-mailchimp/source_mailchimp/streams.py | 518 +++++++ source-mailchimp/unit_tests/conftest.py | 77 + source-mailchimp/unit_tests/test_source.py | 116 ++ source-mailchimp/unit_tests/test_streams.py | 696 +++++++++ source-mailchimp/unit_tests/unit_test.py | 13 + source-mailchimp/unit_tests/utils.py | 27 + 86 files changed, 10175 insertions(+) create mode 100644 source-mailchimp/README.md create mode 100644 source-mailchimp/acceptance-test-config.yml create mode 100644 source-mailchimp/icon.svg create mode 100644 source-mailchimp/integration_tests/__init__.py create mode 100644 source-mailchimp/integration_tests/acceptance.py create mode 100644 source-mailchimp/integration_tests/configured_catalog.json create mode 100644 source-mailchimp/integration_tests/configured_catalog_without_email_activities.json create mode 100644 source-mailchimp/integration_tests/expected_records.jsonl create mode 100644 source-mailchimp/integration_tests/invalid_config.json create mode 100644 source-mailchimp/integration_tests/invalid_config_apikey.json create mode 100644 source-mailchimp/integration_tests/invalid_config_oauth.json create mode 100644 source-mailchimp/integration_tests/state.json create mode 100644 source-mailchimp/main.py create mode 100644 source-mailchimp/metadata.yaml create mode 100644 source-mailchimp/poetry.lock create mode 100644 source-mailchimp/pyproject.toml create mode 100644 source-mailchimp/sample_files/catalog.json create mode 100644 source-mailchimp/sample_files/configured_catalog.json create mode 100644 source-mailchimp/sample_files/state.json create mode 100644 source-mailchimp/source_mailchimp/__init__.py create mode 100644 source-mailchimp/source_mailchimp/run.py create mode 100644 source-mailchimp/source_mailchimp/schemas/automations.json create mode 100644 source-mailchimp/source_mailchimp/schemas/campaigns.json create mode 100644 source-mailchimp/source_mailchimp/schemas/email_activity.json create mode 100644 source-mailchimp/source_mailchimp/schemas/interest_categories.json create mode 100644 source-mailchimp/source_mailchimp/schemas/interests.json create mode 100644 source-mailchimp/source_mailchimp/schemas/list_members.json create mode 100644 source-mailchimp/source_mailchimp/schemas/lists.json create mode 100644 source-mailchimp/source_mailchimp/schemas/reports.json create mode 100644 source-mailchimp/source_mailchimp/schemas/segment_members.json create mode 100644 source-mailchimp/source_mailchimp/schemas/segments.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/addressMergeSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/addressZipWithinSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/aimSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/automationSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/birthdayMergeSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/campaignPollSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/campaignStatus.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/campaignType.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/conversationSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/countryStateSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/dateMergeSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/dateSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/dropdownRadioMergeSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/ecommCategorySegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/ecommNumberSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/ecommPurchasedSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/ecommSpentSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/ecommStoreSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/emailClientSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/emailSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/fuzzySegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/geoInSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/goalActivitySegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/goalTimestampSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/interestSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/ipGeoInZipSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/languageSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/memberRatingSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/newSubscribers.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/predictedAgeSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/predictedGenderSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/segmentCondition.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/segmentationOptions.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/signupSourceSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/socialAgeSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/socialGenderSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/socialInfluenceSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/socialNetworkFollowSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/socialNetworkSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/staticSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/surveyMonkeySegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/textOrNumberMergeSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/unknownSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/vipSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/shared/zipSegment.json create mode 100644 source-mailchimp/source_mailchimp/schemas/tags.json create mode 100644 source-mailchimp/source_mailchimp/schemas/unsubscribes.json create mode 100644 source-mailchimp/source_mailchimp/source.py create mode 100644 source-mailchimp/source_mailchimp/spec.json create mode 100644 source-mailchimp/source_mailchimp/streams.py create mode 100644 source-mailchimp/unit_tests/conftest.py create mode 100644 source-mailchimp/unit_tests/test_source.py create mode 100644 source-mailchimp/unit_tests/test_streams.py create mode 100644 source-mailchimp/unit_tests/unit_test.py create mode 100644 source-mailchimp/unit_tests/utils.py diff --git a/source-mailchimp/README.md b/source-mailchimp/README.md new file mode 100644 index 0000000000..2e6d772187 --- /dev/null +++ b/source-mailchimp/README.md @@ -0,0 +1,91 @@ +# Mailchimp source connector + + +This is the repository for the Mailchimp source connector, written in Python. +For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.com/integrations/sources/mailchimp). + +## Local development + +### Prerequisites +* Python (~=3.9) +* Poetry (~=1.7) - installation instructions [here](https://python-poetry.org/docs/#installation) + + +### Installing the connector +From this connector directory, run: +```bash +poetry install --with dev +``` + + +### Create credentials +**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/mailchimp) +to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_mailchimp/spec.yaml` file. +Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. +See `sample_files/sample_config.json` for a sample config file. + + +### Locally running the connector +``` +poetry run source-mailchimp spec +poetry run source-mailchimp check --config secrets/config.json +poetry run source-mailchimp discover --config secrets/config.json +poetry run source-mailchimp read --config secrets/config.json --catalog sample_files/configured_catalog.json +``` + +### Running unit tests +To run unit tests locally, from the connector directory run: +``` +poetry run pytest unit_tests +``` + +### Building the docker image +1. Install [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md) +2. Run the following command to build the docker image: +```bash +airbyte-ci connectors --name=source-mailchimp build +``` + +An image will be available on your host with the tag `airbyte/source-mailchimp:dev`. + + +### Running as a docker container +Then run any of the connector commands as follows: +``` +docker run --rm airbyte/source-mailchimp:dev spec +docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-mailchimp:dev check --config /secrets/config.json +docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-mailchimp:dev discover --config /secrets/config.json +docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-mailchimp:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json +``` + +### Running our CI test suite +You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): +```bash +airbyte-ci connectors --name=source-mailchimp test +``` + +### Customizing acceptance Tests +Customize `acceptance-test-config.yml` file to configure acceptance tests. See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) for more information. +If your connector requires to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py. + +### Dependency Management +All of your dependencies should be managed via Poetry. +To add a new dependency, run: +```bash +poetry add +``` + +Please commit the changes to `pyproject.toml` and `poetry.lock` files. + +## Publishing a new version of the connector +You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what? +1. Make sure your changes are passing our test suite: `airbyte-ci connectors --name=source-mailchimp test` +2. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): + - bump the `dockerImageTag` value in in `metadata.yaml` + - bump the `version` value in `pyproject.toml` +3. Make sure the `metadata.yaml` content is up to date. +4. Make sure the connector documentation and its changelog is up to date (`docs/integrations/sources/mailchimp.md`). +5. Create a Pull Request: use [our PR naming conventions](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#pull-request-title-convention). +6. Pat yourself on the back for being an awesome contributor. +7. Someone from Airbyte will take a look at your PR and iterate with you to merge it into master. +8. Once your PR is merged, the new version of the connector will be automatically published to Docker Hub and our connector registry. \ No newline at end of file diff --git a/source-mailchimp/acceptance-test-config.yml b/source-mailchimp/acceptance-test-config.yml new file mode 100644 index 0000000000..c5aeffc157 --- /dev/null +++ b/source-mailchimp/acceptance-test-config.yml @@ -0,0 +1,56 @@ +connector_image: airbyte/source-mailchimp:dev +test_strictness_level: high +acceptance_tests: + spec: + tests: + - spec_path: "source_mailchimp/spec.json" + connection: + tests: + # for auth with API token + - config_path: "secrets/config.json" + status: "succeed" + # for auth with oauth2 token + - config_path: "secrets/config_oauth.json" + status: "succeed" + - config_path: "integration_tests/invalid_config.json" + status: "failed" + - config_path: "integration_tests/invalid_config_apikey.json" + status: "failed" + - config_path: "integration_tests/invalid_config_oauth.json" + status: "failed" + discovery: + tests: + # for auth with API token + - config_path: "secrets/config.json" + # for auth with oauth2 token + - config_path: "secrets/config_oauth.json" + basic_read: + tests: + - config_path: "secrets/config.json" + expect_records: + path: "integration_tests/expected_records.jsonl" + fail_on_extra_columns: false + empty_streams: + - name: "automations" + bypass_reason: "Cannot seed in free sandbox account, need to upgrade to paid account." + - config_path: "secrets/config_oauth.json" + expect_records: + path: "integration_tests/expected_records.jsonl" + fail_on_extra_columns: false + empty_streams: + - name: "automations" + bypass_reason: "Cannot seed in free sandbox account, need to upgrade to paid account." + incremental: + tests: + - config_path: "secrets/config.json" + configured_catalog_path: "integration_tests/configured_catalog.json" + future_state: + future_state_path: "integration_tests/state.json" + # Email activities stream has working campaigns with email newsletters. + # Due to this sequential_reads test could be failed. + full_refresh: + tests: + - config_path: "secrets/config.json" + configured_catalog_path: "integration_tests/configured_catalog_without_email_activities.json" + - config_path: "secrets/config_oauth.json" + configured_catalog_path: "integration_tests/configured_catalog_without_email_activities.json" diff --git a/source-mailchimp/icon.svg b/source-mailchimp/icon.svg new file mode 100644 index 0000000000..5b135b29c0 --- /dev/null +++ b/source-mailchimp/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/source-mailchimp/integration_tests/__init__.py b/source-mailchimp/integration_tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/source-mailchimp/integration_tests/acceptance.py b/source-mailchimp/integration_tests/acceptance.py new file mode 100644 index 0000000000..43ce950d77 --- /dev/null +++ b/source-mailchimp/integration_tests/acceptance.py @@ -0,0 +1,16 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +import pytest + +pytest_plugins = ("connector_acceptance_test.plugin",) + + +@pytest.fixture(scope="session", autouse=True) +def connector_setup(): + """This fixture is a placeholder for external resources that acceptance test might require.""" + # TODO: setup test dependencies + yield + # TODO: clean up test dependencies diff --git a/source-mailchimp/integration_tests/configured_catalog.json b/source-mailchimp/integration_tests/configured_catalog.json new file mode 100644 index 0000000000..458ab841ad --- /dev/null +++ b/source-mailchimp/integration_tests/configured_catalog.json @@ -0,0 +1,167 @@ +{ + "streams": [ + { + "stream": { + "name": "automations", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["create_time"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["create_time"], + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "campaigns", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["create_time"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["create_time"], + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "interest_categories", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "full_refresh", + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "interests", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "full_refresh", + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "lists", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["date_created"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["date_created"], + "destination_sync_mode": "append", + "primary_key": [["id"]] + }, + { + "stream": { + "name": "email_activity", + "json_schema": {}, + "supported_sync_modes": ["incremental", "full_refresh"], + "source_defined_cursor": true, + "default_cursor_field": ["timestamp"], + "source_defined_primary_key": [["timestamp"], ["email_id"], ["action"]] + }, + "sync_mode": "incremental", + "cursor_field": ["timestamp"], + "primary_key": [["timestamp"], ["email_id"], ["action"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "list_members", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["last_changed"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["last_changed"], + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "reports", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["send_time"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["send_time"], + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "segment_members", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["last_changed"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["last_changed"], + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "segments", + "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" + }, + { + "stream": { + "name": "tags", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "full_refresh", + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "unsubscribes", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["timestamp"], + "source_defined_primary_key": [ + ["campaign_id"], + ["email_id"], + ["timestamp"] + ] + }, + "sync_mode": "incremental", + "cursor_field": ["timestamp"], + "primary_key": [["campaign_id"], ["email_id"], ["timestamp"]], + "destination_sync_mode": "append" + } + ] +} diff --git a/source-mailchimp/integration_tests/configured_catalog_without_email_activities.json b/source-mailchimp/integration_tests/configured_catalog_without_email_activities.json new file mode 100644 index 0000000000..befee3dcfc --- /dev/null +++ b/source-mailchimp/integration_tests/configured_catalog_without_email_activities.json @@ -0,0 +1,153 @@ +{ + "streams": [ + { + "stream": { + "name": "automations", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["create_time"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["create_time"], + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "campaigns", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["create_time"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["create_time"], + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "interest_categories", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "full_refresh", + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "interests", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "full_refresh", + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "lists", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["date_created"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["date_created"], + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "list_members", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["last_changed"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["last_changed"], + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "reports", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["send_time"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["send_time"], + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "segment_members", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["last_changed"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "incremental", + "cursor_field": ["last_changed"], + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "segments", + "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" + }, + { + "stream": { + "name": "tags", + "json_schema": {}, + "supported_sync_modes": ["full_refresh"], + "source_defined_primary_key": [["id"]] + }, + "sync_mode": "full_refresh", + "primary_key": [["id"]], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "unsubscribes", + "json_schema": {}, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["timestamp"], + "source_defined_primary_key": [ + ["campaign_id"], + ["email_id"], + ["timestamp"] + ] + }, + "sync_mode": "incremental", + "cursor_field": ["timestamp"], + "primary_key": [["campaign_id"], ["email_id"], ["timestamp"]], + "destination_sync_mode": "append" + } + ] +} diff --git a/source-mailchimp/integration_tests/expected_records.jsonl b/source-mailchimp/integration_tests/expected_records.jsonl new file mode 100644 index 0000000000..f9a4f79caa --- /dev/null +++ b/source-mailchimp/integration_tests/expected_records.jsonl @@ -0,0 +1,17 @@ +{"stream": "campaigns", "data": {"id": "324b8a398e", "web_id": 13531140, "type": "regular", "create_time": "2022-12-27T08:12:59+00:00", "archive_url": "http://eepurl.com/ig7RxP", "long_archive_url": "https://us10.campaign-archive.com/?u=caf9055242d41edd9215d1898&id=324b8a398e", "status": "save", "emails_sent": 0, "send_time": null, "content_type": "multichannel", "needs_block_refresh": false, "resendable": false, "recipients": {"list_id": "16d6ec4ffc", "list_is_active": true, "list_name": "Airbyte", "segment_text": null, "recipient_count": 47}, "settings": {"title": "Untitled", "use_conversation": false, "to_name": null, "folder_id": null, "authenticate": true, "auto_footer": false, "inline_css": false, "auto_tweet": false, "fb_comments": true, "timewarp": false, "template_id": 13, "drag_and_drop": false}, "tracking": {"opens": true, "html_clicks": true, "text_clicks": false, "goal_tracking": false, "ecomm360": false, "google_analytics": null, "clicktale": null}, "social_card": {"image_url": "https://cdn-images.mailchimp.com/monkey_rewards/grow-business-banner-2.png", "description": null, "title": null}, "delivery_status": {"enabled": false}}, "emitted_at": 1701638872240} +{"stream": "campaigns", "data": {"id": "3cbed9a0fc", "web_id": 13531144, "type": "regular", "create_time": "2022-12-27T08:21:01+00:00", "archive_url": "http://eepurl.com/ig7SKH", "long_archive_url": "https://us10.campaign-archive.com/?u=caf9055242d41edd9215d1898&id=3cbed9a0fc", "status": "save", "emails_sent": 0, "send_time": null, "content_type": "template", "needs_block_refresh": false, "resendable": false, "recipients": {"list_id": "16d6ec4ffc", "list_is_active": true, "list_name": "Airbyte", "segment_text": null, "recipient_count": 47}, "settings": {"title": "Untitled", "use_conversation": false, "to_name": null, "folder_id": null, "authenticate": true, "auto_footer": false, "inline_css": false, "auto_tweet": false, "fb_comments": true, "timewarp": false, "template_id": 145, "drag_and_drop": true}, "tracking": {"opens": true, "html_clicks": true, "text_clicks": false, "goal_tracking": false, "ecomm360": false, "google_analytics": null, "clicktale": null}, "social_card": {"image_url": "https://cdn-images.mailchimp.com/monkey_rewards/grow-business-banner-2.png", "description": null, "title": null}, "delivery_status": {"enabled": false}}, "emitted_at": 1701638872242} +{"stream": "email_activity", "data": {"campaign_id": "7847cdaeff", "list_id": "16d6ec4ffc", "list_is_active": true, "email_id": "11273c9a5dc6ae6c5aaccfb77b2addfb", "email_address": "AirbyteMailchimpUser@gmail.com", "action": "open", "timestamp": "2023-11-06T20:17:57+00:00", "ip": "74.125.212.231"}, "emitted_at": 1701638876052} +{"stream": "email_activity", "data": {"campaign_id": "7847cdaeff", "list_id": "16d6ec4ffc", "list_is_active": true, "email_id": "11273c9a5dc6ae6c5aaccfb77b2addfb", "email_address": "AirbyteMailchimpUser@gmail.com", "action": "open", "timestamp": "2023-11-07T19:49:10+00:00", "ip": "74.125.215.162"}, "emitted_at": 1701638876053} +{"stream": "interests", "data": {"category_id": "a194ba131d", "list_id": "16d6ec4ffc", "id": "bbbb369575", "name": "Donating", "subscriber_count": "0", "display_order": 1}, "emitted_at": 1699963797987} +{"stream": "interest_categories", "data": {"list_id": "16d6ec4ffc", "id": "1bcbe8ba9b", "title": "Product Preferences", "display_order": 0, "type": "checkboxes"}, "emitted_at": 1699963796751} +{"stream": "list_members", "data": {"id": "87ed95f658a2efab665957871270de69", "email_address": "integration-test+yurii@airbyte.io", "unique_email_id": "38619c0ffd", "contact_id": "6ad2f9e1b25a09421fd8df87662b1634", "full_name": "yurii cherniaiev", "web_id": 546044412, "email_type": "html", "status": "subscribed", "consents_to_one_to_one_messaging": true, "merge_fields": {"FNAME": "yurii", "LNAME": "cherniaiev", "ADDRESS": {"addr1": "Airbyte\nkyiv\nKiev 04200\nUkraine", "addr2": null, "city": null, "state": null, "zip": null, "country": "US"}, "PHONE": null, "BIRTHDAY": null}, "interests": {"bbbb369575": false, "97bbc1227a": false, "d802d794f8": false, "b35e48738e": false, "44d2c158e3": false, "29f73b8209": false, "2010f3c101": false, "75f1cb79fd": false, "aa2fd02c59": false, "f7b60a3c3d": false, "7733d60f61": false, "cc454d76d6": false, "797533254b": false, "9ea08b864b": false, "e2e5fdcac9": false, "8eccc648d6": false, "a7c814599e": false, "20ef45c5d3": false, "1824f5d1a5": false, "644f34517f": false, "c57e1a9ff6": false, "b97fee61c8": false, "b9d16768e3": false, "810348679c": false, "43ebb04472": false, "73ee7c1d1b": false, "045738fa17": false, "0a7cbd4449": false, "fef00a4695": false, "4a19201dc9": false, "571a80ed60": false}, "stats": {"avg_open_rate": 1, "avg_click_rate": 1}, "ip_signup": null, "timestamp_signup": null, "ip_opt": "93.73.161.112", "timestamp_opt": "2022-12-27T07:56:47+00:00", "member_rating": 2, "last_changed": "2022-12-27T07:56:47+00:00", "language": null, "vip": false, "email_client": null, "location": {"latitude": 0, "longitude": 0, "gmtoff": 0, "dstoff": 0, "country_code": null, "timezone": null, "region": null}, "source": "Admin Add", "tags_count": 1, "tags": [{"id": 14351504, "name": "Overlord"}], "list_id": "16d6ec4ffc"}, "emitted_at": 1701638878091} +{"stream": "list_members", "data": {"id": "65a02406e7dc3b786af6b94489721e46", "email_address": "integration-test+Jesse@airbyte.io", "unique_email_id": "475570cf37", "contact_id": "6639385c4bdffe110d88044782e37c12", "full_name": "Jesse", "web_id": 546044440, "email_type": "html", "status": "subscribed", "consents_to_one_to_one_messaging": true, "merge_fields": {"FNAME": "Jesse", "LNAME": null, "ADDRESS": null, "PHONE": null, "BIRTHDAY": null}, "interests": {"bbbb369575": false, "97bbc1227a": false, "d802d794f8": false, "b35e48738e": false, "44d2c158e3": false, "29f73b8209": false, "2010f3c101": false, "75f1cb79fd": false, "aa2fd02c59": false, "f7b60a3c3d": false, "7733d60f61": false, "cc454d76d6": false, "797533254b": false, "9ea08b864b": false, "e2e5fdcac9": false, "8eccc648d6": false, "a7c814599e": false, "20ef45c5d3": false, "1824f5d1a5": false, "644f34517f": false, "c57e1a9ff6": false, "b97fee61c8": false, "b9d16768e3": false, "810348679c": false, "43ebb04472": false, "73ee7c1d1b": false, "045738fa17": false, "0a7cbd4449": false, "fef00a4695": false, "4a19201dc9": false, "571a80ed60": false}, "stats": {"avg_open_rate": 1, "avg_click_rate": 0}, "ip_signup": null, "timestamp_signup": null, "ip_opt": "93.73.161.112", "timestamp_opt": "2022-12-27T08:34:38+00:00", "member_rating": 2, "last_changed": "2022-12-27T08:34:38+00:00", "language": null, "vip": false, "email_client": null, "location": {"latitude": 0, "longitude": 0, "gmtoff": 0, "dstoff": 0, "country_code": null, "timezone": null, "region": null}, "source": "Import", "tags_count": 0, "tags": [], "list_id": "16d6ec4ffc"}, "emitted_at": 1701638878092} +{"stream": "lists", "data": {"id": "16d6ec4ffc", "web_id": 903380, "name": "Airbyte", "contact": {"company": "Airbyte", "address1": "kyiv", "address2": null, "city": "Kiev", "state": "30", "zip": "04200", "country": "UA", "phone": null}, "permission_reminder": "You are receiving this email because you opted in via our website.", "use_archive_bar": true, "campaign_defaults": {"from_name": "yurii", "from_email": "integration-test+yurii@airbyte.io", "subject": null, "language": "en"}, "notify_on_subscribe": null, "notify_on_unsubscribe": null, "date_created": "2022-12-27T07:56:47+00:00", "list_rating": 0, "email_type_option": false, "subscribe_url_short": "http://eepurl.com/ihg3RD", "subscribe_url_long": "https://airbyte.us10.list-manage.com/subscribe?u=caf9055242d41edd9215d1898&id=16d6ec4ffc", "beamer_address": "us10-d527bd96ba-6d1a9988db@inbound.mailchimp.com", "visibility": "prv", "double_optin": false, "has_welcome": false, "marketing_permissions": false, "modules": [], "stats": {"member_count": 47, "unsubscribe_count": 4, "cleaned_count": 0, "member_count_since_send": 0, "unsubscribe_count_since_send": 1, "cleaned_count_since_send": 0, "campaign_count": 6, "campaign_last_sent": "2022-12-27T08:37:53+00:00", "merge_field_count": 5, "avg_sub_rate": 0, "avg_unsub_rate": 0, "target_sub_rate": 0, "open_rate": 100, "click_rate": 64.70588235294117, "last_sub_date": "2022-12-27T08:34:39+00:00", "last_unsub_date": "2023-11-06T20:18:01+00:00"}}, "emitted_at": 1701638875717} +{"stream": "reports", "data": {"id": "a79651273b", "campaign_title": "Untitled", "type": "regular", "list_id": "16d6ec4ffc", "list_is_active": true, "list_name": "Airbyte", "subject_line": "Airbyte Test", "preview_text": null, "emails_sent": 50, "abuse_reports": 0, "unsubscribed": 0, "send_time": "2022-12-27T08:36:55+00:00", "bounces": {"hard_bounces": 0, "soft_bounces": 0, "syntax_errors": 0}, "forwards": {"forwards_count": 0, "forwards_opens": 0}, "opens": {"opens_total": 412, "unique_opens": 50, "open_rate": 1, "last_open": "2023-01-09T10:07:54+00:00"}, "clicks": {"clicks_total": 48, "unique_clicks": 47, "unique_subscriber_clicks": 33, "click_rate": 0.66, "last_click": "2022-12-27T15:28:11+00:00"}, "facebook_likes": {"recipient_likes": 0, "unique_likes": 0, "facebook_likes": 0}, "list_stats": {"sub_rate": 0, "unsub_rate": 0, "open_rate": 100, "click_rate": 64.70588235294117}, "timeseries": [{"timestamp": "2022-12-27T08:00:00+00:00", "emails_sent": 50, "unique_opens": 6, "recipients_clicks": 1}, {"timestamp": "2022-12-27T09:00:00+00:00", "emails_sent": 0, "unique_opens": 43, "recipients_clicks": 0}, {"timestamp": "2022-12-27T10:00:00+00:00", "emails_sent": 0, "unique_opens": 1, "recipients_clicks": 3}, {"timestamp": "2022-12-27T11:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 11}, {"timestamp": "2022-12-27T12:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 10}, {"timestamp": "2022-12-27T13:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 3}, {"timestamp": "2022-12-27T14:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 2}, {"timestamp": "2022-12-27T15:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 3}, {"timestamp": "2022-12-27T16:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-27T17:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-27T18:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-27T19:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-27T20:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-27T21:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-27T22:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-27T23:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-28T00:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-28T01:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-28T02:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-28T03:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-28T04:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-28T05:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-28T06:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-28T07:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}], "ecommerce": {"total_orders": 0, "total_spent": 0, "total_revenue": 0, "currency_code": "USD"}, "delivery_status": {"enabled": false}}, "emitted_at": 1701638878519} +{"stream": "reports", "data": {"id": "7847cdaeff", "campaign_title": "Invitation to unsubscribe", "type": "regular", "list_id": "16d6ec4ffc", "list_is_active": true, "list_name": "Airbyte", "subject_line": "Invitation to Unsubscribe", "preview_text": null, "emails_sent": 1, "abuse_reports": 0, "unsubscribed": 1, "send_time": "2023-11-06T20:17:44+00:00", "bounces": {"hard_bounces": 0, "soft_bounces": 0, "syntax_errors": 0}, "forwards": {"forwards_count": 0, "forwards_opens": 0}, "opens": {"opens_total": 2, "unique_opens": 1, "open_rate": 1, "last_open": "2023-11-07T19:49:10+00:00"}, "clicks": {"clicks_total": 0, "unique_clicks": 0, "unique_subscriber_clicks": 0, "click_rate": 0, "last_click": null}, "facebook_likes": {"recipient_likes": 0, "unique_likes": 0, "facebook_likes": 0}, "list_stats": {"sub_rate": 0, "unsub_rate": 0, "open_rate": 100, "click_rate": 64.70588235294117}, "timeseries": [{"timestamp": "2023-11-06T20:00:00+00:00", "emails_sent": 1, "unique_opens": 1, "recipients_clicks": 0}, {"timestamp": "2023-11-06T21:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-06T22:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-06T23:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T00:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T01:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T02:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T03:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T04:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T05:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T06:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T07:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T08:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T09:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T10:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T11:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T12:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T13:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T14:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T15:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T16:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T17:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T18:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T19:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}], "ecommerce": {"total_orders": 0, "total_spent": 0, "total_revenue": 0, "currency_code": "USD"}, "delivery_status": {"enabled": false}}, "emitted_at": 1701638878520} +{"stream": "segment_members", "data": {"id": "1dd067951f91190b65b43305b9166bc7", "email_address": "integration-test+Michael@airbyte.io", "unique_email_id": "904643439a", "email_type": "html", "status": "subscribed", "merge_fields": {"FNAME": "Michael", "LNAME": null, "ADDRESS": null, "PHONE": null, "BIRTHDAY": null}, "interests": {"bbbb369575": false, "97bbc1227a": false, "d802d794f8": false, "b35e48738e": false, "44d2c158e3": false, "29f73b8209": false, "2010f3c101": false, "75f1cb79fd": false, "aa2fd02c59": false, "f7b60a3c3d": false, "7733d60f61": false, "cc454d76d6": false, "797533254b": false, "9ea08b864b": false, "e2e5fdcac9": false, "8eccc648d6": false, "a7c814599e": false, "20ef45c5d3": false, "1824f5d1a5": false, "644f34517f": false, "c57e1a9ff6": false, "b97fee61c8": false, "b9d16768e3": false, "810348679c": false, "43ebb04472": false, "73ee7c1d1b": false, "045738fa17": false, "0a7cbd4449": false, "fef00a4695": false, "4a19201dc9": false, "571a80ed60": false}, "stats": {"avg_open_rate": 1, "avg_click_rate": 0}, "ip_signup": null, "timestamp_signup": null, "ip_opt": "93.73.161.112", "timestamp_opt": "2022-12-27T08:34:39+00:00", "member_rating": 2, "last_changed": "2022-12-27T08:34:39+00:00", "language": null, "vip": false, "email_client": null, "location": {"latitude": 0, "longitude": 0, "gmtoff": 0, "dstoff": 0, "country_code": null, "timezone": null}, "list_id": "16d6ec4ffc", "segment_id": 13506120}, "emitted_at": 1701638879995} +{"stream": "segment_members", "data": {"id": "802cb9cc84d031ca07cbf9efa3dcdc2c", "email_address": "integration-test+Carlos@airbyte.io", "unique_email_id": "41ec088075", "email_type": "html", "status": "subscribed", "merge_fields": {"FNAME": "Carlos", "LNAME": null, "ADDRESS": null, "PHONE": null, "BIRTHDAY": null}, "interests": {"bbbb369575": false, "97bbc1227a": false, "d802d794f8": false, "b35e48738e": false, "44d2c158e3": false, "29f73b8209": false, "2010f3c101": false, "75f1cb79fd": false, "aa2fd02c59": false, "f7b60a3c3d": false, "7733d60f61": false, "cc454d76d6": false, "797533254b": false, "9ea08b864b": false, "e2e5fdcac9": false, "8eccc648d6": false, "a7c814599e": false, "20ef45c5d3": false, "1824f5d1a5": false, "644f34517f": false, "c57e1a9ff6": false, "b97fee61c8": false, "b9d16768e3": false, "810348679c": false, "43ebb04472": false, "73ee7c1d1b": false, "045738fa17": false, "0a7cbd4449": false, "fef00a4695": false, "4a19201dc9": false, "571a80ed60": false}, "stats": {"avg_open_rate": 1, "avg_click_rate": 0}, "ip_signup": null, "timestamp_signup": null, "ip_opt": "93.73.161.112", "timestamp_opt": "2022-12-27T08:34:39+00:00", "member_rating": 2, "last_changed": "2022-12-27T08:34:39+00:00", "language": null, "vip": false, "email_client": null, "location": {"latitude": 0, "longitude": 0, "gmtoff": 0, "dstoff": 0, "country_code": null, "timezone": null}, "list_id": "16d6ec4ffc", "segment_id": 13506120}, "emitted_at": 1701638879996} +{"stream": "segments", "data": {"id": 13506120, "name": "Customer", "member_count": 2, "type": "static", "created_at": "2022-12-27T08:12:06+00:00", "updated_at": "2022-12-27T08:12:55+00:00", "list_id": "16d6ec4ffc"}, "emitted_at": 1701638883128} +{"stream": "segments", "data": {"id": 13506124, "name": "Member", "member_count": 0, "type": "static", "created_at": "2022-12-27T08:12:06+00:00", "updated_at": "2022-12-27T08:28:44+00:00", "list_id": "16d6ec4ffc"}, "emitted_at": 1701638883129} +{"stream": "tags", "data": {"id": 13506128, "name": "2022", "list_id": "16d6ec4ffc"}, "emitted_at": 1699963804499} +{"stream": "unsubscribes", "data": {"email_id": "11273c9a5dc6ae6c5aaccfb77b2addfb", "email_address": "AirbyteMailchimpUser@gmail.com", "merge_fields": {"FNAME": "Joe", "LNAME": "Barry", "ADDRESS": {"addr1": "109 Barry St", "addr2": null, "city": "Gary", "state": "IN", "zip": "46401", "country": "US"}, "PHONE": null, "BIRTHDAY": null}, "vip": false, "timestamp": "2023-11-06T20:18:01+00:00", "reason": "Did not signup for list", "campaign_id": "7847cdaeff", "list_id": "16d6ec4ffc", "list_is_active": true}, "emitted_at": 1701638884243} diff --git a/source-mailchimp/integration_tests/invalid_config.json b/source-mailchimp/integration_tests/invalid_config.json new file mode 100644 index 0000000000..308434ab6d --- /dev/null +++ b/source-mailchimp/integration_tests/invalid_config.json @@ -0,0 +1,4 @@ +{ + "apikey": "api-key-awesome", + "username": "fakemaster@silly.com" +} diff --git a/source-mailchimp/integration_tests/invalid_config_apikey.json b/source-mailchimp/integration_tests/invalid_config_apikey.json new file mode 100644 index 0000000000..f2fd16517b --- /dev/null +++ b/source-mailchimp/integration_tests/invalid_config_apikey.json @@ -0,0 +1,6 @@ +{ + "credentials": { + "auth_type": "apikey", + "apikey": "api-key-awesome" + } +} diff --git a/source-mailchimp/integration_tests/invalid_config_oauth.json b/source-mailchimp/integration_tests/invalid_config_oauth.json new file mode 100644 index 0000000000..ef7ef97ee2 --- /dev/null +++ b/source-mailchimp/integration_tests/invalid_config_oauth.json @@ -0,0 +1,8 @@ +{ + "credentials": { + "auth_type": "oauth2.0", + "client_id": "client_id", + "client_secret": "client_secret", + "access_token": "access_token" + } +} diff --git a/source-mailchimp/integration_tests/state.json b/source-mailchimp/integration_tests/state.json new file mode 100644 index 0000000000..26b656926f --- /dev/null +++ b/source-mailchimp/integration_tests/state.json @@ -0,0 +1,80 @@ +[ + { + "type": "STREAM", + "stream": { + "stream_state": { "create_time": "2220-11-23T05:42:11+00:00" }, + "stream_descriptor": { "name": "campaigns" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "date_created": "2220-09-25T04:47:31+00:00" }, + "stream_descriptor": { "name": "lists" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "create_time": "2220-11-23T05:42:11+00:00" }, + "stream_descriptor": { "name": "automations" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { + "7847cdaeff": { "timestamp": "2230-11-23T05:42:10+00:00" } + }, + "stream_descriptor": { "name": "email_activity" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { + "16d6ec4ffc": { "last_changed": "2230-02-26T05:42:10+00:00" } + }, + "stream_descriptor": { "name": "list_members" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { "send_time": "2230-02-26T05:42:10+00:00" }, + "stream_descriptor": { "name": "reports" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { + "13506120": { "last_changed": "2222-12-27T08:34:39+00:00" }, + "13506136": { "last_changed": "2222-12-27T08:34:39+00:00" }, + "14351124": { "last_changed": "2222-12-27T08:34:39+00:00" }, + "14351504": { "last_changed": "2222-12-27T07:56:47+00:00" }, + "14351128": { "last_changed": "2222-12-27T08:34:39+00:00" }, + "13506132": { "last_changed": "2222-12-27T08:34:39+00:00" } + }, + "stream_descriptor": { "name": "segment_members" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { + "16d6ec4ffc": { "updated_at": "2230-02-26T05:42:10+00:00" } + }, + "stream_descriptor": { "name": "segments" } + } + }, + { + "type": "STREAM", + "stream": { + "stream_state": { + "7847cdaeff": { "timestamp": "2231-09-26T05:42:10+00:00" } + }, + "stream_descriptor": { "name": "unsubscribes" } + } + } +] diff --git a/source-mailchimp/main.py b/source-mailchimp/main.py new file mode 100644 index 0000000000..c61875fb7a --- /dev/null +++ b/source-mailchimp/main.py @@ -0,0 +1,8 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +from source_mailchimp.run import run + +if __name__ == "__main__": + run() diff --git a/source-mailchimp/metadata.yaml b/source-mailchimp/metadata.yaml new file mode 100644 index 0000000000..eb22bc1ef3 --- /dev/null +++ b/source-mailchimp/metadata.yaml @@ -0,0 +1,48 @@ +data: + ab_internal: + ql: 200 + sl: 200 + allowedHosts: + hosts: + - "*.api.mailchimp.com" + connectorBuildOptions: + baseImage: docker.io/airbyte/python-connector-base:1.1.0@sha256:bd98f6505c6764b1b5f99d3aedc23dfc9e9af631a62533f60eb32b1d3dbab20c + connectorSubtype: api + connectorType: source + definitionId: b03a9f3e-22a5-11eb-adc1-0242ac120002 + dockerImageTag: 1.2.0 + dockerRepository: airbyte/source-mailchimp + documentationUrl: https://docs.airbyte.com/integrations/sources/mailchimp + githubIssueLabel: source-mailchimp + icon: mailchimp.svg + license: MIT + name: Mailchimp + remoteRegistries: + pypi: + enabled: true + packageName: airbyte-source-mailchimp + registries: + cloud: + enabled: true + oss: + enabled: true + releases: + breakingChanges: + 1.0.0: + message: + Version 1.0.0 introduces schema changes to all incremental streams. + A full schema refresh and data reset are required to upgrade to this version. + For more details, see our migration guide. + upgradeDeadline: "2024-01-10" + releaseStage: generally_available + suggestedStreams: + streams: + - email_activity + - campaigns + - lists + - reports + supportLevel: certified + tags: + - language:python + - cdk:python +metadataSpecVersion: "1.0" diff --git a/source-mailchimp/poetry.lock b/source-mailchimp/poetry.lock new file mode 100644 index 0000000000..af61bd6aa3 --- /dev/null +++ b/source-mailchimp/poetry.lock @@ -0,0 +1,1049 @@ +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. + +[[package]] +name = "airbyte-cdk" +version = "0.77.2" +description = "A framework for writing Airbyte Connectors." +optional = false +python-versions = "<4.0,>=3.9" +files = [ + {file = "airbyte_cdk-0.77.2-py3-none-any.whl", hash = "sha256:6dffbe0c4b3454a5cdd20525b4f1e9cfef2e80c005b6b30473fc5bf6f75af64e"}, + {file = "airbyte_cdk-0.77.2.tar.gz", hash = "sha256:84aeb27862a18e135c7bc3a5dfc363037665d428e7495e8824673f853adcca70"}, +] + +[package.dependencies] +airbyte-protocol-models = "0.5.1" +backoff = "*" +cachetools = "*" +Deprecated = ">=1.2,<1.3" +dpath = ">=2.0.1,<2.1.0" +genson = "1.2.2" +isodate = ">=0.6.1,<0.7.0" +Jinja2 = ">=3.1.2,<3.2.0" +jsonref = ">=0.2,<0.3" +jsonschema = ">=3.2.0,<3.3.0" +pendulum = "<3.0.0" +pydantic = ">=1.10.8,<2.0.0" +pyrate-limiter = ">=3.1.0,<3.2.0" +python-dateutil = "*" +PyYAML = ">=6.0.1,<7.0.0" +requests = "*" +requests_cache = "*" +wcmatch = "8.4" + +[package.extras] +file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] +sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] +vector-db-based = ["cohere (==4.21)", "langchain (==0.0.271)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] + +[[package]] +name = "airbyte-protocol-models" +version = "0.5.1" +description = "Declares the Airbyte Protocol." +optional = false +python-versions = ">=3.8" +files = [ + {file = "airbyte_protocol_models-0.5.1-py3-none-any.whl", hash = "sha256:dfe84e130e51ce2ae81a06d5aa36f6c5ce3152b9e36e6f0195fad6c3dab0927e"}, + {file = "airbyte_protocol_models-0.5.1.tar.gz", hash = "sha256:7c8b16c7c1c7956b1996052e40585a3a93b1e44cb509c4e97c1ee4fe507ea086"}, +] + +[package.dependencies] +pydantic = ">=1.9.2,<2.0.0" + +[[package]] +name = "atomicwrites" +version = "1.4.1" +description = "Atomic file writes." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, +] + +[[package]] +name = "attrs" +version = "23.2.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, +] + +[package.extras] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] + +[[package]] +name = "backoff" +version = "2.2.1" +description = "Function decoration for backoff and retry" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, + {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, +] + +[[package]] +name = "bracex" +version = "2.4" +description = "Bash style brace expander." +optional = false +python-versions = ">=3.8" +files = [ + {file = "bracex-2.4-py3-none-any.whl", hash = "sha256:efdc71eff95eaff5e0f8cfebe7d01adf2c8637c8c92edaf63ef348c241a82418"}, + {file = "bracex-2.4.tar.gz", hash = "sha256:a27eaf1df42cf561fed58b7a8f3fdf129d1ea16a81e1fadd1d17989bc6384beb"}, +] + +[[package]] +name = "cachetools" +version = "5.3.3" +description = "Extensible memoizing collections and decorators" +optional = false +python-versions = ">=3.7" +files = [ + {file = "cachetools-5.3.3-py3-none-any.whl", hash = "sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945"}, + {file = "cachetools-5.3.3.tar.gz", hash = "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"}, +] + +[[package]] +name = "cattrs" +version = "23.2.3" +description = "Composable complex class support for attrs and dataclasses." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cattrs-23.2.3-py3-none-any.whl", hash = "sha256:0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108"}, + {file = "cattrs-23.2.3.tar.gz", hash = "sha256:a934090d95abaa9e911dac357e3a8699e0b4b14f8529bcc7d2b1ad9d51672b9f"}, +] + +[package.dependencies] +attrs = ">=23.1.0" +exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} + +[package.extras] +bson = ["pymongo (>=4.4.0)"] +cbor2 = ["cbor2 (>=5.4.6)"] +msgpack = ["msgpack (>=1.0.5)"] +orjson = ["orjson (>=3.9.2)"] +pyyaml = ["pyyaml (>=6.0)"] +tomlkit = ["tomlkit (>=0.11.8)"] +ujson = ["ujson (>=5.7.0)"] + +[[package]] +name = "certifi" +version = "2024.2.2" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "deprecated" +version = "1.2.14" +description = "Python @deprecated decorator to deprecate old python classes, functions or methods." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, + {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, +] + +[package.dependencies] +wrapt = ">=1.10,<2" + +[package.extras] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] + +[[package]] +name = "dpath" +version = "2.0.8" +description = "Filesystem-like pathing and searching for dictionaries" +optional = false +python-versions = ">=3.7" +files = [ + {file = "dpath-2.0.8-py3-none-any.whl", hash = "sha256:f92f595214dd93a00558d75d4b858beee519f4cffca87f02616ad6cd013f3436"}, + {file = "dpath-2.0.8.tar.gz", hash = "sha256:a3440157ebe80d0a3ad794f1b61c571bef125214800ffdb9afc9424e8250fe9b"}, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.0" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, + {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "genson" +version = "1.2.2" +description = "GenSON is a powerful, user-friendly JSON Schema generator." +optional = false +python-versions = "*" +files = [ + {file = "genson-1.2.2.tar.gz", hash = "sha256:8caf69aa10af7aee0e1a1351d1d06801f4696e005f06cedef438635384346a16"}, +] + +[[package]] +name = "idna" +version = "3.6" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, + {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "isodate" +version = "0.6.1" +description = "An ISO 8601 date/time/duration parser and formatter" +optional = false +python-versions = "*" +files = [ + {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, + {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "jinja2" +version = "3.1.3" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, + {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "jsonref" +version = "0.2" +description = "An implementation of JSON Reference for Python" +optional = false +python-versions = "*" +files = [ + {file = "jsonref-0.2-py3-none-any.whl", hash = "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f"}, + {file = "jsonref-0.2.tar.gz", hash = "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697"}, +] + +[[package]] +name = "jsonschema" +version = "3.2.0" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = "*" +files = [ + {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, + {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, +] + +[package.dependencies] +attrs = ">=17.4.0" +pyrsistent = ">=0.14.0" +setuptools = "*" +six = ">=1.11.0" + +[package.extras] +format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] +format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] + +[[package]] +name = "markupsafe" +version = "2.1.5" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +] + +[[package]] +name = "packaging" +version = "24.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, + {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, +] + +[[package]] +name = "pendulum" +version = "2.1.2" +description = "Python datetimes made easy" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, + {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, + {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, + {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, + {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, + {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, + {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, + {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, + {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, + {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, + {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, + {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, + {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, + {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, + {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, + {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, + {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, + {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, + {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, + {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, + {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, +] + +[package.dependencies] +python-dateutil = ">=2.6,<3.0" +pytzdata = ">=2020.1" + +[[package]] +name = "platformdirs" +version = "4.2.0" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, + {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] + +[[package]] +name = "pluggy" +version = "1.4.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, + {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "py" +version = "1.11.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] + +[[package]] +name = "pydantic" +version = "1.10.14" +description = "Data validation and settings management using python type hints" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic-1.10.14-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f4fcec873f90537c382840f330b90f4715eebc2bc9925f04cb92de593eae054"}, + {file = "pydantic-1.10.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e3a76f571970fcd3c43ad982daf936ae39b3e90b8a2e96c04113a369869dc87"}, + {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d886bd3c3fbeaa963692ef6b643159ccb4b4cefaf7ff1617720cbead04fd1d"}, + {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:798a3d05ee3b71967844a1164fd5bdb8c22c6d674f26274e78b9f29d81770c4e"}, + {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:23d47a4b57a38e8652bcab15a658fdb13c785b9ce217cc3a729504ab4e1d6bc9"}, + {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f9f674b5c3bebc2eba401de64f29948ae1e646ba2735f884d1594c5f675d6f2a"}, + {file = "pydantic-1.10.14-cp310-cp310-win_amd64.whl", hash = "sha256:24a7679fab2e0eeedb5a8924fc4a694b3bcaac7d305aeeac72dd7d4e05ecbebf"}, + {file = "pydantic-1.10.14-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d578ac4bf7fdf10ce14caba6f734c178379bd35c486c6deb6f49006e1ba78a7"}, + {file = "pydantic-1.10.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa7790e94c60f809c95602a26d906eba01a0abee9cc24150e4ce2189352deb1b"}, + {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad4e10efa5474ed1a611b6d7f0d130f4aafadceb73c11d9e72823e8f508e663"}, + {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1245f4f61f467cb3dfeced2b119afef3db386aec3d24a22a1de08c65038b255f"}, + {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:21efacc678a11114c765eb52ec0db62edffa89e9a562a94cbf8fa10b5db5c046"}, + {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:412ab4a3f6dbd2bf18aefa9f79c7cca23744846b31f1d6555c2ee2b05a2e14ca"}, + {file = "pydantic-1.10.14-cp311-cp311-win_amd64.whl", hash = "sha256:e897c9f35281f7889873a3e6d6b69aa1447ceb024e8495a5f0d02ecd17742a7f"}, + {file = "pydantic-1.10.14-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d604be0f0b44d473e54fdcb12302495fe0467c56509a2f80483476f3ba92b33c"}, + {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42c7d17706911199798d4c464b352e640cab4351efe69c2267823d619a937e5"}, + {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:596f12a1085e38dbda5cbb874d0973303e34227b400b6414782bf205cc14940c"}, + {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bfb113860e9288d0886e3b9e49d9cf4a9d48b441f52ded7d96db7819028514cc"}, + {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bc3ed06ab13660b565eed80887fcfbc0070f0aa0691fbb351657041d3e874efe"}, + {file = "pydantic-1.10.14-cp37-cp37m-win_amd64.whl", hash = "sha256:ad8c2bc677ae5f6dbd3cf92f2c7dc613507eafe8f71719727cbc0a7dec9a8c01"}, + {file = "pydantic-1.10.14-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c37c28449752bb1f47975d22ef2882d70513c546f8f37201e0fec3a97b816eee"}, + {file = "pydantic-1.10.14-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49a46a0994dd551ec051986806122767cf144b9702e31d47f6d493c336462597"}, + {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53e3819bd20a42470d6dd0fe7fc1c121c92247bca104ce608e609b59bc7a77ee"}, + {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbb503bbbbab0c588ed3cd21975a1d0d4163b87e360fec17a792f7d8c4ff29f"}, + {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:336709883c15c050b9c55a63d6c7ff09be883dbc17805d2b063395dd9d9d0022"}, + {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4ae57b4d8e3312d486e2498d42aed3ece7b51848336964e43abbf9671584e67f"}, + {file = "pydantic-1.10.14-cp38-cp38-win_amd64.whl", hash = "sha256:dba49d52500c35cfec0b28aa8b3ea5c37c9df183ffc7210b10ff2a415c125c4a"}, + {file = "pydantic-1.10.14-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c66609e138c31cba607d8e2a7b6a5dc38979a06c900815495b2d90ce6ded35b4"}, + {file = "pydantic-1.10.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d986e115e0b39604b9eee3507987368ff8148222da213cd38c359f6f57b3b347"}, + {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:646b2b12df4295b4c3148850c85bff29ef6d0d9621a8d091e98094871a62e5c7"}, + {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282613a5969c47c83a8710cc8bfd1e70c9223feb76566f74683af889faadc0ea"}, + {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:466669501d08ad8eb3c4fecd991c5e793c4e0bbd62299d05111d4f827cded64f"}, + {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:13e86a19dca96373dcf3190fcb8797d40a6f12f154a244a8d1e8e03b8f280593"}, + {file = "pydantic-1.10.14-cp39-cp39-win_amd64.whl", hash = "sha256:08b6ec0917c30861e3fe71a93be1648a2aa4f62f866142ba21670b24444d7fd8"}, + {file = "pydantic-1.10.14-py3-none-any.whl", hash = "sha256:8ee853cd12ac2ddbf0ecbac1c289f95882b2d4482258048079d13be700aa114c"}, + {file = "pydantic-1.10.14.tar.gz", hash = "sha256:46f17b832fe27de7850896f3afee50ea682220dd218f7e9c88d436788419dca6"}, +] + +[package.dependencies] +typing-extensions = ">=4.2.0" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] + +[[package]] +name = "pyrate-limiter" +version = "3.1.1" +description = "Python Rate-Limiter using Leaky-Bucket Algorithm" +optional = false +python-versions = ">=3.8,<4.0" +files = [ + {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, + {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, +] + +[package.extras] +all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] +docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] + +[[package]] +name = "pyrsistent" +version = "0.20.0" +description = "Persistent/Functional/Immutable data structures" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pyrsistent-0.20.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c3aba3e01235221e5b229a6c05f585f344734bd1ad42a8ac51493d74722bbce"}, + {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1beb78af5423b879edaf23c5591ff292cf7c33979734c99aa66d5914ead880f"}, + {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cc459636983764e692b9eba7144cdd54fdec23ccdb1e8ba392a63666c60c34"}, + {file = "pyrsistent-0.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5ac696f02b3fc01a710427585c855f65cd9c640e14f52abe52020722bb4906b"}, + {file = "pyrsistent-0.20.0-cp310-cp310-win32.whl", hash = "sha256:0724c506cd8b63c69c7f883cc233aac948c1ea946ea95996ad8b1380c25e1d3f"}, + {file = "pyrsistent-0.20.0-cp310-cp310-win_amd64.whl", hash = "sha256:8441cf9616d642c475684d6cf2520dd24812e996ba9af15e606df5f6fd9d04a7"}, + {file = "pyrsistent-0.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f3b1bcaa1f0629c978b355a7c37acd58907390149b7311b5db1b37648eb6958"}, + {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cdd7ef1ea7a491ae70d826b6cc64868de09a1d5ff9ef8d574250d0940e275b8"}, + {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cae40a9e3ce178415040a0383f00e8d68b569e97f31928a3a8ad37e3fde6df6a"}, + {file = "pyrsistent-0.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6288b3fa6622ad8a91e6eb759cfc48ff3089e7c17fb1d4c59a919769314af224"}, + {file = "pyrsistent-0.20.0-cp311-cp311-win32.whl", hash = "sha256:7d29c23bdf6e5438c755b941cef867ec2a4a172ceb9f50553b6ed70d50dfd656"}, + {file = "pyrsistent-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:59a89bccd615551391f3237e00006a26bcf98a4d18623a19909a2c48b8e986ee"}, + {file = "pyrsistent-0.20.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:09848306523a3aba463c4b49493a760e7a6ca52e4826aa100ee99d8d39b7ad1e"}, + {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a14798c3005ec892bbada26485c2eea3b54109cb2533713e355c806891f63c5e"}, + {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b14decb628fac50db5e02ee5a35a9c0772d20277824cfe845c8a8b717c15daa3"}, + {file = "pyrsistent-0.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e2c116cc804d9b09ce9814d17df5edf1df0c624aba3b43bc1ad90411487036d"}, + {file = "pyrsistent-0.20.0-cp312-cp312-win32.whl", hash = "sha256:e78d0c7c1e99a4a45c99143900ea0546025e41bb59ebc10182e947cf1ece9174"}, + {file = "pyrsistent-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:4021a7f963d88ccd15b523787d18ed5e5269ce57aa4037146a2377ff607ae87d"}, + {file = "pyrsistent-0.20.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:79ed12ba79935adaac1664fd7e0e585a22caa539dfc9b7c7c6d5ebf91fb89054"}, + {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f920385a11207dc372a028b3f1e1038bb244b3ec38d448e6d8e43c6b3ba20e98"}, + {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f5c2d012671b7391803263419e31b5c7c21e7c95c8760d7fc35602353dee714"}, + {file = "pyrsistent-0.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef3992833fbd686ee783590639f4b8343a57f1f75de8633749d984dc0eb16c86"}, + {file = "pyrsistent-0.20.0-cp38-cp38-win32.whl", hash = "sha256:881bbea27bbd32d37eb24dd320a5e745a2a5b092a17f6debc1349252fac85423"}, + {file = "pyrsistent-0.20.0-cp38-cp38-win_amd64.whl", hash = "sha256:6d270ec9dd33cdb13f4d62c95c1a5a50e6b7cdd86302b494217137f760495b9d"}, + {file = "pyrsistent-0.20.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ca52d1ceae015859d16aded12584c59eb3825f7b50c6cfd621d4231a6cc624ce"}, + {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b318ca24db0f0518630e8b6f3831e9cba78f099ed5c1d65ffe3e023003043ba0"}, + {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed2c3216a605dc9a6ea50c7e84c82906e3684c4e80d2908208f662a6cbf9022"}, + {file = "pyrsistent-0.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e14c95c16211d166f59c6611533d0dacce2e25de0f76e4c140fde250997b3ca"}, + {file = "pyrsistent-0.20.0-cp39-cp39-win32.whl", hash = "sha256:f058a615031eea4ef94ead6456f5ec2026c19fb5bd6bfe86e9665c4158cf802f"}, + {file = "pyrsistent-0.20.0-cp39-cp39-win_amd64.whl", hash = "sha256:58b8f6366e152092194ae68fefe18b9f0b4f89227dfd86a07770c3d86097aebf"}, + {file = "pyrsistent-0.20.0-py3-none-any.whl", hash = "sha256:c55acc4733aad6560a7f5f818466631f07efc001fd023f34a6c203f8b6df0f0b"}, + {file = "pyrsistent-0.20.0.tar.gz", hash = "sha256:4c48f78f62ab596c679086084d0dd13254ae4f3d6c72a83ffdf5ebdef8f265a4"}, +] + +[[package]] +name = "pytest" +version = "6.2.5" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, + {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, +] + +[package.dependencies] +atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} +attrs = ">=19.2.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +py = ">=1.8.2" +toml = "*" + +[package.extras] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] + +[[package]] +name = "pytest-mock" +version = "3.14.0" +description = "Thin-wrapper around the mock package for easier use with pytest" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, + {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, +] + +[package.dependencies] +pytest = ">=6.2.5" + +[package.extras] +dev = ["pre-commit", "pytest-asyncio", "tox"] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "pytzdata" +version = "2020.1" +description = "The Olson timezone database for Python." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, + {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, +] + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-cache" +version = "1.2.0" +description = "A persistent cache for python requests" +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests_cache-1.2.0-py3-none-any.whl", hash = "sha256:490324301bf0cb924ff4e6324bd2613453e7e1f847353928b08adb0fdfb7f722"}, + {file = "requests_cache-1.2.0.tar.gz", hash = "sha256:db1c709ca343cc1cd5b6c8b1a5387298eceed02306a6040760db538c885e3838"}, +] + +[package.dependencies] +attrs = ">=21.2" +cattrs = ">=22.2" +platformdirs = ">=2.5" +requests = ">=2.22" +url-normalize = ">=1.4" +urllib3 = ">=1.25.5" + +[package.extras] +all = ["boto3 (>=1.15)", "botocore (>=1.18)", "itsdangerous (>=2.0)", "pymongo (>=3)", "pyyaml (>=6.0.1)", "redis (>=3)", "ujson (>=5.4)"] +bson = ["bson (>=0.5)"] +docs = ["furo (>=2023.3,<2024.0)", "linkify-it-py (>=2.0,<3.0)", "myst-parser (>=1.0,<2.0)", "sphinx (>=5.0.2,<6.0.0)", "sphinx-autodoc-typehints (>=1.19)", "sphinx-automodapi (>=0.14)", "sphinx-copybutton (>=0.5)", "sphinx-design (>=0.2)", "sphinx-notfound-page (>=0.8)", "sphinxcontrib-apidoc (>=0.3)", "sphinxext-opengraph (>=0.9)"] +dynamodb = ["boto3 (>=1.15)", "botocore (>=1.18)"] +json = ["ujson (>=5.4)"] +mongodb = ["pymongo (>=3)"] +redis = ["redis (>=3)"] +security = ["itsdangerous (>=2.0)"] +yaml = ["pyyaml (>=6.0.1)"] + +[[package]] +name = "requests-mock" +version = "1.12.0" +description = "Mock out responses from the requests package" +optional = false +python-versions = "*" +files = [ + {file = "requests-mock-1.12.0.tar.gz", hash = "sha256:4e34f2a2752f0b78397fb414526605d95fcdeab021ac1f26d18960e7eb41f6a8"}, + {file = "requests_mock-1.12.0-py2.py3-none-any.whl", hash = "sha256:4f6fdf956de568e0bac99eee4ad96b391c602e614cc0ad33e7f5c72edd699e70"}, +] + +[package.dependencies] +requests = ">=2.22,<3" + +[package.extras] +fixture = ["fixtures"] + +[[package]] +name = "responses" +version = "0.19.0" +description = "A utility library for mocking out the `requests` Python library." +optional = false +python-versions = ">=3.7" +files = [ + {file = "responses-0.19.0-py3-none-any.whl", hash = "sha256:53354b5de163aa2074312c71d8ebccb8bd1ab336cff7053abb75e84dc5637abe"}, + {file = "responses-0.19.0.tar.gz", hash = "sha256:3fc29c3117e14136b833a0a6d4e7f1217c6301bf08b6086db468e12f1e3290e2"}, +] + +[package.dependencies] +requests = ">=2.0,<3.0" +urllib3 = ">=1.25.10" + +[package.extras] +tests = ["coverage (>=6.0.0)", "flake8", "mypy", "pytest (>=7.0.0)", "pytest-asyncio", "pytest-cov", "pytest-localserver", "types-mock", "types-requests"] + +[[package]] +name = "setuptools" +version = "69.2.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-69.2.0-py3-none-any.whl", hash = "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c"}, + {file = "setuptools-69.2.0.tar.gz", hash = "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, + {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, +] + +[[package]] +name = "typing-extensions" +version = "4.10.0" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, + {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, +] + +[[package]] +name = "url-normalize" +version = "1.4.3" +description = "URL normalization for Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "url-normalize-1.4.3.tar.gz", hash = "sha256:d23d3a070ac52a67b83a1c59a0e68f8608d1cd538783b401bc9de2c0fac999b2"}, + {file = "url_normalize-1.4.3-py2.py3-none-any.whl", hash = "sha256:ec3c301f04e5bb676d333a7fa162fa977ad2ca04b7e652bfc9fac4e405728eed"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "urllib3" +version = "2.2.1" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, + {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "wcmatch" +version = "8.4" +description = "Wildcard/glob file name matcher." +optional = false +python-versions = ">=3.7" +files = [ + {file = "wcmatch-8.4-py3-none-any.whl", hash = "sha256:dc7351e5a7f8bbf4c6828d51ad20c1770113f5f3fd3dfe2a03cfde2a63f03f98"}, + {file = "wcmatch-8.4.tar.gz", hash = "sha256:ba4fc5558f8946bf1ffc7034b05b814d825d694112499c86035e0e4d398b6a67"}, +] + +[package.dependencies] +bracex = ">=2.1.1" + +[[package]] +name = "wrapt" +version = "1.16.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] + +[metadata] +lock-version = "2.0" +python-versions = "^3.9,<3.12" +content-hash = "fe4e36826d87d9a7d36cd58f7f2ede200bffa315a42b37cf046fc495a689984c" diff --git a/source-mailchimp/pyproject.toml b/source-mailchimp/pyproject.toml new file mode 100644 index 0000000000..c3a68b066b --- /dev/null +++ b/source-mailchimp/pyproject.toml @@ -0,0 +1,29 @@ +[build-system] +requires = [ "poetry-core>=1.0.0",] +build-backend = "poetry.core.masonry.api" + +[tool.poetry] +version = "1.2.0" +name = "source-mailchimp" +description = "Source implementation for Mailchimp." +authors = [ "Airbyte ",] +license = "MIT" +readme = "README.md" +documentation = "https://docs.airbyte.com/integrations/sources/mailchimp" +homepage = "https://airbyte.com" +repository = "https://github.com/airbytehq/airbyte" +[[tool.poetry.packages]] +include = "source_mailchimp" + +[tool.poetry.dependencies] +python = "^3.9,<3.12" +airbyte-cdk = "^0" +pytest = "==6.2.5" + +[tool.poetry.scripts] +source-mailchimp = "source_mailchimp.run:run" + +[tool.poetry.group.dev.dependencies] +pytest-mock = "^3.6.1" +responses = "^0.19.0" +requests-mock = "^1.9.3" diff --git a/source-mailchimp/sample_files/catalog.json b/source-mailchimp/sample_files/catalog.json new file mode 100644 index 0000000000..46dba2fd85 --- /dev/null +++ b/source-mailchimp/sample_files/catalog.json @@ -0,0 +1,1370 @@ +{ + "streams": [ + { + "name": "Campaigns", + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": "create_time", + "json_schema": { + "type": "object", + "title": "Campaign", + "description": "A summary of an individual campaign's settings and content.", + "properties": { + "id": { + "type": "string", + "title": "Campaign ID", + "description": "A string that uniquely identifies this campaign.", + "readOnly": true + }, + "web_id": { + "type": "integer", + "title": "Campaign Web ID", + "description": "The ID used in the Mailchimp web application. View this campaign in your Mailchimp account at `https://{dc}.admin.mailchimp.com/campaigns/show/?id={web_id}`.", + "readOnly": true + }, + "parent_campaign_id": { + "type": "string", + "title": "Parent Campaign ID", + "description": "If this campaign is the child of another campaign, this identifies the parent campaign. For Example, for RSS or Automation children.", + "readOnly": true + }, + "type": { + "$ref": "https://us1.api.mailchimp.com/schema/3.0/Definitions/CampaignType.json" + }, + "create_time": { + "type": "string", + "format": "date-time", + "title": "Create Time", + "description": "The date and time the campaign was created in ISO 8601 format.", + "readOnly": true + }, + "archive_url": { + "type": "string", + "title": "Archive URL", + "description": "The link to the campaign's archive version in ISO 8601 format.", + "readOnly": true + }, + "long_archive_url": { + "type": "string", + "title": "Long Archive URL", + "description": "The original link to the campaign's archive version.", + "readOnly": true + }, + "status": { + "$ref": "https://us1.api.mailchimp.com/schema/3.0/Definitions/CampaignStatus.json" + }, + "emails_sent": { + "type": "integer", + "title": "Emails Sent", + "description": "The total number of emails sent for this campaign.", + "readOnly": true + }, + "send_time": { + "type": "string", + "format": "date-time", + "title": "Send Time", + "description": "The date and time a campaign was sent.", + "readOnly": true + }, + "content_type": { + "type": "string", + "title": "Content Type", + "description": "How the campaign's content is put together.", + "enum": ["template", "html", "url", "multichannel"] + }, + "needs_block_refresh": { + "type": "boolean", + "title": "Needs Block Refresh", + "description": "Determines if the campaign needs its blocks refreshed by opening the web-based campaign editor. Deprecated and will always return false.", + "readOnly": true + }, + "resendable": { + "type": "boolean", + "title": "Resendable", + "description": "Determines if the campaign qualifies to be resent to non-openers.", + "readOnly": true + }, + "recipients": { + "type": "object", + "title": "List", + "description": "List settings for the campaign.", + "properties": { + "list_id": { + "type": "string", + "title": "List ID", + "description": "The unique list id." + }, + "list_is_active": { + "type": "boolean", + "title": "List Status", + "description": "The status of the list used, namely if it's deleted or disabled.", + "readOnly": true + }, + "list_name": { + "type": "string", + "title": "List Name", + "description": "The name of the list.", + "readOnly": true + }, + "segment_text": { + "type": "string", + "title": "Segment Text", + "description": "A description of the [segment](https://mailchimp.com/help/create-and-send-to-a-segment/) used for the campaign. Formatted as a string marked up with HTML.", + "readOnly": true + }, + "recipient_count": { + "type": "integer", + "title": "Recipient Count", + "description": "Count of the recipients on the associated list. Formatted as an integer.", + "readOnly": true + }, + "segment_opts": { + "$ref": "https://us1.api.mailchimp.com/schema/3.0/Definitions/SegmentationOptions.json" + } + } + }, + "settings": { + "type": "object", + "title": "Campaign Settings", + "description": "The settings for your campaign, including subject, from name, reply-to address, and more.", + "properties": { + "subject_line": { + "type": "string", + "title": "Campaign Subject Line", + "description": "The subject line for the campaign." + }, + "preview_text": { + "type": "string", + "title": "Campaign Preview Text", + "description": "The preview text for the campaign." + }, + "title": { + "type": "string", + "title": "Campaign Title", + "description": "The title of the campaign." + }, + "from_name": { + "type": "string", + "title": "From Name", + "description": "The 'from' name on the campaign (not an email address)." + }, + "reply_to": { + "type": "string", + "title": "Reply To Address", + "description": "The reply-to email address for the campaign." + }, + "use_conversation": { + "type": "boolean", + "title": "Conversation", + "description": "Use Mailchimp Conversation feature to manage out-of-office replies." + }, + "to_name": { + "type": "string", + "title": "To Name", + "description": "The campaign's custom 'To' name. Typically the first name [merge field](https://mailchimp.com/help/getting-started-with-merge-tags/)." + }, + "folder_id": { + "type": "string", + "title": "Folder ID", + "description": "If the campaign is listed in a folder, the id for that folder." + }, + "authenticate": { + "type": "boolean", + "title": "Authentication", + "description": "Whether Mailchimp [authenticated](https://mailchimp.com/help/about-email-authentication/) the campaign. Defaults to `true`." + }, + "auto_footer": { + "type": "boolean", + "title": "Auto-Footer", + "description": "Automatically append Mailchimp's [default footer](https://mailchimp.com/help/about-campaign-footers/) to the campaign." + }, + "inline_css": { + "type": "boolean", + "title": "Inline CSS", + "description": "Automatically inline the CSS included with the campaign content." + }, + "auto_tweet": { + "type": "boolean", + "title": "Auto-Tweet", + "description": "Automatically tweet a link to the [campaign archive](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) page when the campaign is sent." + }, + "auto_fb_post": { + "type": "array", + "title": "Auto Post to Facebook", + "description": "An array of [Facebook](https://mailchimp.com/help/connect-or-disconnect-the-facebook-integration/) page ids to auto-post to.", + "items": { + "type": "string" + } + }, + "fb_comments": { + "type": "boolean", + "title": "Facebook Comments", + "description": "Allows Facebook comments on the campaign (also force-enables the Campaign Archive toolbar). Defaults to `true`." + }, + "timewarp": { + "type": "boolean", + "title": "Timewarp Send", + "description": "Send this campaign using [Timewarp](https://mailchimp.com/help/use-timewarp/).", + "readOnly": true + }, + "template_id": { + "type": "integer", + "title": "Template ID", + "description": "The id for the template used in this campaign.", + "readOnly": false + }, + "drag_and_drop": { + "type": "boolean", + "title": "Drag And Drop Campaign", + "description": "Whether the campaign uses the drag-and-drop editor.", + "readOnly": true + } + } + }, + "variate_settings": { + "type": "object", + "title": "A/B Test Options", + "description": "The settings specific to A/B test campaigns.", + "properties": { + "winning_combination_id": { + "type": "string", + "title": "Winning Combination ID", + "description": "ID for the winning combination.", + "readOnly": true + }, + "winning_campaign_id": { + "type": "string", + "title": "Winning Campaign ID", + "description": "ID of the campaign that was sent to the remaining recipients based on the winning combination.", + "readOnly": true + }, + "winner_criteria": { + "type": "string", + "title": "Winning Criteria", + "description": "The combination that performs the best. This may be determined automatically by click rate, open rate, or total revenue -- or you may choose manually based on the reporting data you find the most valuable. For Multivariate Campaigns testing send_time, winner_criteria is ignored. For Multivariate Campaigns with 'manual' as the winner_criteria, the winner must be chosen in the Mailchimp web application.", + "enum": ["opens", "clicks", "manual", "total_revenue"] + }, + "wait_time": { + "type": "integer", + "title": "Wait Time", + "description": "The number of minutes to wait before choosing the winning campaign. The value of wait_time must be greater than 0 and in whole hours, specified in minutes." + }, + "test_size": { + "type": "integer", + "title": "Test Size", + "description": "The percentage of recipients to send the test combinations to, must be a value between 10 and 100." + }, + "subject_lines": { + "type": "array", + "title": "Subject Lines", + "description": "The possible subject lines to test. If no subject lines are provided, settings.subject_line will be used.", + "items": { + "type": "string" + } + }, + "send_times": { + "type": "array", + "title": "Send Times", + "description": "The possible send times to test. The times provided should be in the format YYYY-MM-DD HH:MM:SS. If send_times are provided to test, the test_size will be set to 100% and winner_criteria will be ignored.", + "items": { + "type": "string", + "format": "date-time" + } + }, + "from_names": { + "type": "array", + "title": "From Names", + "description": "The possible from names. The number of from_names provided must match the number of reply_to_addresses. If no from_names are provided, settings.from_name will be used.", + "items": { + "type": "string" + } + }, + "reply_to_addresses": { + "type": "array", + "title": "Reply To Addresses", + "description": "The possible reply-to addresses. The number of reply_to_addresses provided must match the number of from_names. If no reply_to_addresses are provided, settings.reply_to will be used.", + "items": { + "type": "string" + } + }, + "contents": { + "type": "array", + "title": "Content Descriptions", + "description": "Descriptions of possible email contents. To set campaign contents, make a PUT request to /campaigns/{campaign_id}/content with the field 'variate_contents'.", + "items": { + "type": "string" + }, + "readOnly": true + }, + "combinations": { + "type": "array", + "title": "Combinations", + "description": "Combinations of possible variables used to build emails.", + "readOnly": true, + "items": { + "type": "object", + "properties": { + "id": { + "type": "string", + "title": "ID", + "description": "Unique ID for the combination." + }, + "subject_line": { + "type": "integer", + "title": "Subject Line", + "description": "The index of `variate_settings.subject_lines` used." + }, + "send_time": { + "type": "integer", + "title": "Send Time", + "description": "The index of `variate_settings.send_times` used." + }, + "from_name": { + "type": "integer", + "title": "From Name", + "description": "The index of `variate_settings.from_names` used." + }, + "reply_to": { + "type": "integer", + "title": "Reply To", + "description": "The index of `variate_settings.reply_to_addresses` used." + }, + "content_description": { + "type": "integer", + "title": "Content Description", + "description": "The index of `variate_settings.contents` used." + }, + "recipients": { + "type": "integer", + "title": "Recipients", + "description": "The number of recipients for this combination." + } + } + } + } + } + }, + "tracking": { + "type": "object", + "title": "Campaign Tracking Options", + "description": "The tracking options for a campaign.", + "properties": { + "opens": { + "type": "boolean", + "title": "Opens", + "description": "Whether to [track opens](https://mailchimp.com/help/about-open-tracking/). Defaults to `true`. Cannot be set to false for variate campaigns." + }, + "html_clicks": { + "type": "boolean", + "title": "HTML Click Tracking", + "description": "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the HTML version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns." + }, + "text_clicks": { + "type": "boolean", + "title": "Plain-Text Click Tracking", + "description": "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the plain-text version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns." + }, + "goal_tracking": { + "type": "boolean", + "title": "Mailchimp Goal Tracking", + "description": "Whether to enable [Goal](https://mailchimp.com/help/about-connected-sites/) tracking." + }, + "ecomm360": { + "type": "boolean", + "title": "E-commerce Tracking", + "description": "Whether to enable [eCommerce360](https://mailchimp.com/help/connect-your-online-store-to-mailchimp/) tracking." + }, + "google_analytics": { + "type": "string", + "title": "Google Analytics Tracking", + "description": "The custom slug for [Google Analytics](https://mailchimp.com/help/integrate-google-analytics-with-mailchimp/) tracking (max of 50 bytes)." + }, + "clicktale": { + "type": "string", + "title": "ClickTale Analytics Tracking", + "description": "The custom slug for [ClickTale](https://mailchimp.com/help/additional-tracking-options-for-campaigns/) tracking (max of 50 bytes)." + }, + "salesforce": { + "type": "object", + "title": "Salesforce CRM Tracking", + "description": "Salesforce tracking options for a campaign. Must be using Mailchimp's built-in [Salesforce integration](https://mailchimp.com/help/integrate-salesforce-with-mailchimp/).", + "properties": { + "campaign": { + "type": "boolean", + "title": "Salesforce Campaign", + "description": "Create a campaign in a connected Salesforce account." + }, + "notes": { + "type": "boolean", + "title": "Salesforce Note", + "description": "Update contact notes for a campaign based on subscriber email addresses." + } + } + }, + "capsule": { + "type": "object", + "title": "Capsule CRM Tracking", + "description": "Capsule tracking options for a campaign. Must be using Mailchimp's built-in Capsule integration.", + "properties": { + "notes": { + "type": "boolean", + "title": "Capsule Note", + "description": "Update contact notes for a campaign based on subscriber email addresses." + } + } + } + } + }, + "rss_opts": { + "type": "object", + "title": "RSS Options", + "description": "[RSS](https://mailchimp.com/help/share-your-blog-posts-with-mailchimp/) options for a campaign.", + "properties": { + "feed_url": { + "type": "string", + "title": "Feed URL", + "format": "uri", + "description": "The URL for the RSS feed." + }, + "frequency": { + "type": "string", + "title": "Frequency", + "description": "The frequency of the RSS Campaign.", + "enum": ["daily", "weekly", "monthly"] + }, + "schedule": { + "type": "object", + "title": "Sending Schedule", + "description": "The schedule for sending the RSS Campaign.", + "properties": { + "hour": { + "type": "integer", + "minimum": 0, + "maximum": 23, + "title": "Sending Hour", + "description": "The hour to send the campaign in local time. Acceptable hours are 0-23. For example, '4' would be 4am in [your account's default time zone](https://mailchimp.com/help/set-account-defaults/)." + }, + "daily_send": { + "type": "object", + "title": "Daily Sending Days", + "description": "The days of the week to send a daily RSS Campaign.", + "properties": { + "sunday": { + "type": "boolean", + "title": "Sunday", + "description": "Sends the daily RSS Campaign on Sundays." + }, + "monday": { + "type": "boolean", + "title": "Monday", + "description": "Sends the daily RSS Campaign on Mondays." + }, + "tuesday": { + "type": "boolean", + "title": "tuesday", + "description": "Sends the daily RSS Campaign on Tuesdays." + }, + "wednesday": { + "type": "boolean", + "title": "Monday", + "description": "Sends the daily RSS Campaign on Wednesdays." + }, + "thursday": { + "type": "boolean", + "title": "Thursday", + "description": "Sends the daily RSS Campaign on Thursdays." + }, + "friday": { + "type": "boolean", + "title": "Friday", + "description": "Sends the daily RSS Campaign on Fridays." + }, + "saturday": { + "type": "boolean", + "title": "Saturday", + "description": "Sends the daily RSS Campaign on Saturdays." + } + } + }, + "weekly_send_day": { + "type": "string", + "enum": [ + "sunday", + "monday", + "tuesday", + "wednesday", + "thursday", + "friday", + "saturday" + ], + "title": "Weekly Sending Day", + "description": "The day of the week to send a weekly RSS Campaign." + }, + "monthly_send_date": { + "type": "number", + "minimum": 0, + "maximum": 31, + "title": "Monthly Sending Day", + "description": "The day of the month to send a monthly RSS Campaign. Acceptable days are 0-31, where '0' is always the last day of a month. Months with fewer than the selected number of days will not have an RSS campaign sent out that day. For example, RSS Campaigns set to send on the 30th will not go out in February." + } + } + }, + "last_sent": { + "type": "string", + "format": "date-time", + "title": "Last Sent", + "description": "The date the campaign was last sent.", + "readOnly": true + }, + "constrain_rss_img": { + "type": "boolean", + "title": "Constrain RSS Images", + "description": "Whether to add CSS to images in the RSS feed to constrain their width in campaigns." + } + } + }, + "ab_split_opts": { + "type": "object", + "title": "A/B Testing Options", + "description": "[A/B Testing](https://mailchimp.com/help/about-ab-testing-campaigns/) options for a campaign.", + "readOnly": true, + "properties": { + "split_test": { + "type": "string", + "title": "Split Test", + "description": "The type of AB split to run.", + "enum": ["subject", "from_name", "schedule"] + }, + "pick_winner": { + "type": "string", + "title": "Pick Winner", + "description": "How we should evaluate a winner. Based on 'opens', 'clicks', or 'manual'.", + "enum": ["opens", "clicks", "manual"] + }, + "wait_units": { + "type": "string", + "title": "Wait Time", + "description": "How unit of time for measuring the winner ('hours' or 'days'). This cannot be changed after a campaign is sent.", + "enum": ["hours", "days"] + }, + "wait_time": { + "type": "integer", + "title": "Wait Time", + "description": "The amount of time to wait before picking a winner. This cannot be changed after a campaign is sent." + }, + "split_size": { + "type": "integer", + "minimum": 1, + "maximum": 50, + "title": "Split Size", + "description": "The size of the split groups. Campaigns split based on 'schedule' are forced to have a 50/50 split. Valid split integers are between 1-50." + }, + "from_name_a": { + "type": "string", + "title": "From Name Group A", + "description": "For campaigns split on 'From Name', the name for Group A." + }, + "from_name_b": { + "type": "string", + "title": "From Name Group B", + "description": "For campaigns split on 'From Name', the name for Group B." + }, + "reply_email_a": { + "type": "string", + "title": "Reply Email Group A", + "description": "For campaigns split on 'From Name', the reply-to address for Group A." + }, + "reply_email_b": { + "type": "string", + "title": "Reply Email Group B", + "description": "For campaigns split on 'From Name', the reply-to address for Group B." + }, + "subject_a": { + "type": "string", + "title": "Subject Line Group A", + "description": "For campaigns split on 'Subject Line', the subject line for Group A." + }, + "subject_b": { + "type": "string", + "title": "Subject Line Group B", + "description": "For campaigns split on 'Subject Line', the subject line for Group B." + }, + "send_time_a": { + "type": "string", + "format": "date-time", + "title": "Send Time Group A", + "description": "The send time for Group A." + }, + "send_time_b": { + "type": "string", + "format": "date-time", + "title": "Send Time Group B", + "description": "The send time for Group B." + }, + "send_time_winner": { + "type": "string", + "title": "Send Time Winner", + "description": "The send time for the winning version." + } + } + }, + "social_card": { + "type": "object", + "title": "Campaign Social Card", + "description": "The preview for the campaign, rendered by social networks like Facebook and Twitter. [Learn more](https://mailchimp.com/help/enable-and-customize-social-cards/).", + "properties": { + "image_url": { + "type": "string", + "title": "Image URL", + "description": "The url for the header image for the card." + }, + "description": { + "type": "string", + "title": "Campaign Description", + "description": "A short summary of the campaign to display." + }, + "title": { + "type": "string", + "title": "Title", + "description": "The title for the card. Typically the subject line of the campaign." + } + } + }, + "report_summary": { + "type": "object", + "title": "Campaign Report Summary", + "description": "For sent campaigns, a summary of opens, clicks, and e-commerce data.", + "properties": { + "opens": { + "type": "integer", + "title": "Automation Opens", + "description": "The total number of opens for a campaign.", + "readOnly": true + }, + "unique_opens": { + "type": "integer", + "title": "Unique Opens", + "description": "The number of unique opens.", + "readOnly": true + }, + "open_rate": { + "type": "number", + "title": "Open Rate", + "description": "The number of unique opens divided by the total number of successful deliveries.", + "readOnly": true + }, + "clicks": { + "type": "integer", + "title": "Total Clicks", + "description": "The total number of clicks for an campaign.", + "readOnly": true + }, + "subscriber_clicks": { + "type": "integer", + "title": "Unique Subscriber Clicks", + "description": "The number of unique clicks.", + "readOnly": true + }, + "click_rate": { + "type": "number", + "title": "Click Rate", + "description": "The number of unique clicks divided by the total number of successful deliveries.", + "readOnly": true + }, + "ecommerce": { + "type": "object", + "title": "E-Commerce Report", + "description": "E-Commerce stats for a campaign.", + "properties": { + "total_orders": { + "type": "integer", + "title": "Total Orders", + "description": "The total orders for a campaign.", + "readOnly": true + }, + "total_spent": { + "type": "number", + "title": "Total Spent", + "description": "The total spent for a campaign. Calculated as the sum of all order totals with no deductions.", + "readOnly": true + }, + "total_revenue": { + "type": "number", + "title": "Total Revenue", + "description": "The total revenue for a campaign. Calculated as the sum of all order totals minus shipping and tax totals.", + "readOnly": true + } + } + } + } + }, + "delivery_status": { + "type": "object", + "title": "Campaign Delivery Status", + "description": "Updates on campaigns in the process of sending.", + "properties": { + "enabled": { + "type": "boolean", + "title": "Delivery Status Enabled", + "description": "Whether Campaign Delivery Status is enabled for this account and campaign.", + "readOnly": true + }, + "can_cancel": { + "type": "boolean", + "title": "Campaign Cancelable", + "description": "Whether a campaign send can be canceled.", + "readOnly": true + }, + "status": { + "type": "string", + "title": "Campaign Delivery Status", + "description": "The current state of a campaign delivery.", + "enum": ["delivering", "delivered", "canceling", "canceled"], + "readOnly": true + }, + "emails_sent": { + "type": "integer", + "title": "Emails Sent", + "description": "The total number of emails confirmed sent for this campaign so far.", + "readOnly": true + }, + "emails_canceled": { + "type": "integer", + "title": "Emails Canceled", + "description": "The total number of emails canceled for this campaign.", + "readOnly": true + } + } + }, + "_links": { + "title": "Links", + "description": "A list of link types and descriptions for the API schema documents.", + "type": "array", + "items": { + "type": "object", + "title": "Resource Link", + "description": "This object represents a link from the resource where it is found to another resource or action that may be performed.", + "properties": { + "rel": { + "type": "string", + "title": "Rel", + "description": "As with an HTML 'rel' attribute, this describes the type of link.", + "readOnly": true + }, + "href": { + "type": "string", + "title": "Href", + "description": "This property contains a fully-qualified URL that can be called to retrieve the linked resource or perform the linked action.", + "readOnly": true + }, + "method": { + "type": "string", + "title": "Method", + "description": "The HTTP method that should be used when accessing the URL defined in 'href'.", + "enum": [ + "GET", + "POST", + "PUT", + "PATCH", + "DELETE", + "OPTIONS", + "HEAD" + ], + "readOnly": true + }, + "targetSchema": { + "type": "string", + "title": "Target Schema", + "description": "For GETs, this is a URL representing the schema that the response should conform to.", + "readOnly": true + }, + "schema": { + "type": "string", + "title": "Schema", + "description": "For HTTP methods that can receive bodies (POST and PUT), this is a URL representing the schema that the body should conform to.", + "readOnly": true + } + } + }, + "readOnly": true + } + } + } + }, + { + "name": "Automations", + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": "create_time", + "json_schema": { + "type": "object", + "title": "Automation", + "description": "A summary of an individual automation's settings and content.", + "properties": { + "id": { + "type": ["null", "string"] + }, + "create_time": { + "type": ["null", "string"] + }, + "start_time": { + "type": ["null", "string"] + }, + "status": { + "type": ["null", "string"] + }, + "emails_sent": { + "type": ["null", "number"] + }, + "recipients": { + "type": ["null", "object"], + "properties": { + "list_id": { + "type": ["null", "string"] + }, + "list_is_active": { + "type": ["null", "boolean"] + }, + "list_name": { + "type": ["null", "string"] + }, + "segment_opts": { + "type": ["null", "object"], + "properties": { + "saved_segment_id": { + "type": ["null", "number"] + }, + "match": { + "type": ["null", "string"] + }, + "conditions": { + "type": ["null", "array"], + "items": {} + } + } + }, + "store_id": { + "type": ["null", "string"] + } + } + }, + "settings": { + "type": ["null", "object"], + "properties": { + "title": { + "type": ["null", "string"] + }, + "from_name": { + "type": ["null", "string"] + }, + "reply_to": { + "type": ["null", "string"] + }, + "use_conversation": { + "type": ["null", "boolean"] + }, + "to_name": { + "type": ["null", "string"] + }, + "authenticate": { + "type": ["null", "boolean"] + }, + "auto_footer": { + "type": ["null", "boolean"] + }, + "inline_css": { + "type": ["null", "boolean"] + } + } + }, + "tracking": { + "type": ["null", "object"], + "properties": { + "opens": { + "type": ["null", "boolean"] + }, + "html_clicks": { + "type": ["null", "boolean"] + }, + "text_clicks": { + "type": ["null", "boolean"] + }, + "goal_tracking": { + "type": ["null", "boolean"] + }, + "ecomm360": { + "type": ["null", "boolean"] + }, + "google_analytics": { + "type": ["null", "string"] + }, + "clicktale": { + "type": ["null", "string"] + }, + "salesforce": { + "type": ["null", "object"], + "properties": { + "campaign": { + "type": ["null", "boolean"] + }, + "notes": { + "type": ["null", "boolean"] + } + } + }, + "capsule": { + "type": ["null", "object"], + "properties": { + "notes": { + "type": ["null", "boolean"] + } + } + } + } + }, + "trigger_settings": { + "type": ["null", "object"], + "properties": { + "workflow_type": { + "type": ["null", "string"] + }, + "workflow_title": { + "type": ["null", "string"] + }, + "runtime": { + "type": ["null", "object"], + "properties": { + "days": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "hours": { + "type": ["null", "object"], + "properties": { + "type": { + "type": ["null", "string"] + } + } + } + } + }, + "workflow_emails_count": { + "type": ["null", "number"] + } + } + }, + "report_summary": { + "type": ["null", "object"], + "properties": { + "opens": { + "type": ["null", "number"] + }, + "unique_opens": { + "type": ["null", "number"] + }, + "open_rate": { + "type": ["null", "number"] + }, + "clicks": { + "type": ["null", "number"] + }, + "subscriber_clicks": { + "type": ["null", "number"] + }, + "click_rate": { + "type": ["null", "number"] + } + } + }, + "_links": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "properties": { + "rel": { + "type": ["null", "string"] + }, + "href": { + "type": ["null", "string"] + }, + "method": { + "type": ["null", "string"] + }, + "targetSchema": { + "type": ["null", "string"] + }, + "schema": { + "type": ["null", "string"] + } + } + } + } + } + } + }, + { + "name": "Lists", + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": "date_created", + "json_schema": { + "type": "object", + "title": "Subscriber List", + "description": "Information about a specific list.", + "properties": { + "id": { + "type": "string", + "title": "List ID", + "description": "A string that uniquely identifies this list.", + "readOnly": true + }, + "web_id": { + "type": "integer", + "title": "List Web ID", + "description": "The ID used in the Mailchimp web application. View this list in your Mailchimp account at `https://{dc}.admin.mailchimp.com/lists/members/?id={web_id}`.", + "readOnly": true + }, + "name": { + "type": "string", + "title": "List Name", + "description": "The name of the list." + }, + "contact": { + "type": "object", + "title": "List Contact", + "description": "[Contact information displayed in campaign footers](https://mailchimp.com/help/about-campaign-footers/) to comply with international spam laws.", + "properties": { + "company": { + "type": "string", + "title": "Company Name", + "description": "The company name for the list." + }, + "address1": { + "type": "string", + "title": "Address", + "description": "The street address for the list contact." + }, + "address2": { + "type": "string", + "title": "Address", + "description": "The street address for the list contact." + }, + "city": { + "type": "string", + "title": "City", + "description": "The city for the list contact." + }, + "state": { + "type": "string", + "title": "State", + "description": "The state for the list contact." + }, + "zip": { + "type": "string", + "title": "Postal Code", + "description": "The postal or zip code for the list contact." + }, + "country": { + "type": "string", + "title": "Country Code", + "description": "A two-character ISO3166 country code. Defaults to US if invalid." + }, + "phone": { + "type": "string", + "title": "Phone Number", + "description": "The phone number for the list contact." + } + } + }, + "permission_reminder": { + "type": "string", + "title": "Permission Reminder", + "description": "The [permission reminder](https://mailchimp.com/help/edit-the-permission-reminder/) for the list." + }, + "use_archive_bar": { + "type": "boolean", + "title": "Use Archive Bar", + "description": "Whether campaigns for this list use the [Archive Bar](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) in archives by default.", + "default": false + }, + "campaign_defaults": { + "type": "object", + "title": "Campaign Defaults", + "description": "[Default values for campaigns](https://mailchimp.com/help/edit-your-emails-subject-preview-text-from-name-or-from-email-address/) created for this list.", + "properties": { + "from_name": { + "type": "string", + "title": "Sender's Name", + "description": "The default from name for campaigns sent to this list." + }, + "from_email": { + "type": "string", + "title": "Sender's Email Address", + "description": "The default from email for campaigns sent to this list." + }, + "subject": { + "type": "string", + "title": "Subject", + "description": "The default subject line for campaigns sent to this list." + }, + "language": { + "type": "string", + "title": "Language", + "description": "The default language for this lists's forms." + } + } + }, + "notify_on_subscribe": { + "type": "string", + "title": "Notify on Subscribe", + "description": "The email address to send [subscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", + "default": false + }, + "notify_on_unsubscribe": { + "type": "string", + "title": "Notify on Unsubscribe", + "description": "The email address to send [unsubscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", + "default": false + }, + "date_created": { + "type": "string", + "title": "Creation Date", + "description": "The date and time that this list was created in ISO 8601 format.", + "format": "date-time", + "readOnly": true + }, + "list_rating": { + "type": "integer", + "title": "List Rating", + "description": "An auto-generated activity score for the list (0-5).", + "readOnly": true + }, + "email_type_option": { + "type": "boolean", + "title": "Email Type Option", + "description": "Whether the list supports [multiple formats for emails](https://mailchimp.com/help/change-list-name-and-defaults/). When set to `true`, subscribers can choose whether they want to receive HTML or plain-text emails. When set to `false`, subscribers will receive HTML emails, with a plain-text alternative backup." + }, + "subscribe_url_short": { + "type": "string", + "title": "Subscribe URL Short", + "description": "Our [EepURL shortened](https://mailchimp.com/help/share-your-signup-form/) version of this list's subscribe form.", + "readOnly": true + }, + "subscribe_url_long": { + "type": "string", + "title": "Subscribe URL Long", + "description": "The full version of this list's subscribe form (host will vary).", + "readOnly": true + }, + "beamer_address": { + "type": "string", + "title": "Beamer Address", + "description": "The list's [Email Beamer](https://mailchimp.com/help/use-email-beamer-to-create-a-campaign/) address.", + "readOnly": true + }, + "visibility": { + "type": "string", + "title": "Visibility", + "enum": ["pub", "prv"], + "description": "Whether this list is [public or private](https://mailchimp.com/help/about-list-publicity/)." + }, + "double_optin": { + "type": "boolean", + "title": "Double Opt In", + "description": "Whether or not to require the subscriber to confirm subscription via email.", + "default": false + }, + "has_welcome": { + "type": "boolean", + "title": "Has Welcome", + "description": "Whether or not this list has a welcome automation connected. Welcome Automations: welcomeSeries, singleWelcome, emailFollowup.", + "default": false, + "example": false + }, + "marketing_permissions": { + "type": "boolean", + "title": "Marketing Permissions", + "description": "Whether or not the list has marketing permissions (eg. GDPR) enabled.", + "default": false + }, + "modules": { + "type": "array", + "title": "Modules", + "description": "Any list-specific modules installed for this list.", + "items": { + "type": "string" + }, + "readOnly": true + }, + "stats": { + "type": "object", + "title": "Statistics", + "description": "Stats for the list. Many of these are cached for at least five minutes.", + "readOnly": true, + "properties": { + "member_count": { + "type": "integer", + "title": "Member Count", + "description": "The number of active members in the list.", + "readOnly": true + }, + "total_contacts": { + "type": "integer", + "title": "Total Contacts", + "description": "The number of contacts in the list, including subscribed, unsubscribed, pending, cleaned, deleted, transactional, and those that need to be reconfirmed.", + "readOnly": true + }, + "unsubscribe_count": { + "type": "integer", + "title": "Unsubscribe Count", + "description": "The number of members who have unsubscribed from the list.", + "readOnly": true + }, + "cleaned_count": { + "type": "integer", + "title": "Cleaned Count", + "description": "The number of members cleaned from the list.", + "readOnly": true + }, + "member_count_since_send": { + "type": "integer", + "title": "Member Count Since Send", + "description": "The number of active members in the list since the last campaign was sent.", + "readOnly": true + }, + "unsubscribe_count_since_send": { + "type": "integer", + "title": "Unsubscribe Count Since Send", + "description": "The number of members who have unsubscribed since the last campaign was sent.", + "readOnly": true + }, + "cleaned_count_since_send": { + "type": "integer", + "title": "Cleaned Count Since Send", + "description": "The number of members cleaned from the list since the last campaign was sent.", + "readOnly": true + }, + "campaign_count": { + "type": "integer", + "title": "Campaign Count", + "description": "The number of campaigns in any status that use this list.", + "readOnly": true + }, + "campaign_last_sent": { + "type": "string", + "format": "date-time", + "title": "Campaign Last Sent", + "description": "The date and time the last campaign was sent to this list in ISO 8601 format. This is updated when a campaign is sent to 10 or more recipients.", + "readOnly": true + }, + "merge_field_count": { + "type": "integer", + "title": "Merge Var Count", + "description": "The number of merge vars for this list (not EMAIL, which is required).", + "readOnly": true + }, + "avg_sub_rate": { + "type": "number", + "title": "Average Subscription Rate", + "description": "The average number of subscriptions per month for the list (not returned if we haven't calculated it yet).", + "readOnly": true + }, + "avg_unsub_rate": { + "type": "number", + "title": "Average Unsubscription Rate", + "description": "The average number of unsubscriptions per month for the list (not returned if we haven't calculated it yet).", + "readOnly": true + }, + "target_sub_rate": { + "type": "number", + "title": "Average Subscription Rate", + "description": "The target number of subscriptions per month for the list to keep it growing (not returned if we haven't calculated it yet).", + "readOnly": true + }, + "open_rate": { + "type": "number", + "title": "Open Rate", + "description": "The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet).", + "readOnly": true + }, + "click_rate": { + "type": "number", + "title": "Click Rate", + "description": "The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet).", + "readOnly": true + }, + "last_sub_date": { + "type": "string", + "format": "date-time", + "title": "Date of Last List Subscribe", + "description": "The date and time of the last time someone subscribed to this list in ISO 8601 format.", + "readOnly": true + }, + "last_unsub_date": { + "type": "string", + "format": "date-time", + "title": "Date of Last List Unsubscribe", + "description": "The date and time of the last time someone unsubscribed from this list in ISO 8601 format.", + "readOnly": true + } + } + }, + "_links": { + "title": "Links", + "description": "A list of link types and descriptions for the API schema documents.", + "type": "array", + "items": { + "type": "object", + "title": "Resource Link", + "description": "This object represents a link from the resource where it is found to another resource or action that may be performed.", + "properties": { + "rel": { + "type": "string", + "title": "Rel", + "description": "As with an HTML 'rel' attribute, this describes the type of link.", + "readOnly": true + }, + "href": { + "type": "string", + "title": "Href", + "description": "This property contains a fully-qualified URL that can be called to retrieve the linked resource or perform the linked action.", + "readOnly": true + }, + "method": { + "type": "string", + "title": "Method", + "description": "The HTTP method that should be used when accessing the URL defined in 'href'.", + "enum": [ + "GET", + "POST", + "PUT", + "PATCH", + "DELETE", + "OPTIONS", + "HEAD" + ], + "readOnly": true + }, + "targetSchema": { + "type": "string", + "title": "Target Schema", + "description": "For GETs, this is a URL representing the schema that the response should conform to.", + "readOnly": true + }, + "schema": { + "type": "string", + "title": "Schema", + "description": "For HTTP methods that can receive bodies (POST and PUT), this is a URL representing the schema that the body should conform to.", + "readOnly": true + } + } + }, + "readOnly": true + } + } + } + } + ] +} diff --git a/source-mailchimp/sample_files/configured_catalog.json b/source-mailchimp/sample_files/configured_catalog.json new file mode 100644 index 0000000000..a4cb2fb0af --- /dev/null +++ b/source-mailchimp/sample_files/configured_catalog.json @@ -0,0 +1,1381 @@ +{ + "streams": [ + { + "stream": { + "name": "campaigns", + "json_schema": { + "type": "object", + "title": "Campaign", + "description": "A summary of an individual campaign's settings and content.", + "properties": { + "id": { + "type": "string", + "title": "Campaign ID", + "description": "A string that uniquely identifies this campaign.", + "readOnly": true + }, + "web_id": { + "type": "integer", + "title": "Campaign Web ID", + "description": "The ID used in the Mailchimp web application. View this campaign in your Mailchimp account at `https://{dc}.admin.mailchimp.com/campaigns/show/?id={web_id}`.", + "readOnly": true + }, + "parent_campaign_id": { + "type": "string", + "title": "Parent Campaign ID", + "description": "If this campaign is the child of another campaign, this identifies the parent campaign. For Example, for RSS or Automation children.", + "readOnly": true + }, + "type": { + "$ref": "https://us1.api.mailchimp.com/schema/3.0/Definitions/CampaignType.json" + }, + "create_time": { + "type": "string", + "format": "date-time", + "title": "Create Time", + "description": "The date and time the campaign was created in ISO 8601 format.", + "readOnly": true + }, + "archive_url": { + "type": "string", + "title": "Archive URL", + "description": "The link to the campaign's archive version in ISO 8601 format.", + "readOnly": true + }, + "long_archive_url": { + "type": "string", + "title": "Long Archive URL", + "description": "The original link to the campaign's archive version.", + "readOnly": true + }, + "status": { + "$ref": "https://us1.api.mailchimp.com/schema/3.0/Definitions/CampaignStatus.json" + }, + "emails_sent": { + "type": "integer", + "title": "Emails Sent", + "description": "The total number of emails sent for this campaign.", + "readOnly": true + }, + "send_time": { + "type": "string", + "format": "date-time", + "title": "Send Time", + "description": "The date and time a campaign was sent.", + "readOnly": true + }, + "content_type": { + "type": "string", + "title": "Content Type", + "description": "How the campaign's content is put together.", + "enum": ["template", "html", "url", "multichannel"] + }, + "needs_block_refresh": { + "type": "boolean", + "title": "Needs Block Refresh", + "description": "Determines if the campaign needs its blocks refreshed by opening the web-based campaign editor. Deprecated and will always return false.", + "readOnly": true + }, + "resendable": { + "type": "boolean", + "title": "Resendable", + "description": "Determines if the campaign qualifies to be resent to non-openers.", + "readOnly": true + }, + "recipients": { + "type": "object", + "title": "List", + "description": "List settings for the campaign.", + "properties": { + "list_id": { + "type": "string", + "title": "List ID", + "description": "The unique list id." + }, + "list_is_active": { + "type": "boolean", + "title": "List Status", + "description": "The status of the list used, namely if it's deleted or disabled.", + "readOnly": true + }, + "list_name": { + "type": "string", + "title": "List Name", + "description": "The name of the list.", + "readOnly": true + }, + "segment_text": { + "type": "string", + "title": "Segment Text", + "description": "A description of the [segment](https://mailchimp.com/help/create-and-send-to-a-segment/) used for the campaign. Formatted as a string marked up with HTML.", + "readOnly": true + }, + "recipient_count": { + "type": "integer", + "title": "Recipient Count", + "description": "Count of the recipients on the associated list. Formatted as an integer.", + "readOnly": true + }, + "segment_opts": { + "$ref": "https://us1.api.mailchimp.com/schema/3.0/Definitions/SegmentationOptions.json" + } + } + }, + "settings": { + "type": "object", + "title": "Campaign Settings", + "description": "The settings for your campaign, including subject, from name, reply-to address, and more.", + "properties": { + "subject_line": { + "type": "string", + "title": "Campaign Subject Line", + "description": "The subject line for the campaign." + }, + "preview_text": { + "type": "string", + "title": "Campaign Preview Text", + "description": "The preview text for the campaign." + }, + "title": { + "type": "string", + "title": "Campaign Title", + "description": "The title of the campaign." + }, + "from_name": { + "type": "string", + "title": "From Name", + "description": "The 'from' name on the campaign (not an email address)." + }, + "reply_to": { + "type": "string", + "title": "Reply To Address", + "description": "The reply-to email address for the campaign." + }, + "use_conversation": { + "type": "boolean", + "title": "Conversation", + "description": "Use Mailchimp Conversation feature to manage out-of-office replies." + }, + "to_name": { + "type": "string", + "title": "To Name", + "description": "The campaign's custom 'To' name. Typically the first name [merge field](https://mailchimp.com/help/getting-started-with-merge-tags/)." + }, + "folder_id": { + "type": "string", + "title": "Folder ID", + "description": "If the campaign is listed in a folder, the id for that folder." + }, + "authenticate": { + "type": "boolean", + "title": "Authentication", + "description": "Whether Mailchimp [authenticated](https://mailchimp.com/help/about-email-authentication/) the campaign. Defaults to `true`." + }, + "auto_footer": { + "type": "boolean", + "title": "Auto-Footer", + "description": "Automatically append Mailchimp's [default footer](https://mailchimp.com/help/about-campaign-footers/) to the campaign." + }, + "inline_css": { + "type": "boolean", + "title": "Inline CSS", + "description": "Automatically inline the CSS included with the campaign content." + }, + "auto_tweet": { + "type": "boolean", + "title": "Auto-Tweet", + "description": "Automatically tweet a link to the [campaign archive](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) page when the campaign is sent." + }, + "auto_fb_post": { + "type": "array", + "title": "Auto Post to Facebook", + "description": "An array of [Facebook](https://mailchimp.com/help/connect-or-disconnect-the-facebook-integration/) page ids to auto-post to.", + "items": { + "type": "string" + } + }, + "fb_comments": { + "type": "boolean", + "title": "Facebook Comments", + "description": "Allows Facebook comments on the campaign (also force-enables the Campaign Archive toolbar). Defaults to `true`." + }, + "timewarp": { + "type": "boolean", + "title": "Timewarp Send", + "description": "Send this campaign using [Timewarp](https://mailchimp.com/help/use-timewarp/).", + "readOnly": true + }, + "template_id": { + "type": "integer", + "title": "Template ID", + "description": "The id for the template used in this campaign.", + "readOnly": false + }, + "drag_and_drop": { + "type": "boolean", + "title": "Drag And Drop Campaign", + "description": "Whether the campaign uses the drag-and-drop editor.", + "readOnly": true + } + } + }, + "variate_settings": { + "type": "object", + "title": "A/B Test Options", + "description": "The settings specific to A/B test campaigns.", + "properties": { + "winning_combination_id": { + "type": "string", + "title": "Winning Combination ID", + "description": "ID for the winning combination.", + "readOnly": true + }, + "winning_campaign_id": { + "type": "string", + "title": "Winning Campaign ID", + "description": "ID of the campaign that was sent to the remaining recipients based on the winning combination.", + "readOnly": true + }, + "winner_criteria": { + "type": "string", + "title": "Winning Criteria", + "description": "The combination that performs the best. This may be determined automatically by click rate, open rate, or total revenue -- or you may choose manually based on the reporting data you find the most valuable. For Multivariate Campaigns testing send_time, winner_criteria is ignored. For Multivariate Campaigns with 'manual' as the winner_criteria, the winner must be chosen in the Mailchimp web application.", + "enum": ["opens", "clicks", "manual", "total_revenue"] + }, + "wait_time": { + "type": "integer", + "title": "Wait Time", + "description": "The number of minutes to wait before choosing the winning campaign. The value of wait_time must be greater than 0 and in whole hours, specified in minutes." + }, + "test_size": { + "type": "integer", + "title": "Test Size", + "description": "The percentage of recipients to send the test combinations to, must be a value between 10 and 100." + }, + "subject_lines": { + "type": "array", + "title": "Subject Lines", + "description": "The possible subject lines to test. If no subject lines are provided, settings.subject_line will be used.", + "items": { + "type": "string" + } + }, + "send_times": { + "type": "array", + "title": "Send Times", + "description": "The possible send times to test. The times provided should be in the format YYYY-MM-DD HH:MM:SS. If send_times are provided to test, the test_size will be set to 100% and winner_criteria will be ignored.", + "items": { + "type": "string", + "format": "date-time" + } + }, + "from_names": { + "type": "array", + "title": "From Names", + "description": "The possible from names. The number of from_names provided must match the number of reply_to_addresses. If no from_names are provided, settings.from_name will be used.", + "items": { + "type": "string" + } + }, + "reply_to_addresses": { + "type": "array", + "title": "Reply To Addresses", + "description": "The possible reply-to addresses. The number of reply_to_addresses provided must match the number of from_names. If no reply_to_addresses are provided, settings.reply_to will be used.", + "items": { + "type": "string" + } + }, + "contents": { + "type": "array", + "title": "Content Descriptions", + "description": "Descriptions of possible email contents. To set campaign contents, make a PUT request to /campaigns/{campaign_id}/content with the field 'variate_contents'.", + "items": { + "type": "string" + }, + "readOnly": true + }, + "combinations": { + "type": "array", + "title": "Combinations", + "description": "Combinations of possible variables used to build emails.", + "readOnly": true, + "items": { + "type": "object", + "properties": { + "id": { + "type": "string", + "title": "ID", + "description": "Unique ID for the combination." + }, + "subject_line": { + "type": "integer", + "title": "Subject Line", + "description": "The index of `variate_settings.subject_lines` used." + }, + "send_time": { + "type": "integer", + "title": "Send Time", + "description": "The index of `variate_settings.send_times` used." + }, + "from_name": { + "type": "integer", + "title": "From Name", + "description": "The index of `variate_settings.from_names` used." + }, + "reply_to": { + "type": "integer", + "title": "Reply To", + "description": "The index of `variate_settings.reply_to_addresses` used." + }, + "content_description": { + "type": "integer", + "title": "Content Description", + "description": "The index of `variate_settings.contents` used." + }, + "recipients": { + "type": "integer", + "title": "Recipients", + "description": "The number of recipients for this combination." + } + } + } + } + } + }, + "tracking": { + "type": "object", + "title": "Campaign Tracking Options", + "description": "The tracking options for a campaign.", + "properties": { + "opens": { + "type": "boolean", + "title": "Opens", + "description": "Whether to [track opens](https://mailchimp.com/help/about-open-tracking/). Defaults to `true`. Cannot be set to false for variate campaigns." + }, + "html_clicks": { + "type": "boolean", + "title": "HTML Click Tracking", + "description": "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the HTML version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns." + }, + "text_clicks": { + "type": "boolean", + "title": "Plain-Text Click Tracking", + "description": "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the plain-text version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns." + }, + "goal_tracking": { + "type": "boolean", + "title": "Mailchimp Goal Tracking", + "description": "Whether to enable [Goal](https://mailchimp.com/help/about-connected-sites/) tracking." + }, + "ecomm360": { + "type": "boolean", + "title": "E-commerce Tracking", + "description": "Whether to enable [eCommerce360](https://mailchimp.com/help/connect-your-online-store-to-mailchimp/) tracking." + }, + "google_analytics": { + "type": "string", + "title": "Google Analytics Tracking", + "description": "The custom slug for [Google Analytics](https://mailchimp.com/help/integrate-google-analytics-with-mailchimp/) tracking (max of 50 bytes)." + }, + "clicktale": { + "type": "string", + "title": "ClickTale Analytics Tracking", + "description": "The custom slug for [ClickTale](https://mailchimp.com/help/additional-tracking-options-for-campaigns/) tracking (max of 50 bytes)." + }, + "salesforce": { + "type": "object", + "title": "Salesforce CRM Tracking", + "description": "Salesforce tracking options for a campaign. Must be using Mailchimp's built-in [Salesforce integration](https://mailchimp.com/help/integrate-salesforce-with-mailchimp/).", + "properties": { + "campaign": { + "type": "boolean", + "title": "Salesforce Campaign", + "description": "Create a campaign in a connected Salesforce account." + }, + "notes": { + "type": "boolean", + "title": "Salesforce Note", + "description": "Update contact notes for a campaign based on subscriber email addresses." + } + } + }, + "capsule": { + "type": "object", + "title": "Capsule CRM Tracking", + "description": "Capsule tracking options for a campaign. Must be using Mailchimp's built-in Capsule integration.", + "properties": { + "notes": { + "type": "boolean", + "title": "Capsule Note", + "description": "Update contact notes for a campaign based on subscriber email addresses." + } + } + } + } + }, + "rss_opts": { + "type": "object", + "title": "RSS Options", + "description": "[RSS](https://mailchimp.com/help/share-your-blog-posts-with-mailchimp/) options for a campaign.", + "properties": { + "feed_url": { + "type": "string", + "title": "Feed URL", + "format": "uri", + "description": "The URL for the RSS feed." + }, + "frequency": { + "type": "string", + "title": "Frequency", + "description": "The frequency of the RSS Campaign.", + "enum": ["daily", "weekly", "monthly"] + }, + "schedule": { + "type": "object", + "title": "Sending Schedule", + "description": "The schedule for sending the RSS Campaign.", + "properties": { + "hour": { + "type": "integer", + "minimum": 0, + "maximum": 23, + "title": "Sending Hour", + "description": "The hour to send the campaign in local time. Acceptable hours are 0-23. For example, '4' would be 4am in [your account's default time zone](https://mailchimp.com/help/set-account-defaults/)." + }, + "daily_send": { + "type": "object", + "title": "Daily Sending Days", + "description": "The days of the week to send a daily RSS Campaign.", + "properties": { + "sunday": { + "type": "boolean", + "title": "Sunday", + "description": "Sends the daily RSS Campaign on Sundays." + }, + "monday": { + "type": "boolean", + "title": "Monday", + "description": "Sends the daily RSS Campaign on Mondays." + }, + "tuesday": { + "type": "boolean", + "title": "tuesday", + "description": "Sends the daily RSS Campaign on Tuesdays." + }, + "wednesday": { + "type": "boolean", + "title": "Monday", + "description": "Sends the daily RSS Campaign on Wednesdays." + }, + "thursday": { + "type": "boolean", + "title": "Thursday", + "description": "Sends the daily RSS Campaign on Thursdays." + }, + "friday": { + "type": "boolean", + "title": "Friday", + "description": "Sends the daily RSS Campaign on Fridays." + }, + "saturday": { + "type": "boolean", + "title": "Saturday", + "description": "Sends the daily RSS Campaign on Saturdays." + } + } + }, + "weekly_send_day": { + "type": "string", + "enum": [ + "sunday", + "monday", + "tuesday", + "wednesday", + "thursday", + "friday", + "saturday" + ], + "title": "Weekly Sending Day", + "description": "The day of the week to send a weekly RSS Campaign." + }, + "monthly_send_date": { + "type": "number", + "minimum": 0, + "maximum": 31, + "title": "Monthly Sending Day", + "description": "The day of the month to send a monthly RSS Campaign. Acceptable days are 0-31, where '0' is always the last day of a month. Months with fewer than the selected number of days will not have an RSS campaign sent out that day. For example, RSS Campaigns set to send on the 30th will not go out in February." + } + } + }, + "last_sent": { + "type": "string", + "format": "date-time", + "title": "Last Sent", + "description": "The date the campaign was last sent.", + "readOnly": true + }, + "constrain_rss_img": { + "type": "boolean", + "title": "Constrain RSS Images", + "description": "Whether to add CSS to images in the RSS feed to constrain their width in campaigns." + } + } + }, + "ab_split_opts": { + "type": "object", + "title": "A/B Testing Options", + "description": "[A/B Testing](https://mailchimp.com/help/about-ab-testing-campaigns/) options for a campaign.", + "readOnly": true, + "properties": { + "split_test": { + "type": "string", + "title": "Split Test", + "description": "The type of AB split to run.", + "enum": ["subject", "from_name", "schedule"] + }, + "pick_winner": { + "type": "string", + "title": "Pick Winner", + "description": "How we should evaluate a winner. Based on 'opens', 'clicks', or 'manual'.", + "enum": ["opens", "clicks", "manual"] + }, + "wait_units": { + "type": "string", + "title": "Wait Time", + "description": "How unit of time for measuring the winner ('hours' or 'days'). This cannot be changed after a campaign is sent.", + "enum": ["hours", "days"] + }, + "wait_time": { + "type": "integer", + "title": "Wait Time", + "description": "The amount of time to wait before picking a winner. This cannot be changed after a campaign is sent." + }, + "split_size": { + "type": "integer", + "minimum": 1, + "maximum": 50, + "title": "Split Size", + "description": "The size of the split groups. Campaigns split based on 'schedule' are forced to have a 50/50 split. Valid split integers are between 1-50." + }, + "from_name_a": { + "type": "string", + "title": "From Name Group A", + "description": "For campaigns split on 'From Name', the name for Group A." + }, + "from_name_b": { + "type": "string", + "title": "From Name Group B", + "description": "For campaigns split on 'From Name', the name for Group B." + }, + "reply_email_a": { + "type": "string", + "title": "Reply Email Group A", + "description": "For campaigns split on 'From Name', the reply-to address for Group A." + }, + "reply_email_b": { + "type": "string", + "title": "Reply Email Group B", + "description": "For campaigns split on 'From Name', the reply-to address for Group B." + }, + "subject_a": { + "type": "string", + "title": "Subject Line Group A", + "description": "For campaigns split on 'Subject Line', the subject line for Group A." + }, + "subject_b": { + "type": "string", + "title": "Subject Line Group B", + "description": "For campaigns split on 'Subject Line', the subject line for Group B." + }, + "send_time_a": { + "type": "string", + "format": "date-time", + "title": "Send Time Group A", + "description": "The send time for Group A." + }, + "send_time_b": { + "type": "string", + "format": "date-time", + "title": "Send Time Group B", + "description": "The send time for Group B." + }, + "send_time_winner": { + "type": "string", + "title": "Send Time Winner", + "description": "The send time for the winning version." + } + } + }, + "social_card": { + "type": "object", + "title": "Campaign Social Card", + "description": "The preview for the campaign, rendered by social networks like Facebook and Twitter. [Learn more](https://mailchimp.com/help/enable-and-customize-social-cards/).", + "properties": { + "image_url": { + "type": "string", + "title": "Image URL", + "description": "The url for the header image for the card." + }, + "description": { + "type": "string", + "title": "Campaign Description", + "description": "A short summary of the campaign to display." + }, + "title": { + "type": "string", + "title": "Title", + "description": "The title for the card. Typically the subject line of the campaign." + } + } + }, + "report_summary": { + "type": "object", + "title": "Campaign Report Summary", + "description": "For sent campaigns, a summary of opens, clicks, and e-commerce data.", + "properties": { + "opens": { + "type": "integer", + "title": "Automation Opens", + "description": "The total number of opens for a campaign.", + "readOnly": true + }, + "unique_opens": { + "type": "integer", + "title": "Unique Opens", + "description": "The number of unique opens.", + "readOnly": true + }, + "open_rate": { + "type": "number", + "title": "Open Rate", + "description": "The number of unique opens divided by the total number of successful deliveries.", + "readOnly": true + }, + "clicks": { + "type": "integer", + "title": "Total Clicks", + "description": "The total number of clicks for an campaign.", + "readOnly": true + }, + "subscriber_clicks": { + "type": "integer", + "title": "Unique Subscriber Clicks", + "description": "The number of unique clicks.", + "readOnly": true + }, + "click_rate": { + "type": "number", + "title": "Click Rate", + "description": "The number of unique clicks divided by the total number of successful deliveries.", + "readOnly": true + }, + "ecommerce": { + "type": "object", + "title": "E-Commerce Report", + "description": "E-Commerce stats for a campaign.", + "properties": { + "total_orders": { + "type": "integer", + "title": "Total Orders", + "description": "The total orders for a campaign.", + "readOnly": true + }, + "total_spent": { + "type": "number", + "title": "Total Spent", + "description": "The total spent for a campaign. Calculated as the sum of all order totals with no deductions.", + "readOnly": true + }, + "total_revenue": { + "type": "number", + "title": "Total Revenue", + "description": "The total revenue for a campaign. Calculated as the sum of all order totals minus shipping and tax totals.", + "readOnly": true + } + } + } + } + }, + "delivery_status": { + "type": "object", + "title": "Campaign Delivery Status", + "description": "Updates on campaigns in the process of sending.", + "properties": { + "enabled": { + "type": "boolean", + "title": "Delivery Status Enabled", + "description": "Whether Campaign Delivery Status is enabled for this account and campaign.", + "readOnly": true + }, + "can_cancel": { + "type": "boolean", + "title": "Campaign Cancelable", + "description": "Whether a campaign send can be canceled.", + "readOnly": true + }, + "status": { + "type": "string", + "title": "Campaign Delivery Status", + "description": "The current state of a campaign delivery.", + "enum": ["delivering", "delivered", "canceling", "canceled"], + "readOnly": true + }, + "emails_sent": { + "type": "integer", + "title": "Emails Sent", + "description": "The total number of emails confirmed sent for this campaign so far.", + "readOnly": true + }, + "emails_canceled": { + "type": "integer", + "title": "Emails Canceled", + "description": "The total number of emails canceled for this campaign.", + "readOnly": true + } + } + } + } + }, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["create_time"] + }, + "sync_mode": "incremental", + "cursor_field": ["create_time"], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "automations", + "json_schema": { + "type": "object", + "title": "Automation", + "description": "A summary of an individual campaign's settings and content.", + "properties": { + "id": { + "type": ["null", "string"] + }, + "create_time": { + "type": ["null", "string"] + }, + "start_time": { + "type": ["null", "string"] + }, + "status": { + "type": ["null", "string"] + }, + "emails_sent": { + "type": ["null", "number"] + }, + "recipients": { + "type": ["null", "object"], + "properties": { + "list_id": { + "type": ["null", "string"] + }, + "list_is_active": { + "type": ["null", "boolean"] + }, + "list_name": { + "type": ["null", "string"] + }, + "segment_opts": { + "type": ["null", "object"], + "properties": { + "saved_segment_id": { + "type": ["null", "number"] + }, + "match": { + "type": ["null", "string"] + }, + "conditions": { + "type": ["null", "array"], + "items": {} + } + } + }, + "store_id": { + "type": ["null", "string"] + } + } + }, + "settings": { + "type": ["null", "object"], + "properties": { + "title": { + "type": ["null", "string"] + }, + "from_name": { + "type": ["null", "string"] + }, + "reply_to": { + "type": ["null", "string"] + }, + "use_conversation": { + "type": ["null", "boolean"] + }, + "to_name": { + "type": ["null", "string"] + }, + "authenticate": { + "type": ["null", "boolean"] + }, + "auto_footer": { + "type": ["null", "boolean"] + }, + "inline_css": { + "type": ["null", "boolean"] + } + } + }, + "tracking": { + "type": ["null", "object"], + "properties": { + "opens": { + "type": ["null", "boolean"] + }, + "html_clicks": { + "type": ["null", "boolean"] + }, + "text_clicks": { + "type": ["null", "boolean"] + }, + "goal_tracking": { + "type": ["null", "boolean"] + }, + "ecomm360": { + "type": ["null", "boolean"] + }, + "google_analytics": { + "type": ["null", "string"] + }, + "clicktale": { + "type": ["null", "string"] + }, + "salesforce": { + "type": ["null", "object"], + "properties": { + "campaign": { + "type": ["null", "boolean"] + }, + "notes": { + "type": ["null", "boolean"] + } + } + }, + "capsule": { + "type": ["null", "object"], + "properties": { + "notes": { + "type": ["null", "boolean"] + } + } + } + } + }, + "trigger_settings": { + "type": ["null", "object"], + "properties": { + "workflow_type": { + "type": ["null", "string"] + }, + "workflow_title": { + "type": ["null", "string"] + }, + "runtime": { + "type": ["null", "object"], + "properties": { + "days": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "hours": { + "type": ["null", "object"], + "properties": { + "type": { + "type": ["null", "string"] + } + } + } + } + }, + "workflow_emails_count": { + "type": ["null", "number"] + } + } + }, + "report_summary": { + "type": ["null", "object"], + "properties": { + "opens": { + "type": ["null", "number"] + }, + "unique_opens": { + "type": ["null", "number"] + }, + "open_rate": { + "type": ["null", "number"] + }, + "clicks": { + "type": ["null", "number"] + }, + "subscriber_clicks": { + "type": ["null", "number"] + }, + "click_rate": { + "type": ["null", "number"] + } + } + }, + "_links": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "properties": { + "rel": { + "type": ["null", "string"] + }, + "href": { + "type": ["null", "string"] + }, + "method": { + "type": ["null", "string"] + }, + "targetSchema": { + "type": ["null", "string"] + }, + "schema": { + "type": ["null", "string"] + } + } + } + } + } + }, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["create_time"] + }, + "sync_mode": "incremental", + "cursor_field": ["create_time"], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "lists", + "json_schema": { + "type": "object", + "title": "Subscriber List", + "description": "Information about a specific list.", + "properties": { + "id": { + "type": "string", + "title": "List ID", + "description": "A string that uniquely identifies this list.", + "readOnly": true + }, + "web_id": { + "type": "integer", + "title": "List Web ID", + "description": "The ID used in the Mailchimp web application. View this list in your Mailchimp account at `https://{dc}.admin.mailchimp.com/lists/members/?id={web_id}`.", + "readOnly": true + }, + "name": { + "type": "string", + "title": "List Name", + "description": "The name of the list." + }, + "contact": { + "type": "object", + "title": "List Contact", + "description": "[Contact information displayed in campaign footers](https://mailchimp.com/help/about-campaign-footers/) to comply with international spam laws.", + "properties": { + "company": { + "type": "string", + "title": "Company Name", + "description": "The company name for the list." + }, + "address1": { + "type": "string", + "title": "Address", + "description": "The street address for the list contact." + }, + "address2": { + "type": "string", + "title": "Address", + "description": "The street address for the list contact." + }, + "city": { + "type": "string", + "title": "City", + "description": "The city for the list contact." + }, + "state": { + "type": "string", + "title": "State", + "description": "The state for the list contact." + }, + "zip": { + "type": "string", + "title": "Postal Code", + "description": "The postal or zip code for the list contact." + }, + "country": { + "type": "string", + "title": "Country Code", + "description": "A two-character ISO3166 country code. Defaults to US if invalid." + }, + "phone": { + "type": "string", + "title": "Phone Number", + "description": "The phone number for the list contact." + } + } + }, + "permission_reminder": { + "type": "string", + "title": "Permission Reminder", + "description": "The [permission reminder](https://mailchimp.com/help/edit-the-permission-reminder/) for the list." + }, + "use_archive_bar": { + "type": "boolean", + "title": "Use Archive Bar", + "description": "Whether campaigns for this list use the [Archive Bar](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) in archives by default.", + "default": false + }, + "campaign_defaults": { + "type": "object", + "title": "Campaign Defaults", + "description": "[Default values for campaigns](https://mailchimp.com/help/edit-your-emails-subject-preview-text-from-name-or-from-email-address/) created for this list.", + "properties": { + "from_name": { + "type": "string", + "title": "Sender's Name", + "description": "The default from name for campaigns sent to this list." + }, + "from_email": { + "type": "string", + "title": "Sender's Email Address", + "description": "The default from email for campaigns sent to this list." + }, + "subject": { + "type": "string", + "title": "Subject", + "description": "The default subject line for campaigns sent to this list." + }, + "language": { + "type": "string", + "title": "Language", + "description": "The default language for this lists's forms." + } + } + }, + "notify_on_subscribe": { + "type": "string", + "title": "Notify on Subscribe", + "description": "The email address to send [subscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", + "default": false + }, + "notify_on_unsubscribe": { + "type": "string", + "title": "Notify on Unsubscribe", + "description": "The email address to send [unsubscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", + "default": false + }, + "date_created": { + "type": "string", + "title": "Creation Date", + "description": "The date and time that this list was created in ISO 8601 format.", + "format": "date-time", + "readOnly": true + }, + "list_rating": { + "type": "integer", + "title": "List Rating", + "description": "An auto-generated activity score for the list (0-5).", + "readOnly": true + }, + "email_type_option": { + "type": "boolean", + "title": "Email Type Option", + "description": "Whether the list supports [multiple formats for emails](https://mailchimp.com/help/change-list-name-and-defaults/). When set to `true`, subscribers can choose whether they want to receive HTML or plain-text emails. When set to `false`, subscribers will receive HTML emails, with a plain-text alternative backup." + }, + "subscribe_url_short": { + "type": "string", + "title": "Subscribe URL Short", + "description": "Our [EepURL shortened](https://mailchimp.com/help/share-your-signup-form/) version of this list's subscribe form.", + "readOnly": true + }, + "subscribe_url_long": { + "type": "string", + "title": "Subscribe URL Long", + "description": "The full version of this list's subscribe form (host will vary).", + "readOnly": true + }, + "beamer_address": { + "type": "string", + "title": "Beamer Address", + "description": "The list's [Email Beamer](https://mailchimp.com/help/use-email-beamer-to-create-a-campaign/) address.", + "readOnly": true + }, + "visibility": { + "type": "string", + "title": "Visibility", + "enum": ["pub", "prv"], + "description": "Whether this list is [public or private](https://mailchimp.com/help/about-list-publicity/)." + }, + "double_optin": { + "type": "boolean", + "title": "Double Opt In", + "description": "Whether or not to require the subscriber to confirm subscription via email.", + "default": false + }, + "has_welcome": { + "type": "boolean", + "title": "Has Welcome", + "description": "Whether or not this list has a welcome automation connected. Welcome Automations: welcomeSeries, singleWelcome, emailFollowup.", + "default": false, + "example": false + }, + "marketing_permissions": { + "type": "boolean", + "title": "Marketing Permissions", + "description": "Whether or not the list has marketing permissions (eg. GDPR) enabled.", + "default": false + }, + "modules": { + "type": "array", + "title": "Modules", + "description": "Any list-specific modules installed for this list.", + "items": { + "type": "string" + }, + "readOnly": true + }, + "stats": { + "type": "object", + "title": "Statistics", + "description": "Stats for the list. Many of these are cached for at least five minutes.", + "readOnly": true, + "properties": { + "member_count": { + "type": "integer", + "title": "Member Count", + "description": "The number of active members in the list.", + "readOnly": true + }, + "total_contacts": { + "type": "integer", + "title": "Total Contacts", + "description": "The number of contacts in the list, including subscribed, unsubscribed, pending, cleaned, deleted, transactional, and those that need to be reconfirmed.", + "readOnly": true + }, + "unsubscribe_count": { + "type": "integer", + "title": "Unsubscribe Count", + "description": "The number of members who have unsubscribed from the list.", + "readOnly": true + }, + "cleaned_count": { + "type": "integer", + "title": "Cleaned Count", + "description": "The number of members cleaned from the list.", + "readOnly": true + }, + "member_count_since_send": { + "type": "integer", + "title": "Member Count Since Send", + "description": "The number of active members in the list since the last campaign was sent.", + "readOnly": true + }, + "unsubscribe_count_since_send": { + "type": "integer", + "title": "Unsubscribe Count Since Send", + "description": "The number of members who have unsubscribed since the last campaign was sent.", + "readOnly": true + }, + "cleaned_count_since_send": { + "type": "integer", + "title": "Cleaned Count Since Send", + "description": "The number of members cleaned from the list since the last campaign was sent.", + "readOnly": true + }, + "campaign_count": { + "type": "integer", + "title": "Campaign Count", + "description": "The number of campaigns in any status that use this list.", + "readOnly": true + }, + "campaign_last_sent": { + "type": "string", + "format": "date-time", + "title": "Campaign Last Sent", + "description": "The date and time the last campaign was sent to this list in ISO 8601 format. This is updated when a campaign is sent to 10 or more recipients.", + "readOnly": true + }, + "merge_field_count": { + "type": "integer", + "title": "Merge Var Count", + "description": "The number of merge vars for this list (not EMAIL, which is required).", + "readOnly": true + }, + "avg_sub_rate": { + "type": "number", + "title": "Average Subscription Rate", + "description": "The average number of subscriptions per month for the list (not returned if we haven't calculated it yet).", + "readOnly": true + }, + "avg_unsub_rate": { + "type": "number", + "title": "Average Unsubscription Rate", + "description": "The average number of unsubscriptions per month for the list (not returned if we haven't calculated it yet).", + "readOnly": true + }, + "target_sub_rate": { + "type": "number", + "title": "Average Subscription Rate", + "description": "The target number of subscriptions per month for the list to keep it growing (not returned if we haven't calculated it yet).", + "readOnly": true + }, + "open_rate": { + "type": "number", + "title": "Open Rate", + "description": "The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet).", + "readOnly": true + }, + "click_rate": { + "type": "number", + "title": "Click Rate", + "description": "The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet).", + "readOnly": true + }, + "last_sub_date": { + "type": "string", + "format": "date-time", + "title": "Date of Last List Subscribe", + "description": "The date and time of the last time someone subscribed to this list in ISO 8601 format.", + "readOnly": true + }, + "last_unsub_date": { + "type": "string", + "format": "date-time", + "title": "Date of Last List Unsubscribe", + "description": "The date and time of the last time someone unsubscribed from this list in ISO 8601 format.", + "readOnly": true + } + } + } + } + }, + "supported_sync_modes": ["full_refresh", "incremental"], + "source_defined_cursor": true, + "default_cursor_field": ["date_created"] + }, + "sync_mode": "incremental", + "cursor_field": ["date_created"], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "email_activity", + "json_schema": { + "type": "object", + "title": "Email Activity", + "description": "A list of member's subscriber activity in a specific campaign.", + "properties": { + "emails": { + "type": "object", + "title": "List members", + "description": "An array of members that were sent the campaign.", + "properties": { + "campaign_id": { + "type": "string", + "title": "The unique id for the campaign.", + "description": "The unique id for the campaign." + }, + "list_id": { + "type": "string", + "title": "The unique id for the list.", + "description": "The unique id for the list." + }, + "list_is_active": { + "type": "boolean", + "title": "The status of the list used.", + "description": "The status of the list used, namely if it's deleted or disabled." + }, + "email_id": { + "type": "string", + "title": "email MD5 hash.", + "description": "The MD5 hash of the lowercase version of the list member's email address." + }, + "email_address": { + "type": "string", + "title": "Email address for a subscriber.", + "description": "Email address for a subscriber." + }, + "action": { + "type": "string", + "title": "action", + "enum": ["open", "click", "bounce"], + "description": "One of the following actions: 'open', 'click', or 'bounce'" + }, + "type": { + "type": "string", + "title": "Type", + "enum": ["hard", "soft"], + "description": "If the action is a 'bounce', the type of bounce received: 'hard', 'soft'." + }, + "timestamp": { + "type": "string", + "title": "Action date and time", + "description": "The date and time recorded for the action in ISO 8601 format.", + "format": "date-time" + }, + "url": { + "type": "string", + "title": "The IP address.", + "description": "The IP address recorded for the action." + }, + "ip": { + "type": "string", + "title": "Action ip address", + "description": "The IP address recorded for the action." + } + } + }, + "campaign_id": { + "type": "string", + "title": "Campaign ID", + "description": "The unique id for the sent campaign." + }, + "total_items": { + "type": "integer", + "title": "Total amount of items", + "description": "The total number of items matching the query regardless of pagination." + } + } + }, + "supported_sync_modes": ["incremental", "full_refresh"], + "source_defined_cursor": true, + "default_cursor_field": ["timestamp"] + }, + "sync_mode": "incremental", + "cursor_field": ["timestamp"], + "destination_sync_mode": "append" + }, + { + "stream": { + "name": "reports", + "json_schema": {}, + "supported_sync_modes": ["incremental", "full_refresh"], + "source_defined_cursor": true, + "default_cursor_field": ["send_time"] + }, + "sync_mode": "incremental", + "cursor_field": ["send_time"], + "destination_sync_mode": "append" + } + ] +} diff --git a/source-mailchimp/sample_files/state.json b/source-mailchimp/sample_files/state.json new file mode 100644 index 0000000000..d01435a925 --- /dev/null +++ b/source-mailchimp/sample_files/state.json @@ -0,0 +1,11 @@ +{ + "campaigns": { "create_time": "2020-11-23T05:42:11+00:00" }, + "lists": { "date_created": "2020-09-25T04:47:31+00:00" }, + "automations": { "create_time": "2020-11-23T05:42:11+00:00" }, + "email_activity": { + "49d68626f3": { "timestamp": "2020-11-23T05:42:10+00:00" } + }, + "reports": { + "49d68626f3": { "send_time": "2020-11-23T05:42:10+00:00" } + } +} diff --git a/source-mailchimp/source_mailchimp/__init__.py b/source-mailchimp/source_mailchimp/__init__.py new file mode 100644 index 0000000000..5087fc54c7 --- /dev/null +++ b/source-mailchimp/source_mailchimp/__init__.py @@ -0,0 +1,3 @@ +from .source import SourceMailchimp + +__all__ = ["SourceMailchimp"] diff --git a/source-mailchimp/source_mailchimp/run.py b/source-mailchimp/source_mailchimp/run.py new file mode 100644 index 0000000000..15226fdfee --- /dev/null +++ b/source-mailchimp/source_mailchimp/run.py @@ -0,0 +1,14 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +import sys + +from airbyte_cdk.entrypoint import launch +from source_mailchimp import SourceMailchimp + + +def run(): + source = SourceMailchimp() + launch(source, sys.argv[1:]) diff --git a/source-mailchimp/source_mailchimp/schemas/automations.json b/source-mailchimp/source_mailchimp/schemas/automations.json new file mode 100644 index 0000000000..27e691cf22 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/automations.json @@ -0,0 +1,192 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "title": "Automations", + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "string"] + }, + "create_time": { + "type": ["null", "string"], + "format": "date-time", + "airbyte-type": "timestamp_with_timezone" + }, + "start_time": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "status": { + "type": ["null", "string"] + }, + "emails_sent": { + "type": ["null", "number"] + }, + "recipients": { + "type": ["null", "object"], + "properties": { + "list_id": { + "type": ["null", "string"] + }, + "list_is_active": { + "type": ["null", "boolean"] + }, + "list_name": { + "type": ["null", "string"] + }, + "segment_opts": { + "type": ["null", "object"], + "properties": { + "saved_segment_id": { + "type": ["null", "number"] + }, + "match": { + "type": ["null", "string"] + }, + "conditions": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "additionalProperties": true + } + } + } + }, + "store_id": { + "type": ["null", "string"] + } + } + }, + "settings": { + "type": ["null", "object"], + "properties": { + "title": { + "type": ["null", "string"] + }, + "from_name": { + "type": ["null", "string"] + }, + "reply_to": { + "type": ["null", "string"] + }, + "use_conversation": { + "type": ["null", "boolean"] + }, + "to_name": { + "type": ["null", "string"] + }, + "authenticate": { + "type": ["null", "boolean"] + }, + "auto_footer": { + "type": ["null", "boolean"] + }, + "inline_css": { + "type": ["null", "boolean"] + } + } + }, + "tracking": { + "type": ["null", "object"], + "properties": { + "opens": { + "type": ["null", "boolean"] + }, + "html_clicks": { + "type": ["null", "boolean"] + }, + "text_clicks": { + "type": ["null", "boolean"] + }, + "goal_tracking": { + "type": ["null", "boolean"] + }, + "ecomm360": { + "type": ["null", "boolean"] + }, + "google_analytics": { + "type": ["null", "string"] + }, + "clicktale": { + "type": ["null", "string"] + }, + "salesforce": { + "type": ["null", "object"], + "properties": { + "campaign": { + "type": ["null", "boolean"] + }, + "notes": { + "type": ["null", "boolean"] + } + } + }, + "capsule": { + "type": ["null", "object"], + "properties": { + "notes": { + "type": ["null", "boolean"] + } + } + } + } + }, + "trigger_settings": { + "type": ["null", "object"], + "properties": { + "workflow_type": { + "type": ["null", "string"] + }, + "workflow_title": { + "type": ["null", "string"] + }, + "runtime": { + "type": ["null", "object"], + "properties": { + "days": { + "type": ["null", "array"], + "items": { + "type": ["null", "string"] + } + }, + "hours": { + "type": ["null", "object"], + "properties": { + "type": { + "type": ["null", "string"] + } + } + } + } + }, + "workflow_emails_count": { + "type": ["null", "number"] + } + } + }, + "report_summary": { + "type": ["null", "object"], + "properties": { + "opens": { + "type": ["null", "number"] + }, + "unique_opens": { + "type": ["null", "number"] + }, + "open_rate": { + "type": ["null", "number"] + }, + "clicks": { + "type": ["null", "number"] + }, + "subscriber_clicks": { + "type": ["null", "number"] + }, + "click_rate": { + "type": ["null", "number"] + } + } + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/campaigns.json b/source-mailchimp/source_mailchimp/schemas/campaigns.json new file mode 100644 index 0000000000..8d058b78e9 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/campaigns.json @@ -0,0 +1,739 @@ +{ + "type": "object", + "title": "Campaign", + "description": "A summary of an individual campaign's settings and content.", + "properties": { + "id": { + "type": "string", + "title": "Campaign ID", + "description": "A string that uniquely identifies this campaign.", + "readOnly": true + }, + "web_id": { + "type": "integer", + "title": "Campaign Web ID", + "description": "The ID used in the Mailchimp web application. View this campaign in your Mailchimp account at `https://{dc}.admin.mailchimp.com/campaigns/show/?id={web_id}`.", + "readOnly": true + }, + "parent_campaign_id": { + "type": ["null", "string"], + "title": "Parent Campaign ID", + "description": "If this campaign is the child of another campaign, this identifies the parent campaign. For Example, for RSS or Automation children.", + "readOnly": true + }, + "type": { + "$ref": "campaignType.json" + }, + "create_time": { + "type": "string", + "title": "Create Time", + "description": "The date and time the campaign was created in ISO 8601 format.", + "readOnly": true, + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "archive_url": { + "type": ["null", "string"], + "title": "Archive URL", + "description": "The link to the campaign's archive version in ISO 8601 format.", + "readOnly": true + }, + "long_archive_url": { + "type": ["null", "string"], + "title": "Long Archive URL", + "description": "The original link to the campaign's archive version.", + "readOnly": true + }, + "status": { + "$ref": "campaignStatus.json" + }, + "emails_sent": { + "type": "integer", + "title": "Emails Sent", + "description": "The total number of emails sent for this campaign.", + "readOnly": true + }, + "send_time": { + "type": ["null", "string"], + "title": "Send Time", + "description": "The date and time a campaign was sent.", + "readOnly": true, + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "content_type": { + "type": ["null", "string"], + "title": "Content Type", + "description": "How the campaign's content is put together.", + "enum": ["template", "html", "url", "multichannel"] + }, + "needs_block_refresh": { + "type": "boolean", + "title": "Needs Block Refresh", + "description": "Determines if the campaign needs its blocks refreshed by opening the web-based campaign editor. Deprecated and will always return false.", + "readOnly": true + }, + "resendable": { + "type": "boolean", + "title": "Resendable", + "description": "Determines if the campaign qualifies to be resent to non-openers.", + "readOnly": true + }, + "recipients": { + "type": "object", + "title": "List", + "description": "List settings for the campaign.", + "properties": { + "list_id": { + "type": ["null", "string"], + "title": "List ID", + "description": "The unique list id." + }, + "list_is_active": { + "type": "boolean", + "title": "List Status", + "description": "The status of the list used, namely if it's deleted or disabled.", + "readOnly": true + }, + "list_name": { + "type": ["null", "string"], + "title": "List Name", + "description": "The name of the list.", + "readOnly": true + }, + "segment_text": { + "type": ["null", "string"], + "title": "Segment Text", + "description": "A description of the [segment](https://mailchimp.com/help/create-and-send-to-a-segment/) used for the campaign. Formatted as a string marked up with HTML.", + "readOnly": true + }, + "recipient_count": { + "type": "integer", + "title": "Recipient Count", + "description": "Count of the recipients on the associated list. Formatted as an integer.", + "readOnly": true + }, + "segment_opts": { + "$ref": "segmentationOptions.json" + } + } + }, + "settings": { + "type": "object", + "title": "Campaign Settings", + "description": "The settings for your campaign, including subject, from name, reply-to address, and more.", + "properties": { + "subject_line": { + "type": ["null", "string"], + "title": "Campaign Subject Line", + "description": "The subject line for the campaign." + }, + "preview_text": { + "type": ["null", "string"], + "title": "Campaign Preview Text", + "description": "The preview text for the campaign." + }, + "title": { + "type": ["null", "string"], + "title": "Campaign Title", + "description": "The title of the campaign." + }, + "from_name": { + "type": ["null", "string"], + "title": "From Name", + "description": "The 'from' name on the campaign (not an email address)." + }, + "reply_to": { + "type": ["null", "string"], + "title": "Reply To Address", + "description": "The reply-to email address for the campaign." + }, + "use_conversation": { + "type": "boolean", + "title": "Conversation", + "description": "Use Mailchimp Conversation feature to manage out-of-office replies." + }, + "to_name": { + "type": ["null", "string"], + "title": "To Name", + "description": "The campaign's custom 'To' name. Typically the first name [merge field](https://mailchimp.com/help/getting-started-with-merge-tags/)." + }, + "folder_id": { + "type": ["null", "string"], + "title": "Folder ID", + "description": "If the campaign is listed in a folder, the id for that folder." + }, + "authenticate": { + "type": "boolean", + "title": "Authentication", + "description": "Whether Mailchimp [authenticated](https://mailchimp.com/help/about-email-authentication/) the campaign. Defaults to `true`." + }, + "auto_footer": { + "type": "boolean", + "title": "Auto-Footer", + "description": "Automatically append Mailchimp's [default footer](https://mailchimp.com/help/about-campaign-footers/) to the campaign." + }, + "inline_css": { + "type": "boolean", + "title": "Inline CSS", + "description": "Automatically inline the CSS included with the campaign content." + }, + "auto_tweet": { + "type": "boolean", + "title": "Auto-Tweet", + "description": "Automatically tweet a link to the [campaign archive](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) page when the campaign is sent." + }, + "auto_fb_post": { + "type": "array", + "title": "Auto Post to Facebook", + "description": "An array of [Facebook](https://mailchimp.com/help/connect-or-disconnect-the-facebook-integration/) page ids to auto-post to.", + "items": { + "type": ["null", "string"] + } + }, + "fb_comments": { + "type": "boolean", + "title": "Facebook Comments", + "description": "Allows Facebook comments on the campaign (also force-enables the Campaign Archive toolbar). Defaults to `true`." + }, + "timewarp": { + "type": "boolean", + "title": "Timewarp Send", + "description": "Send this campaign using [Timewarp](https://mailchimp.com/help/use-timewarp/).", + "readOnly": true + }, + "template_id": { + "type": "integer", + "title": "Template ID", + "description": "The id for the template used in this campaign.", + "readOnly": false + }, + "drag_and_drop": { + "type": "boolean", + "title": "Drag And Drop Campaign", + "description": "Whether the campaign uses the drag-and-drop editor.", + "readOnly": true + } + } + }, + "variate_settings": { + "type": "object", + "title": "A/B Test Options", + "description": "The settings specific to A/B test campaigns.", + "properties": { + "winning_combination_id": { + "type": ["null", "string"], + "title": "Winning Combination ID", + "description": "ID for the winning combination.", + "readOnly": true + }, + "winning_campaign_id": { + "type": ["null", "string"], + "title": "Winning Campaign ID", + "description": "ID of the campaign that was sent to the remaining recipients based on the winning combination.", + "readOnly": true + }, + "winner_criteria": { + "type": ["null", "string"], + "title": "Winning Criteria", + "description": "The combination that performs the best. This may be determined automatically by click rate, open rate, or total revenue -- or you may choose manually based on the reporting data you find the most valuable. For Multivariate Campaigns testing send_time, winner_criteria is ignored. For Multivariate Campaigns with 'manual' as the winner_criteria, the winner must be chosen in the Mailchimp web application.", + "enum": ["opens", "clicks", "manual", "total_revenue"] + }, + "wait_time": { + "type": "integer", + "title": "Wait Time", + "description": "The number of minutes to wait before choosing the winning campaign. The value of wait_time must be greater than 0 and in whole hours, specified in minutes." + }, + "test_size": { + "type": "integer", + "title": "Test Size", + "description": "The percentage of recipients to send the test combinations to, must be a value between 10 and 100." + }, + "subject_lines": { + "type": "array", + "title": "Subject Lines", + "description": "The possible subject lines to test. If no subject lines are provided, settings.subject_line will be used.", + "items": { + "type": ["null", "string"] + } + }, + "send_times": { + "type": "array", + "title": "Send Times", + "description": "The possible send times to test. The times provided should be in the format YYYY-MM-DD HH:MM:SS. If send_times are provided to test, the test_size will be set to 100% and winner_criteria will be ignored.", + "items": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + } + }, + "from_names": { + "type": "array", + "title": "From Names", + "description": "The possible from names. The number of from_names provided must match the number of reply_to_addresses. If no from_names are provided, settings.from_name will be used.", + "items": { + "type": ["null", "string"] + } + }, + "reply_to_addresses": { + "type": "array", + "title": "Reply To Addresses", + "description": "The possible reply-to addresses. The number of reply_to_addresses provided must match the number of from_names. If no reply_to_addresses are provided, settings.reply_to will be used.", + "items": { + "type": ["null", "string"] + } + }, + "contents": { + "type": "array", + "title": "Content Descriptions", + "description": "Descriptions of possible email contents. To set campaign contents, make a PUT request to /campaigns/{campaign_id}/content with the field 'variate_contents'.", + "items": { + "type": ["null", "string"] + }, + "readOnly": true + }, + "combinations": { + "type": "array", + "title": "Combinations", + "description": "Combinations of possible variables used to build emails.", + "readOnly": true, + "items": { + "type": "object", + "properties": { + "id": { + "type": ["null", "string"], + "title": "ID", + "description": "Unique ID for the combination." + }, + "subject_line": { + "type": "integer", + "title": "Subject Line", + "description": "The index of `variate_settings.subject_lines` used." + }, + "send_time": { + "type": "integer", + "title": "Send Time", + "description": "The index of `variate_settings.send_times` used." + }, + "from_name": { + "type": "integer", + "title": "From Name", + "description": "The index of `variate_settings.from_names` used." + }, + "reply_to": { + "type": "integer", + "title": "Reply To", + "description": "The index of `variate_settings.reply_to_addresses` used." + }, + "content_description": { + "type": "integer", + "title": "Content Description", + "description": "The index of `variate_settings.contents` used." + }, + "recipients": { + "type": "integer", + "title": "Recipients", + "description": "The number of recipients for this combination." + } + } + } + } + } + }, + "tracking": { + "type": "object", + "title": "Campaign Tracking Options", + "description": "The tracking options for a campaign.", + "properties": { + "opens": { + "type": "boolean", + "title": "Opens", + "description": "Whether to [track opens](https://mailchimp.com/help/about-open-tracking/). Defaults to `true`. Cannot be set to false for variate campaigns." + }, + "html_clicks": { + "type": "boolean", + "title": "HTML Click Tracking", + "description": "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the HTML version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns." + }, + "text_clicks": { + "type": "boolean", + "title": "Plain-Text Click Tracking", + "description": "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the plain-text version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns." + }, + "goal_tracking": { + "type": "boolean", + "title": "Mailchimp Goal Tracking", + "description": "Whether to enable [Goal](https://mailchimp.com/help/about-connected-sites/) tracking." + }, + "ecomm360": { + "type": "boolean", + "title": "E-commerce Tracking", + "description": "Whether to enable [eCommerce360](https://mailchimp.com/help/connect-your-online-store-to-mailchimp/) tracking." + }, + "google_analytics": { + "type": ["null", "string"], + "title": "Google Analytics Tracking", + "description": "The custom slug for [Google Analytics](https://mailchimp.com/help/integrate-google-analytics-with-mailchimp/) tracking (max of 50 bytes)." + }, + "clicktale": { + "type": ["null", "string"], + "title": "ClickTale Analytics Tracking", + "description": "The custom slug for [ClickTale](https://mailchimp.com/help/additional-tracking-options-for-campaigns/) tracking (max of 50 bytes)." + }, + "salesforce": { + "type": "object", + "title": "Salesforce CRM Tracking", + "description": "Salesforce tracking options for a campaign. Must be using Mailchimp's built-in [Salesforce integration](https://mailchimp.com/help/integrate-salesforce-with-mailchimp/).", + "properties": { + "campaign": { + "type": "boolean", + "title": "Salesforce Campaign", + "description": "Create a campaign in a connected Salesforce account." + }, + "notes": { + "type": "boolean", + "title": "Salesforce Note", + "description": "Update contact notes for a campaign based on subscriber email addresses." + } + } + }, + "capsule": { + "type": "object", + "title": "Capsule CRM Tracking", + "description": "Capsule tracking options for a campaign. Must be using Mailchimp's built-in Capsule integration.", + "properties": { + "notes": { + "type": "boolean", + "title": "Capsule Note", + "description": "Update contact notes for a campaign based on subscriber email addresses." + } + } + } + } + }, + "rss_opts": { + "type": "object", + "title": "RSS Options", + "description": "[RSS](https://mailchimp.com/help/share-your-blog-posts-with-mailchimp/) options for a campaign.", + "properties": { + "feed_url": { + "type": ["null", "string"], + "title": "Feed URL", + "format": "uri", + "description": "The URL for the RSS feed." + }, + "frequency": { + "type": ["null", "string"], + "title": "Frequency", + "description": "The frequency of the RSS Campaign.", + "enum": ["daily", "weekly", "monthly"] + }, + "schedule": { + "type": "object", + "title": "Sending Schedule", + "description": "The schedule for sending the RSS Campaign.", + "properties": { + "hour": { + "type": "integer", + "minimum": 0, + "maximum": 23, + "title": "Sending Hour", + "description": "The hour to send the campaign in local time. Acceptable hours are 0-23. For example, '4' would be 4am in [your account's default time zone](https://mailchimp.com/help/set-account-defaults/)." + }, + "daily_send": { + "type": "object", + "title": "Daily Sending Days", + "description": "The days of the week to send a daily RSS Campaign.", + "properties": { + "sunday": { + "type": "boolean", + "title": "Sunday", + "description": "Sends the daily RSS Campaign on Sundays." + }, + "monday": { + "type": "boolean", + "title": "Monday", + "description": "Sends the daily RSS Campaign on Mondays." + }, + "tuesday": { + "type": "boolean", + "title": "tuesday", + "description": "Sends the daily RSS Campaign on Tuesdays." + }, + "wednesday": { + "type": "boolean", + "title": "Monday", + "description": "Sends the daily RSS Campaign on Wednesdays." + }, + "thursday": { + "type": "boolean", + "title": "Thursday", + "description": "Sends the daily RSS Campaign on Thursdays." + }, + "friday": { + "type": "boolean", + "title": "Friday", + "description": "Sends the daily RSS Campaign on Fridays." + }, + "saturday": { + "type": "boolean", + "title": "Saturday", + "description": "Sends the daily RSS Campaign on Saturdays." + } + } + }, + "weekly_send_day": { + "type": ["null", "string"], + "enum": [ + "sunday", + "monday", + "tuesday", + "wednesday", + "thursday", + "friday", + "saturday" + ], + "title": "Weekly Sending Day", + "description": "The day of the week to send a weekly RSS Campaign." + }, + "monthly_send_date": { + "type": "number", + "minimum": 0, + "maximum": 31, + "title": "Monthly Sending Day", + "description": "The day of the month to send a monthly RSS Campaign. Acceptable days are 0-31, where '0' is always the last day of a month. Months with fewer than the selected number of days will not have an RSS campaign sent out that day. For example, RSS Campaigns set to send on the 30th will not go out in February." + } + } + }, + "last_sent": { + "type": ["null", "string"], + "title": "Last Sent", + "description": "The date the campaign was last sent.", + "readOnly": true, + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "constrain_rss_img": { + "type": "boolean", + "title": "Constrain RSS Images", + "description": "Whether to add CSS to images in the RSS feed to constrain their width in campaigns." + } + } + }, + "ab_split_opts": { + "type": "object", + "title": "A/B Testing Options", + "description": "[A/B Testing](https://mailchimp.com/help/about-ab-testing-campaigns/) options for a campaign.", + "readOnly": true, + "properties": { + "split_test": { + "type": ["null", "string"], + "title": "Split Test", + "description": "The type of AB split to run.", + "enum": ["subject", "from_name", "schedule"] + }, + "pick_winner": { + "type": ["null", "string"], + "title": "Pick Winner", + "description": "How we should evaluate a winner. Based on 'opens', 'clicks', or 'manual'.", + "enum": ["opens", "clicks", "manual"] + }, + "wait_units": { + "type": ["null", "string"], + "title": "Wait Time", + "description": "How unit of time for measuring the winner ('hours' or 'days'). This cannot be changed after a campaign is sent.", + "enum": ["hours", "days"] + }, + "wait_time": { + "type": "integer", + "title": "Wait Time", + "description": "The amount of time to wait before picking a winner. This cannot be changed after a campaign is sent." + }, + "split_size": { + "type": "integer", + "minimum": 1, + "maximum": 50, + "title": "Split Size", + "description": "The size of the split groups. Campaigns split based on 'schedule' are forced to have a 50/50 split. Valid split integers are between 1-50." + }, + "from_name_a": { + "type": ["null", "string"], + "title": "From Name Group A", + "description": "For campaigns split on 'From Name', the name for Group A." + }, + "from_name_b": { + "type": ["null", "string"], + "title": "From Name Group B", + "description": "For campaigns split on 'From Name', the name for Group B." + }, + "reply_email_a": { + "type": ["null", "string"], + "title": "Reply Email Group A", + "description": "For campaigns split on 'From Name', the reply-to address for Group A." + }, + "reply_email_b": { + "type": ["null", "string"], + "title": "Reply Email Group B", + "description": "For campaigns split on 'From Name', the reply-to address for Group B." + }, + "subject_a": { + "type": ["null", "string"], + "title": "Subject Line Group A", + "description": "For campaigns split on 'Subject Line', the subject line for Group A." + }, + "subject_b": { + "type": ["null", "string"], + "title": "Subject Line Group B", + "description": "For campaigns split on 'Subject Line', the subject line for Group B." + }, + "send_time_a": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone", + "title": "Send Time Group A", + "description": "The send time for Group A." + }, + "send_time_b": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone", + "title": "Send Time Group B", + "description": "The send time for Group B." + }, + "send_time_winner": { + "type": ["null", "string"], + "title": "Send Time Winner", + "description": "The send time for the winning version." + } + } + }, + "social_card": { + "type": "object", + "title": "Campaign Social Card", + "description": "The preview for the campaign, rendered by social networks like Facebook and Twitter. [Learn more](https://mailchimp.com/help/enable-and-customize-social-cards/).", + "properties": { + "image_url": { + "type": ["null", "string"], + "title": "Image URL", + "description": "The url for the header image for the card." + }, + "description": { + "type": ["null", "string"], + "title": "Campaign Description", + "description": "A short summary of the campaign to display." + }, + "title": { + "type": ["null", "string"], + "title": "Title", + "description": "The title for the card. Typically the subject line of the campaign." + } + } + }, + "report_summary": { + "type": "object", + "title": "Campaign Report Summary", + "description": "For sent campaigns, a summary of opens, clicks, and e-commerce data.", + "properties": { + "opens": { + "type": "integer", + "title": "Automation Opens", + "description": "The total number of opens for a campaign.", + "readOnly": true + }, + "unique_opens": { + "type": "integer", + "title": "Unique Opens", + "description": "The number of unique opens.", + "readOnly": true + }, + "open_rate": { + "type": "number", + "title": "Open Rate", + "description": "The number of unique opens divided by the total number of successful deliveries.", + "readOnly": true + }, + "clicks": { + "type": "integer", + "title": "Total Clicks", + "description": "The total number of clicks for an campaign.", + "readOnly": true + }, + "subscriber_clicks": { + "type": "integer", + "title": "Unique Subscriber Clicks", + "description": "The number of unique clicks.", + "readOnly": true + }, + "click_rate": { + "type": "number", + "title": "Click Rate", + "description": "The number of unique clicks divided by the total number of successful deliveries.", + "readOnly": true + }, + "ecommerce": { + "type": "object", + "title": "E-Commerce Report", + "description": "E-Commerce stats for a campaign.", + "properties": { + "total_orders": { + "type": "integer", + "title": "Total Orders", + "description": "The total orders for a campaign.", + "readOnly": true + }, + "total_spent": { + "type": "number", + "title": "Total Spent", + "description": "The total spent for a campaign. Calculated as the sum of all order totals with no deductions.", + "readOnly": true + }, + "total_revenue": { + "type": "number", + "title": "Total Revenue", + "description": "The total revenue for a campaign. Calculated as the sum of all order totals minus shipping and tax totals.", + "readOnly": true + } + } + } + } + }, + "delivery_status": { + "type": "object", + "title": "Campaign Delivery Status", + "description": "Updates on campaigns in the process of sending.", + "properties": { + "enabled": { + "type": "boolean", + "title": "Delivery Status Enabled", + "description": "Whether Campaign Delivery Status is enabled for this account and campaign.", + "readOnly": true + }, + "can_cancel": { + "type": "boolean", + "title": "Campaign Cancelable", + "description": "Whether a campaign send can be canceled.", + "readOnly": true + }, + "status": { + "type": ["null", "string"], + "title": "Campaign Delivery Status", + "description": "The current state of a campaign delivery.", + "enum": ["delivering", "delivered", "canceling", "canceled"], + "readOnly": true + }, + "emails_sent": { + "type": "integer", + "title": "Emails Sent", + "description": "The total number of emails confirmed sent for this campaign so far.", + "readOnly": true + }, + "emails_canceled": { + "type": "integer", + "title": "Emails Canceled", + "description": "The total number of emails canceled for this campaign.", + "readOnly": true + } + } + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/email_activity.json b/source-mailchimp/source_mailchimp/schemas/email_activity.json new file mode 100644 index 0000000000..b416956c54 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/email_activity.json @@ -0,0 +1,61 @@ +{ + "type": "object", + "title": "Email Activity", + "description": "A list of member's subscriber activity in a specific campaign.", + "properties": { + "campaign_id": { + "type": "string", + "title": "The unique id for the campaign.", + "description": "The unique id for the campaign." + }, + "list_id": { + "type": "string", + "title": "The unique id for the list.", + "description": "The unique id for the list." + }, + "list_is_active": { + "type": "boolean", + "title": "The status of the list used.", + "description": "The status of the list used, namely if it's deleted or disabled." + }, + "email_id": { + "type": "string", + "title": "email MD5 hash.", + "description": "The MD5 hash of the lowercase version of the list member's email address." + }, + "email_address": { + "type": "string", + "title": "Email address for a subscriber.", + "description": "Email address for a subscriber." + }, + "action": { + "type": ["string", "null"], + "title": "action", + "enum": ["open", "click", "bounce"], + "description": "One of the following actions: 'open', 'click', or 'bounce'" + }, + "type": { + "type": ["string", "null"], + "title": "Type", + "enum": ["hard", "soft"], + "description": "If the action is a 'bounce', the type of bounce received: 'hard', 'soft'." + }, + "timestamp": { + "type": ["string", "null"], + "title": "Action date and time", + "description": "The date and time recorded for the action in ISO 8601 format.", + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "url": { + "type": ["string", "null"], + "title": "Click url", + "description": "If the action is a 'click', the URL on which the member clicked." + }, + "ip": { + "type": ["string", "null"], + "title": "Action ip address", + "description": "The IP address recorded for the action." + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/interest_categories.json b/source-mailchimp/source_mailchimp/schemas/interest_categories.json new file mode 100644 index 0000000000..7d808ecd6a --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/interest_categories.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "list_id": { + "type": ["null", "string"] + }, + "id": { + "type": ["null", "string"] + }, + "title": { + "type": ["null", "string"] + }, + "display_order": { + "type": ["null", "integer"] + }, + "type": { + "type": ["null", "string"] + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/interests.json b/source-mailchimp/source_mailchimp/schemas/interests.json new file mode 100644 index 0000000000..b936326faa --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/interests.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "category_id": { + "type": ["null", "string"] + }, + "list_id": { + "type": ["null", "string"] + }, + "id": { + "type": ["null", "string"] + }, + "name": { + "type": ["null", "string"] + }, + "subscriber_count": { + "type": ["null", "string"] + }, + "display_order": { + "type": ["null", "integer"] + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/list_members.json b/source-mailchimp/source_mailchimp/schemas/list_members.json new file mode 100644 index 0000000000..50376c80b7 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/list_members.json @@ -0,0 +1,185 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "string"] + }, + "email_address": { + "type": ["null", "string"] + }, + "unique_email_id": { + "type": ["null", "string"] + }, + "contact_id": { + "type": ["null", "string"] + }, + "full_name": { + "type": ["null", "string"] + }, + "web_id": { + "type": ["null", "integer"] + }, + "email_type": { + "type": ["null", "string"] + }, + "status": { + "type": ["null", "string"] + }, + "unsubscribe_reason": { + "type": ["null", "string"] + }, + "consents_to_one_to_one_messaging": { + "type": ["null", "boolean"] + }, + "merge_fields": { + "type": ["null", "object"], + "additionalProperties": true + }, + "interests": { + "type": ["null", "object"], + "additionalProperties": true + }, + "stats": { + "type": ["null", "object"], + "properties": { + "avg_open_rate": { + "type": ["null", "number"] + }, + "avg_click_rate": { + "type": ["null", "number"] + }, + "ecommerce_data": { + "type": ["null", "object"], + "properties": { + "total_revenue": { + "type": ["null", "number"] + }, + "number_of_orders": { + "type": ["null", "number"] + }, + "currency_code": { + "type": ["null", "string"] + } + } + } + } + }, + "ip_signup": { + "type": ["null", "string"] + }, + "timestamp_signup": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "ip_opt": { + "type": ["null", "string"] + }, + "timestamp_opt": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "member_rating": { + "type": ["null", "integer"] + }, + "last_changed": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "language": { + "type": ["null", "string"] + }, + "vip": { + "type": ["null", "boolean"] + }, + "email_client": { + "type": ["null", "string"] + }, + "location": { + "type": ["null", "object"], + "properties": { + "latitude": { + "type": ["null", "number"] + }, + "longitude": { + "type": ["null", "number"] + }, + "gmtoff": { + "type": ["null", "integer"] + }, + "dstoff": { + "type": ["null", "integer"] + }, + "country_code": { + "type": ["null", "string"] + }, + "timezone": { + "type": ["null", "string"] + }, + "region": { + "type": ["null", "string"] + } + } + }, + "marketing_permissions": { + "type": ["null", "object"], + "properties": { + "marketing_permission_id": { + "type": ["null", "string"] + }, + "text": { + "type": ["null", "string"] + }, + "enabled": { + "type": ["null", "boolean"] + } + } + }, + "last_note": { + "type": ["null", "object"], + "properties": { + "note_id": { + "type": ["null", "integer"] + }, + "created_at": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "created_by": { + "type": ["null", "string"] + }, + "note": { + "type": ["null", "string"] + } + } + }, + "source": { + "type": ["null", "string"] + }, + "tags_count": { + "type": ["null", "integer"] + }, + "tags": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "properties": { + "id": { + "type": ["null", "integer"] + }, + "name": { + "type": ["null", "string"] + } + } + } + }, + "list_id": { + "type": ["null", "string"] + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/lists.json b/source-mailchimp/source_mailchimp/schemas/lists.json new file mode 100644 index 0000000000..01cd5b3e18 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/lists.json @@ -0,0 +1,308 @@ +{ + "type": "object", + "title": "Subscriber List", + "description": "Information about a specific list.", + "properties": { + "id": { + "type": "string", + "title": "List ID", + "description": "A string that uniquely identifies this list.", + "readOnly": true + }, + "web_id": { + "type": "integer", + "title": "List Web ID", + "description": "The ID used in the Mailchimp web application. View this list in your Mailchimp account at `https://{dc}.admin.mailchimp.com/lists/members/?id={web_id}`.", + "readOnly": true + }, + "name": { + "type": ["null", "string"], + "title": "List Name", + "description": "The name of the list." + }, + "contact": { + "type": "object", + "title": "List Contact", + "description": "[Contact information displayed in campaign footers](https://mailchimp.com/help/about-campaign-footers/) to comply with international spam laws.", + "properties": { + "company": { + "type": ["null", "string"], + "title": "Company Name", + "description": "The company name for the list." + }, + "address1": { + "type": ["null", "string"], + "title": "Address", + "description": "The street address for the list contact." + }, + "address2": { + "type": ["null", "string"], + "title": "Address", + "description": "The street address for the list contact." + }, + "city": { + "type": ["null", "string"], + "title": "City", + "description": "The city for the list contact." + }, + "state": { + "type": ["null", "string"], + "title": "State", + "description": "The state for the list contact." + }, + "zip": { + "type": ["null", "string"], + "title": "Postal Code", + "description": "The postal or zip code for the list contact." + }, + "country": { + "type": ["null", "string"], + "title": "Country Code", + "description": "A two-character ISO3166 country code. Defaults to US if invalid." + }, + "phone": { + "type": ["null", "string"], + "title": "Phone Number", + "description": "The phone number for the list contact." + } + } + }, + "permission_reminder": { + "type": ["null", "string"], + "title": "Permission Reminder", + "description": "The [permission reminder](https://mailchimp.com/help/edit-the-permission-reminder/) for the list." + }, + "use_archive_bar": { + "type": "boolean", + "title": "Use Archive Bar", + "description": "Whether campaigns for this list use the [Archive Bar](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) in archives by default.", + "default": false + }, + "campaign_defaults": { + "type": "object", + "title": "Campaign Defaults", + "description": "[Default values for campaigns](https://mailchimp.com/help/edit-your-emails-subject-preview-text-from-name-or-from-email-address/) created for this list.", + "properties": { + "from_name": { + "type": ["null", "string"], + "title": "Sender's Name", + "description": "The default from name for campaigns sent to this list." + }, + "from_email": { + "type": ["null", "string"], + "title": "Sender's Email Address", + "description": "The default from email for campaigns sent to this list." + }, + "subject": { + "type": ["null", "string"], + "title": "Subject", + "description": "The default subject line for campaigns sent to this list." + }, + "language": { + "type": ["null", "string"], + "title": "Language", + "description": "The default language for this lists's forms." + } + } + }, + "notify_on_subscribe": { + "type": ["null", "string"], + "title": "Notify on Subscribe", + "description": "The email address to send [subscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", + "default": false + }, + "notify_on_unsubscribe": { + "type": ["null", "string"], + "title": "Notify on Unsubscribe", + "description": "The email address to send [unsubscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", + "default": false + }, + "date_created": { + "type": "string", + "title": "Creation Date", + "description": "The date and time that this list was created in ISO 8601 format.", + "format": "date-time", + "airbyte_type": "timestamp_with_timezone", + "readOnly": true + }, + "list_rating": { + "type": "integer", + "title": "List Rating", + "description": "An auto-generated activity score for the list (0-5).", + "readOnly": true + }, + "email_type_option": { + "type": "boolean", + "title": "Email Type Option", + "description": "Whether the list supports [multiple formats for emails](https://mailchimp.com/help/change-list-name-and-defaults/). When set to `true`, subscribers can choose whether they want to receive HTML or plain-text emails. When set to `false`, subscribers will receive HTML emails, with a plain-text alternative backup." + }, + "subscribe_url_short": { + "type": ["null", "string"], + "title": "Subscribe URL Short", + "description": "Our [EepURL shortened](https://mailchimp.com/help/share-your-signup-form/) version of this list's subscribe form.", + "readOnly": true + }, + "subscribe_url_long": { + "type": ["null", "string"], + "title": "Subscribe URL Long", + "description": "The full version of this list's subscribe form (host will vary).", + "readOnly": true + }, + "beamer_address": { + "type": ["null", "string"], + "title": "Beamer Address", + "description": "The list's [Email Beamer](https://mailchimp.com/help/use-email-beamer-to-create-a-campaign/) address.", + "readOnly": true + }, + "visibility": { + "type": ["null", "string"], + "title": "Visibility", + "enum": ["pub", "prv"], + "description": "Whether this list is [public or private](https://mailchimp.com/help/about-list-publicity/)." + }, + "double_optin": { + "type": "boolean", + "title": "Double Opt In", + "description": "Whether or not to require the subscriber to confirm subscription via email.", + "default": false + }, + "has_welcome": { + "type": "boolean", + "title": "Has Welcome", + "description": "Whether or not this list has a welcome automation connected. Welcome Automations: welcomeSeries, singleWelcome, emailFollowup.", + "default": false, + "example": false + }, + "marketing_permissions": { + "type": "boolean", + "title": "Marketing Permissions", + "description": "Whether or not the list has marketing permissions (eg. GDPR) enabled.", + "default": false + }, + "modules": { + "type": "array", + "title": "Modules", + "description": "Any list-specific modules installed for this list.", + "items": { + "type": ["null", "string"] + }, + "readOnly": true + }, + "stats": { + "type": "object", + "title": "Statistics", + "description": "Stats for the list. Many of these are cached for at least five minutes.", + "readOnly": true, + "properties": { + "member_count": { + "type": "integer", + "title": "Member Count", + "description": "The number of active members in the list.", + "readOnly": true + }, + "total_contacts": { + "type": "integer", + "title": "Total Contacts", + "description": "The number of contacts in the list, including subscribed, unsubscribed, pending, cleaned, deleted, transactional, and those that need to be reconfirmed.", + "readOnly": true + }, + "unsubscribe_count": { + "type": "integer", + "title": "Unsubscribe Count", + "description": "The number of members who have unsubscribed from the list.", + "readOnly": true + }, + "cleaned_count": { + "type": "integer", + "title": "Cleaned Count", + "description": "The number of members cleaned from the list.", + "readOnly": true + }, + "member_count_since_send": { + "type": "integer", + "title": "Member Count Since Send", + "description": "The number of active members in the list since the last campaign was sent.", + "readOnly": true + }, + "unsubscribe_count_since_send": { + "type": "integer", + "title": "Unsubscribe Count Since Send", + "description": "The number of members who have unsubscribed since the last campaign was sent.", + "readOnly": true + }, + "cleaned_count_since_send": { + "type": "integer", + "title": "Cleaned Count Since Send", + "description": "The number of members cleaned from the list since the last campaign was sent.", + "readOnly": true + }, + "campaign_count": { + "type": "integer", + "title": "Campaign Count", + "description": "The number of campaigns in any status that use this list.", + "readOnly": true + }, + "campaign_last_sent": { + "type": ["null", "string"], + "title": "Campaign Last Sent", + "description": "The date and time the last campaign was sent to this list in ISO 8601 format. This is updated when a campaign is sent to 10 or more recipients.", + "readOnly": true, + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "merge_field_count": { + "type": "integer", + "title": "Merge Var Count", + "description": "The number of merge vars for this list (not EMAIL, which is required).", + "readOnly": true + }, + "avg_sub_rate": { + "type": "number", + "title": "Average Subscription Rate", + "description": "The average number of subscriptions per month for the list (not returned if we haven't calculated it yet).", + "readOnly": true + }, + "avg_unsub_rate": { + "type": "number", + "title": "Average Unsubscription Rate", + "description": "The average number of unsubscriptions per month for the list (not returned if we haven't calculated it yet).", + "readOnly": true + }, + "target_sub_rate": { + "type": "number", + "title": "Average Subscription Rate", + "description": "The target number of subscriptions per month for the list to keep it growing (not returned if we haven't calculated it yet).", + "readOnly": true + }, + "open_rate": { + "type": "number", + "title": "Open Rate", + "description": "The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet).", + "readOnly": true + }, + "click_rate": { + "type": "number", + "title": "Click Rate", + "description": "The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet).", + "readOnly": true + }, + "last_sub_date": { + "type": ["null", "string"], + "title": "Date of Last List Subscribe", + "description": "The date and time of the last time someone subscribed to this list in ISO 8601 format.", + "readOnly": true, + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "last_unsub_date": { + "type": ["null", "string"], + "title": "Date of Last List Unsubscribe", + "description": "The date and time of the last time someone unsubscribed from this list in ISO 8601 format.", + "readOnly": true, + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + } + } + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/reports.json b/source-mailchimp/source_mailchimp/schemas/reports.json new file mode 100644 index 0000000000..940b0a8320 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/reports.json @@ -0,0 +1,570 @@ +{ + "type": "object", + "title": "Campaign Reports", + "description": "A list of reports containing campaigns marked as Sent.", + "properties": { + "id": { + "type": "string", + "title": "Campaign ID", + "description": "A string that uniquely identifies this campaign." + }, + "campaign_title": { + "type": ["null", "string"], + "title": "Campaign Title", + "description": "The title of the campaign.", + "readOnly": true + }, + "type": { + "type": ["null", "string"], + "title": "Campaign Type", + "description": "The type of campaign (regular, plain-text, ab_split, rss, automation, variate, or auto)." + }, + "list_id": { + "type": "string", + "title": "List ID", + "description": "The unique list id.", + "readOnly": true + }, + "list_is_active": { + "type": "boolean", + "title": "List Status", + "description": "The status of the list used, namely if it's deleted or disabled.", + "readOnly": true + }, + "list_name": { + "type": ["null", "string"], + "title": "List Name", + "description": "The name of the list.", + "readOnly": true + }, + "subject_line": { + "type": ["null", "string"], + "title": "Campaign Subject Line", + "description": "The subject line for the campaign.", + "readOnly": true + }, + "preview_text": { + "type": ["null", "string"], + "title": "Campaign Preview Text", + "description": "The preview text for the campaign." + }, + "emails_sent": { + "type": "integer", + "title": "Emails Sent", + "description": "The total number of emails sent for this campaign." + }, + "abuse_reports": { + "type": "integer", + "title": "Abuse Reports", + "description": "The number of abuse reports generated for this campaign." + }, + "unsubscribed": { + "type": "integer", + "title": "Unsubscribe Count", + "description": "The total number of unsubscribed members for this campaign.", + "readOnly": true + }, + "send_time": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone", + "title": "Send Time", + "description": "The date and time a campaign was sent in ISO 8601 format.", + "readOnly": true + }, + "rss_last_send": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone", + "title": "RSS Last Send", + "description": "For RSS campaigns, the date and time of the last send in ISO 8601 format.", + "readOnly": true + }, + "bounces": { + "type": "object", + "title": "Bounces", + "description": "An object describing the bounce summary for the campaign.", + "properties": { + "hard_bounces": { + "type": "integer", + "title": "Hard Bounces", + "description": "The total number of hard bounced email addresses." + }, + "soft_bounces": { + "type": "integer", + "title": "Soft Bounces", + "description": "The total number of soft bounced email addresses." + }, + "syntax_errors": { + "type": "integer", + "title": "Syntax Errors", + "description": "The total number of addresses that were syntax-related bounces." + } + } + }, + "forwards": { + "type": "object", + "title": "Forwards", + "description": "An object describing the forwards and forward activity for the campaign.", + "properties": { + "forwards_count": { + "type": "integer", + "title": "Total Forwards", + "description": "How many times the campaign has been forwarded." + }, + "forwards_opens": { + "type": "integer", + "title": "Forward Opens", + "description": "How many times the forwarded campaign has been opened." + } + } + }, + "opens": { + "type": "object", + "title": "Opens", + "description": "An object describing the open activity for the campaign.", + "properties": { + "opens_total": { + "type": "integer", + "title": "Total Opens", + "description": "The total number of opens for a campaign." + }, + "unique_opens": { + "type": "integer", + "title": "Unique Opens", + "description": "The total number of unique opens." + }, + "open_rate": { + "type": "number", + "title": "Open Rate", + "description": "The number of unique opens divided by the total number of successful deliveries." + }, + "last_open": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone", + "title": "Last Open", + "description": "The date and time of the last recorded open in ISO 8601 format." + } + } + }, + "clicks": { + "type": "object", + "title": "Clicks", + "description": "An object describing the click activity for the campaign.", + "properties": { + "clicks_total": { + "type": "integer", + "title": "Total Clicks", + "description": "The total number of clicks for the campaign." + }, + "unique_clicks": { + "type": "integer", + "title": "Unique Clicks", + "description": "The total number of unique clicks for links across a campaign." + }, + "unique_subscriber_clicks": { + "type": "integer", + "title": "Unique Subscriber Clicks", + "description": "The total number of subscribers who clicked on a campaign." + }, + "click_rate": { + "type": "number", + "title": "Click Rate", + "description": "The number of unique clicks divided by the total number of successful deliveries." + }, + "last_click": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone", + "title": "Last Click", + "description": "The date and time of the last recorded click for the campaign in ISO 8601 format." + } + } + }, + "facebook_likes": { + "type": "object", + "title": "Facebook Likes", + "description": "An object describing campaign engagement on Facebook.", + "properties": { + "recipient_likes": { + "type": "integer", + "title": "Recipient Likes", + "description": "The number of recipients who liked the campaign on Facebook." + }, + "unique_likes": { + "type": "integer", + "title": "Unique Likes", + "description": "The number of unique likes." + }, + "facebook_likes": { + "type": "integer", + "title": "Facebook Likes", + "description": "The number of Facebook likes for the campaign." + } + } + }, + "industry_stats": { + "type": "object", + "title": "Industry Stats", + "description": "The average campaign statistics for your industry.", + "properties": { + "type": { + "type": ["null", "string"], + "title": "Industry Type", + "description": "The type of business industry associated with your account. For example: retail, education, etc." + }, + "open_rate": { + "type": "number", + "title": "Open Rate", + "description": "The industry open rate." + }, + "click_rate": { + "type": "number", + "title": "Click Rate", + "description": "The industry click rate." + }, + "bounce_rate": { + "type": "number", + "title": "Bounce Rate", + "description": "The industry bounce rate." + }, + "unopen_rate": { + "type": "number", + "title": "Unopened Rate", + "description": "The industry unopened rate." + }, + "unsub_rate": { + "type": "number", + "title": "Unsubscribe Rate", + "description": "The industry unsubscribe rate." + }, + "abuse_rate": { + "type": "number", + "title": "Abuse Rate", + "description": "The industry abuse rate." + } + } + }, + "list_stats": { + "type": "object", + "title": "List Stats", + "description": "The average campaign statistics for your list. This won't be present if we haven't calculated it yet for this list.", + "properties": { + "sub_rate": { + "type": "number", + "title": "Average Subscription Rate", + "description": "The average number of subscriptions per month for the list.", + "readOnly": true + }, + "unsub_rate": { + "type": "number", + "title": "Average Unsubscription Rate", + "description": "The average number of unsubscriptions per month for the list.", + "readOnly": true + }, + "open_rate": { + "type": "number", + "title": "Open Rate", + "description": "The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list.", + "readOnly": true + }, + "click_rate": { + "type": "number", + "title": "Click Rate", + "description": "The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list.", + "readOnly": true + } + } + }, + "ab_split": { + "type": "object", + "title": "A/B Split Stats", + "description": "General stats about different groups of an A/B Split campaign. Does not return information about Multivariate Campaigns.", + "properties": { + "a": { + "type": "object", + "title": "Campaign A", + "description": "Stats for Campaign A.", + "properties": { + "bounces": { + "type": "integer", + "title": "Bounces", + "description": "Bounces for Campaign A." + }, + "abuse_reports": { + "type": "integer", + "title": "Abuse Reports", + "description": "Abuse reports for Campaign A." + }, + "unsubs": { + "type": "integer", + "title": "Unsubscribes", + "description": "Unsubscribes for Campaign A." + }, + "recipient_clicks": { + "type": "integer", + "title": "Recipient Clicks", + "description": "Recipient Clicks for Campaign A." + }, + "forwards": { + "type": "integer", + "title": "Forwards", + "description": "Forwards for Campaign A." + }, + "forwards_opens": { + "type": "integer", + "title": "Forward Opens", + "description": "Opens from forwards for Campaign A." + }, + "opens": { + "type": "integer", + "title": "Opens", + "description": "Opens for Campaign A." + }, + "last_open": { + "type": ["null", "string"], + "title": "Last Open", + "description": "The last open for Campaign A.", + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "unique_opens": { + "type": "integer", + "title": "Unique Opens", + "description": "Unique opens for Campaign A." + } + } + }, + "b": { + "type": "object", + "title": "Campaign B", + "description": "Stats for Campaign B.", + "properties": { + "bounces": { + "type": "integer", + "title": "Bounces", + "description": "Bounces for Campaign B." + }, + "abuse_reports": { + "type": "integer", + "title": "Abuse Reports", + "description": "Abuse reports for Campaign B." + }, + "unsubs": { + "type": "integer", + "title": "Unsubscribes", + "description": "Unsubscribes for Campaign B." + }, + "recipient_clicks": { + "type": "integer", + "title": "Recipient Clicks", + "description": "Recipients clicks for Campaign B." + }, + "forwards": { + "type": "integer", + "title": "Forwards", + "description": "Forwards for Campaign B." + }, + "forwards_opens": { + "type": "integer", + "title": "Forward Opens", + "description": "Opens for forwards from Campaign B." + }, + "opens": { + "type": "integer", + "title": "Opens", + "description": "Opens for Campaign B." + }, + "last_open": { + "type": ["null", "string"], + "title": "Last Open", + "description": "The last open for Campaign B.", + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "unique_opens": { + "type": "integer", + "title": "Unique Opens", + "description": "Unique opens for Campaign B." + } + } + } + } + }, + "timewarp": { + "type": "array", + "title": "Timewarp Stats", + "description": "An hourly breakdown of sends, opens, and clicks if a campaign is sent using timewarp.", + "items": { + "type": "object", + "properties": { + "gmt_offset": { + "type": "integer", + "title": "GMT Offset", + "description": "For campaigns sent with timewarp, the time zone group the member is apart of." + }, + "opens": { + "type": "integer", + "title": "Opens", + "description": "The number of opens." + }, + "last_open": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone", + "title": "Last Open", + "description": "The date and time of the last open in ISO 8601 format." + }, + "unique_opens": { + "type": "integer", + "title": "Unique Opens", + "description": "The number of unique opens." + }, + "clicks": { + "type": "integer", + "title": "Clicks", + "description": "The number of clicks." + }, + "last_click": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone", + "title": "Last Click", + "description": "The date and time of the last click in ISO 8601 format." + }, + "unique_clicks": { + "type": "integer", + "title": "Unique Clicks", + "description": "The number of unique clicks." + }, + "bounces": { + "type": "integer", + "title": "Bounces", + "description": "The number of bounces." + } + } + } + }, + "timeseries": { + "type": "array", + "title": "Timeseries", + "description": "An hourly breakdown of the performance of the campaign over the first 24 hours.", + "items": { + "type": "object", + "properties": { + "timestamp": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone", + "title": "Timestamp", + "description": "The date and time for the series in ISO 8601 format." + }, + "emails_sent": { + "type": "integer", + "title": "Emails Sent", + "description": "The number of emails sent in the timeseries." + }, + "unique_opens": { + "type": "integer", + "title": "Unique Opens", + "description": "The number of unique opens in the timeseries." + }, + "recipients_clicks": { + "type": "integer", + "title": "Recipient Clicks", + "description": "The number of clicks in the timeseries." + } + } + } + }, + "share_report": { + "type": "object", + "title": "Share Report", + "description": "The url and password for the [VIP report](https://mailchimp.com/help/share-a-campaign-report/).", + "properties": { + "share_url": { + "type": ["null", "string"], + "title": "Report URL", + "description": "The URL for the VIP report.", + "readOnly": true + }, + "share_password": { + "type": ["null", "string"], + "title": "Report Password", + "description": "If password protected, the password for the VIP report.", + "readOnly": true + } + } + }, + "ecommerce": { + "type": "object", + "title": "E-Commerce Report", + "description": "E-Commerce stats for a campaign.", + "properties": { + "total_orders": { + "type": "integer", + "title": "Total Orders", + "description": "The total orders for a campaign.", + "readOnly": true + }, + "total_spent": { + "type": "number", + "title": "Total Spent", + "description": "The total spent for a campaign. Calculated as the sum of all order totals with no deductions.", + "readOnly": true + }, + "total_revenue": { + "type": "number", + "title": "Total Revenue", + "description": "The total revenue for a campaign. Calculated as the sum of all order totals minus shipping and tax totals.", + "readOnly": true + }, + "currency_code": { + "type": ["null", "string"], + "title": "Three letter currency code for this user", + "readOnly": true, + "example": "USD" + } + } + }, + "delivery_status": { + "type": "object", + "title": "Campaign Delivery Status", + "description": "Updates on campaigns in the process of sending.", + "properties": { + "enabled": { + "type": "boolean", + "title": "Delivery Status Enabled", + "description": "Whether Campaign Delivery Status is enabled for this account and campaign.", + "readOnly": true + }, + "can_cancel": { + "type": "boolean", + "title": "Campaign Cancelable", + "description": "Whether a campaign send can be canceled.", + "readOnly": true + }, + "status": { + "type": ["null", "string"], + "title": "Campaign Delivery Status", + "description": "The current state of a campaign delivery.", + "enum": ["delivering", "delivered", "canceling", "canceled"], + "readOnly": true + }, + "emails_sent": { + "type": "integer", + "title": "Emails Sent", + "description": "The total number of emails confirmed sent for this campaign so far.", + "readOnly": true + }, + "emails_canceled": { + "type": "integer", + "title": "Emails Canceled", + "description": "The total number of emails canceled for this campaign.", + "readOnly": true + } + } + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/segment_members.json b/source-mailchimp/source_mailchimp/schemas/segment_members.json new file mode 100644 index 0000000000..8766876fd2 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/segment_members.json @@ -0,0 +1,122 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "string"] + }, + "email_address": { + "type": ["null", "string"] + }, + "unique_email_id": { + "type": ["null", "string"] + }, + "email_type": { + "type": ["null", "string"] + }, + "status": { + "type": ["null", "string"] + }, + "merge_fields": { + "type": ["null", "object"], + "additionalProperties": true + }, + "interests": { + "type": ["null", "object"], + "additionalProperties": true + }, + "stats": { + "type": ["null", "object"], + "properties": { + "avg_open_rate": { + "type": ["null", "number"] + }, + "avg_click_rate": { + "type": ["null", "number"] + } + } + }, + "ip_signup": { + "type": ["null", "string"] + }, + "timestamp_signup": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "ip_opt": { + "type": ["null", "string"] + }, + "timestamp_opt": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "member_rating": { + "type": ["null", "integer"] + }, + "last_changed": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "language": { + "type": ["null", "string"] + }, + "vip": { + "type": ["null", "boolean"] + }, + "email_client": { + "type": ["null", "string"] + }, + "location": { + "type": ["null", "object"], + "properties": { + "latitude": { + "type": ["null", "number"] + }, + "longitude": { + "type": ["null", "number"] + }, + "gmtoff": { + "type": ["null", "integer"] + }, + "dstoff": { + "type": ["null", "integer"] + }, + "country_code": { + "type": ["null", "string"] + }, + "timezone": { + "type": ["null", "string"] + } + } + }, + "last_note": { + "type": ["null", "object"], + "properties": { + "note_id": { + "type": ["null", "integer"] + }, + "created_at": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "created_by": { + "type": ["null", "string"] + }, + "note": { + "type": ["null", "string"] + } + } + }, + "list_id": { + "type": ["null", "string"] + }, + "segment_id": { + "type": ["null", "integer"] + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/segments.json b/source-mailchimp/source_mailchimp/schemas/segments.json new file mode 100644 index 0000000000..8840817de2 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/segments.json @@ -0,0 +1,58 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": true, + "properties": { + "id": { + "type": ["null", "integer"] + }, + "name": { + "type": ["null", "string"] + }, + "member_count": { + "type": ["null", "integer"] + }, + "type": { + "type": ["null", "string"] + }, + "created_at": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "updated_at": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "options": { + "type": ["null", "object"], + "properties": { + "match": { + "type": ["null", "string"] + }, + "conditions": { + "type": ["null", "array"], + "items": { + "type": ["null", "object"], + "additionalProperties": true, + "properties": { + "condition_type": { + "type": ["null", "string"] + }, + "field": { + "type": ["null", "string"] + }, + "op": { + "type": ["null", "string"] + } + } + } + } + } + }, + "list_id": { + "type": ["null", "string"] + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/addressMergeSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/addressMergeSegment.json new file mode 100644 index 0000000000..11ce44213a --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/addressMergeSegment.json @@ -0,0 +1,32 @@ +{ + "type": "object", + "title": "Address Merge Field Segment", + "description": "Segment by an address-type merge field.", + "required": ["field", "op"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "AddressMerge", + "enum": ["AddressMerge"] + }, + "field": { + "type": "string", + "title": "Segment Field", + "description": "An address-type merge field to segment.", + "example": "MMERGE3" + }, + "op": { + "type": "string", + "enum": ["contains", "notcontain", "blank", "blank_not"], + "title": "Segment Operator", + "description": "Whether the member's address merge field contains/does not contain a value or is/is not blank.", + "example": "contains" + }, + "value": { + "type": "string", + "title": "Segment Value", + "description": "The value to segment a text merge field with.", + "example": "Atlanta" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/addressZipWithinSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/addressZipWithinSegment.json new file mode 100644 index 0000000000..d66ece7c08 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/addressZipWithinSegment.json @@ -0,0 +1,38 @@ +{ + "type": "object", + "title": "Address/Zip Merge Field Segment", + "description": "Segment by an address-type merge field within a given distance.", + "required": ["field", "op", "value", "extra"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "ZipMerge", + "enum": ["ZipMerge"] + }, + "field": { + "type": "string", + "title": "Segment Field", + "description": "An address or zip-type merge field to segment.", + "example": "MMERGE2" + }, + "op": { + "type": "string", + "enum": ["geoin"], + "title": "Segment Operator", + "description": "Whether the member's address merge field is within a given distance from a city or zip.", + "example": "geoin" + }, + "value": { + "type": "string", + "title": "Segment Value", + "description": "The distance from the city/zip.", + "example": "25" + }, + "extra": { + "type": "string", + "title": "Segment Extra", + "description": "The city or the zip being used to segment against.", + "example": "30318" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/aimSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/aimSegment.json new file mode 100644 index 0000000000..52032da15b --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/aimSegment.json @@ -0,0 +1,32 @@ +{ + "type": "object", + "title": "Aim Segment", + "description": "Segment by interaction with a specific campaign.", + "properties": { + "condition_type": { + "type": "string", + "x-value": "Aim", + "enum": ["Aim"] + }, + "field": { + "type": "string", + "enum": ["aim"], + "title": "Segment Field", + "description": "Segment by interaction with a specific campaign.", + "example": "aim" + }, + "op": { + "type": "string", + "enum": ["open", "click", "sent", "noopen", "noclick", "nosent"], + "title": "Segment Operator", + "description": "The status of the member with regard to their campaign interaction. One of the following: opened, clicked, was sent, didn't open, didn't click, or was not sent.", + "example": "open" + }, + "value": { + "type": "string", + "title": "Segment Data", + "description": "Either the web id value for a specific campaign or 'any' to account for subscribers who have/have not interacted with any campaigns.", + "example": "any" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/automationSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/automationSegment.json new file mode 100644 index 0000000000..cdcb7382ce --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/automationSegment.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "title": "Automation Segment", + "description": "Segment by interaction with an Automation workflow.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "Automation", + "enum": ["Automation"] + }, + "field": { + "type": "string", + "enum": ["automation"], + "title": "Segment Field", + "description": "Segment by interaction with an Automation workflow.", + "example": "automation" + }, + "op": { + "type": "string", + "enum": ["started", "completed", "not_started", "not_completed"], + "title": "Segment Operator", + "description": "The status of the member with regard to the automation workflow. One of the following: has started the workflow, has completed the workflow, has not started the workflow, or has not completed the workflow.", + "example": "started" + }, + "value": { + "type": "string", + "title": "Segment Data", + "description": "The web id for the automation workflow to segment against.", + "example": "2135217" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/birthdayMergeSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/birthdayMergeSegment.json new file mode 100644 index 0000000000..cc79ccb7ad --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/birthdayMergeSegment.json @@ -0,0 +1,32 @@ +{ + "type": "object", + "title": "Birthday Merge Field Segment", + "description": "Segment by a contact's birthday.", + "required": ["field", "op"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "BirthdayMerge", + "enum": ["BirthdayMerge"] + }, + "field": { + "type": "string", + "title": "Segment Field", + "description": "A date merge field to segment.", + "example": "MMERGE4" + }, + "op": { + "type": "string", + "enum": ["is", "not", "blank", "blank_not"], + "title": "Segment Operator", + "description": "Whether the member's birthday merge information is/is not a certain date or is/is not blank.", + "example": "is" + }, + "value": { + "type": "string", + "title": "Segment Value", + "description": "A date to segment against (mm/dd).", + "example": "01/30" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/campaignPollSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/campaignPollSegment.json new file mode 100644 index 0000000000..bfa8d9c6e0 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/campaignPollSegment.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "title": "Poll Activity Segment", + "description": "Segment by poll activity.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "CampaignPoll", + "enum": ["CampaignPoll"] + }, + "field": { + "type": "string", + "enum": ["poll"], + "title": "Segment Field", + "description": "Segment by poll activity.", + "example": "poll" + }, + "op": { + "type": "string", + "enum": ["member", "notmember"], + "title": "Segment Operator", + "description": "Members have/have not interacted with a specific poll in a Mailchimp email.", + "example": "member" + }, + "value": { + "type": "number", + "title": "Segment Operator", + "description": "The id for the poll.", + "example": 409 + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/campaignStatus.json b/source-mailchimp/source_mailchimp/schemas/shared/campaignStatus.json new file mode 100644 index 0000000000..3c7eb614a2 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/campaignStatus.json @@ -0,0 +1,16 @@ +{ + "type": "string", + "title": "Campaign Status", + "description": "The current status of the campaign.", + "enum": [ + "save", + "paused", + "schedule", + "sending", + "sent", + "canceled", + "canceling", + "archived" + ], + "readOnly": true +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/campaignType.json b/source-mailchimp/source_mailchimp/schemas/shared/campaignType.json new file mode 100644 index 0000000000..4e7ad8a597 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/campaignType.json @@ -0,0 +1,13 @@ +{ + "type": "string", + "title": "Campaign Type", + "description": "There are four types of [campaigns](https://mailchimp.com/help/getting-started-with-campaigns/) you can create in Mailchimp. A/B Split campaigns have been deprecated and variate campaigns should be used instead.", + "enum": [ + "automation-email", + "regular", + "plaintext", + "absplit", + "rss", + "variate" + ] +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/conversationSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/conversationSegment.json new file mode 100644 index 0000000000..999c601945 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/conversationSegment.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "title": "Conversation Segment", + "description": "Segment by interaction with a campaign via Conversations.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "Conversation", + "enum": ["Conversation"] + }, + "field": { + "type": "string", + "enum": ["conversation"], + "title": "Segment Field", + "description": "Segment by interaction with a campaign via Conversations.", + "example": "conversation" + }, + "op": { + "type": "string", + "enum": ["member", "notmember"], + "title": "Segment Operator", + "description": "The status of a member's interaction with a conversation. One of the following: has replied or has not replied.", + "example": "member" + }, + "value": { + "type": "string", + "title": "Segment Data", + "description": "The web id value for a specific campaign or 'any' to account for subscribers who have/have not interacted with any campaigns.", + "example": "any" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/countryStateSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/countryStateSegment.json new file mode 100644 index 0000000000..1eebe6505a --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/countryStateSegment.json @@ -0,0 +1,38 @@ +{ + "type": "object", + "title": "Location-Based Segment", + "description": "Segment by a specific country or US state.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "IPGeoCountryState", + "enum": ["IPGeoCountryState"] + }, + "field": { + "type": "string", + "enum": ["ipgeo"], + "title": "Segment Field", + "description": "Segmenting subscribers who are within a specific location.", + "example": "ipgeo" + }, + "op": { + "type": "string", + "enum": [ + "ipgeocountry", + "ipgeonotcountry", + "ipgeostate", + "ipgeonotstate" + ], + "title": "Segment Operator", + "description": "Segment members who are within a specific country or US state.", + "example": "ipgeocountry" + }, + "value": { + "type": "string", + "title": "Segment Data", + "description": "The two-letter country code or US state abbreviation.", + "example": "US" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/dateMergeSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/dateMergeSegment.json new file mode 100644 index 0000000000..ff04cc1b25 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/dateMergeSegment.json @@ -0,0 +1,32 @@ +{ + "type": "object", + "title": "Date Merge Field Segment", + "description": "Segment by a given date merge field.", + "required": ["field", "op"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "DateMerge", + "enum": ["DateMerge"] + }, + "field": { + "type": "string", + "title": "Segment Field", + "description": "A date merge field to segment.", + "example": "MMERGE5" + }, + "op": { + "type": "string", + "enum": ["is", "not", "less", "blank", "blank_not", "greater"], + "title": "Segment Operator", + "description": "Whether the member's merge information is/is not, is greater/less than a value or is/is not blank.", + "example": "is" + }, + "value": { + "type": "string", + "title": "Segment Value", + "description": "A date to segment against.", + "example": "01/30/2015" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/dateSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/dateSegment.json new file mode 100644 index 0000000000..ded5777752 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/dateSegment.json @@ -0,0 +1,48 @@ +{ + "type": "object", + "title": "Date Segment", + "description": "Segment by a specific date field.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "Date", + "enum": ["Date"] + }, + "field": { + "type": "string", + "enum": ["timestamp_opt", "info_changed", "ecomm_date"], + "title": "Segment Field", + "description": "The type of date field to segment on: The opt-in time for a signup, the date the subscriber was last updated, or the date of their last ecomm purchase.", + "example": "timestamp_opt" + }, + "op": { + "type": "string", + "enum": [ + "greater", + "less", + "is", + "not", + "blank", + "blank_not", + "within", + "notwithin" + ], + "title": "Segment Operator", + "description": "When the event took place: Before, after, is a specific date, is not a specific date, is blank, or is not blank.", + "example": "greater" + }, + "value": { + "type": "string", + "title": "Segment Data", + "description": "What type of data to segment on: a specific date, a specific campaign, or the last campaign sent.", + "example": "date" + }, + "extra": { + "type": "string", + "title": "Segment Extra Value", + "description": "When segmenting on 'date' or 'campaign', the date for the segment formatted as YYYY-MM-DD or the web id for the campaign.", + "example": "2015-01-30" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/dropdownRadioMergeSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/dropdownRadioMergeSegment.json new file mode 100644 index 0000000000..f06f3347f6 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/dropdownRadioMergeSegment.json @@ -0,0 +1,32 @@ +{ + "type": "object", + "title": "Dropdown/Radio Merge Field Segment", + "description": "An individual segment condition", + "required": ["field", "op"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "SelectMerge", + "enum": ["SelectMerge"] + }, + "field": { + "type": "string", + "title": "Segment Field", + "description": "A merge field to segment.", + "example": "MMERGE6" + }, + "op": { + "type": "string", + "enum": ["is", "not", "blank", "blank_not", "notcontain", "contains"], + "title": "Segment Operator", + "description": "Whether the member's merge information is/is not a value or is/is not blank.", + "example": "is" + }, + "value": { + "type": "string", + "title": "Segment Value", + "description": "The value to segment a text merge field with.", + "example": "Second Choice" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/ecommCategorySegment.json b/source-mailchimp/source_mailchimp/schemas/shared/ecommCategorySegment.json new file mode 100644 index 0000000000..af1dafc8dc --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/ecommCategorySegment.json @@ -0,0 +1,32 @@ +{ + "type": "object", + "title": "Ecommerce Category Segment", + "description": "Segment by purchases in specific items or categories.", + "properties": { + "condition_type": { + "type": "string", + "x-value": "EcommCategory", + "enum": ["EcommCategory"] + }, + "field": { + "type": "string", + "enum": ["ecomm_cat", "ecomm_prod"], + "title": "Segment Field", + "description": "Segment by purchases in specific items or categories.", + "example": "ecomm_cat" + }, + "op": { + "type": "string", + "enum": ["is", "not", "contains", "notcontain", "starts", "ends"], + "title": "Segment Operator", + "description": "A member who has purchased from a category/specific item that is/is not a specific name, where the category/item name contains/doesn't contain a specific phrase or string, or a category/item name that starts/ends with a string.", + "example": "is" + }, + "value": { + "type": "string", + "title": "Segment Data", + "description": "The ecommerce category/item information.", + "example": "Product" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/ecommNumberSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/ecommNumberSegment.json new file mode 100644 index 0000000000..aa2edb9e49 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/ecommNumberSegment.json @@ -0,0 +1,38 @@ +{ + "type": "object", + "title": "Ecommerce Number Segment", + "description": "Segment by average spent total, number of orders, total number of products purchased, or average number of products per order.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "EcommNumber", + "enum": ["EcommNumber"] + }, + "field": { + "type": "string", + "enum": [ + "ecomm_spent_avg", + "ecomm_orders", + "ecomm_prod_all", + "ecomm_avg_ord" + ], + "title": "Segment Field", + "description": "Segment by average spent total, number of orders, total number of products purchased, or average number of products per order.", + "example": "ecomm_orders" + }, + "op": { + "type": "string", + "enum": ["is", "not", "greater", "less"], + "title": "Segment Operator", + "description": "Members who have spent exactly, have not spent exactly, spent more, or spent less than the segment value.", + "example": "greater" + }, + "value": { + "type": "number", + "title": "Segment Operator", + "description": "Members who have spent exactly, have not spent exactly, spent more, or spent less than this amount.", + "example": 42 + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/ecommPurchasedSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/ecommPurchasedSegment.json new file mode 100644 index 0000000000..5d4e3823f5 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/ecommPurchasedSegment.json @@ -0,0 +1,26 @@ +{ + "type": "object", + "title": "Ecommerce Purchased Segment", + "description": "Segment by whether someone has purchased anything.", + "properties": { + "condition_type": { + "type": "string", + "x-value": "EcommPurchased", + "enum": ["EcommPurchased"] + }, + "field": { + "type": "string", + "enum": ["ecomm_purchased"], + "title": "Segment Field", + "description": "Segment by whether someone has purchased anything.", + "example": "ecomm_purchased" + }, + "op": { + "type": "string", + "enum": ["member", "notmember"], + "title": "Segment Operator", + "description": "Members who have have ('member') or have not ('notmember') purchased.", + "example": "member" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/ecommSpentSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/ecommSpentSegment.json new file mode 100644 index 0000000000..39d192a6a2 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/ecommSpentSegment.json @@ -0,0 +1,32 @@ +{ + "type": "object", + "title": "Ecommerce Spent Segment", + "description": "Segment by amount spent on a single order or across all orders.", + "properties": { + "condition_type": { + "type": "string", + "x-value": "EcommSpent", + "enum": ["EcommSpent"] + }, + "field": { + "type": "string", + "enum": ["ecomm_spent_one", "ecomm_spent_all"], + "title": "Segment Field", + "description": "Segment by amount spent on a single order or across all orders.", + "example": "ecomm_spent_one" + }, + "op": { + "type": "string", + "enum": ["greater", "less"], + "title": "Segment Operator", + "description": "Members who have spent 'more' or 'less' than then specified value.", + "example": "greater" + }, + "value": { + "type": "integer", + "title": "Segment Data", + "description": "The total amount a member spent.", + "example": 42 + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/ecommStoreSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/ecommStoreSegment.json new file mode 100644 index 0000000000..73d62796d5 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/ecommStoreSegment.json @@ -0,0 +1,32 @@ +{ + "type": "object", + "title": "Ecommerce Purchased Store Segment", + "description": "Segment by purchases from a specific store.", + "properties": { + "condition_type": { + "type": "string", + "x-value": "EcommStore", + "enum": ["EcommStore"] + }, + "field": { + "type": "string", + "enum": ["ecomm_store"], + "title": "Segment Field", + "description": "Segment by purchases from a specific store.", + "example": "ecomm_store" + }, + "op": { + "type": "string", + "enum": ["is", "not"], + "title": "Segment Operator", + "description": "Members who have or have not purchased from a specific store.", + "example": "is" + }, + "value": { + "type": "string", + "title": "Segment Operator", + "description": "The store id to segment against.", + "example": "289" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/emailClientSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/emailClientSegment.json new file mode 100644 index 0000000000..8f3b1d97f2 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/emailClientSegment.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "title": "Email Client Segment", + "description": "Segment by use of a particular email client.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "EmailClient", + "enum": ["EmailClient"] + }, + "field": { + "type": "string", + "enum": ["email_client"], + "title": "Segment Field", + "description": "Segment by use of a particular email client.", + "example": "email_client" + }, + "op": { + "type": "string", + "enum": ["client_is", "client_not"], + "title": "Segment Operator", + "description": "The operation to determine whether we select clients that match the value, or clients that do not match the value.", + "example": "client_is" + }, + "value": { + "type": "string", + "title": "Segment Data", + "description": "The name of the email client.", + "example": "Gmail" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/emailSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/emailSegment.json new file mode 100644 index 0000000000..1ae58bf836 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/emailSegment.json @@ -0,0 +1,41 @@ +{ + "type": "object", + "title": "Email Segment", + "description": "Segment by email address.", + "required": ["field", "op"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "EmailAddress", + "enum": ["EmailAddress"] + }, + "field": { + "type": "string", + "enum": ["merge0", "EMAIL"], + "title": "Segment Field", + "description": "Segmenting based off of a subscriber's email address.", + "example": "EMAIL" + }, + "op": { + "type": "string", + "enum": [ + "is", + "not", + "contains", + "notcontain", + "starts", + "ends", + "greater", + "less" + ], + "title": "Segment Operator", + "description": "Whether the email address is/not exactly, contains/doesn't contain, starts/ends with a string." + }, + "value": { + "type": "string", + "title": "Segment Value", + "description": "The value to compare the email against.", + "example": "urist.mcvankab@freddiesjokes.com" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/fuzzySegment.json b/source-mailchimp/source_mailchimp/schemas/shared/fuzzySegment.json new file mode 100644 index 0000000000..94135fca3b --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/fuzzySegment.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "title": "Similar Subscribers Segment Member Segment", + "description": "Segment by similar subscribers.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "FuzzySegment", + "enum": ["FuzzySegment"] + }, + "field": { + "type": "string", + "enum": ["fuzzy_segment"], + "title": "Segment Field", + "description": "Segment by similar subscribers.", + "example": "fuzzy_segment" + }, + "op": { + "type": "string", + "enum": ["fuzzy_is", "fuzzy_not"], + "title": "Segment Operator", + "description": "Members who are/are not apart of a 'similar subscribers' segment.", + "example": "fuzzy_is" + }, + "value": { + "type": "number", + "title": "Segment Operator", + "description": "The id for the 'similar subscribers' segment.", + "example": 48433 + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/geoInSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/geoInSegment.json new file mode 100644 index 0000000000..a56c67b769 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/geoInSegment.json @@ -0,0 +1,51 @@ +{ + "type": "object", + "title": "Geolocation Segment", + "description": "Segment by a specific geographic region.", + "required": ["field", "op", "value", "addr", "lat", "lng"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "IPGeoIn", + "enum": ["IPGeoIn"] + }, + "field": { + "type": "string", + "enum": ["ipgeo"], + "title": "Segment Field", + "description": "Segmenting subscribers who are within a specific location.", + "example": "ipgeo" + }, + "op": { + "type": "string", + "enum": ["ipgeoin", "ipgeonotin"], + "title": "Segment Operator", + "description": "Segment members who are within a specific geographic region.", + "example": "ipgeoin" + }, + "value": { + "type": "integer", + "title": "Segment Data", + "description": "The radius of the target location.", + "example": 42 + }, + "addr": { + "type": "string", + "title": "Segment Location Address", + "description": "The address of the target location.", + "example": "Atlanta, GA, USA" + }, + "lat": { + "type": "string", + "title": "Segment Location Latitude", + "description": "The latitude of the target location.", + "example": "33.7489954" + }, + "lng": { + "type": "string", + "title": "Segment Location Longitude", + "description": "The longitude of the target location.", + "example": "-84.3879824" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/goalActivitySegment.json b/source-mailchimp/source_mailchimp/schemas/shared/goalActivitySegment.json new file mode 100644 index 0000000000..bf2263238c --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/goalActivitySegment.json @@ -0,0 +1,39 @@ +{ + "type": "object", + "title": "Goal Activity Segment", + "description": "Segment by Goal activity.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "GoalActivity", + "enum": ["GoalActivity"] + }, + "field": { + "type": "string", + "enum": ["goal"], + "title": "Segment Field", + "description": "Segment by Goal activity.", + "example": "goal" + }, + "op": { + "type": "string", + "enum": [ + "is", + "goal_not", + "contains", + "goal_notcontain", + "starts", + "ends" + ], + "title": "Segment Operator", + "description": "Whether the website URL is/not exactly, contains/doesn't contain, starts with/ends with a string.", + "example": "is" + }, + "value": { + "type": "string", + "title": "Segment Value", + "description": "The URL to check Goal activity against." + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/goalTimestampSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/goalTimestampSegment.json new file mode 100644 index 0000000000..b811092ead --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/goalTimestampSegment.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "title": "Goal Timestamp Segment", + "description": "Segment by most recent interaction with a website.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "GoalTimestamp", + "enum": ["GoalTimestamp"] + }, + "field": { + "type": "string", + "enum": ["goal_last_visited"], + "title": "Segment Field", + "description": "Segment by most recent interaction with a website.", + "example": "goal_last_visited" + }, + "op": { + "type": "string", + "enum": ["greater", "less", "is"], + "title": "Segment Operator", + "description": "Whether the website activity happened after, before, or at a given timestamp.", + "example": "greater" + }, + "value": { + "type": "string", + "title": "Segment Value", + "description": "The date to check Goal activity against.", + "example": "2015-07-20 19:45:21" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/interestSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/interestSegment.json new file mode 100644 index 0000000000..cfebde7cb1 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/interestSegment.json @@ -0,0 +1,38 @@ +{ + "type": "object", + "title": "Interests Segment", + "description": "Segment by an interest group merge field.", + "properties": { + "condition_type": { + "type": "string", + "x-value": "Interests", + "enum": ["Interests"] + }, + "field": { + "type": "string", + "title": "Segment Field", + "description": "Segmenting based on interest group information. This should start with 'interests-' followed by the grouping id. Ex. 'interests-123'.", + "example": "interests-123" + }, + "op": { + "type": "string", + "enum": [ + "interestcontains", + "interestcontainsall", + "interestnotcontains" + ], + "title": "Segment Operator", + "description": "Whether the member is a part of one, all, or none of the groups.", + "example": "interestcontains" + }, + "value": { + "type": "array", + "title": "Segment Value", + "description": "An array containing strings, each representing a group id.", + "items": { + "type": "string", + "example": ["44401", "44405", "44409"] + } + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/ipGeoInZipSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/ipGeoInZipSegment.json new file mode 100644 index 0000000000..a69999ab15 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/ipGeoInZipSegment.json @@ -0,0 +1,39 @@ +{ + "type": "object", + "title": "US Zip Code Segment", + "description": "Segment by a specific US ZIP code.", + "required": ["field", "op", "value", "extra"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "IPGeoInZip", + "enum": ["IPGeoInZip"] + }, + "field": { + "type": "string", + "enum": ["ipgeo"], + "title": "Segment Field", + "description": "Segmenting subscribers who are within a specific location.", + "example": "ipgeo" + }, + "op": { + "type": "string", + "enum": ["ipgeoinzip"], + "title": "Segment Operator", + "description": "Segment members who are within a specific US zip code.", + "example": "ipgeoinzip" + }, + "value": { + "type": "integer", + "title": "Segment Data", + "description": "The radius of the target location.", + "example": 25 + }, + "extra": { + "type": "integer", + "title": "Extra Data", + "description": "The zip code to segment against.", + "example": 30318 + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/languageSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/languageSegment.json new file mode 100644 index 0000000000..d9f91b6eab --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/languageSegment.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "title": "Language Segment", + "description": "Segment by language.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "Language", + "enum": ["Language"] + }, + "field": { + "type": "string", + "enum": ["language"], + "title": "Segment Field", + "description": "Segmenting based off of a subscriber's language.", + "example": "language" + }, + "op": { + "type": "string", + "enum": ["is", "not"], + "title": "Segment Operator", + "description": "Whether the member's language is or is not set to a specific language.", + "example": "is" + }, + "value": { + "type": "string", + "title": "Segment Data", + "description": "A two-letter language identifier.", + "example": "en" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/memberRatingSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/memberRatingSegment.json new file mode 100644 index 0000000000..4933d6a8c0 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/memberRatingSegment.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "title": "Member Rating Segment", + "description": "Segment by member rating.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "MemberRating", + "enum": ["MemberRating"] + }, + "field": { + "type": "string", + "enum": ["rating"], + "title": "Segment Field", + "description": "Segment by member rating.", + "example": "rating" + }, + "op": { + "type": "string", + "enum": ["is", "not", "greater", "less"], + "title": "Segment Operator", + "description": "Members who have have a rating that is/not exactly a given number or members who have a rating greater/less than a given number.", + "example": "greater" + }, + "value": { + "type": "number", + "title": "Segment Operator", + "description": "The star rating number to segment against.", + "example": 4 + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/newSubscribers.json b/source-mailchimp/source_mailchimp/schemas/shared/newSubscribers.json new file mode 100644 index 0000000000..d9355aa707 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/newSubscribers.json @@ -0,0 +1,29 @@ +{ + "type": "object", + "title": "New Subscribers Prebuilt Segment", + "description": "Segment by when people subscribed.", + "properties": { + "condition_type": { + "type": "string", + "x-value": "NewSubscribers", + "enum": ["NewSubscribers"] + }, + "field": { + "type": "string", + "enum": ["timestamp_opt"], + "title": "Segment Field", + "description": "Segment by when people subscribed." + }, + "op": { + "type": "string", + "enum": ["date_within"], + "title": "Segment Operator", + "description": "Whe the event took place, namely within a time frame." + }, + "value": { + "type": "string", + "title": "Segment Data", + "description": "What type of data to segment on: a specific date, a specific campaign, or the last campaign sent." + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/predictedAgeSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/predictedAgeSegment.json new file mode 100644 index 0000000000..a7dda4a8e4 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/predictedAgeSegment.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "title": "Predicted Age Segment", + "description": "Segment by predicted age.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "PredictedAge", + "enum": ["PredictedAge"] + }, + "field": { + "type": "string", + "enum": ["predicted_age_range"], + "title": "Segment Field", + "description": "Segment by predicted age." + }, + "op": { + "type": "string", + "enum": ["is"], + "title": "Segment Operator", + "description": "Members who are/not the exact criteria listed.", + "example": "is" + }, + "value": { + "type": "string", + "enum": ["18-24", "25-34", "35-44", "45-54", "55-64", "65+"], + "title": "Segment Operator", + "description": "The predicted age to segment.", + "example": "female" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/predictedGenderSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/predictedGenderSegment.json new file mode 100644 index 0000000000..0f54255083 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/predictedGenderSegment.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "title": "Predicted Gender Segment", + "description": "Segment by predicted gender.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "PredictedGender", + "enum": ["PredictedGender"] + }, + "field": { + "type": "string", + "enum": ["predicted_gender"], + "title": "Segment Field", + "description": "Segment by predicted gender." + }, + "op": { + "type": "string", + "enum": ["is", "not"], + "title": "Segment Operator", + "description": "Members who are/not the exact criteria listed.", + "example": "is" + }, + "value": { + "type": "string", + "enum": ["male", "female"], + "title": "Segment Operator", + "description": "The predicted gender to segment.", + "example": "female" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/segmentCondition.json b/source-mailchimp/source_mailchimp/schemas/shared/segmentCondition.json new file mode 100644 index 0000000000..eba1935986 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/segmentCondition.json @@ -0,0 +1,135 @@ +{ + "type": "array", + "title": "Segment Type", + "description": "Segment match conditions. There are multiple possible types, see the [condition types documentation](https://mailchimp.com/developer/marketing/docs/alternative-schemas/#segment-condition-schemas).", + "items": { + "x-discriminator": { + "propertyName": "condition_type" + }, + "oneOf": [ + { + "$ref": "aimSegment.json" + }, + { + "$ref": "automationSegment.json" + }, + { + "$ref": "campaignPollSegment.json" + }, + { + "$ref": "conversationSegment.json" + }, + { + "$ref": "dateSegment.json" + }, + { + "$ref": "emailClientSegment.json" + }, + { + "$ref": "languageSegment.json" + }, + { + "$ref": "memberRatingSegment.json" + }, + { + "$ref": "signupSourceSegment.json" + }, + { + "$ref": "surveyMonkeySegment.json" + }, + { + "$ref": "vipSegment.json" + }, + { + "$ref": "interestSegment.json" + }, + { + "$ref": "ecommCategorySegment.json" + }, + { + "$ref": "ecommNumberSegment.json" + }, + { + "$ref": "ecommPurchasedSegment.json" + }, + { + "$ref": "ecommSpentSegment.json" + }, + { + "$ref": "ecommStoreSegment.json" + }, + { + "$ref": "goalActivitySegment.json" + }, + { + "$ref": "goalTimestampSegment.json" + }, + { + "$ref": "fuzzySegment.json" + }, + { + "$ref": "staticSegment.json" + }, + { + "$ref": "countryStateSegment.json" + }, + { + "$ref": "geoInSegment.json" + }, + { + "$ref": "ipGeoInZipSegment.json" + }, + { + "$ref": "unknownSegment.json" + }, + { + "$ref": "zipSegment.json" + }, + { + "$ref": "socialAgeSegment.json" + }, + { + "$ref": "socialGenderSegment.json" + }, + { + "$ref": "socialInfluenceSegment.json" + }, + { + "$ref": "socialNetworkSegment.json" + }, + { + "$ref": "socialNetworkFollowSegment.json" + }, + { + "$ref": "addressMergeSegment.json" + }, + { + "$ref": "addressZipWithinSegment.json" + }, + { + "$ref": "birthdayMergeSegment.json" + }, + { + "$ref": "dateMergeSegment.json" + }, + { + "$ref": "dropdownRadioMergeSegment.json" + }, + { + "$ref": "textOrNumberMergeSegment.json" + }, + { + "$ref": "emailSegment.json" + }, + { + "$ref": "predictedGenderSegment.json" + }, + { + "$ref": "predictedAgeSegment.json" + }, + { + "$ref": "newSubscribers.json" + } + ] + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/segmentationOptions.json b/source-mailchimp/source_mailchimp/schemas/shared/segmentationOptions.json new file mode 100644 index 0000000000..18292c74cd --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/segmentationOptions.json @@ -0,0 +1,27 @@ +{ + "type": "object", + "title": "Segment Options", + "description": "An object representing all segmentation options. This object should contain a `saved_segment_id` to use an existing segment, or you can create a new segment by including both `match` and `conditions` options.", + "properties": { + "saved_segment_id": { + "type": "integer", + "title": "Saved Segment ID", + "description": "The id for an existing saved segment." + }, + "prebuilt_segment_id": { + "type": "string", + "title": "Prebuilt Segment Id", + "description": "The prebuilt segment id, if a prebuilt segment has been designated for this campaign.", + "example": "subscribers-female" + }, + "match": { + "type": "string", + "title": "Match Type", + "description": "Segment match type.", + "enum": ["any", "all"] + }, + "conditions": { + "$ref": "segmentCondition.json" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/signupSourceSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/signupSourceSegment.json new file mode 100644 index 0000000000..d9f6f91ff5 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/signupSourceSegment.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "title": "Signup Source Segment", + "description": "Segment by signup source.", + "required": ["field", "condition_type", "op"], + "properties": { + "condition_type": { + "type": "string", + "enum": ["SignupSource"], + "x-value": "SignupSource", + "title": "Type" + }, + "field": { + "type": "string", + "enum": ["source"], + "title": "Segment Field", + "example": "source" + }, + "op": { + "type": "string", + "enum": ["source_is", "source_not"], + "title": "Segment Operator", + "description": "Whether the member's signup source was/was not a particular value.", + "example": "source_is" + }, + "value": { + "type": "string", + "title": "Segment Data", + "description": "The signup source.", + "example": "List Import" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/socialAgeSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/socialAgeSegment.json new file mode 100644 index 0000000000..2be004d924 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/socialAgeSegment.json @@ -0,0 +1,34 @@ +{ + "type": "object", + "title": "Social Profiles Age Segment", + "description": "Segment by age ranges in Social Profiles data.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "SocialAge", + "enum": ["SocialAge"] + }, + "field": { + "type": "string", + "enum": ["social_age"], + "title": "Segment Field", + "description": "Segment by age ranges in Social Profiles data.", + "example": "social_age" + }, + "op": { + "type": "string", + "enum": ["is", "not"], + "title": "Segment Operator", + "description": "Members who are/not the exact criteria listed.", + "example": "is" + }, + "value": { + "type": "string", + "enum": ["18-24", "25-34", "35-54", "55+"], + "title": "Segment Operator", + "description": "The age range to segment.", + "example": "35-54" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/socialGenderSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/socialGenderSegment.json new file mode 100644 index 0000000000..fcbb9d6508 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/socialGenderSegment.json @@ -0,0 +1,34 @@ +{ + "type": "object", + "title": "Social Profiles Gender Segment", + "description": "Segment by listed gender in Social Profiles data.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "SocialGender", + "enum": ["SocialGender"] + }, + "field": { + "type": "string", + "enum": ["social_gender"], + "title": "Segment Field", + "description": "Segment by listed gender in Social Profiles data.", + "example": "social_gender" + }, + "op": { + "type": "string", + "enum": ["is", "not"], + "title": "Segment Operator", + "description": "Members who are/not the exact criteria listed.", + "example": "is" + }, + "value": { + "type": "string", + "enum": ["male", "female"], + "title": "Segment Operator", + "description": "The Social Profiles gender to segment.", + "example": "female" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/socialInfluenceSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/socialInfluenceSegment.json new file mode 100644 index 0000000000..959bca99d9 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/socialInfluenceSegment.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "title": "Social Profiles Influence Segment", + "description": "Segment by influence rating in Social Profiles data.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "SocialInfluence", + "enum": ["SocialInfluence"] + }, + "field": { + "type": "string", + "enum": ["social_influence"], + "title": "Segment Field", + "description": "Segment by influence rating in Social Profiles data.", + "example": "social_influence" + }, + "op": { + "type": "string", + "enum": ["is", "not", "greater", "less"], + "title": "Segment Operator", + "description": "Members who have a rating that is/not or greater/less than the rating provided.", + "example": "greater" + }, + "value": { + "type": "number", + "title": "Segment Operator", + "description": "The Social Profiles influence rating to segment.", + "example": 2 + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/socialNetworkFollowSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/socialNetworkFollowSegment.json new file mode 100644 index 0000000000..2c239fb193 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/socialNetworkFollowSegment.json @@ -0,0 +1,34 @@ +{ + "type": "object", + "title": "Social Profiles Social Network Follow Segment", + "description": "Segment by social network in Social Profiles data.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "SocialNetworkFollow", + "enum": ["SocialNetworkFollow"] + }, + "field": { + "type": "string", + "enum": ["social_network"], + "title": "Segment Field", + "description": "Segment by social network in Social Profiles data.", + "example": "social_network" + }, + "op": { + "type": "string", + "enum": ["follow", "notfollow"], + "title": "Segment Operator", + "description": "Members who are/not following a linked account on a given social network.", + "example": "follow" + }, + "value": { + "type": "string", + "enum": ["twitter_follow"], + "title": "Segment Operator", + "description": "The social network to segment against.", + "example": "twitter_follow" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/socialNetworkSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/socialNetworkSegment.json new file mode 100644 index 0000000000..f28908f4ce --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/socialNetworkSegment.json @@ -0,0 +1,46 @@ +{ + "type": "object", + "title": "Social Profiles Social Network Segment", + "description": "Segment by social network in Social Profiles data.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "SocialNetworkMember", + "enum": ["SocialNetworkMember"] + }, + "field": { + "type": "string", + "enum": ["social_network"], + "title": "Segment Field", + "description": "Segment by social network in Social Profiles data.", + "example": "social_network" + }, + "op": { + "type": "string", + "enum": ["member", "notmember"], + "title": "Segment Operator", + "description": "Members who are/not on a given social network.", + "example": "member" + }, + "value": { + "type": "string", + "enum": [ + "twitter", + "facebook", + "linkedin", + "flickr", + "foursquare", + "lastfm", + "myspace", + "quora", + "vimeo", + "yelp", + "youtube" + ], + "title": "Segment Operator", + "description": "The social network to segment against.", + "example": "twitter" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/staticSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/staticSegment.json new file mode 100644 index 0000000000..c7c1bbc781 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/staticSegment.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "title": "Static Segment Member Segment", + "description": "Segment by a given static segment.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "StaticSegment", + "enum": ["StaticSegment"] + }, + "field": { + "type": "string", + "enum": ["static_segment"], + "title": "Segment Field", + "description": "Segment by a given static segment.", + "example": "static_segment" + }, + "op": { + "type": "string", + "enum": ["static_is", "static_not"], + "title": "Segment Operator", + "description": "Members who are/are not apart of a static segment.", + "example": "static_is" + }, + "value": { + "type": "number", + "title": "Segment Operator", + "description": "The id for the static segment.", + "example": 48433 + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/surveyMonkeySegment.json b/source-mailchimp/source_mailchimp/schemas/shared/surveyMonkeySegment.json new file mode 100644 index 0000000000..c50a402c27 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/surveyMonkeySegment.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "title": "SurveyMonkey Segment", + "description": "Segment by interaction with a SurveyMonkey survey.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "SurveyMonkey", + "enum": ["SurveyMonkey"] + }, + "field": { + "type": "string", + "enum": ["survey_monkey"], + "title": "Segment Field", + "description": "Segment by interaction with a SurveyMonkey survey.", + "example": "survey_monkey" + }, + "op": { + "type": "string", + "enum": ["started", "completed", "not_started", "not_completed"], + "title": "Segment Operator", + "description": "The status of the member with regard to the survey. One of the following: has started the survey, has completed the survey, has not started the survey, or has not completed the survey.", + "example": "started" + }, + "value": { + "type": "string", + "title": "Survey ID", + "description": "The unique ID of the SurveyMonkey survey.", + "example": "32179586" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/textOrNumberMergeSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/textOrNumberMergeSegment.json new file mode 100644 index 0000000000..a313e70810 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/textOrNumberMergeSegment.json @@ -0,0 +1,43 @@ +{ + "type": "object", + "title": "Text or Number Merge Field Segment", + "description": "Segment by a given text or number merge field.", + "required": ["field", "op"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "TextMerge", + "enum": ["TextMerge"] + }, + "field": { + "type": "string", + "title": "Segment Field", + "description": "A text or number merge field to segment.", + "example": "MMERGE7" + }, + "op": { + "type": "string", + "enum": [ + "is", + "not", + "contains", + "notcontain", + "starts", + "ends", + "greater", + "less", + "blank", + "blank_not" + ], + "title": "Segment Operator", + "description": "Whether the member's merge information is/is not, contains/does not contain, starts/ends with, or is greater/less than a value", + "example": "contains" + }, + "value": { + "type": "string", + "title": "Segment Value", + "description": "The value to segment a text or number merge field with.", + "example": "Freddie's Jokes" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/unknownSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/unknownSegment.json new file mode 100644 index 0000000000..008cf86dc3 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/unknownSegment.json @@ -0,0 +1,27 @@ +{ + "type": "object", + "title": "Unknown Location-Based Segment", + "description": "Segment members whose location information is unknown.", + "required": ["field", "op"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "IPGeoUnknown", + "enum": ["IPGeoUnknown"] + }, + "field": { + "type": "string", + "enum": ["ipgeo"], + "title": "Segment Field", + "description": "Segmenting subscribers who are within a specific location.", + "example": "ipgeo" + }, + "op": { + "type": "string", + "enum": ["ipgeounknown"], + "title": "Segment Operator", + "description": "Segment members for which location information is unknown.", + "example": "ipgeounknown" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/vipSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/vipSegment.json new file mode 100644 index 0000000000..08664d5178 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/vipSegment.json @@ -0,0 +1,27 @@ +{ + "type": "object", + "title": "VIP Segment", + "description": "Segment by VIP status.", + "required": ["field", "op"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "VIP", + "enum": ["VIP"] + }, + "field": { + "type": "string", + "enum": ["gmonkey"], + "title": "Segment Field", + "description": "Segment by VIP status.", + "example": "gmonkey" + }, + "op": { + "type": "string", + "enum": ["member", "notmember"], + "title": "Segment Operator", + "description": "Whether the member is or is not marked as VIP.", + "example": "member" + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/shared/zipSegment.json b/source-mailchimp/source_mailchimp/schemas/shared/zipSegment.json new file mode 100644 index 0000000000..78f462f529 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/shared/zipSegment.json @@ -0,0 +1,33 @@ +{ + "type": "object", + "title": "Zip Code Location-Based Segment", + "description": "Segment by a specific US ZIP code.", + "required": ["field", "op", "value"], + "properties": { + "condition_type": { + "type": "string", + "x-value": "IPGeoZip", + "enum": ["IPGeoZip"] + }, + "field": { + "type": "string", + "enum": ["ipgeo"], + "title": "Segment Field", + "description": "Segmenting subscribers who are within a specific location.", + "example": "ipgeo" + }, + "op": { + "type": "string", + "enum": ["ipgeoiszip", "ipgeonotzip"], + "title": "Segment Operator", + "description": "Segment members who are/are not within a specific US zip code.", + "example": "ipgeonotzip" + }, + "value": { + "type": "integer", + "title": "Segment Data", + "description": "The 5-digit zip code.", + "example": 30318 + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/tags.json b/source-mailchimp/source_mailchimp/schemas/tags.json new file mode 100644 index 0000000000..93e81d28f9 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/tags.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "id": { + "type": ["null", "integer"] + }, + "name": { + "type": ["null", "string"] + }, + "list_id": { + "type": ["null", "string"] + } + } +} diff --git a/source-mailchimp/source_mailchimp/schemas/unsubscribes.json b/source-mailchimp/source_mailchimp/schemas/unsubscribes.json new file mode 100644 index 0000000000..ead264a0c1 --- /dev/null +++ b/source-mailchimp/source_mailchimp/schemas/unsubscribes.json @@ -0,0 +1,37 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "additionalProperties": true, + "properties": { + "email_id": { + "type": ["null", "string"] + }, + "email_address": { + "type": ["null", "string"] + }, + "merge_fields": { + "type": ["null", "object"], + "additionalProperties": true + }, + "vip": { + "type": ["null", "boolean"] + }, + "timestamp": { + "type": ["null", "string"], + "format": "date-time", + "airbyte_type": "timestamp_with_timezone" + }, + "reason": { + "type": ["null", "string"] + }, + "campaign_id": { + "type": ["null", "string"] + }, + "list_id": { + "type": ["null", "string"] + }, + "list_is_active": { + "type": ["null", "boolean"] + } + } +} diff --git a/source-mailchimp/source_mailchimp/source.py b/source-mailchimp/source_mailchimp/source.py new file mode 100644 index 0000000000..0edf00993e --- /dev/null +++ b/source-mailchimp/source_mailchimp/source.py @@ -0,0 +1,149 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +import base64 +import re +from typing import Any, List, Mapping, Tuple + +import pendulum +import requests +from airbyte_cdk import AirbyteLogger +from airbyte_cdk.sources import AbstractSource +from airbyte_cdk.sources.streams import Stream +from airbyte_cdk.sources.streams.http.auth import TokenAuthenticator +from pendulum.parsing.exceptions import ParserError +from requests.auth import AuthBase + +from .streams import ( + Automations, + Campaigns, + EmailActivity, + InterestCategories, + Interests, + ListMembers, + Lists, + Reports, + SegmentMembers, + Segments, + Tags, + Unsubscribes, +) + + +class MailChimpAuthenticator: + @staticmethod + def get_oauth_data_center(access_token: str) -> str: + """ + Every Mailchimp API request must be sent to a specific data center. + The data center is already embedded in API keys, but not OAuth access tokens. + This method retrieves the data center for OAuth credentials. + """ + try: + response = requests.get( + "https://login.mailchimp.com/oauth2/metadata", headers={"Authorization": "OAuth {}".format(access_token)} + ) + + # Requests to this endpoint will return a 200 status code even if the access token is invalid. + error = response.json().get("error") + if error == "invalid_token": + raise ValueError("The access token you provided was invalid. Please check your credentials and try again.") + return response.json()["dc"] + + # Handle any other exceptions that may occur. + except Exception as e: + raise Exception(f"An error occured while retrieving the data center for your account. \n {repr(e)}") + + def get_auth(self, config: Mapping[str, Any]) -> AuthBase: + authorization = config.get("credentials", {}) + auth_type = authorization.get("auth_type") + if auth_type == "apikey" or not authorization: + # API keys have the format -. + # See https://mailchimp.com/developer/marketing/docs/fundamentals/#api-structure + apikey = authorization.get("apikey") or config.get("apikey") + if not apikey: + raise Exception("Please provide a valid API key for authentication.") + auth_string = f"anystring:{apikey}".encode("utf8") + b64_encoded = base64.b64encode(auth_string).decode("utf8") + auth = TokenAuthenticator(token=b64_encoded, auth_method="Basic") + auth.data_center = apikey.split("-").pop() + + elif auth_type == "oauth2.0": + access_token = authorization["access_token"] + auth = TokenAuthenticator(token=access_token, auth_method="Bearer") + auth.data_center = self.get_oauth_data_center(access_token) + + else: + raise Exception(f"Invalid auth type: {auth_type}") + + return auth + + +class SourceMailchimp(AbstractSource): + def _validate_start_date(self, config: Mapping[str, Any]): + start_date = config.get("start_date") + + if start_date: + pattern = re.compile(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z") + if not pattern.match(start_date): # Compare against the pattern descriptor. + return "Please check the format of the start date against the pattern descriptor." + + try: # Handle invalid dates. + parsed_start_date = pendulum.parse(start_date) + except ParserError: + return "The provided start date is not a valid date. Please check the date you input and try again." + + if parsed_start_date > pendulum.now("UTC"): # Handle future start date. + return "The start date cannot be greater than the current date." + + return None + + def check_connection(self, logger: AirbyteLogger, config: Mapping[str, Any]) -> Tuple[bool, Any]: + # First, check for a valid start date if it is provided + start_date_validation_error = self._validate_start_date(config) + if start_date_validation_error: + return False, start_date_validation_error + + try: + authenticator = MailChimpAuthenticator().get_auth(config) + response = requests.get( + f"https://{authenticator.data_center}.api.mailchimp.com/3.0/ping", headers=authenticator.get_auth_header() + ) + + # A successful response will return a simple JSON object with a single key: health_status. + # Otherwise, errors are returned as a JSON object with keys: + # {type, title, status, detail, instance} + + if not response.json().get("health_status"): + error_title = response.json().get("title", "Unknown Error") + error_details = response.json().get("details", "An unknown error occurred. Please verify your credentials and try again.") + return False, f"Encountered an error while connecting to Mailchimp. Type: {error_title}. Details: {error_details}" + return True, None + + # Handle any other exceptions that may occur. + except Exception as e: + return False, repr(e) + + def streams(self, config: Mapping[str, Any]) -> List[Stream]: + authenticator = MailChimpAuthenticator().get_auth(config) + campaign_id = config.get("campaign_id") + start_date = config.get("start_date") + + lists = Lists(authenticator=authenticator, start_date=start_date) + interest_categories = InterestCategories(authenticator=authenticator, parent=lists) + + return [ + Automations(authenticator=authenticator, start_date=start_date), + Campaigns(authenticator=authenticator, start_date=start_date), + EmailActivity(authenticator=authenticator, start_date=start_date, campaign_id=campaign_id), + interest_categories, + Interests(authenticator=authenticator, parent=interest_categories), + lists, + ListMembers(authenticator=authenticator, start_date=start_date), + Reports(authenticator=authenticator, start_date=start_date), + SegmentMembers(authenticator=authenticator, start_date=start_date), + Segments(authenticator=authenticator, start_date=start_date), + Tags(authenticator=authenticator, parent=lists), + Unsubscribes(authenticator=authenticator, start_date=start_date, campaign_id=campaign_id), + ] diff --git a/source-mailchimp/source_mailchimp/spec.json b/source-mailchimp/source_mailchimp/spec.json new file mode 100644 index 0000000000..f88649faa1 --- /dev/null +++ b/source-mailchimp/source_mailchimp/spec.json @@ -0,0 +1,123 @@ +{ + "documentationUrl": "https://docs.airbyte.com/integrations/sources/mailchimp", + "connectionSpecification": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Mailchimp Spec", + "type": "object", + "required": [], + "additionalProperties": true, + "properties": { + "credentials": { + "type": "object", + "title": "Authentication", + "oneOf": [ + { + "title": "OAuth2.0", + "type": "object", + "required": ["auth_type", "access_token"], + "properties": { + "auth_type": { + "type": "string", + "const": "oauth2.0", + "order": 0 + }, + "client_id": { + "title": "Client ID", + "type": "string", + "description": "The Client ID of your OAuth application.", + "airbyte_secret": true + }, + "client_secret": { + "title": "Client Secret", + "type": "string", + "description": "The Client Secret of your OAuth application.", + "airbyte_secret": true + }, + "access_token": { + "title": "Access Token", + "type": "string", + "description": "An access token generated using the above client ID and secret.", + "airbyte_secret": true + } + } + }, + { + "type": "object", + "title": "API Key", + "required": ["auth_type", "apikey"], + "properties": { + "auth_type": { + "type": "string", + "const": "apikey", + "order": 1 + }, + "apikey": { + "type": "string", + "title": "API Key", + "description": "Mailchimp API Key. See the docs for information on how to generate this key.", + "airbyte_secret": true + } + } + } + ] + }, + "start_date": { + "title": "Incremental Sync Start Date", + "description": "The date from which you want to start syncing data for Incremental streams. Only records that have been created or modified since this date will be synced. If left blank, all data will by synced.", + "type": "string", + "format": "date-time", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}Z$", + "pattern_descriptor": "YYYY-MM-DDTHH:MM:SS.000Z", + "examples": ["2020-01-01T00:00:00.000Z"] + }, + "campaign_id": { + "type": "string", + "title": "ID of a campaign to sync email activities", + "airbyte_hidden": true + } + } + }, + "advanced_auth": { + "auth_flow_type": "oauth2.0", + "predicate_key": ["credentials", "auth_type"], + "predicate_value": "oauth2.0", + "oauth_config_specification": { + "complete_oauth_output_specification": { + "type": "object", + "additionalProperties": false, + "properties": { + "access_token": { + "type": "string", + "path_in_connector_config": ["credentials", "access_token"] + } + } + }, + "complete_oauth_server_input_specification": { + "type": "object", + "additionalProperties": false, + "properties": { + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + } + } + }, + "complete_oauth_server_output_specification": { + "type": "object", + "additionalProperties": false, + "properties": { + "client_id": { + "type": "string", + "path_in_connector_config": ["credentials", "client_id"] + }, + "client_secret": { + "type": "string", + "path_in_connector_config": ["credentials", "client_secret"] + } + } + } + } + } +} diff --git a/source-mailchimp/source_mailchimp/streams.py b/source-mailchimp/source_mailchimp/streams.py new file mode 100644 index 0000000000..158eaf1e8b --- /dev/null +++ b/source-mailchimp/source_mailchimp/streams.py @@ -0,0 +1,518 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import logging +import math +from abc import ABC, abstractmethod +from typing import Any, Iterable, List, Mapping, MutableMapping, Optional + +import pendulum +import requests +from airbyte_cdk.models import SyncMode +from airbyte_cdk.sources.streams.core import StreamData +from airbyte_cdk.sources.streams.http import HttpStream, HttpSubStream + +logger = logging.getLogger("airbyte") + + +class MailChimpStream(HttpStream, ABC): + primary_key = "id" + page_size = 1000 + + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.current_offset = 0 + self.data_center = kwargs["authenticator"].data_center + + @property + def url_base(self) -> str: + return f"https://{self.data_center}.api.mailchimp.com/3.0/" + + def next_page_token(self, response: requests.Response) -> Optional[Mapping[str, Any]]: + decoded_response = response.json() + api_data = decoded_response[self.data_field] + if len(api_data) < self.page_size: + self.current_offset = 0 + return None + else: + self.current_offset += self.page_size + return {"offset": self.current_offset} + + def request_params( + self, + stream_state: Mapping[str, Any], + stream_slice: Mapping[str, Any] = None, + next_page_token: Mapping[str, Any] = None, + ) -> MutableMapping[str, Any]: + + # The ._links field is returned by most Mailchimp endpoints and contains non-relevant schema metadata. + params = {"count": self.page_size, "exclude_fields": f"{self.data_field}._links"} + + # Handle pagination by inserting the next page's token in the request parameters + if next_page_token: + params.update(next_page_token) + return params + + def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapping]: + response_json = response.json() + yield from response_json[self.data_field] + + @property + @abstractmethod + def data_field(self) -> str: + """The response entry that contains useful data""" + pass + + def read_records( + self, + sync_mode: SyncMode, + cursor_field: List[str] = None, + stream_slice: Mapping[str, Any] = None, + stream_state: Mapping[str, Any] = None, + ) -> Iterable[StreamData]: + try: + yield from super().read_records( + sync_mode=sync_mode, cursor_field=cursor_field, stream_slice=stream_slice, stream_state=stream_state + ) + except requests.exceptions.JSONDecodeError: + logger.error(f"Unknown error while reading stream {self.name}. Response cannot be read properly. ") + + +class IncrementalMailChimpStream(MailChimpStream, ABC): + state_checkpoint_interval = math.inf + + def __init__(self, **kwargs): + self.start_date = kwargs.pop("start_date", None) + super().__init__(**kwargs) + + @property + @abstractmethod + def cursor_field(self) -> str: + """ + Defining a cursor field indicates that a stream is incremental, so any incremental stream must extend this class + and define a cursor field. + """ + pass + + @property + def filter_field(self): + return f"since_{self.cursor_field}" + + @property + def sort_field(self): + return self.cursor_field + + def filter_empty_fields(self, element: Mapping[str, Any]) -> Mapping[str, Any]: + """ + Many Mailchimp endpoints return empty strings instead of null values. + This causes validation errors on datetime columns, so for safety, we need to check for empty strings and set their value to None/null. + This method recursively traverses each element in a record and replaces any "" values with None, based on three conditions: + + 1. If the element is a dictionary, apply the method recursively to each value in the dictionary. + 2. If the element is a list, apply the method recursively to each item in the list. + 3. If the element is a string, check if it is an empty string. If so, replace it with None. + """ + + if isinstance(element, dict): + element = {k: self.filter_empty_fields(v) if v != "" else None for k, v in element.items()} + elif isinstance(element, list): + element = [self.filter_empty_fields(v) for v in element] + return element + + def get_updated_state(self, current_stream_state: MutableMapping[str, Any], latest_record: Mapping[str, Any]) -> Mapping[str, Any]: + """ + Return the latest state by comparing the cursor value in the latest record with the stream's most recent state object + and returning an updated state object. + """ + latest_state = latest_record.get(self.cursor_field) + current_state = current_stream_state.get(self.cursor_field) or latest_state + return {self.cursor_field: max(latest_state, current_state)} + + def stream_slices( + self, *, sync_mode: SyncMode, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None + ) -> Iterable[Optional[Mapping[str, Any]]]: + slice_ = {} + stream_state = stream_state or {} + cursor_value = self.get_filter_date(self.start_date, stream_state.get(self.cursor_field)) + if cursor_value: + slice_[self.filter_field] = cursor_value + yield slice_ + + @staticmethod + def get_filter_date(start_date: str, state_date: str) -> str: + """ + Calculate the filter date to pass in the request parameters by comparing the start_date + with the value of state obtained from the stream_slice. + If only one value exists, use it by default. Otherwise, return None. + If no filter_date is provided, the API will fetch all available records. + """ + + start_date_parsed = pendulum.parse(start_date).to_iso8601_string() if start_date else None + state_date_parsed = pendulum.parse(state_date).to_iso8601_string() if state_date else None + + # Return the max of the two dates if both are present. Otherwise return whichever is present, or None. + if start_date_parsed or state_date_parsed: + return max(filter(None, [start_date_parsed, state_date_parsed]), default=None) + + def filter_old_records(self, records: Iterable, filter_date) -> Iterable: + """ + Filters out records with older cursor_values than the filter_date. + This can be used to enforce the filter for incremental streams that do not support sorting/filtering via query params. + """ + for record in records: + record_cursor_value = record.get(self.cursor_field) + if not filter_date or record_cursor_value >= filter_date: + yield record + + def request_params(self, stream_state=None, stream_slice=None, **kwargs): + stream_state = stream_state or {} + stream_slice = stream_slice or {} + params = super().request_params(stream_state=stream_state, stream_slice=stream_slice, **kwargs) + default_params = {"sort_field": self.sort_field, "sort_dir": "ASC", **stream_slice} + params.update(default_params) + return params + + def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapping]: + response = super().parse_response(response, **kwargs) + for record in response: + yield self.filter_empty_fields(record) + + +class MailChimpListSubStream(IncrementalMailChimpStream): + """ + Base class for incremental Mailchimp streams that are children of the Lists stream. + """ + + def stream_slices(self, stream_state: Mapping[str, Any] = None, **kwargs) -> Iterable[Optional[Mapping[str, Any]]]: + stream_state = stream_state or {} + parent = Lists(authenticator=self.authenticator).read_records(sync_mode=SyncMode.full_refresh) + for parent_record in parent: + slice = {"list_id": parent_record["id"]} + cursor_value = self.get_filter_date(self.start_date, stream_state.get(parent_record["id"], {}).get(self.cursor_field)) + if cursor_value: + slice[self.filter_field] = cursor_value + yield slice + + def path(self, stream_slice: Mapping[str, Any] = None, **kwargs) -> str: + list_id = stream_slice.get("list_id") + return f"lists/{list_id}/{self.data_field}" + + def request_params(self, stream_state=None, stream_slice=None, **kwargs) -> MutableMapping[str, Any]: + params = super().request_params(stream_state=stream_state, stream_slice=stream_slice, **kwargs) + + # Get the current state value for this list_id, if it exists + # Then, use the value in state to filter the request + current_slice = stream_slice.get("list_id") + filter_date = stream_state.get(current_slice) + if filter_date: + params[self.filter_field] = filter_date.get(self.cursor_field) + return params + + def get_updated_state(self, current_stream_state: MutableMapping[str, Any], latest_record: Mapping[str, Any]) -> Mapping[str, Any]: + current_stream_state = current_stream_state or {} + list_id = latest_record.get("list_id") + latest_cursor_value = latest_record.get(self.cursor_field) + + # Get the current state value for this list, if it exists + list_state = current_stream_state.get(list_id, {}) + current_cursor_value = list_state.get(self.cursor_field, latest_cursor_value) + + # Update the cursor value and set it in state + updated_cursor_value = max(current_cursor_value, latest_cursor_value) + current_stream_state[list_id] = {self.cursor_field: updated_cursor_value} + + return current_stream_state + + +class Lists(IncrementalMailChimpStream): + cursor_field = "date_created" + data_field = "lists" + + def path(self, **kwargs) -> str: + return "lists" + + +class Campaigns(IncrementalMailChimpStream): + cursor_field = "create_time" + data_field = "campaigns" + + def path(self, **kwargs) -> str: + return "campaigns" + + +class Automations(IncrementalMailChimpStream): + """Doc Link: https://mailchimp.com/developer/marketing/api/automation/get-automation-info/""" + + cursor_field = "create_time" + data_field = "automations" + + def path(self, **kwargs) -> str: + return "automations" + + +class EmailActivity(IncrementalMailChimpStream): + cursor_field = "timestamp" + filter_field = "since" + sort_field = "create_time" + data_field = "emails" + primary_key = ["timestamp", "email_id", "action"] + + def __init__(self, campaign_id: Optional[str] = None, **kwargs): + super().__init__(**kwargs) + self.campaign_id = campaign_id + + def stream_slices( + self, *, sync_mode: SyncMode, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None + ) -> Iterable[Optional[Mapping[str, Any]]]: + stream_state = stream_state or {} + if self.campaign_id: + # this is a workaround to speed up SATs and enable incremental tests + campaigns = [{"id": self.campaign_id}] + else: + campaigns = Campaigns(authenticator=self.authenticator).read_records(sync_mode=SyncMode.full_refresh) + for campaign in campaigns: + slice_ = {"campaign_id": campaign["id"]} + state_value = stream_state.get(campaign["id"], {}).get(self.cursor_field) + cursor_value = self.get_filter_date(self.start_date, state_value) + if cursor_value: + slice_[self.filter_field] = cursor_value + yield slice_ + + def path(self, stream_slice: Mapping[str, Any] = None, **kwargs) -> str: + campaign_id = stream_slice["campaign_id"] + return f"reports/{campaign_id}/email-activity" + + def get_updated_state(self, current_stream_state: MutableMapping[str, Any], latest_record: Mapping[str, Any]) -> Mapping[str, Any]: + """ + Return the latest state by comparing the campaign_id and cursor value in the latest record with the stream's most recent state object + and returning an updated state object. + """ + campaign_id = latest_record.get("campaign_id") + latest_cursor_value = latest_record.get(self.cursor_field) + current_stream_state = current_stream_state or {} + current_state = current_stream_state.get(campaign_id) if current_stream_state else None + if current_state: + current_state = current_state.get(self.cursor_field) + current_state_value = current_state or latest_cursor_value + max_value = max(current_state_value, latest_cursor_value) + new_value = {self.cursor_field: max_value} + + current_stream_state[campaign_id] = new_value + return current_stream_state + + def parse_response(self, response: requests.Response, **kwargs) -> Iterable[Mapping]: + try: + response_json = response.json() + except requests.exceptions.JSONDecodeError: + logger.error(f"Response returned with {response.status_code=}, {response.content=}") + response_json = {} + # transform before save + # [{'campaign_id', 'list_id', 'list_is_active', 'email_id', 'email_address', 'activity[array[object]]', '_links'}] -> + # -> [[{'campaign_id', 'list_id', 'list_is_active', 'email_id', 'email_address', '**activity[i]', '_links'}, ...]] + data = response_json.get(self.data_field, []) + for item in data: + for activity_item in item.pop("activity", []): + yield {**item, **activity_item} + + +class InterestCategories(MailChimpStream, HttpSubStream): + """ + Get information about interest categories for a specific list. + Docs link: https://mailchimp.com/developer/marketing/api/interest-categories/list-interest-categories/ + """ + + data_field = "categories" + + def path(self, stream_slice: Mapping[str, Any] = None, **kwargs) -> str: + """ + Get the list_id from the parent stream slice and use it to construct the path. + """ + list_id = stream_slice.get("parent").get("id") + return f"lists/{list_id}/interest-categories" + + +class Interests(MailChimpStream, HttpSubStream): + """ + Get a list of interests for a specific interest category. + Docs link: https://mailchimp.com/developer/marketing/api/interests/list-interests-in-category/ + """ + + data_field = "interests" + + def path(self, stream_slice: Mapping[str, Any] = None, **kwargs) -> str: + """ + Get the list_id from the parent stream slice and use it to construct the path. + """ + list_id = stream_slice.get("parent").get("list_id") + category_id = stream_slice.get("parent").get("id") + return f"lists/{list_id}/interest-categories/{category_id}/interests" + + +class ListMembers(MailChimpListSubStream): + """ + Get information about members in a specific Mailchimp list. + Docs link: https://mailchimp.com/developer/marketing/api/list-members/list-members-info/ + """ + + cursor_field = "last_changed" + data_field = "members" + + +class Reports(IncrementalMailChimpStream): + cursor_field = "send_time" + data_field = "reports" + + def path(self, **kwargs) -> str: + return "reports" + + +class SegmentMembers(MailChimpListSubStream): + """ + Get information about members in a specific segment. + Docs link: https://mailchimp.com/developer/marketing/api/list-segment-members/list-members-in-segment/ + """ + + cursor_field = "last_changed" + data_field = "members" + + def stream_slices(self, **kwargs) -> Iterable[Optional[Mapping[str, Any]]]: + """ + Each slice consists of a list_id and segment_id pair + """ + segments_slices = Segments(authenticator=self.authenticator).stream_slices(sync_mode=SyncMode.full_refresh) + + for slice in segments_slices: + segment_records = Segments(authenticator=self.authenticator).read_records(sync_mode=SyncMode.full_refresh, stream_slice=slice) + + for segment in segment_records: + yield {"list_id": segment["list_id"], "segment_id": segment["id"]} + + def path(self, stream_slice: Mapping[str, Any] = None, **kwargs) -> str: + list_id = stream_slice.get("list_id") + segment_id = stream_slice.get("segment_id") + return f"lists/{list_id}/segments/{segment_id}/members" + + def parse_response(self, response: requests.Response, stream_state: Mapping[str, Any], stream_slice, **kwargs) -> Iterable[Mapping]: + """ + The SegmentMembers endpoint does not support sorting or filtering, + so we need to apply our own filtering logic before reading. + The foreign key "segment_id" is also added to each record before being read. + """ + response = super().parse_response(response, **kwargs) + + # Calculate the filter date to compare all records against in this slice + slice_cursor_value = stream_state.get(str(stream_slice.get("segment_id")), {}).get(self.cursor_field) + filter_date = self.get_filter_date(self.start_date, slice_cursor_value) + + for record in self.filter_old_records(response, filter_date): + # Add the segment_id foreign_key to each record + record["segment_id"] = stream_slice.get("segment_id") + yield record + + def get_updated_state(self, current_stream_state: MutableMapping[str, Any], latest_record: Mapping[str, Any]) -> Mapping[str, Any]: + current_stream_state = current_stream_state or {} + segment_id = str(latest_record.get("segment_id")) + latest_cursor_value = latest_record.get(self.cursor_field) + + # Get the current state value for this list, if it exists + segment_state = current_stream_state.get(segment_id, {}) + current_cursor_value = segment_state.get(self.cursor_field, latest_cursor_value) + + # Update the cursor value and set it in state + updated_cursor_value = max(current_cursor_value, latest_cursor_value) + current_stream_state[segment_id] = {self.cursor_field: updated_cursor_value} + return current_stream_state + + +class Segments(MailChimpListSubStream): + """ + Get information about all available segments for a specific list. + Docs link: https://mailchimp.com/developer/marketing/api/list-segments/list-segments/ + """ + + cursor_field = "updated_at" + data_field = "segments" + + +class Tags(MailChimpStream, HttpSubStream): + """ + Get information about tags for a specific list. + Docs link: https://mailchimp.com/developer/marketing/api/list-tags/list-tags-for-list/ + """ + + data_field = "tags" + + def path(self, stream_slice: Mapping[str, Any] = None, **kwargs) -> str: + list_id = stream_slice.get("parent").get("id") + return f"lists/{list_id}/tag-search" + + def parse_response(self, response: requests.Response, stream_slice, **kwargs) -> Iterable[Mapping]: + """ + Tags do not reference parent_ids, so we need to add the list_id to each record. + """ + response = super().parse_response(response, **kwargs) + + for record in response: + record["list_id"] = stream_slice.get("parent").get("id") + yield record + + +class Unsubscribes(IncrementalMailChimpStream): + """ + List of members who have unsubscribed from a specific campaign. + Docs link: https://mailchimp.com/developer/marketing/api/unsub-reports/list-unsubscribed-members/ + """ + + cursor_field = "timestamp" + data_field = "unsubscribes" + # There is no unique identifier for unsubscribes, so we use a composite key + # consisting of the campaign_id, email_id, and timestamp. + primary_key = ["campaign_id", "email_id", "timestamp"] + + def __init__(self, campaign_id: Optional[str] = None, **kwargs): + super().__init__(**kwargs) + self.campaign_id = campaign_id + + def stream_slices( + self, *, sync_mode: SyncMode, cursor_field: List[str] = None, stream_state: Mapping[str, Any] = None + ) -> Iterable[Optional[Mapping[str, Any]]]: + + if self.campaign_id: + # Similar to EmailActivity stream, this is a workaround to speed up SATs + # and enable incremental tests by reading from a single campaign + campaigns = [{"id": self.campaign_id}] + else: + campaigns = Campaigns(authenticator=self.authenticator).read_records(sync_mode=SyncMode.full_refresh) + for campaign in campaigns: + yield {"campaign_id": campaign["id"]} + + def path(self, stream_slice: Mapping[str, Any] = None, **kwargs) -> str: + campaign_id = stream_slice.get("campaign_id") + return f"reports/{campaign_id}/unsubscribed" + + def parse_response(self, response: requests.Response, stream_state: Mapping[str, Any], stream_slice, **kwargs) -> Iterable[Mapping]: + """ + The Unsubscribes endpoint does not support sorting or filtering, + so we need to apply our own filtering logic before reading. + """ + + response = super().parse_response(response, **kwargs) + + slice_cursor_value = stream_state.get(stream_slice.get("campaign_id", {}), {}).get(self.cursor_field) + filter_date = self.get_filter_date(self.start_date, slice_cursor_value) + yield from self.filter_old_records(response, filter_date) + + def get_updated_state(self, current_stream_state: MutableMapping[str, Any], latest_record: Mapping[str, Any]) -> Mapping[str, Any]: + current_stream_state = current_stream_state or {} + campaign_id = latest_record.get("campaign_id") + latest_cursor_value = latest_record.get(self.cursor_field) + + # Get the current state value for this campaign, if it exists + campaign_state = current_stream_state.get(campaign_id, {}) + current_cursor_value = campaign_state.get(self.cursor_field, latest_cursor_value) + + # Update the cursor value and set it in state + updated_cursor_value = max(current_cursor_value, latest_cursor_value) + current_stream_state[campaign_id] = {self.cursor_field: updated_cursor_value} + return current_stream_state diff --git a/source-mailchimp/unit_tests/conftest.py b/source-mailchimp/unit_tests/conftest.py new file mode 100644 index 0000000000..5305f0dada --- /dev/null +++ b/source-mailchimp/unit_tests/conftest.py @@ -0,0 +1,77 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +from pytest import fixture +from source_mailchimp.source import MailChimpAuthenticator +from source_mailchimp.streams import Campaigns, Unsubscribes + + +@fixture(name="data_center") +def data_center_fixture(): + return "some_dc" + + +@fixture(name="config") +def config_fixture(data_center): + return {"apikey": f"API_KEY-{data_center}", "start_date": "2022-01-01T00:00:00.000Z"} + + +@fixture(name="access_token") +def access_token_fixture(): + return "some_access_token" + + +@fixture(name="oauth_config") +def oauth_config_fixture(access_token): + return { + "credentials": { + "auth_type": "oauth2.0", + "client_id": "111111111", + "client_secret": "secret_1111111111", + "access_token": access_token, + } + } + + +@fixture(name="apikey_config") +def apikey_config_fixture(data_center): + return {"credentials": {"auth_type": "apikey", "apikey": f"some_api_key-{data_center}"}} + + +@fixture(name="wrong_config") +def wrong_config_fixture(): + return {"credentials": {"auth_type": "not auth_type"}} + + +@fixture(name="auth") +def authenticator_fixture(apikey_config): + return MailChimpAuthenticator().get_auth(apikey_config) + + +@fixture(name="campaigns_stream") +def campaigns_stream_fixture(auth): + return Campaigns(authenticator=auth) + + +@fixture(name="unsubscribes_stream") +def unsubscribes_stream_fixture(auth): + return Unsubscribes(authenticator=auth) + + +@fixture(name="mock_campaigns_response") +def mock_campaigns_response_fixture(): + return [ + {"id": "campaign_1", "web_id": 1, "type": "regular", "create_time": "2022-01-01T00:00:00Z"}, + {"id": "campaign_2", "web_id": 2, "type": "plaintext", "create_time": "2022-01-02T00:00:00Z"}, + {"id": "campaign_3", "web_id": 3, "type": "variate", "create_time": "2022-01-03T00:00:00Z"}, + ] + + +@fixture(name="mock_unsubscribes_state") +def mock_unsubscribes_state_fixture(): + return { + "campaign_1": {"timestamp": "2022-01-01T00:00:00Z"}, + "campaign_2": {"timestamp": "2022-01-02T00:00:00Z"}, + "campaign_3": {"timestamp": "2022-01-03T00:00:00Z"}, + } diff --git a/source-mailchimp/unit_tests/test_source.py b/source-mailchimp/unit_tests/test_source.py new file mode 100644 index 0000000000..b1ccfcddac --- /dev/null +++ b/source-mailchimp/unit_tests/test_source.py @@ -0,0 +1,116 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import logging + +import pytest +from source_mailchimp.source import MailChimpAuthenticator, SourceMailchimp + +logger = logging.getLogger("airbyte") + + +def test_check_connection_ok(requests_mock, config, data_center): + responses = [ + {"json": {"health_status": "Everything's Chimpy!"}}, + ] + requests_mock.register_uri("GET", f"https://{data_center}.api.mailchimp.com/3.0/ping", responses) + ok, error_msg = SourceMailchimp().check_connection(logger, config=config) + + assert ok + assert not error_msg + + +@pytest.mark.parametrize( + "response, expected_message", + [ + ( + { + "json": { + "title": "API Key Invalid", + "details": "Your API key may be invalid, or you've attempted to access the wrong datacenter.", + } + }, + "Encountered an error while connecting to Mailchimp. Type: API Key Invalid. Details: Your API key may be invalid, or you've attempted to access the wrong datacenter.", + ), + ( + {"json": {"title": "Forbidden", "details": "You don't have permission to access this resource."}}, + "Encountered an error while connecting to Mailchimp. Type: Forbidden. Details: You don't have permission to access this resource.", + ), + ( + {"json": {}}, + "Encountered an error while connecting to Mailchimp. Type: Unknown Error. Details: An unknown error occurred. Please verify your credentials and try again.", + ), + ], + ids=["API Key Invalid", "Forbidden", "Unknown Error"], +) +def test_check_connection_error(requests_mock, config, data_center, response, expected_message): + requests_mock.register_uri("GET", f"https://{data_center}.api.mailchimp.com/3.0/ping", json=response["json"]) + ok, error_msg = SourceMailchimp().check_connection(logger, config=config) + + assert not ok + assert error_msg == expected_message + + +def test_get_oauth_data_center_ok(requests_mock, access_token, data_center): + responses = [ + {"json": {"dc": data_center}, "status_code": 200}, + ] + requests_mock.register_uri("GET", "https://login.mailchimp.com/oauth2/metadata", responses) + assert MailChimpAuthenticator().get_oauth_data_center(access_token) == data_center + + +def test_get_oauth_data_center_exception(requests_mock, access_token): + responses = [ + {"json": {}, "status_code": 200}, + {"json": {"error": "invalid_token"}, "status_code": 200}, + {"status_code": 403}, + ] + requests_mock.register_uri("GET", "https://login.mailchimp.com/oauth2/metadata", responses) + with pytest.raises(Exception): + MailChimpAuthenticator().get_oauth_data_center(access_token) + + +def test_oauth_config(requests_mock, oauth_config, data_center): + responses = [ + {"json": {"dc": data_center}, "status_code": 200}, + ] + requests_mock.register_uri("GET", "https://login.mailchimp.com/oauth2/metadata", responses) + assert MailChimpAuthenticator().get_auth(oauth_config) + + +def test_apikey_config(apikey_config): + assert MailChimpAuthenticator().get_auth(apikey_config) + + +def test_wrong_config(wrong_config): + with pytest.raises(Exception): + MailChimpAuthenticator().get_auth(wrong_config) + + +@pytest.mark.parametrize( + "config, expected_return", + [ + ({}, None), + ({"start_date": "2021-01-01T00:00:00.000Z"}, None), + ({"start_date": "2021-99-99T79:89:99.123Z"}, "The provided start date is not a valid date. Please check the date you input and try again."), + ({"start_date": "2021-01-01T00:00:00.000"}, "Please check the format of the start date against the pattern descriptor."), + ({"start_date": "2025-01-25T00:00:00.000Z"}, "The start date cannot be greater than the current date."), + ], + ids=[ + "No start date", + "Valid start date", + "Invalid start date", + "Invalid format", + "Future start date", + ] +) +def test_validate_start_date(config, expected_return): + source = SourceMailchimp() + result = source._validate_start_date(config) + assert result == expected_return + + +def test_streams_count(config): + streams = SourceMailchimp().streams(config) + assert len(streams) == 12 diff --git a/source-mailchimp/unit_tests/test_streams.py b/source-mailchimp/unit_tests/test_streams.py new file mode 100644 index 0000000000..b441fe26f7 --- /dev/null +++ b/source-mailchimp/unit_tests/test_streams.py @@ -0,0 +1,696 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +import logging +from unittest.mock import MagicMock + +import pytest +import requests +import responses +from airbyte_cdk.models import SyncMode +from requests.exceptions import HTTPError +from source_mailchimp.streams import ( + Automations, + Campaigns, + EmailActivity, + InterestCategories, + Interests, + ListMembers, + Lists, + Reports, + SegmentMembers, + Segments, + Tags, + Unsubscribes, +) +from utils import read_full_refresh, read_incremental + + +@pytest.mark.parametrize( + "stream, endpoint", + [ + (Lists, "lists"), + (Campaigns, "campaigns"), + (Segments, "lists/123/segments"), + ], +) +def test_stream_read(requests_mock, auth, stream, endpoint): + args = {"authenticator": auth} + stream = stream(**args) + stream_responses = [ + { + "json": { + stream.data_field: [{"id": "test_id"}], + } + } + ] + stream_url = stream.url_base + endpoint + requests_mock.register_uri("GET", stream_url, stream_responses) + + # Mock the 'lists' endpoint as Segments stream_slice + lists_url = stream.url_base + "lists" + lists_response = {"json": {"lists": [{"id": "123"}]}} + requests_mock.register_uri("GET", lists_url, [lists_response]) + records = read_full_refresh(stream) + + assert records + + +def test_next_page_token(auth): + args = {"authenticator": auth} + stream = Lists(**args) + inputs = {"response": MagicMock()} + expected_token = None + assert stream.next_page_token(**inputs) == expected_token + + resp = {"lists": [{"id": i} for i in range(1001)]} + inputs = {"response": MagicMock(json=MagicMock(return_value=resp))} + expected_token = {"offset": 1000} + assert stream.next_page_token(**inputs) == expected_token + + +@pytest.mark.parametrize( + "stream, inputs, expected_params", + [ + ( + Lists, + {"stream_slice": None, "stream_state": None, "next_page_token": None}, + {"count": 1000, "sort_dir": "ASC", "sort_field": "date_created", "exclude_fields": "lists._links"}, + ), + ( + Lists, + {"stream_slice": None, "stream_state": None, "next_page_token": {"offset": 1000}}, + {"count": 1000, "sort_dir": "ASC", "sort_field": "date_created", "offset": 1000, "exclude_fields": "lists._links"}, + ), + ( + InterestCategories, + {"stream_slice": {"parent": {"id": "123"}}, "stream_state": None, "next_page_token": None}, + {"count": 1000, "exclude_fields": "categories._links"}, + ), + ( + Interests, + {"stream_slice": {"parent": {"id": "123"}}, "stream_state": None, "next_page_token": {"offset": 2000}}, + {"count": 1000, "exclude_fields": "interests._links", "offset": 2000}, + ), + ], + ids=[ + "Lists: no next_page_token or state to add to request params", + "Lists: next_page_token added to request params", + "InterestCategories: no next_page_token to add to request params", + "Interests: next_page_token added to request params", + ], +) +def test_request_params(auth, stream, inputs, expected_params): + args = {"authenticator": auth} + if stream == InterestCategories: + args["parent"] = Lists(**args) + elif stream == Interests: + args["parent"] = InterestCategories(authenticator=auth, parent=Lists(authenticator=auth)) + stream = stream(**args) + assert stream.request_params(**inputs) == expected_params + + +@pytest.mark.parametrize( + "current_state_stream, latest_record, expected_state", + [ + ({}, {"date_created": "2020-01-01"}, {"date_created": "2020-01-01"}), + ({"date_created": "2020-01-01"}, {"date_created": "2021-01-01"}, {"date_created": "2021-01-01"}), + ({"date_created": "2021-01-01"}, {"date_created": "2022-01-01"}, {"date_created": "2022-01-01"}), + ], +) +def test_get_updated_state(auth, current_state_stream, latest_record, expected_state): + args = {"authenticator": auth} + stream = Lists(**args) + + new_stream_state = stream.get_updated_state(current_state_stream, latest_record) + assert new_stream_state == expected_state + + +@responses.activate +def test_stream_teams_read(auth): + args = {"authenticator": auth} + stream = EmailActivity(**args) + stream_url = stream.url_base + "reports/123/email-activity" + campaigns_stream_url = stream.url_base + "campaigns" + responses.add("GET", campaigns_stream_url, json={"campaigns": [{"id": 123}]}) + + response = {"emails": [{"campaign_id": 123, "activity": [{"action": "q", "timestamp": "2021-08-24T14:15:22Z"}]}]} + responses.add("GET", stream_url, json=response) + records = read_incremental(stream, {}) + + assert records + assert records == [{"campaign_id": 123, "action": "q", "timestamp": "2021-08-24T14:15:22Z"}] + assert len(responses.calls) == 2 + + +@responses.activate +def test_stream_parse_json_error(auth, caplog): + args = {"authenticator": auth} + stream = EmailActivity(**args) + stream_url = stream.url_base + "reports/123/email-activity" + campaigns_stream_url = stream.url_base + "campaigns" + responses.add("GET", campaigns_stream_url, json={"campaigns": [{"id": 123}]}) + responses.add("GET", stream_url, body="not_valid_json") + read_incremental(stream, {}) + assert "response.content=b'not_valid_json'" in caplog.text + + +@pytest.mark.parametrize( + "stream_class, stream_slice, stream_state, next_page_token, expected_params", + [ + # Test case 1: no state, no next_page_token + ( + Segments, + {"list_id": "123"}, + {}, + None, + {"count": 1000, "sort_dir": "ASC", "sort_field": "updated_at", "list_id": "123", "exclude_fields": "segments._links"}, + ), + # Test case 2: state and next_page_token + ( + ListMembers, + {"list_id": "123", "since_last_changed": "2023-10-15T00:00:00Z"}, + {"123": {"last_changed": "2023-10-15T00:00:00Z"}}, + {"offset": 1000}, + { + "count": 1000, + "sort_dir": "ASC", + "sort_field": "last_changed", + "list_id": "123", + "offset": 1000, + "exclude_fields": "members._links", + "since_last_changed": "2023-10-15T00:00:00Z", + }, + ), + ], + ids=[ + "Segments: no next_page_token or state to add to request params", + "ListMembers: next_page_token and state filter added to request params", + ], +) +def test_list_child_request_params(auth, stream_class, stream_slice, stream_state, next_page_token, expected_params): + """ + Tests the request_params method for the shared MailChimpListSubStream class. + """ + stream = stream_class(authenticator=auth) + params = stream.request_params(stream_slice=stream_slice, stream_state=stream_state, next_page_token=next_page_token) + assert params == expected_params + + +@pytest.mark.parametrize( + "stream_class, current_stream_state,latest_record,expected_state", + [ + # Test case 1: current_stream_state is empty + (Segments, {}, {"list_id": "list_1", "updated_at": "2023-10-15T00:00:00Z"}, {"list_1": {"updated_at": "2023-10-15T00:00:00Z"}}), + # Test case 2: latest_record's cursor is higher than current_stream_state for list_1 and updates it + ( + Segments, + {"list_1": {"updated_at": "2023-10-14T00:00:00Z"}, "list_2": {"updated_at": "2023-10-15T00:00:00Z"}}, + {"list_id": "list_1", "updated_at": "2023-10-15T00:00:00Z"}, + {"list_1": {"updated_at": "2023-10-15T00:00:00Z"}, "list_2": {"updated_at": "2023-10-15T00:00:00Z"}}, + ), + # Test case 3: latest_record's cursor is lower than current_stream_state for list_2, no state update + ( + ListMembers, + {"list_1": {"last_changed": "2023-10-15T00:00:00Z"}, "list_2": {"last_changed": "2023-10-15T00:00:00Z"}}, + {"list_id": "list_2", "last_changed": "2023-10-14T00:00:00Z"}, + {"list_1": {"last_changed": "2023-10-15T00:00:00Z"}, "list_2": {"last_changed": "2023-10-15T00:00:00Z"}}, + ), + ( + SegmentMembers, + {"segment_1": {"last_changed": "2023-10-15T00:00:00Z"}, "segment_2": {"last_changed": "2023-10-15T00:00:00Z"}}, + {"segment_id": "segment_1", "last_changed": "2023-10-16T00:00:00Z"}, + {"segment_1": {"last_changed": "2023-10-16T00:00:00Z"}, "segment_2": {"last_changed": "2023-10-15T00:00:00Z"}}, + ), + ( + SegmentMembers, + {"segment_1": {"last_changed": "2023-10-15T00:00:00Z"}}, + {"segment_id": "segment_2", "last_changed": "2023-10-16T00:00:00Z"}, + {"segment_1": {"last_changed": "2023-10-15T00:00:00Z"}, "segment_2": {"last_changed": "2023-10-16T00:00:00Z"}}, + ) + ], + ids=[ + "Segments: no current_stream_state", + "Segments: latest_record's cursor > than current_stream_state for list_1", + "ListMembers: latest_record's cursor < current_stream_state for list_2", + "SegmentMembers: latest_record's cursor > current_stream_state for segment_1", + "SegmentMembers: no stream_state for current slice, new slice added to state" + ], +) +def test_list_child_get_updated_state(auth, stream_class, current_stream_state, latest_record, expected_state): + """ + Tests that the get_updated_state method for the shared MailChimpListSubStream class + correctly updates state only for its slice. + """ + segments_stream = stream_class(authenticator=auth) + updated_state = segments_stream.get_updated_state(current_stream_state, latest_record) + assert updated_state == expected_state + + +@pytest.mark.parametrize( + "stream_state, records, expected", + [ + # Test case 1: No stream state, all records should be yielded + ( + {}, + {"members": [ + {"id": 1, "segment_id": "segment_1", "last_changed": "2021-01-01T00:00:00Z"}, + {"id": 2, "segment_id": "segment_1", "last_changed": "2021-01-02T00:00:00Z"} + ]}, + [ + {"id": 1, "segment_id": "segment_1", "last_changed": "2021-01-01T00:00:00Z"}, + {"id": 2, "segment_id": "segment_1", "last_changed": "2021-01-02T00:00:00Z"} + ] + ), + + # Test case 2: Records older than stream state should be filtered out + ( + {"segment_1": {"last_changed": "2021-02-01T00:00:00Z"}}, + {"members": [ + {"id": 1, "segment_id": "segment_1", "last_changed": "2021-01-01T00:00:00Z"}, + {"id": 2, "segment_id": "segment_1", "last_changed": "2021-03-01T00:00:00Z"} + ]}, + [{"id": 2, "segment_id": "segment_1", "last_changed": "2021-03-01T00:00:00Z"}] + ), + + # Test case 3: Two lists in stream state, only state for segment_id_1 determines filtering + ( + {"segment_1": {"last_changed": "2021-01-02T00:00:00Z"}, "segment_2": {"last_changed": "2022-01-01T00:00:00Z"}}, + {"members": [ + {"id": 1, "segment_id": "segment_1", "last_changed": "2021-01-01T00:00:00Z"}, + {"id": 2, "segment_id": "segment_1", "last_changed": "2021-03-01T00:00:00Z"} + ]}, + [{"id": 2, "segment_id": "segment_1", "last_changed": "2021-03-01T00:00:00Z"}] + ), + ], + ids=[ + "No stream state, all records should be yielded", + "Record < stream state, should be filtered out", + "Record >= stream state, should be yielded", + ] +) +def test_segment_members_parse_response(auth, stream_state, records, expected): + segment_members_stream = SegmentMembers(authenticator=auth) + response = MagicMock() + response.json.return_value = records + parsed_records = list(segment_members_stream.parse_response(response, stream_state, stream_slice={"segment_id": "segment_1"})) + assert parsed_records == expected, f"Expected: {expected}, Actual: {parsed_records}" + + +@pytest.mark.parametrize( + "stream, record, expected_record", + [ + ( + SegmentMembers, + {"id": 1, "email_address": "a@gmail.com", "email_type": "html", "opt_timestamp": ""}, + {"id": 1, "email_address": "a@gmail.com", "email_type": "html", "opt_timestamp": None} + ), + ( + SegmentMembers, + {"id": 1, "email_address": "a@gmail.com", "email_type": "html", "opt_timestamp": "2022-01-01T00:00:00.000Z", "merge_fields": {"FNAME": "Bob", "LNAME": "", "ADDRESS": "", "PHONE": ""}}, + {"id": 1, "email_address": "a@gmail.com", "email_type": "html", "opt_timestamp": "2022-01-01T00:00:00.000Z", "merge_fields": {"FNAME": "Bob", "LNAME": None, "ADDRESS": None, "PHONE": None}} + ), + ( + Campaigns, + {"id": "1", "web_id": 2, "email_type": "html", "create_time": "2022-01-01T00:00:00.000Z", "send_time": ""}, + {"id": "1", "web_id": 2, "email_type": "html", "create_time": "2022-01-01T00:00:00.000Z", "send_time": None} + ), + ( + Reports, + {"id": "1", "type": "rss", "clicks": {"clicks_total": 1, "last_click": "2022-01-01T00:00:00Z"}, "opens": {"opens_total": 0, "last_open": ""}}, + {"id": "1", "type": "rss", "clicks": {"clicks_total": 1, "last_click": "2022-01-01T00:00:00Z"}, "opens": {"opens_total": 0, "last_open": None}} + ), + ( + Lists, + {"id": "1", "name": "Santa's List", "stats": {"last_sub_date": "2022-01-01T00:00:00Z", "last_unsub_date": ""}}, + {"id": "1", "name": "Santa's List", "stats": {"last_sub_date": "2022-01-01T00:00:00Z", "last_unsub_date": None}} + ) + ], + ids=[ + "segment_members: opt_timestamp nullified", + "segment_members: nested merge_fields nullified", + "campaigns: send_time nullified", + "reports: nested opens.last_open nullified", + "lists: stats.last_unsub_date nullified" + ] +) +def test_filter_empty_fields(auth, stream, record, expected_record): + """ + Tests that empty string values are converted to None. + """ + stream = stream(authenticator=auth) + assert stream.filter_empty_fields(record) == expected_record + + +def test_unsubscribes_stream_slices(requests_mock, unsubscribes_stream, campaigns_stream, mock_campaigns_response): + campaigns_url = campaigns_stream.url_base + campaigns_stream.path() + requests_mock.register_uri("GET", campaigns_url, json={"campaigns": mock_campaigns_response}) + + expected_slices = [{"campaign_id": "campaign_1"}, {"campaign_id": "campaign_2"}, {"campaign_id": "campaign_3"}] + slices = list(unsubscribes_stream.stream_slices(sync_mode=SyncMode.incremental)) + assert slices == expected_slices + + +@pytest.mark.parametrize( + "stream_state, expected_records", + [ + ( # Test case 1: all records >= state + {"campaign_1": {"timestamp": "2022-01-01T00:00:00Z"}}, + [ + {"campaign_id": "campaign_1", "email_id": "email_1", "timestamp": "2022-01-02T00:00:00Z"}, + {"campaign_id": "campaign_1", "email_id": "email_2", "timestamp": "2022-01-02T00:00:00Z"}, + {"campaign_id": "campaign_1", "email_id": "email_3", "timestamp": "2022-01-01T00:00:00Z"}, + {"campaign_id": "campaign_1", "email_id": "email_4", "timestamp": "2022-01-03T00:00:00Z"}, + ], + ), + ( # Test case 2: one record < state + {"campaign_1": {"timestamp": "2022-01-02T00:00:00Z"}}, + [ + {"campaign_id": "campaign_1", "email_id": "email_1", "timestamp": "2022-01-02T00:00:00Z"}, + {"campaign_id": "campaign_1", "email_id": "email_2", "timestamp": "2022-01-02T00:00:00Z"}, + {"campaign_id": "campaign_1", "email_id": "email_4", "timestamp": "2022-01-03T00:00:00Z"}, + ], + ), + ( # Test case 3: one record >= state + {"campaign_1": {"timestamp": "2022-01-03T00:00:00Z"}}, + [ + {"campaign_id": "campaign_1", "email_id": "email_4", "timestamp": "2022-01-03T00:00:00Z"}, + ], + ), + ( # Test case 4: no state, all records returned + {}, + [ + {"campaign_id": "campaign_1", "email_id": "email_1", "timestamp": "2022-01-02T00:00:00Z"}, + {"campaign_id": "campaign_1", "email_id": "email_2", "timestamp": "2022-01-02T00:00:00Z"}, + {"campaign_id": "campaign_1", "email_id": "email_3", "timestamp": "2022-01-01T00:00:00Z"}, + {"campaign_id": "campaign_1", "email_id": "email_4", "timestamp": "2022-01-03T00:00:00Z"}, + ], + ), + ], + ids=[ + "all records >= state", + "one record < state", + "one record >= state", + "no state, all records returned", + ], +) +def test_parse_response(stream_state, expected_records, unsubscribes_stream): + mock_response = MagicMock(spec=requests.Response) + mock_response.json.return_value = { + "unsubscribes": [ + {"campaign_id": "campaign_1", "email_id": "email_1", "timestamp": "2022-01-02T00:00:00Z"}, + {"campaign_id": "campaign_1", "email_id": "email_2", "timestamp": "2022-01-02T00:00:00Z"}, + {"campaign_id": "campaign_1", "email_id": "email_3", "timestamp": "2022-01-01T00:00:00Z"}, + {"campaign_id": "campaign_1", "email_id": "email_4", "timestamp": "2022-01-03T00:00:00Z"}, + ] + } + stream_slice = {"campaign_id": "campaign_1"} + records = list(unsubscribes_stream.parse_response(response=mock_response, stream_slice=stream_slice, stream_state=stream_state)) + assert records == expected_records + + +@pytest.mark.parametrize( + "latest_record, expected_updated_state", + [ + # Test case 1: latest_record > and updates the state of campaign_1 + ( + { + "email_id": "email_1", + "email_address": "address1@email.io", + "reason": "None given", + "timestamp": "2022-01-05T00:00:00Z", + "campaign_id": "campaign_1", + }, + { + "campaign_1": {"timestamp": "2022-01-05T00:00:00Z"}, + "campaign_2": {"timestamp": "2022-01-02T00:00:00Z"}, + "campaign_3": {"timestamp": "2022-01-03T00:00:00Z"}, + }, + ), + # Test case 2: latest_record > and updates the state of campaign_2 + ( + { + "email_id": "email_2", + "email_address": "address2@email.io", + "reason": "Inappropriate content", + "timestamp": "2022-01-05T00:00:00Z", + "campaign_id": "campaign_2", + }, + { + "campaign_1": {"timestamp": "2022-01-01T00:00:00Z"}, + "campaign_2": {"timestamp": "2022-01-05T00:00:00Z"}, + "campaign_3": {"timestamp": "2022-01-03T00:00:00Z"}, + }, + ), + # Test case 3: latest_record < and does not update the state of campaign_3 + ( + { + "email_id": "email_3", + "email_address": "address3@email.io", + "reason": "No longer interested", + "timestamp": "2021-01-01T00:00:00Z", + "campaign_id": "campaign_3", + }, + { + "campaign_1": {"timestamp": "2022-01-01T00:00:00Z"}, + "campaign_2": {"timestamp": "2022-01-02T00:00:00Z"}, + "campaign_3": {"timestamp": "2022-01-03T00:00:00Z"}, + }, + ), + # Test case 4: latest_record sets state campaign_4 + ( + { + "email_id": "email_4", + "email_address": "address4@email.io", + "reason": "No longer interested", + "timestamp": "2022-01-04T00:00:00Z", + "campaign_id": "campaign_4", + }, + { + "campaign_1": {"timestamp": "2022-01-01T00:00:00Z"}, + "campaign_2": {"timestamp": "2022-01-02T00:00:00Z"}, + "campaign_3": {"timestamp": "2022-01-03T00:00:00Z"}, + "campaign_4": {"timestamp": "2022-01-04T00:00:00Z"}, + }, + ), + ], + ids=[ + "latest_record > and updates the state of campaign_1", + "latest_record > and updates the state of campaign_2", + "latest_record < and does not update the state of campaign_3", + "latest_record sets state of campaign_4", + ], +) +def test_unsubscribes_get_updated_state(unsubscribes_stream, mock_unsubscribes_state, latest_record, expected_updated_state): + updated_state = unsubscribes_stream.get_updated_state(mock_unsubscribes_state, latest_record) + assert updated_state == expected_updated_state + + +@pytest.mark.parametrize( + "stream,url,status_code,response_content,expected_availability,expected_reason_substring", + [ + ( + Campaigns, + "https://some_dc.api.mailchimp.com/3.0/campaigns", + 403, + b'{"object": "error", "status": 403, "code": "restricted_resource"}', + False, + "Unable to read campaigns stream", + ), + ( + EmailActivity, + "https://some_dc.api.mailchimp.com/3.0/reports/123/email-activity", + 403, + b'{"object": "error", "status": 403, "code": "restricted_resource"}', + False, + "Unable to read email_activity stream", + ), + ( + Lists, + "https://some_dc.api.mailchimp.com/3.0/lists", + 200, + b'{ "lists": [{"id": "123", "date_created": "2022-01-01T00:00:00+000"}]}', + True, + None, + ), + ( + Lists, + "https://some_dc.api.mailchimp.com/3.0/lists", + 400, + b'{ "object": "error", "status": 404, "code": "invalid_action"}', + False, + None, + ), + ], + ids=[ + "Campaigns 403 error", + "EmailActivity 403 error", + "Lists 200 success", + "Lists 400 error", + ], +) +def test_403_error_handling( + auth, requests_mock, stream, url, status_code, response_content, expected_availability, expected_reason_substring +): + """ + Test that availability strategy flags streams with 403 error as unavailable + and returns appropriate message. + """ + + requests_mock.get(url=url, status_code=status_code, content=response_content) + + stream = stream(authenticator=auth) + + if stream.__class__.__name__ == "EmailActivity": + stream.stream_slices = MagicMock(return_value=[{"campaign_id": "123"}]) + + try: + is_available, reason = stream.check_availability(logger=logging.Logger, source=MagicMock()) + + assert is_available is expected_availability + + if expected_reason_substring: + assert expected_reason_substring in reason + else: + assert reason is None + + # Handle non-403 error + except HTTPError as e: + assert e.response.status_code == status_code + + +@pytest.mark.parametrize( + "stream, stream_slice, expected_endpoint", + [ + (Automations, {}, "automations"), + (Lists, {}, "lists"), + (Campaigns, {}, "campaigns"), + (EmailActivity, {"campaign_id": "123"}, "reports/123/email-activity"), + (InterestCategories, {"parent": {"id": "123"}}, "lists/123/interest-categories"), + (Interests, {"parent": {"list_id": "123", "id": "456"}}, "lists/123/interest-categories/456/interests"), + (ListMembers, {"list_id": "123"}, "lists/123/members"), + (Reports, {}, "reports"), + (SegmentMembers, {"list_id": "123", "segment_id": "456"}, "lists/123/segments/456/members"), + (Segments, {"list_id": "123"}, "lists/123/segments"), + (Tags, {"parent": {"id": "123"}}, "lists/123/tag-search"), + (Unsubscribes, {"campaign_id": "123"}, "reports/123/unsubscribed"), + ], + ids=[ + "Automations", + "Lists", + "Campaigns", + "EmailActivity", + "InterestCategories", + "Interests", + "ListMembers", + "Reports", + "SegmentMembers", + "Segments", + "Tags", + "Unsubscribes", + ], +) +def test_path(auth, stream, stream_slice, expected_endpoint): + """ + Test the path method for each stream. + """ + + # Add parent stream where necessary + if stream is InterestCategories or stream is Tags: + stream = stream(authenticator=auth, parent=Lists(authenticator=auth)) + elif stream is Interests: + stream = stream(authenticator=auth, parent=InterestCategories(authenticator=auth, parent=Lists(authenticator=auth))) + else: + stream = stream(authenticator=auth) + + endpoint = stream.path(stream_slice=stream_slice) + + assert endpoint == expected_endpoint, f"Stream {stream}: expected path '{expected_endpoint}', got '{endpoint}'" + + +@pytest.mark.parametrize( + "start_date, state_date, expected_return_value", + [ + ( + "2021-01-01T00:00:00.000Z", + "2020-01-01T00:00:00+00:00", + "2021-01-01T00:00:00Z" + ), + ( + "2021-01-01T00:00:00.000Z", + "2023-10-05T00:00:00+00:00", + "2023-10-05T00:00:00+00:00" + ), + ( + None, + "2022-01-01T00:00:00+00:00", + "2022-01-01T00:00:00+00:00" + ), + ( + "2020-01-01T00:00:00.000Z", + None, + "2020-01-01T00:00:00Z" + ), + ( + None, + None, + None + ) + ] +) +def test_get_filter_date(auth, start_date, state_date, expected_return_value): + """ + Tests that the get_filter_date method returns the correct date string + """ + stream = Campaigns(authenticator=auth, start_date=start_date) + result = stream.get_filter_date(start_date, state_date) + assert result == expected_return_value, f"Expected: {expected_return_value}, Actual: {result}" + + +@pytest.mark.parametrize( + "stream_class, records, filter_date, expected_return_value", + [ + ( + Unsubscribes, + [ + {"campaign_id": "campaign_1", "email_id": "email_1", "timestamp": "2022-01-02T00:00:00Z"}, + {"campaign_id": "campaign_1", "email_id": "email_2", "timestamp": "2022-01-04T00:00:00Z"}, + {"campaign_id": "campaign_1", "email_id": "email_3", "timestamp": "2022-01-03T00:00:00Z"}, + {"campaign_id": "campaign_1", "email_id": "email_4", "timestamp": "2022-01-01T00:00:00Z"}, + ], + "2022-01-02T12:00:00+00:00", + [ + {"campaign_id": "campaign_1", "email_id": "email_2", "timestamp": "2022-01-04T00:00:00Z"}, + {"campaign_id": "campaign_1", "email_id": "email_3", "timestamp": "2022-01-03T00:00:00Z"}, + ], + ), + ( + SegmentMembers, + [ + {"id": 1, "segment_id": "segment_1", "last_changed": "2021-01-04T00:00:00Z"}, + {"id": 2, "segment_id": "segment_1", "last_changed": "2021-01-01T00:00:00Z"}, + {"id": 3, "segment_id": "segment_1", "last_changed": "2021-01-03T00:00:00Z"}, + {"id": 4, "segment_id": "segment_1", "last_changed": "2021-01-02T00:00:00Z"}, + ], + None, + [ + {"id": 1, "segment_id": "segment_1", "last_changed": "2021-01-04T00:00:00Z"}, + {"id": 2, "segment_id": "segment_1", "last_changed": "2021-01-01T00:00:00Z"}, + {"id": 3, "segment_id": "segment_1", "last_changed": "2021-01-03T00:00:00Z"}, + {"id": 4, "segment_id": "segment_1", "last_changed": "2021-01-02T00:00:00Z"}, + ], + ) + ], + ids=[ + "Unsubscribes: filter_date is set, records filtered", + "SegmentMembers: filter_date is None, all records returned" + ] +) +def test_filter_old_records(auth, stream_class, records, filter_date, expected_return_value): + """ + Tests the logic for filtering old records in streams that do not support query_param filtering. + """ + stream = stream_class(authenticator=auth) + filtered_records = list(stream.filter_old_records(records, filter_date)) + assert filtered_records == expected_return_value diff --git a/source-mailchimp/unit_tests/unit_test.py b/source-mailchimp/unit_tests/unit_test.py new file mode 100644 index 0000000000..0371987d87 --- /dev/null +++ b/source-mailchimp/unit_tests/unit_test.py @@ -0,0 +1,13 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + + +from airbyte_cdk.logger import AirbyteLogger +from source_mailchimp import SourceMailchimp + + +def test_client_wrong_credentials(): + source = SourceMailchimp() + status, error = source.check_connection(logger=AirbyteLogger, config={"username": "Jonny", "apikey": "blah-blah"}) + assert not status diff --git a/source-mailchimp/unit_tests/utils.py b/source-mailchimp/unit_tests/utils.py new file mode 100644 index 0000000000..ca673999a9 --- /dev/null +++ b/source-mailchimp/unit_tests/utils.py @@ -0,0 +1,27 @@ +# +# Copyright (c) 2023 Airbyte, Inc., all rights reserved. +# + +from typing import Any, MutableMapping + +from airbyte_cdk.models import SyncMode +from airbyte_cdk.sources.streams import Stream + + +def read_incremental(stream_instance: Stream, stream_state: MutableMapping[str, Any]): + res = [] + slices = stream_instance.stream_slices(sync_mode=SyncMode.incremental, stream_state=stream_state) + for slice in slices: + records = stream_instance.read_records(sync_mode=SyncMode.incremental, stream_slice=slice, stream_state=stream_state) + for record in records: + stream_state = stream_instance.get_updated_state(stream_state, record) + res.append(record) + return res + + +def read_full_refresh(stream_instance: Stream): + records = [] + slices = stream_instance.stream_slices(sync_mode=SyncMode.full_refresh) + for slice in slices: + records.extend(list(stream_instance.read_records(stream_slice=slice, sync_mode=SyncMode.full_refresh))) + return records From 61ea27fd9cbc2f0bd6d70ee27a5d8780b712a548 Mon Sep 17 00:00:00 2001 From: Luishfs Date: Fri, 26 Apr 2024 16:07:38 -0300 Subject: [PATCH 3/5] Removing unused files & applying airbyte-to-flow changes --- source-mailchimp/README.md | 91 - source-mailchimp/acceptance-test-config.yml | 56 - .../acmeCo/automations.schema.yaml | 238 ++ source-mailchimp/acmeCo/campaigns.schema.yaml | 2300 +++++++++-------- .../acmeCo/email_activity.schema.yaml | 82 +- source-mailchimp/acmeCo/flow.yaml | 120 + .../acmeCo/list_members.schema.yaml | 232 ++ source-mailchimp/acmeCo/lists.schema.yaml | 423 +-- source-mailchimp/acmeCo/reports.schema.yaml | 788 +++--- .../acmeCo/segment_members.schema.yaml | 153 ++ source-mailchimp/acmeCo/segments.schema.yaml | 73 + .../acmeCo/unsubscribes.schema.yaml | 48 + source-mailchimp/icon.svg | 1 - .../integration_tests/__init__.py | 0 .../integration_tests/acceptance.py | 16 - .../integration_tests/configured_catalog.json | 167 -- ...ured_catalog_without_email_activities.json | 153 -- .../integration_tests/expected_records.jsonl | 17 - .../integration_tests/invalid_config.json | 4 - .../invalid_config_apikey.json | 6 - .../invalid_config_oauth.json | 8 - source-mailchimp/integration_tests/state.json | 80 - source-mailchimp/main.py | 8 - source-mailchimp/metadata.yaml | 48 - source-mailchimp/poetry.lock | 1176 +++++++-- source-mailchimp/pyproject.toml | 39 +- source-mailchimp/sample_files/catalog.json | 1370 ---------- .../sample_files/configured_catalog.json | 1381 ---------- source-mailchimp/sample_files/state.json | 11 - source-mailchimp/source_mailchimp/__main__.py | 34 + .../source_mailchimp/schemas/automations.json | 9 +- .../source_mailchimp/schemas/campaigns.json | 15 +- .../schemas/email_activity.json | 8 +- .../schemas/interest_categories.json | 3 +- .../source_mailchimp/schemas/interests.json | 3 +- .../schemas/list_members.json | 15 +- .../source_mailchimp/schemas/lists.json | 18 +- .../source_mailchimp/schemas/reports.json | 14 +- .../schemas/segment_members.json | 15 +- .../source_mailchimp/schemas/segments.json | 9 +- .../schemas/shared/campaignType.json | 10 +- .../source_mailchimp/schemas/tags.json | 3 +- .../schemas/unsubscribes.json | 10 +- source-mailchimp/source_mailchimp/spec.json | 18 +- source-mailchimp/test.flow.yaml | 55 +- .../{unit_tests => tests}/conftest.py | 0 .../{unit_tests => tests}/test_source.py | 0 .../{unit_tests => tests}/test_streams.py | 2 +- .../{unit_tests => tests}/unit_test.py | 0 .../{unit_tests => tests}/utils.py | 0 50 files changed, 3998 insertions(+), 5332 deletions(-) delete mode 100644 source-mailchimp/README.md delete mode 100644 source-mailchimp/acceptance-test-config.yml create mode 100644 source-mailchimp/acmeCo/automations.schema.yaml create mode 100644 source-mailchimp/acmeCo/list_members.schema.yaml create mode 100644 source-mailchimp/acmeCo/segment_members.schema.yaml create mode 100644 source-mailchimp/acmeCo/segments.schema.yaml create mode 100644 source-mailchimp/acmeCo/unsubscribes.schema.yaml delete mode 100644 source-mailchimp/icon.svg delete mode 100644 source-mailchimp/integration_tests/__init__.py delete mode 100644 source-mailchimp/integration_tests/acceptance.py delete mode 100644 source-mailchimp/integration_tests/configured_catalog.json delete mode 100644 source-mailchimp/integration_tests/configured_catalog_without_email_activities.json delete mode 100644 source-mailchimp/integration_tests/expected_records.jsonl delete mode 100644 source-mailchimp/integration_tests/invalid_config.json delete mode 100644 source-mailchimp/integration_tests/invalid_config_apikey.json delete mode 100644 source-mailchimp/integration_tests/invalid_config_oauth.json delete mode 100644 source-mailchimp/integration_tests/state.json delete mode 100644 source-mailchimp/main.py delete mode 100644 source-mailchimp/metadata.yaml delete mode 100644 source-mailchimp/sample_files/catalog.json delete mode 100644 source-mailchimp/sample_files/configured_catalog.json delete mode 100644 source-mailchimp/sample_files/state.json create mode 100644 source-mailchimp/source_mailchimp/__main__.py rename source-mailchimp/{unit_tests => tests}/conftest.py (100%) rename source-mailchimp/{unit_tests => tests}/test_source.py (100%) rename source-mailchimp/{unit_tests => tests}/test_streams.py (99%) rename source-mailchimp/{unit_tests => tests}/unit_test.py (100%) rename source-mailchimp/{unit_tests => tests}/utils.py (100%) diff --git a/source-mailchimp/README.md b/source-mailchimp/README.md deleted file mode 100644 index 2e6d772187..0000000000 --- a/source-mailchimp/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# Mailchimp source connector - - -This is the repository for the Mailchimp source connector, written in Python. -For information about how to use this connector within Airbyte, see [the documentation](https://docs.airbyte.com/integrations/sources/mailchimp). - -## Local development - -### Prerequisites -* Python (~=3.9) -* Poetry (~=1.7) - installation instructions [here](https://python-poetry.org/docs/#installation) - - -### Installing the connector -From this connector directory, run: -```bash -poetry install --with dev -``` - - -### Create credentials -**If you are a community contributor**, follow the instructions in the [documentation](https://docs.airbyte.com/integrations/sources/mailchimp) -to generate the necessary credentials. Then create a file `secrets/config.json` conforming to the `source_mailchimp/spec.yaml` file. -Note that any directory named `secrets` is gitignored across the entire Airbyte repo, so there is no danger of accidentally checking in sensitive information. -See `sample_files/sample_config.json` for a sample config file. - - -### Locally running the connector -``` -poetry run source-mailchimp spec -poetry run source-mailchimp check --config secrets/config.json -poetry run source-mailchimp discover --config secrets/config.json -poetry run source-mailchimp read --config secrets/config.json --catalog sample_files/configured_catalog.json -``` - -### Running unit tests -To run unit tests locally, from the connector directory run: -``` -poetry run pytest unit_tests -``` - -### Building the docker image -1. Install [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md) -2. Run the following command to build the docker image: -```bash -airbyte-ci connectors --name=source-mailchimp build -``` - -An image will be available on your host with the tag `airbyte/source-mailchimp:dev`. - - -### Running as a docker container -Then run any of the connector commands as follows: -``` -docker run --rm airbyte/source-mailchimp:dev spec -docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-mailchimp:dev check --config /secrets/config.json -docker run --rm -v $(pwd)/secrets:/secrets airbyte/source-mailchimp:dev discover --config /secrets/config.json -docker run --rm -v $(pwd)/secrets:/secrets -v $(pwd)/integration_tests:/integration_tests airbyte/source-mailchimp:dev read --config /secrets/config.json --catalog /integration_tests/configured_catalog.json -``` - -### Running our CI test suite -You can run our full test suite locally using [`airbyte-ci`](https://github.com/airbytehq/airbyte/blob/master/airbyte-ci/connectors/pipelines/README.md): -```bash -airbyte-ci connectors --name=source-mailchimp test -``` - -### Customizing acceptance Tests -Customize `acceptance-test-config.yml` file to configure acceptance tests. See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference) for more information. -If your connector requires to create or destroy resources for use during acceptance tests create fixtures for it and place them inside integration_tests/acceptance.py. - -### Dependency Management -All of your dependencies should be managed via Poetry. -To add a new dependency, run: -```bash -poetry add -``` - -Please commit the changes to `pyproject.toml` and `poetry.lock` files. - -## Publishing a new version of the connector -You've checked out the repo, implemented a million dollar feature, and you're ready to share your changes with the world. Now what? -1. Make sure your changes are passing our test suite: `airbyte-ci connectors --name=source-mailchimp test` -2. Bump the connector version (please follow [semantic versioning for connectors](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#semantic-versioning-for-connectors)): - - bump the `dockerImageTag` value in in `metadata.yaml` - - bump the `version` value in `pyproject.toml` -3. Make sure the `metadata.yaml` content is up to date. -4. Make sure the connector documentation and its changelog is up to date (`docs/integrations/sources/mailchimp.md`). -5. Create a Pull Request: use [our PR naming conventions](https://docs.airbyte.com/contributing-to-airbyte/resources/pull-requests-handbook/#pull-request-title-convention). -6. Pat yourself on the back for being an awesome contributor. -7. Someone from Airbyte will take a look at your PR and iterate with you to merge it into master. -8. Once your PR is merged, the new version of the connector will be automatically published to Docker Hub and our connector registry. \ No newline at end of file diff --git a/source-mailchimp/acceptance-test-config.yml b/source-mailchimp/acceptance-test-config.yml deleted file mode 100644 index c5aeffc157..0000000000 --- a/source-mailchimp/acceptance-test-config.yml +++ /dev/null @@ -1,56 +0,0 @@ -connector_image: airbyte/source-mailchimp:dev -test_strictness_level: high -acceptance_tests: - spec: - tests: - - spec_path: "source_mailchimp/spec.json" - connection: - tests: - # for auth with API token - - config_path: "secrets/config.json" - status: "succeed" - # for auth with oauth2 token - - config_path: "secrets/config_oauth.json" - status: "succeed" - - config_path: "integration_tests/invalid_config.json" - status: "failed" - - config_path: "integration_tests/invalid_config_apikey.json" - status: "failed" - - config_path: "integration_tests/invalid_config_oauth.json" - status: "failed" - discovery: - tests: - # for auth with API token - - config_path: "secrets/config.json" - # for auth with oauth2 token - - config_path: "secrets/config_oauth.json" - basic_read: - tests: - - config_path: "secrets/config.json" - expect_records: - path: "integration_tests/expected_records.jsonl" - fail_on_extra_columns: false - empty_streams: - - name: "automations" - bypass_reason: "Cannot seed in free sandbox account, need to upgrade to paid account." - - config_path: "secrets/config_oauth.json" - expect_records: - path: "integration_tests/expected_records.jsonl" - fail_on_extra_columns: false - empty_streams: - - name: "automations" - bypass_reason: "Cannot seed in free sandbox account, need to upgrade to paid account." - incremental: - tests: - - config_path: "secrets/config.json" - configured_catalog_path: "integration_tests/configured_catalog.json" - future_state: - future_state_path: "integration_tests/state.json" - # Email activities stream has working campaigns with email newsletters. - # Due to this sequential_reads test could be failed. - full_refresh: - tests: - - config_path: "secrets/config.json" - configured_catalog_path: "integration_tests/configured_catalog_without_email_activities.json" - - config_path: "secrets/config_oauth.json" - configured_catalog_path: "integration_tests/configured_catalog_without_email_activities.json" diff --git a/source-mailchimp/acmeCo/automations.schema.yaml b/source-mailchimp/acmeCo/automations.schema.yaml new file mode 100644 index 0000000000..a517322cc5 --- /dev/null +++ b/source-mailchimp/acmeCo/automations.schema.yaml @@ -0,0 +1,238 @@ +--- +$schema: "http://json-schema.org/draft-07/schema#" +type: object +title: Automations +additionalProperties: true +required: + - id +properties: + id: + type: string + create_time: + type: + - "null" + - string + format: date-time + start_time: + type: + - "null" + - string + format: date-time + status: + type: + - "null" + - string + emails_sent: + type: + - "null" + - number + recipients: + type: + - "null" + - object + properties: + list_id: + type: + - "null" + - string + list_is_active: + type: + - "null" + - boolean + list_name: + type: + - "null" + - string + segment_opts: + type: + - "null" + - object + properties: + saved_segment_id: + type: + - "null" + - number + match: + type: + - "null" + - string + conditions: + type: + - "null" + - array + items: + type: + - "null" + - object + additionalProperties: true + store_id: + type: + - "null" + - string + settings: + type: + - "null" + - object + properties: + title: + type: + - "null" + - string + from_name: + type: + - "null" + - string + reply_to: + type: + - "null" + - string + use_conversation: + type: + - "null" + - boolean + to_name: + type: + - "null" + - string + authenticate: + type: + - "null" + - boolean + auto_footer: + type: + - "null" + - boolean + inline_css: + type: + - "null" + - boolean + tracking: + type: + - "null" + - object + properties: + opens: + type: + - "null" + - boolean + html_clicks: + type: + - "null" + - boolean + text_clicks: + type: + - "null" + - boolean + goal_tracking: + type: + - "null" + - boolean + ecomm360: + type: + - "null" + - boolean + google_analytics: + type: + - "null" + - string + clicktale: + type: + - "null" + - string + salesforce: + type: + - "null" + - object + properties: + campaign: + type: + - "null" + - boolean + notes: + type: + - "null" + - boolean + capsule: + type: + - "null" + - object + properties: + notes: + type: + - "null" + - boolean + trigger_settings: + type: + - "null" + - object + properties: + workflow_type: + type: + - "null" + - string + workflow_title: + type: + - "null" + - string + runtime: + type: + - "null" + - object + properties: + days: + type: + - "null" + - array + items: + type: + - "null" + - string + hours: + type: + - "null" + - object + properties: + type: + type: + - "null" + - string + workflow_emails_count: + type: + - "null" + - number + report_summary: + type: + - "null" + - object + properties: + opens: + type: + - "null" + - number + unique_opens: + type: + - "null" + - number + open_rate: + type: + - "null" + - number + clicks: + type: + - "null" + - number + subscriber_clicks: + type: + - "null" + - number + click_rate: + type: + - "null" + - number + _meta: + type: object + properties: + row_id: + type: integer + required: + - row_id diff --git a/source-mailchimp/acmeCo/campaigns.schema.yaml b/source-mailchimp/acmeCo/campaigns.schema.yaml index 0f76d0092f..11711ef60e 100644 --- a/source-mailchimp/acmeCo/campaigns.schema.yaml +++ b/source-mailchimp/acmeCo/campaigns.schema.yaml @@ -1,184 +1,188 @@ --- +type: object +title: Campaign description: "A summary of an individual campaign's settings and content." +required: + - id properties: - ab_split_opts: - description: "[A/B Testing](https://mailchimp.com/help/about-ab-testing-campaigns/) options for a campaign." - properties: - from_name_a: - description: "For campaigns split on 'From Name', the name for Group A." - title: From Name Group A - type: string - from_name_b: - description: "For campaigns split on 'From Name', the name for Group B." - title: From Name Group B - type: string - pick_winner: - description: "How we should evaluate a winner. Based on 'opens', 'clicks', or 'manual'." - title: Pick Winner - type: string - reply_email_a: - description: "For campaigns split on 'From Name', the reply-to address for Group A." - title: Reply Email Group A - type: string - reply_email_b: - description: "For campaigns split on 'From Name', the reply-to address for Group B." - title: Reply Email Group B - type: string - send_time_a: - description: The send time for Group A. - title: Send Time Group A - type: string - send_time_b: - description: The send time for Group B. - title: Send Time Group B - type: string - send_time_winner: - description: The send time for the winning version. - title: Send Time Winner - type: string - split_size: - description: "The size of the split groups. Campaigns split based on 'schedule' are forced to have a 50/50 split. Valid split integers are between 1-50." - maximum: 50 - minimum: 1 - title: Split Size - type: integer - split_test: - description: The type of AB split to run. - title: Split Test - type: string - subject_a: - description: "For campaigns split on 'Subject Line', the subject line for Group A." - title: Subject Line Group A - type: string - subject_b: - description: "For campaigns split on 'Subject Line', the subject line for Group B." - title: Subject Line Group B - type: string - wait_time: - description: The amount of time to wait before picking a winner. This cannot be changed after a campaign is sent. - title: Wait Time - type: integer - wait_units: - description: "How unit of time for measuring the winner ('hours' or 'days'). This cannot be changed after a campaign is sent." - title: Wait Time - type: string + id: + type: string + title: Campaign ID + description: A string that uniquely identifies this campaign. readOnly: true - title: A/B Testing Options - type: object - archive_url: - description: "The link to the campaign's archive version in ISO 8601 format." + web_id: + type: integer + title: Campaign Web ID + description: "The ID used in the Mailchimp web application. View this campaign in your Mailchimp account at `https://{dc}.admin.mailchimp.com/campaigns/show/?id={web_id}`." readOnly: true - title: Archive URL - type: string - content_type: - description: "How the campaign's content is put together." - title: Content Type + parent_campaign_id: + type: + - "null" + - string + title: Parent Campaign ID + description: "If this campaign is the child of another campaign, this identifies the parent campaign. For Example, for RSS or Automation children." + readOnly: true + type: type: string + title: Campaign Type + description: "There are four types of [campaigns](https://mailchimp.com/help/getting-started-with-campaigns/) you can create in Mailchimp. A/B Split campaigns have been deprecated and variate campaigns should be used instead." + enum: + - automation-email + - regular + - plaintext + - absplit + - rss + - variate create_time: - description: The date and time the campaign was created in ISO 8601 format. - readOnly: true - title: Create Time type: string - delivery_status: - description: Updates on campaigns in the process of sending. - properties: - can_cancel: - description: Whether a campaign send can be canceled. - readOnly: true - title: Campaign Cancelable - type: boolean - emails_canceled: - description: The total number of emails canceled for this campaign. - readOnly: true - title: Emails Canceled - type: integer - emails_sent: - description: The total number of emails confirmed sent for this campaign so far. - readOnly: true - title: Emails Sent - type: integer - enabled: - description: Whether Campaign Delivery Status is enabled for this account and campaign. - readOnly: true - title: Delivery Status Enabled - type: boolean - status: - description: The current state of a campaign delivery. - readOnly: true - title: Campaign Delivery Status - type: string - title: Campaign Delivery Status - type: object - emails_sent: - description: The total number of emails sent for this campaign. + title: Create Time + description: The date and time the campaign was created in ISO 8601 format. readOnly: true - title: Emails Sent - type: integer - id: - description: A string that uniquely identifies this campaign. + format: date-time + archive_url: + type: + - "null" + - string + title: Archive URL + description: "The link to the campaign's archive version in ISO 8601 format." readOnly: true - title: Campaign ID - type: string long_archive_url: + type: + - "null" + - string + title: Long Archive URL description: "The original link to the campaign's archive version." readOnly: true - title: Long Archive URL + status: type: string + title: Campaign Status + description: The current status of the campaign. + enum: + - save + - paused + - schedule + - sending + - sent + - canceled + - canceling + - archived + readOnly: true + emails_sent: + type: integer + title: Emails Sent + description: The total number of emails sent for this campaign. + readOnly: true + send_time: + type: + - "null" + - string + title: Send Time + description: The date and time a campaign was sent. + readOnly: true + format: date-time + content_type: + type: + - "null" + - string + title: Content Type + description: "How the campaign's content is put together." + enum: + - template + - html + - url + - multichannel needs_block_refresh: + type: boolean + title: Needs Block Refresh description: Determines if the campaign needs its blocks refreshed by opening the web-based campaign editor. Deprecated and will always return false. readOnly: true - title: Needs Block Refresh + resendable: type: boolean - parent_campaign_id: - description: "If this campaign is the child of another campaign, this identifies the parent campaign. For Example, for RSS or Automation children." + title: Resendable + description: Determines if the campaign qualifies to be resent to non-openers. readOnly: true - title: Parent Campaign ID - type: string recipients: + type: object + title: List description: List settings for the campaign. properties: list_id: - description: The unique list id. + type: + - "null" + - string title: List ID - type: string + description: The unique list id. list_is_active: + type: boolean + title: List Status description: "The status of the list used, namely if it's deleted or disabled." readOnly: true - title: List Status - type: boolean list_name: + type: + - "null" + - string + title: List Name description: The name of the list. readOnly: true - title: List Name - type: string + segment_text: + type: + - "null" + - string + title: Segment Text + description: "A description of the [segment](https://mailchimp.com/help/create-and-send-to-a-segment/) used for the campaign. Formatted as a string marked up with HTML." + readOnly: true recipient_count: + type: integer + title: Recipient Count description: Count of the recipients on the associated list. Formatted as an integer. readOnly: true - title: Recipient Count - type: integer segment_opts: + type: object + title: Segment Options description: "An object representing all segmentation options. This object should contain a `saved_segment_id` to use an existing segment, or you can create a new segment by including both `match` and `conditions` options." properties: + saved_segment_id: + type: integer + title: Saved Segment ID + description: The id for an existing saved segment. + prebuilt_segment_id: + type: string + title: Prebuilt Segment Id + description: "The prebuilt segment id, if a prebuilt segment has been designated for this campaign." + example: subscribers-female + match: + type: string + title: Match Type + description: Segment match type. + enum: + - any + - all conditions: + type: array + title: Segment Type description: "Segment match conditions. There are multiple possible types, see the [condition types documentation](https://mailchimp.com/developer/marketing/docs/alternative-schemas/#segment-condition-schemas)." items: + x-discriminator: + propertyName: condition_type oneOf: - - description: Segment by interaction with a specific campaign. + - type: object + title: Aim Segment + description: Segment by interaction with a specific campaign. properties: condition_type: - enum: - - Aim type: string x-value: Aim + enum: + - Aim field: - description: Segment by interaction with a specific campaign. + type: string enum: - aim - example: aim title: Segment Field - type: string + description: Segment by interaction with a specific campaign. + example: aim op: - description: "The status of the member with regard to their campaign interaction. One of the following: opened, clicked, was sent, didn't open, didn't click, or was not sent." + type: string enum: - open - click @@ -186,140 +190,139 @@ properties: - noopen - noclick - nosent - example: open title: Segment Operator - type: string + description: "The status of the member with regard to their campaign interaction. One of the following: opened, clicked, was sent, didn't open, didn't click, or was not sent." + example: open value: + type: string + title: Segment Data description: "Either the web id value for a specific campaign or 'any' to account for subscribers who have/have not interacted with any campaigns." example: any - title: Segment Data - type: string - title: Aim Segment - type: object - - description: Segment by interaction with an Automation workflow. + - type: object + title: Automation Segment + description: Segment by interaction with an Automation workflow. + required: + - field + - op + - value properties: condition_type: - enum: - - Automation type: string x-value: Automation + enum: + - Automation field: - description: Segment by interaction with an Automation workflow. + type: string enum: - automation - example: automation title: Segment Field - type: string + description: Segment by interaction with an Automation workflow. + example: automation op: - description: "The status of the member with regard to the automation workflow. One of the following: has started the workflow, has completed the workflow, has not started the workflow, or has not completed the workflow." + type: string enum: - started - completed - not_started - not_completed - example: started title: Segment Operator - type: string + description: "The status of the member with regard to the automation workflow. One of the following: has started the workflow, has completed the workflow, has not started the workflow, or has not completed the workflow." + example: started value: + type: string + title: Segment Data description: The web id for the automation workflow to segment against. example: "2135217" - title: Segment Data - type: string + - type: object + title: Poll Activity Segment + description: Segment by poll activity. required: - field - op - value - title: Automation Segment - type: object - - description: Segment by poll activity. properties: condition_type: - enum: - - CampaignPoll type: string x-value: CampaignPoll + enum: + - CampaignPoll field: - description: Segment by poll activity. + type: string enum: - poll - example: poll title: Segment Field - type: string + description: Segment by poll activity. + example: poll op: - description: Members have/have not interacted with a specific poll in a Mailchimp email. + type: string enum: - member - notmember - example: member title: Segment Operator - type: string + description: Members have/have not interacted with a specific poll in a Mailchimp email. + example: member value: + type: number + title: Segment Operator description: The id for the poll. example: 409 - title: Segment Operator - type: number + - type: object + title: Conversation Segment + description: Segment by interaction with a campaign via Conversations. required: - field - op - value - title: Poll Activity Segment - type: object - - description: Segment by interaction with a campaign via Conversations. properties: condition_type: - enum: - - Conversation type: string x-value: Conversation + enum: + - Conversation field: - description: Segment by interaction with a campaign via Conversations. + type: string enum: - conversation - example: conversation title: Segment Field - type: string + description: Segment by interaction with a campaign via Conversations. + example: conversation op: - description: "The status of a member's interaction with a conversation. One of the following: has replied or has not replied." + type: string enum: - member - notmember - example: member title: Segment Operator - type: string + description: "The status of a member's interaction with a conversation. One of the following: has replied or has not replied." + example: member value: + type: string + title: Segment Data description: "The web id value for a specific campaign or 'any' to account for subscribers who have/have not interacted with any campaigns." example: any - title: Segment Data - type: string + - type: object + title: Date Segment + description: Segment by a specific date field. required: - field - op - value - title: Conversation Segment - type: object - - description: Segment by a specific date field. properties: condition_type: - enum: - - Date type: string x-value: Date - extra: - description: "When segmenting on 'date' or 'campaign', the date for the segment formatted as YYYY-MM-DD or the web id for the campaign." - example: 2015-01-30 - title: Segment Extra Value - type: string + enum: + - Date field: - description: "The type of date field to segment on: The opt-in time for a signup, the date the subscriber was last updated, or the date of their last ecomm purchase." + type: string enum: - timestamp_opt - info_changed - ecomm_date - example: timestamp_opt title: Segment Field - type: string + description: "The type of date field to segment on: The opt-in time for a signup, the date the subscriber was last updated, or the date of their last ecomm purchase." + example: timestamp_opt op: - description: "When the event took place: Before, after, is a specific date, is not a specific date, is blank, or is not blank." + type: string enum: - greater - less @@ -329,266 +332,267 @@ properties: - blank_not - within - notwithin - example: greater title: Segment Operator - type: string + description: "When the event took place: Before, after, is a specific date, is not a specific date, is blank, or is not blank." + example: greater value: + type: string + title: Segment Data description: "What type of data to segment on: a specific date, a specific campaign, or the last campaign sent." example: date - title: Segment Data + extra: type: string + title: Segment Extra Value + description: "When segmenting on 'date' or 'campaign', the date for the segment formatted as YYYY-MM-DD or the web id for the campaign." + example: 2015-01-30 + - type: object + title: Email Client Segment + description: Segment by use of a particular email client. required: - field - op - value - title: Date Segment - type: object - - description: Segment by use of a particular email client. properties: condition_type: - enum: - - EmailClient type: string x-value: EmailClient + enum: + - EmailClient field: - description: Segment by use of a particular email client. + type: string enum: - email_client - example: email_client title: Segment Field - type: string + description: Segment by use of a particular email client. + example: email_client op: - description: "The operation to determine whether we select clients that match the value, or clients that do not match the value." + type: string enum: - client_is - client_not - example: client_is title: Segment Operator - type: string + description: "The operation to determine whether we select clients that match the value, or clients that do not match the value." + example: client_is value: + type: string + title: Segment Data description: The name of the email client. example: Gmail - title: Segment Data - type: string + - type: object + title: Language Segment + description: Segment by language. required: - field - op - value - title: Email Client Segment - type: object - - description: Segment by language. properties: condition_type: - enum: - - Language type: string x-value: Language + enum: + - Language field: - description: "Segmenting based off of a subscriber's language." + type: string enum: - language - example: language title: Segment Field - type: string + description: "Segmenting based off of a subscriber's language." + example: language op: - description: "Whether the member's language is or is not set to a specific language." + type: string enum: - is - not - example: is title: Segment Operator - type: string + description: "Whether the member's language is or is not set to a specific language." + example: is value: + type: string + title: Segment Data description: A two-letter language identifier. example: en - title: Segment Data - type: string + - type: object + title: Member Rating Segment + description: Segment by member rating. required: - field - op - value - title: Language Segment - type: object - - description: Segment by member rating. properties: condition_type: - enum: - - MemberRating type: string x-value: MemberRating + enum: + - MemberRating field: - description: Segment by member rating. + type: string enum: - rating - example: rating title: Segment Field - type: string + description: Segment by member rating. + example: rating op: - description: Members who have have a rating that is/not exactly a given number or members who have a rating greater/less than a given number. + type: string enum: - is - not - greater - less - example: greater title: Segment Operator - type: string + description: Members who have have a rating that is/not exactly a given number or members who have a rating greater/less than a given number. + example: greater value: + type: number + title: Segment Operator description: The star rating number to segment against. example: 4 - title: Segment Operator - type: number + - type: object + title: Signup Source Segment + description: Segment by signup source. required: - field + - condition_type - op - - value - title: Member Rating Segment - type: object - - description: Segment by signup source. properties: condition_type: + type: string enum: - SignupSource - title: Type - type: string x-value: SignupSource + title: Type field: + type: string enum: - source - example: source title: Segment Field - type: string + example: source op: - description: "Whether the member's signup source was/was not a particular value." + type: string enum: - source_is - source_not - example: source_is title: Segment Operator - type: string + description: "Whether the member's signup source was/was not a particular value." + example: source_is value: + type: string + title: Segment Data description: The signup source. example: List Import - title: Segment Data - type: string + - type: object + title: SurveyMonkey Segment + description: Segment by interaction with a SurveyMonkey survey. required: - field - - condition_type - op - title: Signup Source Segment - type: object - - description: Segment by interaction with a SurveyMonkey survey. + - value properties: condition_type: - enum: - - SurveyMonkey type: string x-value: SurveyMonkey + enum: + - SurveyMonkey field: - description: Segment by interaction with a SurveyMonkey survey. + type: string enum: - survey_monkey - example: survey_monkey title: Segment Field - type: string + description: Segment by interaction with a SurveyMonkey survey. + example: survey_monkey op: - description: "The status of the member with regard to the survey. One of the following: has started the survey, has completed the survey, has not started the survey, or has not completed the survey." + type: string enum: - started - completed - not_started - not_completed - example: started title: Segment Operator - type: string + description: "The status of the member with regard to the survey. One of the following: has started the survey, has completed the survey, has not started the survey, or has not completed the survey." + example: started value: + type: string + title: Survey ID description: The unique ID of the SurveyMonkey survey. example: "32179586" - title: Survey ID - type: string + - type: object + title: VIP Segment + description: Segment by VIP status. required: - field - op - - value - title: SurveyMonkey Segment - type: object - - description: Segment by VIP status. properties: condition_type: - enum: - - VIP type: string x-value: VIP + enum: + - VIP field: - description: Segment by VIP status. + type: string enum: - gmonkey - example: gmonkey title: Segment Field - type: string + description: Segment by VIP status. + example: gmonkey op: - description: Whether the member is or is not marked as VIP. + type: string enum: - member - notmember - example: member title: Segment Operator - type: string - required: - - field - - op - title: VIP Segment - type: object - - description: Segment by an interest group merge field. + description: Whether the member is or is not marked as VIP. + example: member + - type: object + title: Interests Segment + description: Segment by an interest group merge field. properties: condition_type: - enum: - - Interests type: string x-value: Interests + enum: + - Interests field: + type: string + title: Segment Field description: "Segmenting based on interest group information. This should start with 'interests-' followed by the grouping id. Ex. 'interests-123'." example: interests-123 - title: Segment Field - type: string op: - description: "Whether the member is a part of one, all, or none of the groups." + type: string enum: - interestcontains - interestcontainsall - interestnotcontains - example: interestcontains title: Segment Operator - type: string + description: "Whether the member is a part of one, all, or none of the groups." + example: interestcontains value: + type: array + title: Segment Value description: "An array containing strings, each representing a group id." items: + type: string example: - "44401" - "44405" - "44409" - type: string - title: Segment Value - type: array - title: Interests Segment - type: object - - description: Segment by purchases in specific items or categories. + - type: object + title: Ecommerce Category Segment + description: Segment by purchases in specific items or categories. properties: condition_type: - enum: - - EcommCategory type: string x-value: EcommCategory + enum: + - EcommCategory field: - description: Segment by purchases in specific items or categories. + type: string enum: - ecomm_cat - ecomm_prod - example: ecomm_cat title: Segment Field - type: string + description: Segment by purchases in specific items or categories. + example: ecomm_cat op: - description: "A member who has purchased from a category/specific item that is/is not a specific name, where the category/item name contains/doesn't contain a specific phrase or string, or a category/item name that starts/ends with a string." + type: string enum: - is - not @@ -596,153 +600,157 @@ properties: - notcontain - starts - ends - example: is title: Segment Operator - type: string + description: "A member who has purchased from a category/specific item that is/is not a specific name, where the category/item name contains/doesn't contain a specific phrase or string, or a category/item name that starts/ends with a string." + example: is value: + type: string + title: Segment Data description: The ecommerce category/item information. example: Product - title: Segment Data - type: string - title: Ecommerce Category Segment - type: object - - description: "Segment by average spent total, number of orders, total number of products purchased, or average number of products per order." + - type: object + title: Ecommerce Number Segment + description: "Segment by average spent total, number of orders, total number of products purchased, or average number of products per order." + required: + - field + - op + - value properties: condition_type: - enum: - - EcommNumber type: string x-value: EcommNumber + enum: + - EcommNumber field: - description: "Segment by average spent total, number of orders, total number of products purchased, or average number of products per order." + type: string enum: - ecomm_spent_avg - ecomm_orders - ecomm_prod_all - ecomm_avg_ord - example: ecomm_orders title: Segment Field - type: string + description: "Segment by average spent total, number of orders, total number of products purchased, or average number of products per order." + example: ecomm_orders op: - description: "Members who have spent exactly, have not spent exactly, spent more, or spent less than the segment value." + type: string enum: - is - not - greater - less - example: greater title: Segment Operator - type: string + description: "Members who have spent exactly, have not spent exactly, spent more, or spent less than the segment value." + example: greater value: + type: number + title: Segment Operator description: "Members who have spent exactly, have not spent exactly, spent more, or spent less than this amount." example: 42 - title: Segment Operator - type: number - required: - - field - - op - - value - title: Ecommerce Number Segment - type: object - - description: Segment by whether someone has purchased anything. + - type: object + title: Ecommerce Purchased Segment + description: Segment by whether someone has purchased anything. properties: condition_type: - enum: - - EcommPurchased type: string x-value: EcommPurchased + enum: + - EcommPurchased field: - description: Segment by whether someone has purchased anything. + type: string enum: - ecomm_purchased - example: ecomm_purchased title: Segment Field - type: string + description: Segment by whether someone has purchased anything. + example: ecomm_purchased op: - description: "Members who have have ('member') or have not ('notmember') purchased." + type: string enum: - member - notmember - example: member title: Segment Operator - type: string - title: Ecommerce Purchased Segment - type: object - - description: Segment by amount spent on a single order or across all orders. + description: "Members who have have ('member') or have not ('notmember') purchased." + example: member + - type: object + title: Ecommerce Spent Segment + description: Segment by amount spent on a single order or across all orders. properties: condition_type: - enum: - - EcommSpent type: string x-value: EcommSpent + enum: + - EcommSpent field: - description: Segment by amount spent on a single order or across all orders. + type: string enum: - ecomm_spent_one - ecomm_spent_all - example: ecomm_spent_one title: Segment Field - type: string + description: Segment by amount spent on a single order or across all orders. + example: ecomm_spent_one op: - description: "Members who have spent 'more' or 'less' than then specified value." + type: string enum: - greater - less - example: greater title: Segment Operator - type: string + description: "Members who have spent 'more' or 'less' than then specified value." + example: greater value: + type: integer + title: Segment Data description: The total amount a member spent. example: 42 - title: Segment Data - type: integer - title: Ecommerce Spent Segment - type: object - - description: Segment by purchases from a specific store. + - type: object + title: Ecommerce Purchased Store Segment + description: Segment by purchases from a specific store. properties: condition_type: - enum: - - EcommStore type: string x-value: EcommStore + enum: + - EcommStore field: - description: Segment by purchases from a specific store. + type: string enum: - ecomm_store - example: ecomm_store title: Segment Field - type: string + description: Segment by purchases from a specific store. + example: ecomm_store op: - description: Members who have or have not purchased from a specific store. + type: string enum: - is - not - example: is title: Segment Operator - type: string + description: Members who have or have not purchased from a specific store. + example: is value: + type: string + title: Segment Operator description: The store id to segment against. example: "289" - title: Segment Operator - type: string - title: Ecommerce Purchased Store Segment - type: object - - description: Segment by Goal activity. + - type: object + title: Goal Activity Segment + description: Segment by Goal activity. + required: + - field + - op + - value properties: condition_type: - enum: - - GoalActivity type: string x-value: GoalActivity + enum: + - GoalActivity field: - description: Segment by Goal activity. + type: string enum: - goal - example: goal title: Segment Field - type: string + description: Segment by Goal activity. + example: goal op: - description: "Whether the website URL is/not exactly, contains/doesn't contain, starts with/ends with a string." + type: string enum: - is - goal_not @@ -750,435 +758,435 @@ properties: - goal_notcontain - starts - ends - example: is title: Segment Operator - type: string + description: "Whether the website URL is/not exactly, contains/doesn't contain, starts with/ends with a string." + example: is value: - description: The URL to check Goal activity against. - title: Segment Value type: string + title: Segment Value + description: The URL to check Goal activity against. + - type: object + title: Goal Timestamp Segment + description: Segment by most recent interaction with a website. required: - field - op - value - title: Goal Activity Segment - type: object - - description: Segment by most recent interaction with a website. properties: condition_type: - enum: - - GoalTimestamp type: string x-value: GoalTimestamp + enum: + - GoalTimestamp field: - description: Segment by most recent interaction with a website. + type: string enum: - goal_last_visited - example: goal_last_visited title: Segment Field - type: string + description: Segment by most recent interaction with a website. + example: goal_last_visited op: - description: "Whether the website activity happened after, before, or at a given timestamp." + type: string enum: - greater - less - is - example: greater title: Segment Operator - type: string + description: "Whether the website activity happened after, before, or at a given timestamp." + example: greater value: + type: string + title: Segment Value description: The date to check Goal activity against. example: "2015-07-20 19:45:21" - title: Segment Value - type: string + - type: object + title: Similar Subscribers Segment Member Segment + description: Segment by similar subscribers. required: - field - op - value - title: Goal Timestamp Segment - type: object - - description: Segment by similar subscribers. properties: condition_type: - enum: - - FuzzySegment type: string x-value: FuzzySegment + enum: + - FuzzySegment field: - description: Segment by similar subscribers. + type: string enum: - fuzzy_segment - example: fuzzy_segment title: Segment Field - type: string + description: Segment by similar subscribers. + example: fuzzy_segment op: - description: "Members who are/are not apart of a 'similar subscribers' segment." + type: string enum: - fuzzy_is - fuzzy_not - example: fuzzy_is title: Segment Operator - type: string + description: "Members who are/are not apart of a 'similar subscribers' segment." + example: fuzzy_is value: + type: number + title: Segment Operator description: "The id for the 'similar subscribers' segment." example: 48433 - title: Segment Operator - type: number + - type: object + title: Static Segment Member Segment + description: Segment by a given static segment. required: - field - op - value - title: Similar Subscribers Segment Member Segment - type: object - - description: Segment by a given static segment. properties: condition_type: - enum: - - StaticSegment type: string x-value: StaticSegment + enum: + - StaticSegment field: - description: Segment by a given static segment. + type: string enum: - static_segment - example: static_segment title: Segment Field - type: string + description: Segment by a given static segment. + example: static_segment op: - description: Members who are/are not apart of a static segment. + type: string enum: - static_is - static_not - example: static_is title: Segment Operator - type: string + description: Members who are/are not apart of a static segment. + example: static_is value: + type: number + title: Segment Operator description: The id for the static segment. example: 48433 - title: Segment Operator - type: number + - type: object + title: Location-Based Segment + description: Segment by a specific country or US state. required: - field - op - value - title: Static Segment Member Segment - type: object - - description: Segment by a specific country or US state. properties: condition_type: - enum: - - IPGeoCountryState type: string x-value: IPGeoCountryState + enum: + - IPGeoCountryState field: - description: Segmenting subscribers who are within a specific location. + type: string enum: - ipgeo - example: ipgeo title: Segment Field - type: string + description: Segmenting subscribers who are within a specific location. + example: ipgeo op: - description: Segment members who are within a specific country or US state. + type: string enum: - ipgeocountry - ipgeonotcountry - ipgeostate - ipgeonotstate - example: ipgeocountry title: Segment Operator - type: string + description: Segment members who are within a specific country or US state. + example: ipgeocountry value: + type: string + title: Segment Data description: The two-letter country code or US state abbreviation. example: US - title: Segment Data - type: string + - type: object + title: Geolocation Segment + description: Segment by a specific geographic region. required: - field - op - value - title: Location-Based Segment - type: object - - description: Segment by a specific geographic region. + - addr + - lat + - lng properties: - addr: - description: The address of the target location. - example: "Atlanta, GA, USA" - title: Segment Location Address - type: string condition_type: - enum: - - IPGeoIn type: string x-value: IPGeoIn + enum: + - IPGeoIn field: - description: Segmenting subscribers who are within a specific location. + type: string enum: - ipgeo - example: ipgeo title: Segment Field - type: string - lat: - description: The latitude of the target location. - example: "33.7489954" - title: Segment Location Latitude - type: string - lng: - description: The longitude of the target location. - example: "-84.3879824" - title: Segment Location Longitude - type: string + description: Segmenting subscribers who are within a specific location. + example: ipgeo op: - description: Segment members who are within a specific geographic region. + type: string enum: - ipgeoin - ipgeonotin - example: ipgeoin title: Segment Operator - type: string + description: Segment members who are within a specific geographic region. + example: ipgeoin value: + type: integer + title: Segment Data description: The radius of the target location. example: 42 - title: Segment Data - type: integer + addr: + type: string + title: Segment Location Address + description: The address of the target location. + example: "Atlanta, GA, USA" + lat: + type: string + title: Segment Location Latitude + description: The latitude of the target location. + example: "33.7489954" + lng: + type: string + title: Segment Location Longitude + description: The longitude of the target location. + example: "-84.3879824" + - type: object + title: US Zip Code Segment + description: Segment by a specific US ZIP code. required: - field - op - value - - addr - - lat - - lng - title: Geolocation Segment - type: object - - description: Segment by a specific US ZIP code. + - extra properties: condition_type: - enum: - - IPGeoInZip type: string x-value: IPGeoInZip - extra: - description: The zip code to segment against. - example: 30318 - title: Extra Data - type: integer + enum: + - IPGeoInZip field: - description: Segmenting subscribers who are within a specific location. + type: string enum: - ipgeo - example: ipgeo title: Segment Field - type: string + description: Segmenting subscribers who are within a specific location. + example: ipgeo op: - description: Segment members who are within a specific US zip code. + type: string enum: - ipgeoinzip - example: ipgeoinzip title: Segment Operator - type: string + description: Segment members who are within a specific US zip code. + example: ipgeoinzip value: + type: integer + title: Segment Data description: The radius of the target location. example: 25 - title: Segment Data + extra: type: integer + title: Extra Data + description: The zip code to segment against. + example: 30318 + - type: object + title: Unknown Location-Based Segment + description: Segment members whose location information is unknown. required: - field - op - - value - - extra - title: US Zip Code Segment - type: object - - description: Segment members whose location information is unknown. properties: condition_type: - enum: - - IPGeoUnknown type: string x-value: IPGeoUnknown + enum: + - IPGeoUnknown field: - description: Segmenting subscribers who are within a specific location. + type: string enum: - ipgeo - example: ipgeo title: Segment Field - type: string + description: Segmenting subscribers who are within a specific location. + example: ipgeo op: - description: Segment members for which location information is unknown. + type: string enum: - ipgeounknown - example: ipgeounknown title: Segment Operator - type: string + description: Segment members for which location information is unknown. + example: ipgeounknown + - type: object + title: Zip Code Location-Based Segment + description: Segment by a specific US ZIP code. required: - field - op - title: Unknown Location-Based Segment - type: object - - description: Segment by a specific US ZIP code. + - value properties: condition_type: - enum: - - IPGeoZip type: string x-value: IPGeoZip + enum: + - IPGeoZip field: - description: Segmenting subscribers who are within a specific location. + type: string enum: - ipgeo - example: ipgeo title: Segment Field - type: string + description: Segmenting subscribers who are within a specific location. + example: ipgeo op: - description: Segment members who are/are not within a specific US zip code. + type: string enum: - ipgeoiszip - ipgeonotzip - example: ipgeonotzip title: Segment Operator - type: string + description: Segment members who are/are not within a specific US zip code. + example: ipgeonotzip value: + type: integer + title: Segment Data description: The 5-digit zip code. example: 30318 - title: Segment Data - type: integer + - type: object + title: Social Profiles Age Segment + description: Segment by age ranges in Social Profiles data. required: - field - op - value - title: Zip Code Location-Based Segment - type: object - - description: Segment by age ranges in Social Profiles data. properties: condition_type: - enum: - - SocialAge type: string x-value: SocialAge + enum: + - SocialAge field: - description: Segment by age ranges in Social Profiles data. + type: string enum: - social_age - example: social_age title: Segment Field - type: string + description: Segment by age ranges in Social Profiles data. + example: social_age op: - description: Members who are/not the exact criteria listed. + type: string enum: - is - not - example: is title: Segment Operator - type: string + description: Members who are/not the exact criteria listed. + example: is value: - description: The age range to segment. + type: string enum: - 18-24 - 25-34 - 35-54 - 55+ - example: 35-54 title: Segment Operator - type: string + description: The age range to segment. + example: 35-54 + - type: object + title: Social Profiles Gender Segment + description: Segment by listed gender in Social Profiles data. required: - field - op - value - title: Social Profiles Age Segment - type: object - - description: Segment by listed gender in Social Profiles data. properties: condition_type: - enum: - - SocialGender type: string x-value: SocialGender + enum: + - SocialGender field: - description: Segment by listed gender in Social Profiles data. + type: string enum: - social_gender - example: social_gender title: Segment Field - type: string + description: Segment by listed gender in Social Profiles data. + example: social_gender op: - description: Members who are/not the exact criteria listed. + type: string enum: - is - not - example: is title: Segment Operator - type: string + description: Members who are/not the exact criteria listed. + example: is value: - description: The Social Profiles gender to segment. + type: string enum: - male - female - example: female title: Segment Operator - type: string + description: The Social Profiles gender to segment. + example: female + - type: object + title: Social Profiles Influence Segment + description: Segment by influence rating in Social Profiles data. required: - field - op - value - title: Social Profiles Gender Segment - type: object - - description: Segment by influence rating in Social Profiles data. properties: condition_type: - enum: - - SocialInfluence type: string x-value: SocialInfluence + enum: + - SocialInfluence field: - description: Segment by influence rating in Social Profiles data. + type: string enum: - social_influence - example: social_influence title: Segment Field - type: string + description: Segment by influence rating in Social Profiles data. + example: social_influence op: - description: Members who have a rating that is/not or greater/less than the rating provided. + type: string enum: - is - not - greater - less - example: greater title: Segment Operator - type: string + description: Members who have a rating that is/not or greater/less than the rating provided. + example: greater value: + type: number + title: Segment Operator description: The Social Profiles influence rating to segment. example: 2 - title: Segment Operator - type: number + - type: object + title: Social Profiles Social Network Segment + description: Segment by social network in Social Profiles data. required: - field - op - value - title: Social Profiles Influence Segment - type: object - - description: Segment by social network in Social Profiles data. properties: condition_type: - enum: - - SocialNetworkMember type: string x-value: SocialNetworkMember + enum: + - SocialNetworkMember field: - description: Segment by social network in Social Profiles data. + type: string enum: - social_network - example: social_network title: Segment Field - type: string + description: Segment by social network in Social Profiles data. + example: social_network op: - description: Members who are/not on a given social network. + type: string enum: - member - notmember - example: member title: Segment Operator - type: string + description: Members who are/not on a given social network. + example: member value: - description: The social network to segment against. + type: string enum: - twitter - facebook @@ -1191,164 +1199,163 @@ properties: - vimeo - yelp - youtube - example: twitter title: Segment Operator - type: string + description: The social network to segment against. + example: twitter + - type: object + title: Social Profiles Social Network Follow Segment + description: Segment by social network in Social Profiles data. required: - field - op - value - title: Social Profiles Social Network Segment - type: object - - description: Segment by social network in Social Profiles data. properties: condition_type: - enum: - - SocialNetworkFollow type: string x-value: SocialNetworkFollow + enum: + - SocialNetworkFollow field: - description: Segment by social network in Social Profiles data. + type: string enum: - social_network - example: social_network title: Segment Field - type: string + description: Segment by social network in Social Profiles data. + example: social_network op: - description: Members who are/not following a linked account on a given social network. + type: string enum: - follow - notfollow - example: follow title: Segment Operator - type: string + description: Members who are/not following a linked account on a given social network. + example: follow value: - description: The social network to segment against. + type: string enum: - twitter_follow - example: twitter_follow title: Segment Operator - type: string + description: The social network to segment against. + example: twitter_follow + - type: object + title: Address Merge Field Segment + description: Segment by an address-type merge field. required: - field - op - - value - title: Social Profiles Social Network Follow Segment - type: object - - description: Segment by an address-type merge field. properties: condition_type: - enum: - - AddressMerge type: string x-value: AddressMerge + enum: + - AddressMerge field: + type: string + title: Segment Field description: An address-type merge field to segment. example: MMERGE3 - title: Segment Field - type: string op: - description: "Whether the member's address merge field contains/does not contain a value or is/is not blank." + type: string enum: - contains - notcontain - blank - blank_not - example: contains title: Segment Operator - type: string + description: "Whether the member's address merge field contains/does not contain a value or is/is not blank." + example: contains value: + type: string + title: Segment Value description: The value to segment a text merge field with. example: Atlanta - title: Segment Value - type: string + - type: object + title: Address/Zip Merge Field Segment + description: Segment by an address-type merge field within a given distance. required: - field - op - title: Address Merge Field Segment - type: object - - description: Segment by an address-type merge field within a given distance. + - value + - extra properties: condition_type: - enum: - - ZipMerge type: string x-value: ZipMerge - extra: - description: The city or the zip being used to segment against. - example: "30318" - title: Segment Extra - type: string + enum: + - ZipMerge field: + type: string + title: Segment Field description: An address or zip-type merge field to segment. example: MMERGE2 - title: Segment Field - type: string op: - description: "Whether the member's address merge field is within a given distance from a city or zip." + type: string enum: - geoin - example: geoin title: Segment Operator - type: string + description: "Whether the member's address merge field is within a given distance from a city or zip." + example: geoin value: + type: string + title: Segment Value description: The distance from the city/zip. example: "25" - title: Segment Value + extra: type: string + title: Segment Extra + description: The city or the zip being used to segment against. + example: "30318" + - type: object + title: Birthday Merge Field Segment + description: "Segment by a contact's birthday." required: - field - op - - value - - extra - title: Address/Zip Merge Field Segment - type: object - - description: "Segment by a contact's birthday." properties: condition_type: - enum: - - BirthdayMerge type: string x-value: BirthdayMerge + enum: + - BirthdayMerge field: + type: string + title: Segment Field description: A date merge field to segment. example: MMERGE4 - title: Segment Field - type: string op: - description: "Whether the member's birthday merge information is/is not a certain date or is/is not blank." + type: string enum: - is - not - blank - blank_not - example: is title: Segment Operator - type: string + description: "Whether the member's birthday merge information is/is not a certain date or is/is not blank." + example: is value: + type: string + title: Segment Value description: A date to segment against (mm/dd). example: 01/30 - title: Segment Value - type: string + - type: object + title: Date Merge Field Segment + description: Segment by a given date merge field. required: - field - op - title: Birthday Merge Field Segment - type: object - - description: Segment by a given date merge field. properties: condition_type: - enum: - - DateMerge type: string x-value: DateMerge + enum: + - DateMerge field: + type: string + title: Segment Field description: A date merge field to segment. example: MMERGE5 - title: Segment Field - type: string op: - description: "Whether the member's merge information is/is not, is greater/less than a value or is/is not blank." + type: string enum: - is - not @@ -1356,33 +1363,33 @@ properties: - blank - blank_not - greater - example: is title: Segment Operator - type: string + description: "Whether the member's merge information is/is not, is greater/less than a value or is/is not blank." + example: is value: + type: string + title: Segment Value description: A date to segment against. example: 01/30/2015 - title: Segment Value - type: string + - type: object + title: Dropdown/Radio Merge Field Segment + description: An individual segment condition required: - field - op - title: Date Merge Field Segment - type: object - - description: An individual segment condition properties: condition_type: - enum: - - SelectMerge type: string x-value: SelectMerge + enum: + - SelectMerge field: + type: string + title: Segment Field description: A merge field to segment. example: MMERGE6 - title: Segment Field - type: string op: - description: "Whether the member's merge information is/is not a value or is/is not blank." + type: string enum: - is - not @@ -1390,33 +1397,33 @@ properties: - blank_not - notcontain - contains - example: is title: Segment Operator - type: string + description: "Whether the member's merge information is/is not a value or is/is not blank." + example: is value: + type: string + title: Segment Value description: The value to segment a text merge field with. example: Second Choice - title: Segment Value - type: string + - type: object + title: Text or Number Merge Field Segment + description: Segment by a given text or number merge field. required: - field - op - title: Dropdown/Radio Merge Field Segment - type: object - - description: Segment by a given text or number merge field. properties: condition_type: - enum: - - TextMerge type: string x-value: TextMerge + enum: + - TextMerge field: + type: string + title: Segment Field description: A text or number merge field to segment. example: MMERGE7 - title: Segment Field - type: string op: - description: "Whether the member's merge information is/is not, contains/does not contain, starts/ends with, or is greater/less than a value" + type: string enum: - is - not @@ -1428,36 +1435,36 @@ properties: - less - blank - blank_not - example: contains title: Segment Operator - type: string + description: "Whether the member's merge information is/is not, contains/does not contain, starts/ends with, or is greater/less than a value" + example: contains value: + type: string + title: Segment Value description: The value to segment a text or number merge field with. example: "Freddie's Jokes" - title: Segment Value - type: string + - type: object + title: Email Segment + description: Segment by email address. required: - field - op - title: Text or Number Merge Field Segment - type: object - - description: Segment by email address. properties: condition_type: - enum: - - EmailAddress type: string x-value: EmailAddress + enum: + - EmailAddress field: - description: "Segmenting based off of a subscriber's email address." + type: string enum: - merge0 - EMAIL - example: EMAIL title: Segment Field - type: string + description: "Segmenting based off of a subscriber's email address." + example: EMAIL op: - description: "Whether the email address is/not exactly, contains/doesn't contain, starts/ends with a string." + type: string enum: - is - not @@ -1468,74 +1475,75 @@ properties: - greater - less title: Segment Operator - type: string + description: "Whether the email address is/not exactly, contains/doesn't contain, starts/ends with a string." value: + type: string + title: Segment Value description: The value to compare the email against. example: urist.mcvankab@freddiesjokes.com - title: Segment Value - type: string + - type: object + title: Predicted Gender Segment + description: Segment by predicted gender. required: - field - op - title: Email Segment - type: object - - description: Segment by predicted gender. + - value properties: condition_type: - enum: - - PredictedGender type: string x-value: PredictedGender + enum: + - PredictedGender field: - description: Segment by predicted gender. + type: string enum: - predicted_gender title: Segment Field - type: string + description: Segment by predicted gender. op: - description: Members who are/not the exact criteria listed. + type: string enum: - is - not - example: is title: Segment Operator - type: string + description: Members who are/not the exact criteria listed. + example: is value: - description: The predicted gender to segment. + type: string enum: - male - female - example: female title: Segment Operator - type: string + description: The predicted gender to segment. + example: female + - type: object + title: Predicted Age Segment + description: Segment by predicted age. required: - field - op - value - title: Predicted Gender Segment - type: object - - description: Segment by predicted age. properties: condition_type: - enum: - - PredictedAge type: string x-value: PredictedAge + enum: + - PredictedAge field: - description: Segment by predicted age. + type: string enum: - predicted_age_range title: Segment Field - type: string + description: Segment by predicted age. op: - description: Members who are/not the exact criteria listed. + type: string enum: - is - example: is title: Segment Operator - type: string + description: Members who are/not the exact criteria listed. + example: is value: - description: The predicted age to segment. + type: string enum: - 18-24 - 25-34 @@ -1543,467 +1551,623 @@ properties: - 45-54 - 55-64 - 65+ - example: female title: Segment Operator - type: string - required: - - field - - op - - value - title: Predicted Age Segment - type: object - - description: Segment by when people subscribed. + description: The predicted age to segment. + example: female + - type: object + title: New Subscribers Prebuilt Segment + description: Segment by when people subscribed. properties: condition_type: - enum: - - NewSubscribers type: string x-value: NewSubscribers + enum: + - NewSubscribers field: - description: Segment by when people subscribed. + type: string enum: - timestamp_opt title: Segment Field - type: string + description: Segment by when people subscribed. op: - description: "Whe the event took place, namely within a time frame." + type: string enum: - date_within title: Segment Operator - type: string + description: "Whe the event took place, namely within a time frame." value: - description: "What type of data to segment on: a specific date, a specific campaign, or the last campaign sent." - title: Segment Data type: string - title: New Subscribers Prebuilt Segment - type: object - x-discriminator: - propertyName: condition_type - title: Segment Type - type: array - match: - description: Segment match type. - title: Match Type - type: string - prebuilt_segment_id: - description: "The prebuilt segment id, if a prebuilt segment has been designated for this campaign." - example: subscribers-female - title: Prebuilt Segment Id - type: string - saved_segment_id: - description: The id for an existing saved segment. - title: Saved Segment ID - type: integer - title: Segment Options - type: object - segment_text: - description: "A description of the [segment](https://mailchimp.com/help/create-and-send-to-a-segment/) used for the campaign. Formatted as a string marked up with HTML." + title: Segment Data + description: "What type of data to segment on: a specific date, a specific campaign, or the last campaign sent." + settings: + type: object + title: Campaign Settings + description: "The settings for your campaign, including subject, from name, reply-to address, and more." + properties: + subject_line: + type: + - "null" + - string + title: Campaign Subject Line + description: The subject line for the campaign. + preview_text: + type: + - "null" + - string + title: Campaign Preview Text + description: The preview text for the campaign. + title: + type: + - "null" + - string + title: Campaign Title + description: The title of the campaign. + from_name: + type: + - "null" + - string + title: From Name + description: "The 'from' name on the campaign (not an email address)." + reply_to: + type: + - "null" + - string + title: Reply To Address + description: The reply-to email address for the campaign. + use_conversation: + type: boolean + title: Conversation + description: Use Mailchimp Conversation feature to manage out-of-office replies. + to_name: + type: + - "null" + - string + title: To Name + description: "The campaign's custom 'To' name. Typically the first name [merge field](https://mailchimp.com/help/getting-started-with-merge-tags/)." + folder_id: + type: + - "null" + - string + title: Folder ID + description: "If the campaign is listed in a folder, the id for that folder." + authenticate: + type: boolean + title: Authentication + description: "Whether Mailchimp [authenticated](https://mailchimp.com/help/about-email-authentication/) the campaign. Defaults to `true`." + auto_footer: + type: boolean + title: Auto-Footer + description: "Automatically append Mailchimp's [default footer](https://mailchimp.com/help/about-campaign-footers/) to the campaign." + inline_css: + type: boolean + title: Inline CSS + description: Automatically inline the CSS included with the campaign content. + auto_tweet: + type: boolean + title: Auto-Tweet + description: "Automatically tweet a link to the [campaign archive](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) page when the campaign is sent." + auto_fb_post: + type: array + title: Auto Post to Facebook + description: "An array of [Facebook](https://mailchimp.com/help/connect-or-disconnect-the-facebook-integration/) page ids to auto-post to." + items: + type: + - "null" + - string + fb_comments: + type: boolean + title: Facebook Comments + description: "Allows Facebook comments on the campaign (also force-enables the Campaign Archive toolbar). Defaults to `true`." + timewarp: + type: boolean + title: Timewarp Send + description: "Send this campaign using [Timewarp](https://mailchimp.com/help/use-timewarp/)." readOnly: true - title: Segment Text - type: string - title: List + template_id: + type: integer + title: Template ID + description: The id for the template used in this campaign. + readOnly: false + drag_and_drop: + type: boolean + title: Drag And Drop Campaign + description: Whether the campaign uses the drag-and-drop editor. + readOnly: true + variate_settings: type: object - report_summary: - description: "For sent campaigns, a summary of opens, clicks, and e-commerce data." + title: A/B Test Options + description: The settings specific to A/B test campaigns. properties: - click_rate: - description: The number of unique clicks divided by the total number of successful deliveries. + winning_combination_id: + type: + - "null" + - string + title: Winning Combination ID + description: ID for the winning combination. readOnly: true - title: Click Rate - type: number - clicks: - description: The total number of clicks for an campaign. + winning_campaign_id: + type: + - "null" + - string + title: Winning Campaign ID + description: ID of the campaign that was sent to the remaining recipients based on the winning combination. readOnly: true - title: Total Clicks + winner_criteria: + type: + - "null" + - string + title: Winning Criteria + description: "The combination that performs the best. This may be determined automatically by click rate, open rate, or total revenue -- or you may choose manually based on the reporting data you find the most valuable. For Multivariate Campaigns testing send_time, winner_criteria is ignored. For Multivariate Campaigns with 'manual' as the winner_criteria, the winner must be chosen in the Mailchimp web application." + enum: + - opens + - clicks + - manual + - total_revenue + wait_time: type: integer - ecommerce: - description: E-Commerce stats for a campaign. - properties: - total_orders: - description: The total orders for a campaign. - readOnly: true - title: Total Orders - type: integer - total_revenue: - description: The total revenue for a campaign. Calculated as the sum of all order totals minus shipping and tax totals. - readOnly: true - title: Total Revenue - type: number - total_spent: - description: The total spent for a campaign. Calculated as the sum of all order totals with no deductions. - readOnly: true - title: Total Spent - type: number - title: E-Commerce Report - type: object - open_rate: - description: The number of unique opens divided by the total number of successful deliveries. - readOnly: true - title: Open Rate - type: number - opens: - description: The total number of opens for a campaign. - readOnly: true - title: Automation Opens + title: Wait Time + description: "The number of minutes to wait before choosing the winning campaign. The value of wait_time must be greater than 0 and in whole hours, specified in minutes." + test_size: type: integer - subscriber_clicks: - description: The number of unique clicks. + title: Test Size + description: "The percentage of recipients to send the test combinations to, must be a value between 10 and 100." + subject_lines: + type: array + title: Subject Lines + description: "The possible subject lines to test. If no subject lines are provided, settings.subject_line will be used." + items: + type: + - "null" + - string + send_times: + type: array + title: Send Times + description: "The possible send times to test. The times provided should be in the format YYYY-MM-DD HH:MM:SS. If send_times are provided to test, the test_size will be set to 100% and winner_criteria will be ignored." + items: + type: + - "null" + - string + format: date-time + from_names: + type: array + title: From Names + description: "The possible from names. The number of from_names provided must match the number of reply_to_addresses. If no from_names are provided, settings.from_name will be used." + items: + type: + - "null" + - string + reply_to_addresses: + type: array + title: Reply To Addresses + description: "The possible reply-to addresses. The number of reply_to_addresses provided must match the number of from_names. If no reply_to_addresses are provided, settings.reply_to will be used." + items: + type: + - "null" + - string + contents: + type: array + title: Content Descriptions + description: "Descriptions of possible email contents. To set campaign contents, make a PUT request to /campaigns/{campaign_id}/content with the field 'variate_contents'." + items: + type: + - "null" + - string readOnly: true - title: Unique Subscriber Clicks - type: integer - unique_opens: - description: The number of unique opens. + combinations: + type: array + title: Combinations + description: Combinations of possible variables used to build emails. readOnly: true - title: Unique Opens - type: integer - title: Campaign Report Summary + items: + type: object + properties: + id: + type: + - "null" + - string + title: ID + description: Unique ID for the combination. + subject_line: + type: integer + title: Subject Line + description: "The index of `variate_settings.subject_lines` used." + send_time: + type: integer + title: Send Time + description: "The index of `variate_settings.send_times` used." + from_name: + type: integer + title: From Name + description: "The index of `variate_settings.from_names` used." + reply_to: + type: integer + title: Reply To + description: "The index of `variate_settings.reply_to_addresses` used." + content_description: + type: integer + title: Content Description + description: "The index of `variate_settings.contents` used." + recipients: + type: integer + title: Recipients + description: The number of recipients for this combination. + tracking: type: object - resendable: - description: Determines if the campaign qualifies to be resent to non-openers. - readOnly: true - title: Resendable - type: boolean + title: Campaign Tracking Options + description: The tracking options for a campaign. + properties: + opens: + type: boolean + title: Opens + description: "Whether to [track opens](https://mailchimp.com/help/about-open-tracking/). Defaults to `true`. Cannot be set to false for variate campaigns." + html_clicks: + type: boolean + title: HTML Click Tracking + description: "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the HTML version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns." + text_clicks: + type: boolean + title: Plain-Text Click Tracking + description: "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the plain-text version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns." + goal_tracking: + type: boolean + title: Mailchimp Goal Tracking + description: "Whether to enable [Goal](https://mailchimp.com/help/about-connected-sites/) tracking." + ecomm360: + type: boolean + title: E-commerce Tracking + description: "Whether to enable [eCommerce360](https://mailchimp.com/help/connect-your-online-store-to-mailchimp/) tracking." + google_analytics: + type: + - "null" + - string + title: Google Analytics Tracking + description: "The custom slug for [Google Analytics](https://mailchimp.com/help/integrate-google-analytics-with-mailchimp/) tracking (max of 50 bytes)." + clicktale: + type: + - "null" + - string + title: ClickTale Analytics Tracking + description: "The custom slug for [ClickTale](https://mailchimp.com/help/additional-tracking-options-for-campaigns/) tracking (max of 50 bytes)." + salesforce: + type: object + title: Salesforce CRM Tracking + description: "Salesforce tracking options for a campaign. Must be using Mailchimp's built-in [Salesforce integration](https://mailchimp.com/help/integrate-salesforce-with-mailchimp/)." + properties: + campaign: + type: boolean + title: Salesforce Campaign + description: Create a campaign in a connected Salesforce account. + notes: + type: boolean + title: Salesforce Note + description: Update contact notes for a campaign based on subscriber email addresses. + capsule: + type: object + title: Capsule CRM Tracking + description: "Capsule tracking options for a campaign. Must be using Mailchimp's built-in Capsule integration." + properties: + notes: + type: boolean + title: Capsule Note + description: Update contact notes for a campaign based on subscriber email addresses. rss_opts: + type: object + title: RSS Options description: "[RSS](https://mailchimp.com/help/share-your-blog-posts-with-mailchimp/) options for a campaign." properties: - constrain_rss_img: - description: Whether to add CSS to images in the RSS feed to constrain their width in campaigns. - title: Constrain RSS Images - type: boolean feed_url: - description: The URL for the RSS feed. - format: uri + type: + - "null" + - string title: Feed URL - type: string + format: uri + description: The URL for the RSS feed. frequency: - description: The frequency of the RSS Campaign. + type: + - "null" + - string title: Frequency - type: string - last_sent: - description: The date the campaign was last sent. - readOnly: true - title: Last Sent - type: string + description: The frequency of the RSS Campaign. + enum: + - daily + - weekly + - monthly schedule: + type: object + title: Sending Schedule description: The schedule for sending the RSS Campaign. properties: + hour: + type: integer + minimum: 0 + maximum: 23 + title: Sending Hour + description: "The hour to send the campaign in local time. Acceptable hours are 0-23. For example, '4' would be 4am in [your account's default time zone](https://mailchimp.com/help/set-account-defaults/)." daily_send: + type: object + title: Daily Sending Days description: The days of the week to send a daily RSS Campaign. properties: - friday: - description: Sends the daily RSS Campaign on Fridays. - title: Friday + sunday: type: boolean + title: Sunday + description: Sends the daily RSS Campaign on Sundays. monday: - description: Sends the daily RSS Campaign on Mondays. - title: Monday type: boolean - saturday: - description: Sends the daily RSS Campaign on Saturdays. - title: Saturday + title: Monday + description: Sends the daily RSS Campaign on Mondays. + tuesday: type: boolean - sunday: - description: Sends the daily RSS Campaign on Sundays. - title: Sunday + title: tuesday + description: Sends the daily RSS Campaign on Tuesdays. + wednesday: type: boolean + title: Monday + description: Sends the daily RSS Campaign on Wednesdays. thursday: - description: Sends the daily RSS Campaign on Thursdays. - title: Thursday type: boolean - tuesday: - description: Sends the daily RSS Campaign on Tuesdays. - title: tuesday + title: Thursday + description: Sends the daily RSS Campaign on Thursdays. + friday: type: boolean - wednesday: - description: Sends the daily RSS Campaign on Wednesdays. - title: Monday + title: Friday + description: Sends the daily RSS Campaign on Fridays. + saturday: type: boolean - title: Daily Sending Days - type: object - hour: - description: "The hour to send the campaign in local time. Acceptable hours are 0-23. For example, '4' would be 4am in [your account's default time zone](https://mailchimp.com/help/set-account-defaults/)." - maximum: 23 - minimum: 0 - title: Sending Hour - type: integer + title: Saturday + description: Sends the daily RSS Campaign on Saturdays. + weekly_send_day: + type: + - "null" + - string + enum: + - sunday + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + title: Weekly Sending Day + description: The day of the week to send a weekly RSS Campaign. monthly_send_date: - description: "The day of the month to send a monthly RSS Campaign. Acceptable days are 0-31, where '0' is always the last day of a month. Months with fewer than the selected number of days will not have an RSS campaign sent out that day. For example, RSS Campaigns set to send on the 30th will not go out in February." - maximum: 31 + type: number minimum: 0 + maximum: 31 title: Monthly Sending Day - type: number - weekly_send_day: - description: The day of the week to send a weekly RSS Campaign. - title: Weekly Sending Day - type: string - title: Sending Schedule - type: object - title: RSS Options + description: "The day of the month to send a monthly RSS Campaign. Acceptable days are 0-31, where '0' is always the last day of a month. Months with fewer than the selected number of days will not have an RSS campaign sent out that day. For example, RSS Campaigns set to send on the 30th will not go out in February." + last_sent: + type: + - "null" + - string + title: Last Sent + description: The date the campaign was last sent. + readOnly: true + format: date-time + constrain_rss_img: + type: boolean + title: Constrain RSS Images + description: Whether to add CSS to images in the RSS feed to constrain their width in campaigns. + ab_split_opts: type: object - send_time: - description: The date and time a campaign was sent. - readOnly: true - title: Send Time - type: string - settings: - description: "The settings for your campaign, including subject, from name, reply-to address, and more." + title: A/B Testing Options + description: "[A/B Testing](https://mailchimp.com/help/about-ab-testing-campaigns/) options for a campaign." + readOnly: true properties: - authenticate: - description: "Whether Mailchimp [authenticated](https://mailchimp.com/help/about-email-authentication/) the campaign. Defaults to `true`." - title: Authentication - type: boolean - auto_fb_post: - description: "An array of [Facebook](https://mailchimp.com/help/connect-or-disconnect-the-facebook-integration/) page ids to auto-post to." - items: - type: string - title: Auto Post to Facebook - type: array - auto_footer: - description: "Automatically append Mailchimp's [default footer](https://mailchimp.com/help/about-campaign-footers/) to the campaign." - title: Auto-Footer - type: boolean - auto_tweet: - description: "Automatically tweet a link to the [campaign archive](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) page when the campaign is sent." - title: Auto-Tweet - type: boolean - drag_and_drop: - description: Whether the campaign uses the drag-and-drop editor. - readOnly: true - title: Drag And Drop Campaign - type: boolean - fb_comments: - description: "Allows Facebook comments on the campaign (also force-enables the Campaign Archive toolbar). Defaults to `true`." - title: Facebook Comments - type: boolean - folder_id: - description: "If the campaign is listed in a folder, the id for that folder." - title: Folder ID - type: string - from_name: - description: "The 'from' name on the campaign (not an email address)." - title: From Name - type: string - inline_css: - description: Automatically inline the CSS included with the campaign content. - title: Inline CSS - type: boolean - preview_text: - description: The preview text for the campaign. - title: Campaign Preview Text - type: string - reply_to: - description: The reply-to email address for the campaign. - title: Reply To Address - type: string - subject_line: - description: The subject line for the campaign. - title: Campaign Subject Line - type: string - template_id: - description: The id for the template used in this campaign. - readOnly: false - title: Template ID + split_test: + type: + - "null" + - string + title: Split Test + description: The type of AB split to run. + enum: + - subject + - from_name + - schedule + pick_winner: + type: + - "null" + - string + title: Pick Winner + description: "How we should evaluate a winner. Based on 'opens', 'clicks', or 'manual'." + enum: + - opens + - clicks + - manual + wait_units: + type: + - "null" + - string + title: Wait Time + description: "How unit of time for measuring the winner ('hours' or 'days'). This cannot be changed after a campaign is sent." + enum: + - hours + - days + wait_time: type: integer - timewarp: - description: "Send this campaign using [Timewarp](https://mailchimp.com/help/use-timewarp/)." - readOnly: true - title: Timewarp Send - type: boolean - title: - description: The title of the campaign. - title: Campaign Title - type: string - to_name: - description: "The campaign's custom 'To' name. Typically the first name [merge field](https://mailchimp.com/help/getting-started-with-merge-tags/)." - title: To Name - type: string - use_conversation: - description: Use Mailchimp Conversation feature to manage out-of-office replies. - title: Conversation - type: boolean - title: Campaign Settings - type: object + title: Wait Time + description: The amount of time to wait before picking a winner. This cannot be changed after a campaign is sent. + split_size: + type: integer + minimum: 1 + maximum: 50 + title: Split Size + description: "The size of the split groups. Campaigns split based on 'schedule' are forced to have a 50/50 split. Valid split integers are between 1-50." + from_name_a: + type: + - "null" + - string + title: From Name Group A + description: "For campaigns split on 'From Name', the name for Group A." + from_name_b: + type: + - "null" + - string + title: From Name Group B + description: "For campaigns split on 'From Name', the name for Group B." + reply_email_a: + type: + - "null" + - string + title: Reply Email Group A + description: "For campaigns split on 'From Name', the reply-to address for Group A." + reply_email_b: + type: + - "null" + - string + title: Reply Email Group B + description: "For campaigns split on 'From Name', the reply-to address for Group B." + subject_a: + type: + - "null" + - string + title: Subject Line Group A + description: "For campaigns split on 'Subject Line', the subject line for Group A." + subject_b: + type: + - "null" + - string + title: Subject Line Group B + description: "For campaigns split on 'Subject Line', the subject line for Group B." + send_time_a: + type: + - "null" + - string + format: date-time + title: Send Time Group A + description: The send time for Group A. + send_time_b: + type: + - "null" + - string + format: date-time + title: Send Time Group B + description: The send time for Group B. + send_time_winner: + type: + - "null" + - string + title: Send Time Winner + description: The send time for the winning version. social_card: + type: object + title: Campaign Social Card description: "The preview for the campaign, rendered by social networks like Facebook and Twitter. [Learn more](https://mailchimp.com/help/enable-and-customize-social-cards/)." properties: - description: - description: A short summary of the campaign to display. - title: Campaign Description - type: string image_url: - description: The url for the header image for the card. + type: + - "null" + - string title: Image URL - type: string + description: The url for the header image for the card. + description: + type: + - "null" + - string + title: Campaign Description + description: A short summary of the campaign to display. title: - description: The title for the card. Typically the subject line of the campaign. + type: + - "null" + - string title: Title - type: string - title: Campaign Social Card + description: The title for the card. Typically the subject line of the campaign. + report_summary: type: object - status: - description: The current status of the campaign. - readOnly: true - title: Campaign Status - type: string - tracking: - description: The tracking options for a campaign. + title: Campaign Report Summary + description: "For sent campaigns, a summary of opens, clicks, and e-commerce data." properties: - capsule: - description: "Capsule tracking options for a campaign. Must be using Mailchimp's built-in Capsule integration." - properties: - notes: - description: Update contact notes for a campaign based on subscriber email addresses. - title: Capsule Note - type: boolean - title: Capsule CRM Tracking - type: object - clicktale: - description: "The custom slug for [ClickTale](https://mailchimp.com/help/additional-tracking-options-for-campaigns/) tracking (max of 50 bytes)." - title: ClickTale Analytics Tracking - type: string - ecomm360: - description: "Whether to enable [eCommerce360](https://mailchimp.com/help/connect-your-online-store-to-mailchimp/) tracking." - title: E-commerce Tracking - type: boolean - goal_tracking: - description: "Whether to enable [Goal](https://mailchimp.com/help/about-connected-sites/) tracking." - title: Mailchimp Goal Tracking - type: boolean - google_analytics: - description: "The custom slug for [Google Analytics](https://mailchimp.com/help/integrate-google-analytics-with-mailchimp/) tracking (max of 50 bytes)." - title: Google Analytics Tracking - type: string - html_clicks: - description: "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the HTML version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns." - title: HTML Click Tracking - type: boolean opens: - description: "Whether to [track opens](https://mailchimp.com/help/about-open-tracking/). Defaults to `true`. Cannot be set to false for variate campaigns." - title: Opens - type: boolean - salesforce: - description: "Salesforce tracking options for a campaign. Must be using Mailchimp's built-in [Salesforce integration](https://mailchimp.com/help/integrate-salesforce-with-mailchimp/)." - properties: - campaign: - description: Create a campaign in a connected Salesforce account. - title: Salesforce Campaign - type: boolean - notes: - description: Update contact notes for a campaign based on subscriber email addresses. - title: Salesforce Note - type: boolean - title: Salesforce CRM Tracking + type: integer + title: Automation Opens + description: The total number of opens for a campaign. + readOnly: true + unique_opens: + type: integer + title: Unique Opens + description: The number of unique opens. + readOnly: true + open_rate: + type: number + title: Open Rate + description: The number of unique opens divided by the total number of successful deliveries. + readOnly: true + clicks: + type: integer + title: Total Clicks + description: The total number of clicks for an campaign. + readOnly: true + subscriber_clicks: + type: integer + title: Unique Subscriber Clicks + description: The number of unique clicks. + readOnly: true + click_rate: + type: number + title: Click Rate + description: The number of unique clicks divided by the total number of successful deliveries. + readOnly: true + ecommerce: type: object - text_clicks: - description: "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the plain-text version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns." - title: Plain-Text Click Tracking - type: boolean - title: Campaign Tracking Options + title: E-Commerce Report + description: E-Commerce stats for a campaign. + properties: + total_orders: + type: integer + title: Total Orders + description: The total orders for a campaign. + readOnly: true + total_spent: + type: number + title: Total Spent + description: The total spent for a campaign. Calculated as the sum of all order totals with no deductions. + readOnly: true + total_revenue: + type: number + title: Total Revenue + description: The total revenue for a campaign. Calculated as the sum of all order totals minus shipping and tax totals. + readOnly: true + delivery_status: type: object - type: - description: "There are four types of [campaigns](https://mailchimp.com/help/getting-started-with-campaigns/) you can create in Mailchimp. A/B Split campaigns have been deprecated and variate campaigns should be used instead." - title: Campaign Type - type: string - variate_settings: - description: The settings specific to A/B test campaigns. + title: Campaign Delivery Status + description: Updates on campaigns in the process of sending. properties: - combinations: - description: Combinations of possible variables used to build emails. - items: - properties: - content_description: - description: "The index of `variate_settings.contents` used." - title: Content Description - type: integer - from_name: - description: "The index of `variate_settings.from_names` used." - title: From Name - type: integer - id: - description: Unique ID for the combination. - title: ID - type: string - recipients: - description: The number of recipients for this combination. - title: Recipients - type: integer - reply_to: - description: "The index of `variate_settings.reply_to_addresses` used." - title: Reply To - type: integer - send_time: - description: "The index of `variate_settings.send_times` used." - title: Send Time - type: integer - subject_line: - description: "The index of `variate_settings.subject_lines` used." - title: Subject Line - type: integer - type: object + enabled: + type: boolean + title: Delivery Status Enabled + description: Whether Campaign Delivery Status is enabled for this account and campaign. readOnly: true - title: Combinations - type: array - contents: - description: "Descriptions of possible email contents. To set campaign contents, make a PUT request to /campaigns/{campaign_id}/content with the field 'variate_contents'." - items: - type: string + can_cancel: + type: boolean + title: Campaign Cancelable + description: Whether a campaign send can be canceled. readOnly: true - title: Content Descriptions - type: array - from_names: - description: "The possible from names. The number of from_names provided must match the number of reply_to_addresses. If no from_names are provided, settings.from_name will be used." - items: - type: string - title: From Names - type: array - reply_to_addresses: - description: "The possible reply-to addresses. The number of reply_to_addresses provided must match the number of from_names. If no reply_to_addresses are provided, settings.reply_to will be used." - items: - type: string - title: Reply To Addresses - type: array - send_times: - description: "The possible send times to test. The times provided should be in the format YYYY-MM-DD HH:MM:SS. If send_times are provided to test, the test_size will be set to 100% and winner_criteria will be ignored." - items: - type: string - title: Send Times - type: array - subject_lines: - description: "The possible subject lines to test. If no subject lines are provided, settings.subject_line will be used." - items: - type: string - title: Subject Lines - type: array - test_size: - description: "The percentage of recipients to send the test combinations to, must be a value between 10 and 100." - title: Test Size - type: integer - wait_time: - description: "The number of minutes to wait before choosing the winning campaign. The value of wait_time must be greater than 0 and in whole hours, specified in minutes." - title: Wait Time + status: + type: + - "null" + - string + title: Campaign Delivery Status + description: The current state of a campaign delivery. + enum: + - delivering + - delivered + - canceling + - canceled + readOnly: true + emails_sent: type: integer - winner_criteria: - description: "The combination that performs the best. This may be determined automatically by click rate, open rate, or total revenue -- or you may choose manually based on the reporting data you find the most valuable. For Multivariate Campaigns testing send_time, winner_criteria is ignored. For Multivariate Campaigns with 'manual' as the winner_criteria, the winner must be chosen in the Mailchimp web application." - title: Winning Criteria - type: string - winning_campaign_id: - description: ID of the campaign that was sent to the remaining recipients based on the winning combination. + title: Emails Sent + description: The total number of emails confirmed sent for this campaign so far. readOnly: true - title: Winning Campaign ID - type: string - winning_combination_id: - description: ID for the winning combination. + emails_canceled: + type: integer + title: Emails Canceled + description: The total number of emails canceled for this campaign. readOnly: true - title: Winning Combination ID - type: string - title: A/B Test Options + _meta: type: object - web_id: - description: "The ID used in the Mailchimp web application. View this campaign in your Mailchimp account at `https://{dc}.admin.mailchimp.com/campaigns/show/?id={web_id}`." - readOnly: true - title: Campaign Web ID - type: integer -required: - - id -title: Campaign -type: object + properties: + row_id: + type: integer + required: + - row_id diff --git a/source-mailchimp/acmeCo/email_activity.schema.yaml b/source-mailchimp/acmeCo/email_activity.schema.yaml index 745521e673..d8e96620e8 100644 --- a/source-mailchimp/acmeCo/email_activity.schema.yaml +++ b/source-mailchimp/acmeCo/email_activity.schema.yaml @@ -1,56 +1,70 @@ --- +type: object +title: Email Activity description: "A list of member's subscriber activity in a specific campaign." +required: + - timestamp + - email_id + - action properties: - action: - description: "One of the following actions: 'open', 'click', or 'bounce'" - title: action - type: string campaign_id: - description: The unique id for the campaign. - title: The unique id for the campaign. type: string - email_address: - description: Email address for a subscriber. - title: Email address for a subscriber. + title: The unique id for the campaign. + description: The unique id for the campaign. + list_id: type: string + title: The unique id for the list. + description: The unique id for the list. + list_is_active: + type: boolean + title: The status of the list used. + description: "The status of the list used, namely if it's deleted or disabled." email_id: - description: "The MD5 hash of the lowercase version of the list member's email address." + type: string title: email MD5 hash. + description: "The MD5 hash of the lowercase version of the list member's email address." + email_address: type: string - ip: - description: The IP address recorded for the action. - title: Action ip address + title: Email address for a subscriber. + description: Email address for a subscriber. + action: + type: string + title: action + enum: + - open + - click + - bounce + description: "One of the following actions: 'open', 'click', or 'bounce'" + type: type: - string - "null" - list_id: - description: The unique id for the list. - title: The unique id for the list. - type: string - list_is_active: - description: "The status of the list used, namely if it's deleted or disabled." - title: The status of the list used. - type: boolean + title: Type + enum: + - hard + - soft + description: "If the action is a 'bounce', the type of bounce received: 'hard', 'soft'." timestamp: + type: string + title: Action date and time description: The date and time recorded for the action in ISO 8601 format. format: date-time - title: Action date and time - type: string - type: - description: "If the action is a 'bounce', the type of bounce received: 'hard', 'soft'." - title: Type + url: type: - string - "null" - url: - description: "If the action is a 'click', the URL on which the member clicked." title: Click url + description: "If the action is a 'click', the URL on which the member clicked." + ip: type: - string - "null" -required: - - timestamp - - email_id - - action -title: Email Activity -type: object + title: Action ip address + description: The IP address recorded for the action. + _meta: + type: object + properties: + row_id: + type: integer + required: + - row_id diff --git a/source-mailchimp/acmeCo/flow.yaml b/source-mailchimp/acmeCo/flow.yaml index 83fcaf0811..922eff01a8 100644 --- a/source-mailchimp/acmeCo/flow.yaml +++ b/source-mailchimp/acmeCo/flow.yaml @@ -1,5 +1,9 @@ --- collections: + acmeCo/automations: + schema: automations.schema.yaml + key: + - /id acmeCo/campaigns: schema: campaigns.schema.yaml key: @@ -10,6 +14,82 @@ collections: - /timestamp - /email_id - /action + acmeCo/interest_categories: + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: object + required: + - id + properties: + list_id: + type: + - "null" + - string + id: + type: string + title: + type: + - "null" + - string + display_order: + type: + - "null" + - integer + type: + type: + - "null" + - string + _meta: + type: object + properties: + row_id: + type: integer + required: + - row_id + key: + - /id + acmeCo/interests: + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: object + required: + - id + properties: + category_id: + type: + - "null" + - string + list_id: + type: + - "null" + - string + id: + type: string + name: + type: + - "null" + - string + subscriber_count: + type: + - "null" + - string + display_order: + type: + - "null" + - integer + _meta: + type: object + properties: + row_id: + type: integer + required: + - row_id + key: + - /id + acmeCo/list_members: + schema: list_members.schema.yaml + key: + - /id acmeCo/lists: schema: lists.schema.yaml key: @@ -18,3 +98,43 @@ collections: schema: reports.schema.yaml key: - /id + acmeCo/segment_members: + schema: segment_members.schema.yaml + key: + - /id + acmeCo/segments: + schema: segments.schema.yaml + key: + - /id + acmeCo/tags: + schema: + $schema: "http://json-schema.org/draft-07/schema#" + type: object + required: + - id + properties: + id: + type: integer + name: + type: + - "null" + - string + list_id: + type: + - "null" + - string + _meta: + type: object + properties: + row_id: + type: integer + required: + - row_id + key: + - /id + acmeCo/unsubscribes: + schema: unsubscribes.schema.yaml + key: + - /campaign_id + - /email_id + - /timestamp diff --git a/source-mailchimp/acmeCo/list_members.schema.yaml b/source-mailchimp/acmeCo/list_members.schema.yaml new file mode 100644 index 0000000000..9461b9151b --- /dev/null +++ b/source-mailchimp/acmeCo/list_members.schema.yaml @@ -0,0 +1,232 @@ +--- +$schema: "http://json-schema.org/draft-07/schema#" +type: object +additionalProperties: true +required: + - id +properties: + id: + type: string + email_address: + type: + - "null" + - string + unique_email_id: + type: + - "null" + - string + contact_id: + type: + - "null" + - string + full_name: + type: + - "null" + - string + web_id: + type: + - "null" + - integer + email_type: + type: + - "null" + - string + status: + type: + - "null" + - string + unsubscribe_reason: + type: + - "null" + - string + consents_to_one_to_one_messaging: + type: + - "null" + - boolean + merge_fields: + type: + - "null" + - object + additionalProperties: true + interests: + type: + - "null" + - object + additionalProperties: true + stats: + type: + - "null" + - object + properties: + avg_open_rate: + type: + - "null" + - number + avg_click_rate: + type: + - "null" + - number + ecommerce_data: + type: + - "null" + - object + properties: + total_revenue: + type: + - "null" + - number + number_of_orders: + type: + - "null" + - number + currency_code: + type: + - "null" + - string + ip_signup: + type: + - "null" + - string + timestamp_signup: + type: + - "null" + - string + format: date-time + ip_opt: + type: + - "null" + - string + timestamp_opt: + type: + - "null" + - string + format: date-time + member_rating: + type: + - "null" + - integer + last_changed: + type: + - "null" + - string + format: date-time + language: + type: + - "null" + - string + vip: + type: + - "null" + - boolean + email_client: + type: + - "null" + - string + location: + type: + - "null" + - object + properties: + latitude: + type: + - "null" + - number + longitude: + type: + - "null" + - number + gmtoff: + type: + - "null" + - integer + dstoff: + type: + - "null" + - integer + country_code: + type: + - "null" + - string + timezone: + type: + - "null" + - string + region: + type: + - "null" + - string + marketing_permissions: + type: + - "null" + - object + properties: + marketing_permission_id: + type: + - "null" + - string + text: + type: + - "null" + - string + enabled: + type: + - "null" + - boolean + last_note: + type: + - "null" + - object + properties: + note_id: + type: + - "null" + - integer + created_at: + type: + - "null" + - string + format: date-time + created_by: + type: + - "null" + - string + note: + type: + - "null" + - string + source: + type: + - "null" + - string + tags_count: + type: + - "null" + - integer + tags: + type: + - "null" + - array + items: + type: + - "null" + - object + properties: + id: + type: + - "null" + - integer + name: + type: + - "null" + - string + list_id: + type: + - "null" + - string + _meta: + type: object + properties: + row_id: + type: integer + required: + - row_id diff --git a/source-mailchimp/acmeCo/lists.schema.yaml b/source-mailchimp/acmeCo/lists.schema.yaml index 03f1e089c9..256c713c8d 100644 --- a/source-mailchimp/acmeCo/lists.schema.yaml +++ b/source-mailchimp/acmeCo/lists.schema.yaml @@ -1,246 +1,305 @@ --- +type: object +title: Subscriber List description: Information about a specific list. +required: + - id properties: - beamer_address: - description: "The list's [Email Beamer](https://mailchimp.com/help/use-email-beamer-to-create-a-campaign/) address." - readOnly: true - title: Beamer Address + id: type: string - campaign_defaults: - description: "[Default values for campaigns](https://mailchimp.com/help/edit-your-emails-subject-preview-text-from-name-or-from-email-address/) created for this list." - properties: - from_email: - description: The default from email for campaigns sent to this list. - title: "Sender's Email Address" - type: string - from_name: - description: The default from name for campaigns sent to this list. - title: "Sender's Name" - type: string - language: - description: "The default language for this lists's forms." - title: Language - type: string - subject: - description: The default subject line for campaigns sent to this list. - title: Subject - type: string - title: Campaign Defaults - type: object + title: List ID + description: A string that uniquely identifies this list. + readOnly: true + web_id: + type: integer + title: List Web ID + description: "The ID used in the Mailchimp web application. View this list in your Mailchimp account at `https://{dc}.admin.mailchimp.com/lists/members/?id={web_id}`." + readOnly: true + name: + type: + - "null" + - string + title: List Name + description: The name of the list. contact: + type: object + title: List Contact description: "[Contact information displayed in campaign footers](https://mailchimp.com/help/about-campaign-footers/) to comply with international spam laws." properties: + company: + type: + - "null" + - string + title: Company Name + description: The company name for the list. address1: - description: The street address for the list contact. + type: + - "null" + - string title: Address - type: string - address2: description: The street address for the list contact. + address2: + type: + - "null" + - string title: Address - type: string + description: The street address for the list contact. city: - description: The city for the list contact. + type: + - "null" + - string title: City - type: string - company: - description: The company name for the list. - title: Company Name - type: string - country: - description: A two-character ISO3166 country code. Defaults to US if invalid. - title: Country Code - type: string - phone: - description: The phone number for the list contact. - title: Phone Number - type: string + description: The city for the list contact. state: - description: The state for the list contact. + type: + - "null" + - string title: State - type: string + description: The state for the list contact. zip: - description: The postal or zip code for the list contact. + type: + - "null" + - string title: Postal Code - type: string - title: List Contact + description: The postal or zip code for the list contact. + country: + type: + - "null" + - string + title: Country Code + description: A two-character ISO3166 country code. Defaults to US if invalid. + phone: + type: + - "null" + - string + title: Phone Number + description: The phone number for the list contact. + permission_reminder: + type: + - "null" + - string + title: Permission Reminder + description: "The [permission reminder](https://mailchimp.com/help/edit-the-permission-reminder/) for the list." + use_archive_bar: + type: boolean + title: Use Archive Bar + description: "Whether campaigns for this list use the [Archive Bar](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) in archives by default." + default: false + campaign_defaults: type: object + title: Campaign Defaults + description: "[Default values for campaigns](https://mailchimp.com/help/edit-your-emails-subject-preview-text-from-name-or-from-email-address/) created for this list." + properties: + from_name: + type: + - "null" + - string + title: "Sender's Name" + description: The default from name for campaigns sent to this list. + from_email: + type: + - "null" + - string + title: "Sender's Email Address" + description: The default from email for campaigns sent to this list. + subject: + type: + - "null" + - string + title: Subject + description: The default subject line for campaigns sent to this list. + language: + type: + - "null" + - string + title: Language + description: "The default language for this lists's forms." + notify_on_subscribe: + type: + - "null" + - string + title: Notify on Subscribe + description: "The email address to send [subscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to." + notify_on_unsubscribe: + type: + - "null" + - string + title: Notify on Unsubscribe + description: "The email address to send [unsubscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to." date_created: + type: string + title: Creation Date description: The date and time that this list was created in ISO 8601 format. format: date-time readOnly: true - title: Creation Date - type: string - double_optin: - default: false - description: Whether or not to require the subscriber to confirm subscription via email. - title: Double Opt In - type: boolean + list_rating: + type: integer + title: List Rating + description: An auto-generated activity score for the list (0-5). + readOnly: true email_type_option: - description: "Whether the list supports [multiple formats for emails](https://mailchimp.com/help/change-list-name-and-defaults/). When set to `true`, subscribers can choose whether they want to receive HTML or plain-text emails. When set to `false`, subscribers will receive HTML emails, with a plain-text alternative backup." + type: boolean title: Email Type Option + description: "Whether the list supports [multiple formats for emails](https://mailchimp.com/help/change-list-name-and-defaults/). When set to `true`, subscribers can choose whether they want to receive HTML or plain-text emails. When set to `false`, subscribers will receive HTML emails, with a plain-text alternative backup." + subscribe_url_short: + type: + - "null" + - string + title: Subscribe URL Short + description: "Our [EepURL shortened](https://mailchimp.com/help/share-your-signup-form/) version of this list's subscribe form." + readOnly: true + subscribe_url_long: + type: + - "null" + - string + title: Subscribe URL Long + description: "The full version of this list's subscribe form (host will vary)." + readOnly: true + beamer_address: + type: + - "null" + - string + title: Beamer Address + description: "The list's [Email Beamer](https://mailchimp.com/help/use-email-beamer-to-create-a-campaign/) address." + readOnly: true + visibility: + type: + - "null" + - string + title: Visibility + enum: + - pub + - prv + description: "Whether this list is [public or private](https://mailchimp.com/help/about-list-publicity/)." + double_optin: type: boolean - has_welcome: + title: Double Opt In + description: Whether or not to require the subscriber to confirm subscription via email. default: false + has_welcome: + type: boolean + title: Has Welcome description: "Whether or not this list has a welcome automation connected. Welcome Automations: welcomeSeries, singleWelcome, emailFollowup." + default: false example: false - title: Has Welcome - type: boolean - id: - description: A string that uniquely identifies this list. - readOnly: true - title: List ID - type: string - list_rating: - description: An auto-generated activity score for the list (0-5). - readOnly: true - title: List Rating - type: integer marketing_permissions: - default: false - description: Whether or not the list has marketing permissions (eg. GDPR) enabled. - title: Marketing Permissions type: boolean + title: Marketing Permissions + description: Whether or not the list has marketing permissions (eg. GDPR) enabled. + default: false modules: + type: array + title: Modules description: Any list-specific modules installed for this list. items: - type: string + type: + - "null" + - string readOnly: true - title: Modules - type: array - name: - description: The name of the list. - title: List Name - type: string - notify_on_subscribe: - default: "false" - description: "The email address to send [subscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to." - title: Notify on Subscribe - type: string - notify_on_unsubscribe: - default: "false" - description: "The email address to send [unsubscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to." - title: Notify on Unsubscribe - type: string - permission_reminder: - description: "The [permission reminder](https://mailchimp.com/help/edit-the-permission-reminder/) for the list." - title: Permission Reminder - type: string stats: + type: object + title: Statistics description: Stats for the list. Many of these are cached for at least five minutes. + readOnly: true properties: - avg_sub_rate: - description: "The average number of subscriptions per month for the list (not returned if we haven't calculated it yet)." - readOnly: true - title: Average Subscription Rate - type: number - avg_unsub_rate: - description: "The average number of unsubscriptions per month for the list (not returned if we haven't calculated it yet)." + member_count: + type: integer + title: Member Count + description: The number of active members in the list. readOnly: true - title: Average Unsubscription Rate - type: number - campaign_count: - description: The number of campaigns in any status that use this list. + total_contacts: + type: integer + title: Total Contacts + description: "The number of contacts in the list, including subscribed, unsubscribed, pending, cleaned, deleted, transactional, and those that need to be reconfirmed." readOnly: true - title: Campaign Count + unsubscribe_count: type: integer - campaign_last_sent: - description: The date and time the last campaign was sent to this list in ISO 8601 format. This is updated when a campaign is sent to 10 or more recipients. + title: Unsubscribe Count + description: The number of members who have unsubscribed from the list. readOnly: true - title: Campaign Last Sent - type: string cleaned_count: + type: integer + title: Cleaned Count description: The number of members cleaned from the list. readOnly: true - title: Cleaned Count + member_count_since_send: type: integer - cleaned_count_since_send: - description: The number of members cleaned from the list since the last campaign was sent. + title: Member Count Since Send + description: The number of active members in the list since the last campaign was sent. readOnly: true - title: Cleaned Count Since Send + unsubscribe_count_since_send: type: integer - click_rate: - description: "The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet)." - readOnly: true - title: Click Rate - type: number - last_sub_date: - description: The date and time of the last time someone subscribed to this list in ISO 8601 format. - readOnly: true - title: Date of Last List Subscribe - type: string - last_unsub_date: - description: The date and time of the last time someone unsubscribed from this list in ISO 8601 format. - readOnly: true - title: Date of Last List Unsubscribe - type: string - member_count: - description: The number of active members in the list. + title: Unsubscribe Count Since Send + description: The number of members who have unsubscribed since the last campaign was sent. readOnly: true - title: Member Count + cleaned_count_since_send: type: integer - member_count_since_send: - description: The number of active members in the list since the last campaign was sent. + title: Cleaned Count Since Send + description: The number of members cleaned from the list since the last campaign was sent. readOnly: true - title: Member Count Since Send + campaign_count: type: integer + title: Campaign Count + description: The number of campaigns in any status that use this list. + readOnly: true + campaign_last_sent: + type: + - "null" + - string + title: Campaign Last Sent + description: The date and time the last campaign was sent to this list in ISO 8601 format. This is updated when a campaign is sent to 10 or more recipients. + readOnly: true + format: date-time merge_field_count: + type: integer + title: Merge Var Count description: "The number of merge vars for this list (not EMAIL, which is required)." readOnly: true - title: Merge Var Count - type: integer - open_rate: - description: "The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet)." + avg_sub_rate: + type: number + title: Average Subscription Rate + description: "The average number of subscriptions per month for the list (not returned if we haven't calculated it yet)." readOnly: true - title: Open Rate + avg_unsub_rate: type: number + title: Average Unsubscription Rate + description: "The average number of unsubscriptions per month for the list (not returned if we haven't calculated it yet)." + readOnly: true target_sub_rate: + type: number + title: Average Subscription Rate description: "The target number of subscriptions per month for the list to keep it growing (not returned if we haven't calculated it yet)." readOnly: true - title: Average Subscription Rate + open_rate: type: number - total_contacts: - description: "The number of contacts in the list, including subscribed, unsubscribed, pending, cleaned, deleted, transactional, and those that need to be reconfirmed." + title: Open Rate + description: "The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet)." readOnly: true - title: Total Contacts - type: integer - unsubscribe_count: - description: The number of members who have unsubscribed from the list. + click_rate: + type: number + title: Click Rate + description: "The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet)." readOnly: true - title: Unsubscribe Count - type: integer - unsubscribe_count_since_send: - description: The number of members who have unsubscribed since the last campaign was sent. + last_sub_date: + type: + - "null" + - string + title: Date of Last List Subscribe + description: The date and time of the last time someone subscribed to this list in ISO 8601 format. readOnly: true - title: Unsubscribe Count Since Send - type: integer - readOnly: true - title: Statistics + format: date-time + last_unsub_date: + type: + - "null" + - string + title: Date of Last List Unsubscribe + description: The date and time of the last time someone unsubscribed from this list in ISO 8601 format. + readOnly: true + format: date-time + _meta: type: object - subscribe_url_long: - description: "The full version of this list's subscribe form (host will vary)." - readOnly: true - title: Subscribe URL Long - type: string - subscribe_url_short: - description: "Our [EepURL shortened](https://mailchimp.com/help/share-your-signup-form/) version of this list's subscribe form." - readOnly: true - title: Subscribe URL Short - type: string - use_archive_bar: - default: false - description: "Whether campaigns for this list use the [Archive Bar](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) in archives by default." - title: Use Archive Bar - type: boolean - visibility: - description: "Whether this list is [public or private](https://mailchimp.com/help/about-list-publicity/)." - title: Visibility - type: string - web_id: - description: "The ID used in the Mailchimp web application. View this list in your Mailchimp account at `https://{dc}.admin.mailchimp.com/lists/members/?id={web_id}`." - readOnly: true - title: List Web ID - type: integer -required: - - id -title: Subscriber List -type: object + properties: + row_id: + type: integer + required: + - row_id diff --git a/source-mailchimp/acmeCo/reports.schema.yaml b/source-mailchimp/acmeCo/reports.schema.yaml index e6cd4a6dd1..5f91f03bf6 100644 --- a/source-mailchimp/acmeCo/reports.schema.yaml +++ b/source-mailchimp/acmeCo/reports.schema.yaml @@ -1,444 +1,496 @@ --- +type: object +title: Campaign Reports description: A list of reports containing campaigns marked as Sent. +required: + - id properties: - ab_split: - description: General stats about different groups of an A/B Split campaign. Does not return information about Multivariate Campaigns. - properties: - a: - description: Stats for Campaign A. - properties: - abuse_reports: - description: Abuse reports for Campaign A. - title: Abuse Reports - type: integer - bounces: - description: Bounces for Campaign A. - title: Bounces - type: integer - forwards: - description: Forwards for Campaign A. - title: Forwards - type: integer - forwards_opens: - description: Opens from forwards for Campaign A. - title: Forward Opens - type: integer - last_open: - description: The last open for Campaign A. - title: Last Open - type: string - opens: - description: Opens for Campaign A. - title: Opens - type: integer - recipient_clicks: - description: Recipient Clicks for Campaign A. - title: Recipient Clicks - type: integer - unique_opens: - description: Unique opens for Campaign A. - title: Unique Opens - type: integer - unsubs: - description: Unsubscribes for Campaign A. - title: Unsubscribes - type: integer - title: Campaign A - type: object - b: - description: Stats for Campaign B. - properties: - abuse_reports: - description: Abuse reports for Campaign B. - title: Abuse Reports - type: integer - bounces: - description: Bounces for Campaign B. - title: Bounces - type: integer - forwards: - description: Forwards for Campaign B. - title: Forwards - type: integer - forwards_opens: - description: Opens for forwards from Campaign B. - title: Forward Opens - type: integer - last_open: - description: The last open for Campaign B. - title: Last Open - type: string - opens: - description: Opens for Campaign B. - title: Opens - type: integer - recipient_clicks: - description: Recipients clicks for Campaign B. - title: Recipient Clicks - type: integer - unique_opens: - description: Unique opens for Campaign B. - title: Unique Opens - type: integer - unsubs: - description: Unsubscribes for Campaign B. - title: Unsubscribes - type: integer - title: Campaign B - type: object - title: A/B Split Stats - type: object + id: + type: string + title: Campaign ID + description: A string that uniquely identifies this campaign. + campaign_title: + type: + - "null" + - string + title: Campaign Title + description: The title of the campaign. + readOnly: true + type: + type: + - "null" + - string + title: Campaign Type + description: "The type of campaign (regular, plain-text, ab_split, rss, automation, variate, or auto)." + list_id: + type: string + title: List ID + description: The unique list id. + readOnly: true + list_is_active: + type: boolean + title: List Status + description: "The status of the list used, namely if it's deleted or disabled." + readOnly: true + list_name: + type: + - "null" + - string + title: List Name + description: The name of the list. + readOnly: true + subject_line: + type: + - "null" + - string + title: Campaign Subject Line + description: The subject line for the campaign. + readOnly: true + preview_text: + type: + - "null" + - string + title: Campaign Preview Text + description: The preview text for the campaign. + emails_sent: + type: integer + title: Emails Sent + description: The total number of emails sent for this campaign. abuse_reports: - description: The number of abuse reports generated for this campaign. + type: integer title: Abuse Reports + description: The number of abuse reports generated for this campaign. + unsubscribed: type: integer + title: Unsubscribe Count + description: The total number of unsubscribed members for this campaign. + readOnly: true + send_time: + type: + - "null" + - string + format: date-time + title: Send Time + description: The date and time a campaign was sent in ISO 8601 format. + readOnly: true + rss_last_send: + type: + - "null" + - string + format: date-time + title: RSS Last Send + description: "For RSS campaigns, the date and time of the last send in ISO 8601 format." + readOnly: true bounces: + type: object + title: Bounces description: An object describing the bounce summary for the campaign. properties: hard_bounces: - description: The total number of hard bounced email addresses. - title: Hard Bounces type: integer + title: Hard Bounces + description: The total number of hard bounced email addresses. soft_bounces: - description: The total number of soft bounced email addresses. - title: Soft Bounces type: integer + title: Soft Bounces + description: The total number of soft bounced email addresses. syntax_errors: - description: The total number of addresses that were syntax-related bounces. + type: integer title: Syntax Errors + description: The total number of addresses that were syntax-related bounces. + forwards: + type: object + title: Forwards + description: An object describing the forwards and forward activity for the campaign. + properties: + forwards_count: type: integer - title: Bounces + title: Total Forwards + description: How many times the campaign has been forwarded. + forwards_opens: + type: integer + title: Forward Opens + description: How many times the forwarded campaign has been opened. + opens: type: object - campaign_title: - description: The title of the campaign. - readOnly: true - title: Campaign Title - type: string + title: Opens + description: An object describing the open activity for the campaign. + properties: + opens_total: + type: integer + title: Total Opens + description: The total number of opens for a campaign. + unique_opens: + type: integer + title: Unique Opens + description: The total number of unique opens. + open_rate: + type: number + title: Open Rate + description: The number of unique opens divided by the total number of successful deliveries. + last_open: + type: + - "null" + - string + format: date-time + title: Last Open + description: The date and time of the last recorded open in ISO 8601 format. clicks: + type: object + title: Clicks description: An object describing the click activity for the campaign. properties: - click_rate: - description: The number of unique clicks divided by the total number of successful deliveries. - title: Click Rate - type: number clicks_total: - description: The total number of clicks for the campaign. - title: Total Clicks type: integer - last_click: - description: The date and time of the last recorded click for the campaign in ISO 8601 format. - format: date-time - title: Last Click - type: string + title: Total Clicks + description: The total number of clicks for the campaign. unique_clicks: - description: The total number of unique clicks for links across a campaign. - title: Unique Clicks type: integer + title: Unique Clicks + description: The total number of unique clicks for links across a campaign. unique_subscriber_clicks: - description: The total number of subscribers who clicked on a campaign. - title: Unique Subscriber Clicks type: integer - title: Clicks + title: Unique Subscriber Clicks + description: The total number of subscribers who clicked on a campaign. + click_rate: + type: number + title: Click Rate + description: The number of unique clicks divided by the total number of successful deliveries. + last_click: + type: + - "null" + - string + format: date-time + title: Last Click + description: The date and time of the last recorded click for the campaign in ISO 8601 format. + facebook_likes: type: object - delivery_status: - description: Updates on campaigns in the process of sending. + title: Facebook Likes + description: An object describing campaign engagement on Facebook. properties: - can_cancel: - description: Whether a campaign send can be canceled. - readOnly: true - title: Campaign Cancelable - type: boolean - emails_canceled: - description: The total number of emails canceled for this campaign. - readOnly: true - title: Emails Canceled + recipient_likes: type: integer - emails_sent: - description: The total number of emails confirmed sent for this campaign so far. - readOnly: true - title: Emails Sent + title: Recipient Likes + description: The number of recipients who liked the campaign on Facebook. + unique_likes: type: integer - enabled: - description: Whether Campaign Delivery Status is enabled for this account and campaign. - readOnly: true - title: Delivery Status Enabled - type: boolean - status: - description: The current state of a campaign delivery. - readOnly: true - title: Campaign Delivery Status - type: string - title: Campaign Delivery Status - type: object - ecommerce: - description: E-Commerce stats for a campaign. - properties: - currency_code: - example: USD - readOnly: true - title: Three letter currency code for this user - type: string - total_orders: - description: The total orders for a campaign. - readOnly: true - title: Total Orders - type: integer - total_revenue: - description: The total revenue for a campaign. Calculated as the sum of all order totals minus shipping and tax totals. - readOnly: true - title: Total Revenue - type: number - total_spent: - description: The total spent for a campaign. Calculated as the sum of all order totals with no deductions. - readOnly: true - title: Total Spent - type: number - title: E-Commerce Report - type: object - emails_sent: - description: The total number of emails sent for this campaign. - title: Emails Sent - type: integer - facebook_likes: - description: An object describing campaign engagement on Facebook. - properties: - facebook_likes: - description: The number of Facebook likes for the campaign. - title: Facebook Likes - type: integer - recipient_likes: - description: The number of recipients who liked the campaign on Facebook. - title: Recipient Likes - type: integer - unique_likes: - description: The number of unique likes. title: Unique Likes + description: The number of unique likes. + facebook_likes: type: integer - title: Facebook Likes - type: object - forwards: - description: An object describing the forwards and forward activity for the campaign. - properties: - forwards_count: - description: How many times the campaign has been forwarded. - title: Total Forwards - type: integer - forwards_opens: - description: How many times the forwarded campaign has been opened. - title: Forward Opens - type: integer - title: Forwards - type: object - id: - description: A string that uniquely identifies this campaign. - title: Campaign ID - type: string + title: Facebook Likes + description: The number of Facebook likes for the campaign. industry_stats: + type: object + title: Industry Stats description: The average campaign statistics for your industry. properties: - abuse_rate: - description: The industry abuse rate. - title: Abuse Rate - type: number - bounce_rate: - description: The industry bounce rate. - title: Bounce Rate + type: + type: + - "null" + - string + title: Industry Type + description: "The type of business industry associated with your account. For example: retail, education, etc." + open_rate: type: number + title: Open Rate + description: The industry open rate. click_rate: - description: The industry click rate. - title: Click Rate type: number - open_rate: - description: The industry open rate. - title: Open Rate + title: Click Rate + description: The industry click rate. + bounce_rate: type: number - type: - description: "The type of business industry associated with your account. For example: retail, education, etc." - title: Industry Type - type: string + title: Bounce Rate + description: The industry bounce rate. unopen_rate: - description: The industry unopened rate. - title: Unopened Rate type: number + title: Unopened Rate + description: The industry unopened rate. unsub_rate: - description: The industry unsubscribe rate. + type: number title: Unsubscribe Rate + description: The industry unsubscribe rate. + abuse_rate: type: number - title: Industry Stats - type: object - list_id: - description: The unique list id. - readOnly: true - title: List ID - type: string - list_is_active: - description: "The status of the list used, namely if it's deleted or disabled." - readOnly: true - title: List Status - type: boolean - list_name: - description: The name of the list. - readOnly: true - title: List Name - type: string + title: Abuse Rate + description: The industry abuse rate. list_stats: + type: object + title: List Stats description: "The average campaign statistics for your list. This won't be present if we haven't calculated it yet for this list." properties: - click_rate: - description: The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list. - readOnly: true - title: Click Rate - type: number - open_rate: - description: The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list. - readOnly: true - title: Open Rate - type: number sub_rate: + type: number + title: Average Subscription Rate description: The average number of subscriptions per month for the list. readOnly: true - title: Average Subscription Rate - type: number unsub_rate: + type: number + title: Average Unsubscription Rate description: The average number of unsubscriptions per month for the list. readOnly: true - title: Average Unsubscription Rate - type: number - title: List Stats - type: object - opens: - description: An object describing the open activity for the campaign. - properties: - last_open: - description: The date and time of the last recorded open in ISO 8601 format. - format: date-time - title: Last Open - type: string open_rate: - description: The number of unique opens divided by the total number of successful deliveries. - title: Open Rate type: number - opens_total: - description: The total number of opens for a campaign. - title: Total Opens - type: integer - unique_opens: - description: The total number of unique opens. - title: Unique Opens - type: integer - title: Opens - type: object - preview_text: - description: The preview text for the campaign. - title: Campaign Preview Text - type: string - rss_last_send: - description: "For RSS campaigns, the date and time of the last send in ISO 8601 format." - format: date-time - readOnly: true - title: RSS Last Send - type: string - send_time: - description: The date and time a campaign was sent in ISO 8601 format. - format: date-time - readOnly: true - title: Send Time - type: string - share_report: - description: "The url and password for the [VIP report](https://mailchimp.com/help/share-a-campaign-report/)." - properties: - share_password: - description: "If password protected, the password for the VIP report." + title: Open Rate + description: The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list. readOnly: true - title: Report Password - type: string - share_url: - description: The URL for the VIP report. + click_rate: + type: number + title: Click Rate + description: The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list. readOnly: true - title: Report URL - type: string - title: Share Report + ab_split: type: object - subject_line: - description: The subject line for the campaign. - readOnly: true - title: Campaign Subject Line - type: string - timeseries: - description: An hourly breakdown of the performance of the campaign over the first 24 hours. + title: A/B Split Stats + description: General stats about different groups of an A/B Split campaign. Does not return information about Multivariate Campaigns. + properties: + a: + type: object + title: Campaign A + description: Stats for Campaign A. + properties: + bounces: + type: integer + title: Bounces + description: Bounces for Campaign A. + abuse_reports: + type: integer + title: Abuse Reports + description: Abuse reports for Campaign A. + unsubs: + type: integer + title: Unsubscribes + description: Unsubscribes for Campaign A. + recipient_clicks: + type: integer + title: Recipient Clicks + description: Recipient Clicks for Campaign A. + forwards: + type: integer + title: Forwards + description: Forwards for Campaign A. + forwards_opens: + type: integer + title: Forward Opens + description: Opens from forwards for Campaign A. + opens: + type: integer + title: Opens + description: Opens for Campaign A. + last_open: + type: + - "null" + - string + title: Last Open + description: The last open for Campaign A. + format: date-time + unique_opens: + type: integer + title: Unique Opens + description: Unique opens for Campaign A. + b: + type: object + title: Campaign B + description: Stats for Campaign B. + properties: + bounces: + type: integer + title: Bounces + description: Bounces for Campaign B. + abuse_reports: + type: integer + title: Abuse Reports + description: Abuse reports for Campaign B. + unsubs: + type: integer + title: Unsubscribes + description: Unsubscribes for Campaign B. + recipient_clicks: + type: integer + title: Recipient Clicks + description: Recipients clicks for Campaign B. + forwards: + type: integer + title: Forwards + description: Forwards for Campaign B. + forwards_opens: + type: integer + title: Forward Opens + description: Opens for forwards from Campaign B. + opens: + type: integer + title: Opens + description: Opens for Campaign B. + last_open: + type: + - "null" + - string + title: Last Open + description: The last open for Campaign B. + format: date-time + unique_opens: + type: integer + title: Unique Opens + description: Unique opens for Campaign B. + timewarp: + type: array + title: Timewarp Stats + description: "An hourly breakdown of sends, opens, and clicks if a campaign is sent using timewarp." items: + type: object properties: - emails_sent: - description: The number of emails sent in the timeseries. - title: Emails Sent + gmt_offset: type: integer - recipients_clicks: - description: The number of clicks in the timeseries. - title: Recipient Clicks + title: GMT Offset + description: "For campaigns sent with timewarp, the time zone group the member is apart of." + opens: type: integer - timestamp: - description: The date and time for the series in ISO 8601 format. + title: Opens + description: The number of opens. + last_open: + type: + - "null" + - string format: date-time - title: Timestamp - type: string + title: Last Open + description: The date and time of the last open in ISO 8601 format. unique_opens: - description: The number of unique opens in the timeseries. - title: Unique Opens - type: integer - type: object - title: Timeseries - type: array - timewarp: - description: "An hourly breakdown of sends, opens, and clicks if a campaign is sent using timewarp." - items: - properties: - bounces: - description: The number of bounces. - title: Bounces type: integer + title: Unique Opens + description: The number of unique opens. clicks: - description: The number of clicks. - title: Clicks - type: integer - gmt_offset: - description: "For campaigns sent with timewarp, the time zone group the member is apart of." - title: GMT Offset type: integer + title: Clicks + description: The number of clicks. last_click: - description: The date and time of the last click in ISO 8601 format. + type: + - "null" + - string format: date-time title: Last Click - type: string - last_open: - description: The date and time of the last open in ISO 8601 format. - format: date-time - title: Last Open - type: string - opens: - description: The number of opens. - title: Opens - type: integer + description: The date and time of the last click in ISO 8601 format. unique_clicks: - description: The number of unique clicks. + type: integer title: Unique Clicks + description: The number of unique clicks. + bounces: type: integer + title: Bounces + description: The number of bounces. + timeseries: + type: array + title: Timeseries + description: An hourly breakdown of the performance of the campaign over the first 24 hours. + items: + type: object + properties: + timestamp: + type: + - "null" + - string + format: date-time + title: Timestamp + description: The date and time for the series in ISO 8601 format. + emails_sent: + type: integer + title: Emails Sent + description: The number of emails sent in the timeseries. unique_opens: - description: The number of unique opens. + type: integer title: Unique Opens + description: The number of unique opens in the timeseries. + recipients_clicks: type: integer - type: object - title: Timewarp Stats - type: array - type: - description: "The type of campaign (regular, plain-text, ab_split, rss, automation, variate, or auto)." - title: Campaign Type - type: string - unsubscribed: - description: The total number of unsubscribed members for this campaign. - readOnly: true - title: Unsubscribe Count - type: integer -required: - - id -title: Campaign Reports -type: object + title: Recipient Clicks + description: The number of clicks in the timeseries. + share_report: + type: object + title: Share Report + description: "The url and password for the [VIP report](https://mailchimp.com/help/share-a-campaign-report/)." + properties: + share_url: + type: + - "null" + - string + title: Report URL + description: The URL for the VIP report. + readOnly: true + share_password: + type: + - "null" + - string + title: Report Password + description: "If password protected, the password for the VIP report." + readOnly: true + ecommerce: + type: object + title: E-Commerce Report + description: E-Commerce stats for a campaign. + properties: + total_orders: + type: integer + title: Total Orders + description: The total orders for a campaign. + readOnly: true + total_spent: + type: number + title: Total Spent + description: The total spent for a campaign. Calculated as the sum of all order totals with no deductions. + readOnly: true + total_revenue: + type: number + title: Total Revenue + description: The total revenue for a campaign. Calculated as the sum of all order totals minus shipping and tax totals. + readOnly: true + currency_code: + type: + - "null" + - string + title: Three letter currency code for this user + readOnly: true + example: USD + delivery_status: + type: object + title: Campaign Delivery Status + description: Updates on campaigns in the process of sending. + properties: + enabled: + type: boolean + title: Delivery Status Enabled + description: Whether Campaign Delivery Status is enabled for this account and campaign. + readOnly: true + can_cancel: + type: boolean + title: Campaign Cancelable + description: Whether a campaign send can be canceled. + readOnly: true + status: + type: + - "null" + - string + title: Campaign Delivery Status + description: The current state of a campaign delivery. + enum: + - delivering + - delivered + - canceling + - canceled + readOnly: true + emails_sent: + type: integer + title: Emails Sent + description: The total number of emails confirmed sent for this campaign so far. + readOnly: true + emails_canceled: + type: integer + title: Emails Canceled + description: The total number of emails canceled for this campaign. + readOnly: true + _meta: + type: object + properties: + row_id: + type: integer + required: + - row_id diff --git a/source-mailchimp/acmeCo/segment_members.schema.yaml b/source-mailchimp/acmeCo/segment_members.schema.yaml new file mode 100644 index 0000000000..f3ba7a31fd --- /dev/null +++ b/source-mailchimp/acmeCo/segment_members.schema.yaml @@ -0,0 +1,153 @@ +--- +$schema: "http://json-schema.org/draft-07/schema#" +type: object +additionalProperties: true +required: + - id +properties: + id: + type: string + email_address: + type: + - "null" + - string + unique_email_id: + type: + - "null" + - string + email_type: + type: + - "null" + - string + status: + type: + - "null" + - string + merge_fields: + type: + - "null" + - object + additionalProperties: true + interests: + type: + - "null" + - object + additionalProperties: true + stats: + type: + - "null" + - object + properties: + avg_open_rate: + type: + - "null" + - number + avg_click_rate: + type: + - "null" + - number + ip_signup: + type: + - "null" + - string + timestamp_signup: + type: + - "null" + - string + format: date-time + ip_opt: + type: + - "null" + - string + timestamp_opt: + type: + - "null" + - string + format: date-time + member_rating: + type: + - "null" + - integer + last_changed: + type: + - "null" + - string + format: date-time + language: + type: + - "null" + - string + vip: + type: + - "null" + - boolean + email_client: + type: + - "null" + - string + location: + type: + - "null" + - object + properties: + latitude: + type: + - "null" + - number + longitude: + type: + - "null" + - number + gmtoff: + type: + - "null" + - integer + dstoff: + type: + - "null" + - integer + country_code: + type: + - "null" + - string + timezone: + type: + - "null" + - string + last_note: + type: + - "null" + - object + properties: + note_id: + type: + - "null" + - integer + created_at: + type: + - "null" + - string + format: date-time + created_by: + type: + - "null" + - string + note: + type: + - "null" + - string + list_id: + type: + - "null" + - string + segment_id: + type: + - "null" + - integer + _meta: + type: object + properties: + row_id: + type: integer + required: + - row_id diff --git a/source-mailchimp/acmeCo/segments.schema.yaml b/source-mailchimp/acmeCo/segments.schema.yaml new file mode 100644 index 0000000000..4ff4943917 --- /dev/null +++ b/source-mailchimp/acmeCo/segments.schema.yaml @@ -0,0 +1,73 @@ +--- +$schema: "http://json-schema.org/draft-07/schema#" +type: object +additionalProperties: true +required: + - id +properties: + id: + type: integer + name: + type: + - "null" + - string + member_count: + type: + - "null" + - integer + type: + type: + - "null" + - string + created_at: + type: + - "null" + - string + format: date-time + updated_at: + type: + - "null" + - string + format: date-time + options: + type: + - "null" + - object + properties: + match: + type: + - "null" + - string + conditions: + type: + - "null" + - array + items: + type: + - "null" + - object + additionalProperties: true + properties: + condition_type: + type: + - "null" + - string + field: + type: + - "null" + - string + op: + type: + - "null" + - string + list_id: + type: + - "null" + - string + _meta: + type: object + properties: + row_id: + type: integer + required: + - row_id diff --git a/source-mailchimp/acmeCo/unsubscribes.schema.yaml b/source-mailchimp/acmeCo/unsubscribes.schema.yaml new file mode 100644 index 0000000000..de939a331c --- /dev/null +++ b/source-mailchimp/acmeCo/unsubscribes.schema.yaml @@ -0,0 +1,48 @@ +--- +$schema: "http://json-schema.org/draft-07/schema#" +type: object +additionalProperties: true +required: + - campaign_id + - email_id + - timestamp +properties: + email_id: + type: string + email_address: + type: + - "null" + - string + merge_fields: + type: + - "null" + - object + additionalProperties: true + vip: + type: + - "null" + - boolean + timestamp: + type: string + format: date-time + reason: + type: + - "null" + - string + campaign_id: + type: string + list_id: + type: + - "null" + - string + list_is_active: + type: + - "null" + - boolean + _meta: + type: object + properties: + row_id: + type: integer + required: + - row_id diff --git a/source-mailchimp/icon.svg b/source-mailchimp/icon.svg deleted file mode 100644 index 5b135b29c0..0000000000 --- a/source-mailchimp/icon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source-mailchimp/integration_tests/__init__.py b/source-mailchimp/integration_tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/source-mailchimp/integration_tests/acceptance.py b/source-mailchimp/integration_tests/acceptance.py deleted file mode 100644 index 43ce950d77..0000000000 --- a/source-mailchimp/integration_tests/acceptance.py +++ /dev/null @@ -1,16 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - - -import pytest - -pytest_plugins = ("connector_acceptance_test.plugin",) - - -@pytest.fixture(scope="session", autouse=True) -def connector_setup(): - """This fixture is a placeholder for external resources that acceptance test might require.""" - # TODO: setup test dependencies - yield - # TODO: clean up test dependencies diff --git a/source-mailchimp/integration_tests/configured_catalog.json b/source-mailchimp/integration_tests/configured_catalog.json deleted file mode 100644 index 458ab841ad..0000000000 --- a/source-mailchimp/integration_tests/configured_catalog.json +++ /dev/null @@ -1,167 +0,0 @@ -{ - "streams": [ - { - "stream": { - "name": "automations", - "json_schema": {}, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["create_time"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "incremental", - "cursor_field": ["create_time"], - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "campaigns", - "json_schema": {}, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["create_time"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "incremental", - "cursor_field": ["create_time"], - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "interest_categories", - "json_schema": {}, - "supported_sync_modes": ["full_refresh"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "full_refresh", - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "interests", - "json_schema": {}, - "supported_sync_modes": ["full_refresh"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "full_refresh", - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "lists", - "json_schema": {}, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["date_created"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "incremental", - "cursor_field": ["date_created"], - "destination_sync_mode": "append", - "primary_key": [["id"]] - }, - { - "stream": { - "name": "email_activity", - "json_schema": {}, - "supported_sync_modes": ["incremental", "full_refresh"], - "source_defined_cursor": true, - "default_cursor_field": ["timestamp"], - "source_defined_primary_key": [["timestamp"], ["email_id"], ["action"]] - }, - "sync_mode": "incremental", - "cursor_field": ["timestamp"], - "primary_key": [["timestamp"], ["email_id"], ["action"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "list_members", - "json_schema": {}, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["last_changed"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "incremental", - "cursor_field": ["last_changed"], - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "reports", - "json_schema": {}, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["send_time"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "incremental", - "cursor_field": ["send_time"], - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "segment_members", - "json_schema": {}, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["last_changed"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "incremental", - "cursor_field": ["last_changed"], - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "segments", - "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" - }, - { - "stream": { - "name": "tags", - "json_schema": {}, - "supported_sync_modes": ["full_refresh"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "full_refresh", - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "unsubscribes", - "json_schema": {}, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["timestamp"], - "source_defined_primary_key": [ - ["campaign_id"], - ["email_id"], - ["timestamp"] - ] - }, - "sync_mode": "incremental", - "cursor_field": ["timestamp"], - "primary_key": [["campaign_id"], ["email_id"], ["timestamp"]], - "destination_sync_mode": "append" - } - ] -} diff --git a/source-mailchimp/integration_tests/configured_catalog_without_email_activities.json b/source-mailchimp/integration_tests/configured_catalog_without_email_activities.json deleted file mode 100644 index befee3dcfc..0000000000 --- a/source-mailchimp/integration_tests/configured_catalog_without_email_activities.json +++ /dev/null @@ -1,153 +0,0 @@ -{ - "streams": [ - { - "stream": { - "name": "automations", - "json_schema": {}, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["create_time"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "incremental", - "cursor_field": ["create_time"], - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "campaigns", - "json_schema": {}, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["create_time"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "incremental", - "cursor_field": ["create_time"], - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "interest_categories", - "json_schema": {}, - "supported_sync_modes": ["full_refresh"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "full_refresh", - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "interests", - "json_schema": {}, - "supported_sync_modes": ["full_refresh"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "full_refresh", - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "lists", - "json_schema": {}, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["date_created"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "incremental", - "cursor_field": ["date_created"], - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "list_members", - "json_schema": {}, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["last_changed"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "incremental", - "cursor_field": ["last_changed"], - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "reports", - "json_schema": {}, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["send_time"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "incremental", - "cursor_field": ["send_time"], - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "segment_members", - "json_schema": {}, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["last_changed"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "incremental", - "cursor_field": ["last_changed"], - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "segments", - "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" - }, - { - "stream": { - "name": "tags", - "json_schema": {}, - "supported_sync_modes": ["full_refresh"], - "source_defined_primary_key": [["id"]] - }, - "sync_mode": "full_refresh", - "primary_key": [["id"]], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "unsubscribes", - "json_schema": {}, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["timestamp"], - "source_defined_primary_key": [ - ["campaign_id"], - ["email_id"], - ["timestamp"] - ] - }, - "sync_mode": "incremental", - "cursor_field": ["timestamp"], - "primary_key": [["campaign_id"], ["email_id"], ["timestamp"]], - "destination_sync_mode": "append" - } - ] -} diff --git a/source-mailchimp/integration_tests/expected_records.jsonl b/source-mailchimp/integration_tests/expected_records.jsonl deleted file mode 100644 index f9a4f79caa..0000000000 --- a/source-mailchimp/integration_tests/expected_records.jsonl +++ /dev/null @@ -1,17 +0,0 @@ -{"stream": "campaigns", "data": {"id": "324b8a398e", "web_id": 13531140, "type": "regular", "create_time": "2022-12-27T08:12:59+00:00", "archive_url": "http://eepurl.com/ig7RxP", "long_archive_url": "https://us10.campaign-archive.com/?u=caf9055242d41edd9215d1898&id=324b8a398e", "status": "save", "emails_sent": 0, "send_time": null, "content_type": "multichannel", "needs_block_refresh": false, "resendable": false, "recipients": {"list_id": "16d6ec4ffc", "list_is_active": true, "list_name": "Airbyte", "segment_text": null, "recipient_count": 47}, "settings": {"title": "Untitled", "use_conversation": false, "to_name": null, "folder_id": null, "authenticate": true, "auto_footer": false, "inline_css": false, "auto_tweet": false, "fb_comments": true, "timewarp": false, "template_id": 13, "drag_and_drop": false}, "tracking": {"opens": true, "html_clicks": true, "text_clicks": false, "goal_tracking": false, "ecomm360": false, "google_analytics": null, "clicktale": null}, "social_card": {"image_url": "https://cdn-images.mailchimp.com/monkey_rewards/grow-business-banner-2.png", "description": null, "title": null}, "delivery_status": {"enabled": false}}, "emitted_at": 1701638872240} -{"stream": "campaigns", "data": {"id": "3cbed9a0fc", "web_id": 13531144, "type": "regular", "create_time": "2022-12-27T08:21:01+00:00", "archive_url": "http://eepurl.com/ig7SKH", "long_archive_url": "https://us10.campaign-archive.com/?u=caf9055242d41edd9215d1898&id=3cbed9a0fc", "status": "save", "emails_sent": 0, "send_time": null, "content_type": "template", "needs_block_refresh": false, "resendable": false, "recipients": {"list_id": "16d6ec4ffc", "list_is_active": true, "list_name": "Airbyte", "segment_text": null, "recipient_count": 47}, "settings": {"title": "Untitled", "use_conversation": false, "to_name": null, "folder_id": null, "authenticate": true, "auto_footer": false, "inline_css": false, "auto_tweet": false, "fb_comments": true, "timewarp": false, "template_id": 145, "drag_and_drop": true}, "tracking": {"opens": true, "html_clicks": true, "text_clicks": false, "goal_tracking": false, "ecomm360": false, "google_analytics": null, "clicktale": null}, "social_card": {"image_url": "https://cdn-images.mailchimp.com/monkey_rewards/grow-business-banner-2.png", "description": null, "title": null}, "delivery_status": {"enabled": false}}, "emitted_at": 1701638872242} -{"stream": "email_activity", "data": {"campaign_id": "7847cdaeff", "list_id": "16d6ec4ffc", "list_is_active": true, "email_id": "11273c9a5dc6ae6c5aaccfb77b2addfb", "email_address": "AirbyteMailchimpUser@gmail.com", "action": "open", "timestamp": "2023-11-06T20:17:57+00:00", "ip": "74.125.212.231"}, "emitted_at": 1701638876052} -{"stream": "email_activity", "data": {"campaign_id": "7847cdaeff", "list_id": "16d6ec4ffc", "list_is_active": true, "email_id": "11273c9a5dc6ae6c5aaccfb77b2addfb", "email_address": "AirbyteMailchimpUser@gmail.com", "action": "open", "timestamp": "2023-11-07T19:49:10+00:00", "ip": "74.125.215.162"}, "emitted_at": 1701638876053} -{"stream": "interests", "data": {"category_id": "a194ba131d", "list_id": "16d6ec4ffc", "id": "bbbb369575", "name": "Donating", "subscriber_count": "0", "display_order": 1}, "emitted_at": 1699963797987} -{"stream": "interest_categories", "data": {"list_id": "16d6ec4ffc", "id": "1bcbe8ba9b", "title": "Product Preferences", "display_order": 0, "type": "checkboxes"}, "emitted_at": 1699963796751} -{"stream": "list_members", "data": {"id": "87ed95f658a2efab665957871270de69", "email_address": "integration-test+yurii@airbyte.io", "unique_email_id": "38619c0ffd", "contact_id": "6ad2f9e1b25a09421fd8df87662b1634", "full_name": "yurii cherniaiev", "web_id": 546044412, "email_type": "html", "status": "subscribed", "consents_to_one_to_one_messaging": true, "merge_fields": {"FNAME": "yurii", "LNAME": "cherniaiev", "ADDRESS": {"addr1": "Airbyte\nkyiv\nKiev 04200\nUkraine", "addr2": null, "city": null, "state": null, "zip": null, "country": "US"}, "PHONE": null, "BIRTHDAY": null}, "interests": {"bbbb369575": false, "97bbc1227a": false, "d802d794f8": false, "b35e48738e": false, "44d2c158e3": false, "29f73b8209": false, "2010f3c101": false, "75f1cb79fd": false, "aa2fd02c59": false, "f7b60a3c3d": false, "7733d60f61": false, "cc454d76d6": false, "797533254b": false, "9ea08b864b": false, "e2e5fdcac9": false, "8eccc648d6": false, "a7c814599e": false, "20ef45c5d3": false, "1824f5d1a5": false, "644f34517f": false, "c57e1a9ff6": false, "b97fee61c8": false, "b9d16768e3": false, "810348679c": false, "43ebb04472": false, "73ee7c1d1b": false, "045738fa17": false, "0a7cbd4449": false, "fef00a4695": false, "4a19201dc9": false, "571a80ed60": false}, "stats": {"avg_open_rate": 1, "avg_click_rate": 1}, "ip_signup": null, "timestamp_signup": null, "ip_opt": "93.73.161.112", "timestamp_opt": "2022-12-27T07:56:47+00:00", "member_rating": 2, "last_changed": "2022-12-27T07:56:47+00:00", "language": null, "vip": false, "email_client": null, "location": {"latitude": 0, "longitude": 0, "gmtoff": 0, "dstoff": 0, "country_code": null, "timezone": null, "region": null}, "source": "Admin Add", "tags_count": 1, "tags": [{"id": 14351504, "name": "Overlord"}], "list_id": "16d6ec4ffc"}, "emitted_at": 1701638878091} -{"stream": "list_members", "data": {"id": "65a02406e7dc3b786af6b94489721e46", "email_address": "integration-test+Jesse@airbyte.io", "unique_email_id": "475570cf37", "contact_id": "6639385c4bdffe110d88044782e37c12", "full_name": "Jesse", "web_id": 546044440, "email_type": "html", "status": "subscribed", "consents_to_one_to_one_messaging": true, "merge_fields": {"FNAME": "Jesse", "LNAME": null, "ADDRESS": null, "PHONE": null, "BIRTHDAY": null}, "interests": {"bbbb369575": false, "97bbc1227a": false, "d802d794f8": false, "b35e48738e": false, "44d2c158e3": false, "29f73b8209": false, "2010f3c101": false, "75f1cb79fd": false, "aa2fd02c59": false, "f7b60a3c3d": false, "7733d60f61": false, "cc454d76d6": false, "797533254b": false, "9ea08b864b": false, "e2e5fdcac9": false, "8eccc648d6": false, "a7c814599e": false, "20ef45c5d3": false, "1824f5d1a5": false, "644f34517f": false, "c57e1a9ff6": false, "b97fee61c8": false, "b9d16768e3": false, "810348679c": false, "43ebb04472": false, "73ee7c1d1b": false, "045738fa17": false, "0a7cbd4449": false, "fef00a4695": false, "4a19201dc9": false, "571a80ed60": false}, "stats": {"avg_open_rate": 1, "avg_click_rate": 0}, "ip_signup": null, "timestamp_signup": null, "ip_opt": "93.73.161.112", "timestamp_opt": "2022-12-27T08:34:38+00:00", "member_rating": 2, "last_changed": "2022-12-27T08:34:38+00:00", "language": null, "vip": false, "email_client": null, "location": {"latitude": 0, "longitude": 0, "gmtoff": 0, "dstoff": 0, "country_code": null, "timezone": null, "region": null}, "source": "Import", "tags_count": 0, "tags": [], "list_id": "16d6ec4ffc"}, "emitted_at": 1701638878092} -{"stream": "lists", "data": {"id": "16d6ec4ffc", "web_id": 903380, "name": "Airbyte", "contact": {"company": "Airbyte", "address1": "kyiv", "address2": null, "city": "Kiev", "state": "30", "zip": "04200", "country": "UA", "phone": null}, "permission_reminder": "You are receiving this email because you opted in via our website.", "use_archive_bar": true, "campaign_defaults": {"from_name": "yurii", "from_email": "integration-test+yurii@airbyte.io", "subject": null, "language": "en"}, "notify_on_subscribe": null, "notify_on_unsubscribe": null, "date_created": "2022-12-27T07:56:47+00:00", "list_rating": 0, "email_type_option": false, "subscribe_url_short": "http://eepurl.com/ihg3RD", "subscribe_url_long": "https://airbyte.us10.list-manage.com/subscribe?u=caf9055242d41edd9215d1898&id=16d6ec4ffc", "beamer_address": "us10-d527bd96ba-6d1a9988db@inbound.mailchimp.com", "visibility": "prv", "double_optin": false, "has_welcome": false, "marketing_permissions": false, "modules": [], "stats": {"member_count": 47, "unsubscribe_count": 4, "cleaned_count": 0, "member_count_since_send": 0, "unsubscribe_count_since_send": 1, "cleaned_count_since_send": 0, "campaign_count": 6, "campaign_last_sent": "2022-12-27T08:37:53+00:00", "merge_field_count": 5, "avg_sub_rate": 0, "avg_unsub_rate": 0, "target_sub_rate": 0, "open_rate": 100, "click_rate": 64.70588235294117, "last_sub_date": "2022-12-27T08:34:39+00:00", "last_unsub_date": "2023-11-06T20:18:01+00:00"}}, "emitted_at": 1701638875717} -{"stream": "reports", "data": {"id": "a79651273b", "campaign_title": "Untitled", "type": "regular", "list_id": "16d6ec4ffc", "list_is_active": true, "list_name": "Airbyte", "subject_line": "Airbyte Test", "preview_text": null, "emails_sent": 50, "abuse_reports": 0, "unsubscribed": 0, "send_time": "2022-12-27T08:36:55+00:00", "bounces": {"hard_bounces": 0, "soft_bounces": 0, "syntax_errors": 0}, "forwards": {"forwards_count": 0, "forwards_opens": 0}, "opens": {"opens_total": 412, "unique_opens": 50, "open_rate": 1, "last_open": "2023-01-09T10:07:54+00:00"}, "clicks": {"clicks_total": 48, "unique_clicks": 47, "unique_subscriber_clicks": 33, "click_rate": 0.66, "last_click": "2022-12-27T15:28:11+00:00"}, "facebook_likes": {"recipient_likes": 0, "unique_likes": 0, "facebook_likes": 0}, "list_stats": {"sub_rate": 0, "unsub_rate": 0, "open_rate": 100, "click_rate": 64.70588235294117}, "timeseries": [{"timestamp": "2022-12-27T08:00:00+00:00", "emails_sent": 50, "unique_opens": 6, "recipients_clicks": 1}, {"timestamp": "2022-12-27T09:00:00+00:00", "emails_sent": 0, "unique_opens": 43, "recipients_clicks": 0}, {"timestamp": "2022-12-27T10:00:00+00:00", "emails_sent": 0, "unique_opens": 1, "recipients_clicks": 3}, {"timestamp": "2022-12-27T11:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 11}, {"timestamp": "2022-12-27T12:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 10}, {"timestamp": "2022-12-27T13:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 3}, {"timestamp": "2022-12-27T14:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 2}, {"timestamp": "2022-12-27T15:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 3}, {"timestamp": "2022-12-27T16:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-27T17:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-27T18:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-27T19:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-27T20:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-27T21:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-27T22:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-27T23:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-28T00:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-28T01:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-28T02:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-28T03:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-28T04:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-28T05:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-28T06:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2022-12-28T07:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}], "ecommerce": {"total_orders": 0, "total_spent": 0, "total_revenue": 0, "currency_code": "USD"}, "delivery_status": {"enabled": false}}, "emitted_at": 1701638878519} -{"stream": "reports", "data": {"id": "7847cdaeff", "campaign_title": "Invitation to unsubscribe", "type": "regular", "list_id": "16d6ec4ffc", "list_is_active": true, "list_name": "Airbyte", "subject_line": "Invitation to Unsubscribe", "preview_text": null, "emails_sent": 1, "abuse_reports": 0, "unsubscribed": 1, "send_time": "2023-11-06T20:17:44+00:00", "bounces": {"hard_bounces": 0, "soft_bounces": 0, "syntax_errors": 0}, "forwards": {"forwards_count": 0, "forwards_opens": 0}, "opens": {"opens_total": 2, "unique_opens": 1, "open_rate": 1, "last_open": "2023-11-07T19:49:10+00:00"}, "clicks": {"clicks_total": 0, "unique_clicks": 0, "unique_subscriber_clicks": 0, "click_rate": 0, "last_click": null}, "facebook_likes": {"recipient_likes": 0, "unique_likes": 0, "facebook_likes": 0}, "list_stats": {"sub_rate": 0, "unsub_rate": 0, "open_rate": 100, "click_rate": 64.70588235294117}, "timeseries": [{"timestamp": "2023-11-06T20:00:00+00:00", "emails_sent": 1, "unique_opens": 1, "recipients_clicks": 0}, {"timestamp": "2023-11-06T21:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-06T22:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-06T23:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T00:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T01:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T02:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T03:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T04:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T05:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T06:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T07:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T08:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T09:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T10:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T11:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T12:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T13:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T14:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T15:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T16:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T17:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T18:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}, {"timestamp": "2023-11-07T19:00:00+00:00", "emails_sent": 0, "unique_opens": 0, "recipients_clicks": 0}], "ecommerce": {"total_orders": 0, "total_spent": 0, "total_revenue": 0, "currency_code": "USD"}, "delivery_status": {"enabled": false}}, "emitted_at": 1701638878520} -{"stream": "segment_members", "data": {"id": "1dd067951f91190b65b43305b9166bc7", "email_address": "integration-test+Michael@airbyte.io", "unique_email_id": "904643439a", "email_type": "html", "status": "subscribed", "merge_fields": {"FNAME": "Michael", "LNAME": null, "ADDRESS": null, "PHONE": null, "BIRTHDAY": null}, "interests": {"bbbb369575": false, "97bbc1227a": false, "d802d794f8": false, "b35e48738e": false, "44d2c158e3": false, "29f73b8209": false, "2010f3c101": false, "75f1cb79fd": false, "aa2fd02c59": false, "f7b60a3c3d": false, "7733d60f61": false, "cc454d76d6": false, "797533254b": false, "9ea08b864b": false, "e2e5fdcac9": false, "8eccc648d6": false, "a7c814599e": false, "20ef45c5d3": false, "1824f5d1a5": false, "644f34517f": false, "c57e1a9ff6": false, "b97fee61c8": false, "b9d16768e3": false, "810348679c": false, "43ebb04472": false, "73ee7c1d1b": false, "045738fa17": false, "0a7cbd4449": false, "fef00a4695": false, "4a19201dc9": false, "571a80ed60": false}, "stats": {"avg_open_rate": 1, "avg_click_rate": 0}, "ip_signup": null, "timestamp_signup": null, "ip_opt": "93.73.161.112", "timestamp_opt": "2022-12-27T08:34:39+00:00", "member_rating": 2, "last_changed": "2022-12-27T08:34:39+00:00", "language": null, "vip": false, "email_client": null, "location": {"latitude": 0, "longitude": 0, "gmtoff": 0, "dstoff": 0, "country_code": null, "timezone": null}, "list_id": "16d6ec4ffc", "segment_id": 13506120}, "emitted_at": 1701638879995} -{"stream": "segment_members", "data": {"id": "802cb9cc84d031ca07cbf9efa3dcdc2c", "email_address": "integration-test+Carlos@airbyte.io", "unique_email_id": "41ec088075", "email_type": "html", "status": "subscribed", "merge_fields": {"FNAME": "Carlos", "LNAME": null, "ADDRESS": null, "PHONE": null, "BIRTHDAY": null}, "interests": {"bbbb369575": false, "97bbc1227a": false, "d802d794f8": false, "b35e48738e": false, "44d2c158e3": false, "29f73b8209": false, "2010f3c101": false, "75f1cb79fd": false, "aa2fd02c59": false, "f7b60a3c3d": false, "7733d60f61": false, "cc454d76d6": false, "797533254b": false, "9ea08b864b": false, "e2e5fdcac9": false, "8eccc648d6": false, "a7c814599e": false, "20ef45c5d3": false, "1824f5d1a5": false, "644f34517f": false, "c57e1a9ff6": false, "b97fee61c8": false, "b9d16768e3": false, "810348679c": false, "43ebb04472": false, "73ee7c1d1b": false, "045738fa17": false, "0a7cbd4449": false, "fef00a4695": false, "4a19201dc9": false, "571a80ed60": false}, "stats": {"avg_open_rate": 1, "avg_click_rate": 0}, "ip_signup": null, "timestamp_signup": null, "ip_opt": "93.73.161.112", "timestamp_opt": "2022-12-27T08:34:39+00:00", "member_rating": 2, "last_changed": "2022-12-27T08:34:39+00:00", "language": null, "vip": false, "email_client": null, "location": {"latitude": 0, "longitude": 0, "gmtoff": 0, "dstoff": 0, "country_code": null, "timezone": null}, "list_id": "16d6ec4ffc", "segment_id": 13506120}, "emitted_at": 1701638879996} -{"stream": "segments", "data": {"id": 13506120, "name": "Customer", "member_count": 2, "type": "static", "created_at": "2022-12-27T08:12:06+00:00", "updated_at": "2022-12-27T08:12:55+00:00", "list_id": "16d6ec4ffc"}, "emitted_at": 1701638883128} -{"stream": "segments", "data": {"id": 13506124, "name": "Member", "member_count": 0, "type": "static", "created_at": "2022-12-27T08:12:06+00:00", "updated_at": "2022-12-27T08:28:44+00:00", "list_id": "16d6ec4ffc"}, "emitted_at": 1701638883129} -{"stream": "tags", "data": {"id": 13506128, "name": "2022", "list_id": "16d6ec4ffc"}, "emitted_at": 1699963804499} -{"stream": "unsubscribes", "data": {"email_id": "11273c9a5dc6ae6c5aaccfb77b2addfb", "email_address": "AirbyteMailchimpUser@gmail.com", "merge_fields": {"FNAME": "Joe", "LNAME": "Barry", "ADDRESS": {"addr1": "109 Barry St", "addr2": null, "city": "Gary", "state": "IN", "zip": "46401", "country": "US"}, "PHONE": null, "BIRTHDAY": null}, "vip": false, "timestamp": "2023-11-06T20:18:01+00:00", "reason": "Did not signup for list", "campaign_id": "7847cdaeff", "list_id": "16d6ec4ffc", "list_is_active": true}, "emitted_at": 1701638884243} diff --git a/source-mailchimp/integration_tests/invalid_config.json b/source-mailchimp/integration_tests/invalid_config.json deleted file mode 100644 index 308434ab6d..0000000000 --- a/source-mailchimp/integration_tests/invalid_config.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "apikey": "api-key-awesome", - "username": "fakemaster@silly.com" -} diff --git a/source-mailchimp/integration_tests/invalid_config_apikey.json b/source-mailchimp/integration_tests/invalid_config_apikey.json deleted file mode 100644 index f2fd16517b..0000000000 --- a/source-mailchimp/integration_tests/invalid_config_apikey.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "credentials": { - "auth_type": "apikey", - "apikey": "api-key-awesome" - } -} diff --git a/source-mailchimp/integration_tests/invalid_config_oauth.json b/source-mailchimp/integration_tests/invalid_config_oauth.json deleted file mode 100644 index ef7ef97ee2..0000000000 --- a/source-mailchimp/integration_tests/invalid_config_oauth.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "credentials": { - "auth_type": "oauth2.0", - "client_id": "client_id", - "client_secret": "client_secret", - "access_token": "access_token" - } -} diff --git a/source-mailchimp/integration_tests/state.json b/source-mailchimp/integration_tests/state.json deleted file mode 100644 index 26b656926f..0000000000 --- a/source-mailchimp/integration_tests/state.json +++ /dev/null @@ -1,80 +0,0 @@ -[ - { - "type": "STREAM", - "stream": { - "stream_state": { "create_time": "2220-11-23T05:42:11+00:00" }, - "stream_descriptor": { "name": "campaigns" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "date_created": "2220-09-25T04:47:31+00:00" }, - "stream_descriptor": { "name": "lists" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "create_time": "2220-11-23T05:42:11+00:00" }, - "stream_descriptor": { "name": "automations" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { - "7847cdaeff": { "timestamp": "2230-11-23T05:42:10+00:00" } - }, - "stream_descriptor": { "name": "email_activity" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { - "16d6ec4ffc": { "last_changed": "2230-02-26T05:42:10+00:00" } - }, - "stream_descriptor": { "name": "list_members" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { "send_time": "2230-02-26T05:42:10+00:00" }, - "stream_descriptor": { "name": "reports" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { - "13506120": { "last_changed": "2222-12-27T08:34:39+00:00" }, - "13506136": { "last_changed": "2222-12-27T08:34:39+00:00" }, - "14351124": { "last_changed": "2222-12-27T08:34:39+00:00" }, - "14351504": { "last_changed": "2222-12-27T07:56:47+00:00" }, - "14351128": { "last_changed": "2222-12-27T08:34:39+00:00" }, - "13506132": { "last_changed": "2222-12-27T08:34:39+00:00" } - }, - "stream_descriptor": { "name": "segment_members" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { - "16d6ec4ffc": { "updated_at": "2230-02-26T05:42:10+00:00" } - }, - "stream_descriptor": { "name": "segments" } - } - }, - { - "type": "STREAM", - "stream": { - "stream_state": { - "7847cdaeff": { "timestamp": "2231-09-26T05:42:10+00:00" } - }, - "stream_descriptor": { "name": "unsubscribes" } - } - } -] diff --git a/source-mailchimp/main.py b/source-mailchimp/main.py deleted file mode 100644 index c61875fb7a..0000000000 --- a/source-mailchimp/main.py +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2023 Airbyte, Inc., all rights reserved. -# - -from source_mailchimp.run import run - -if __name__ == "__main__": - run() diff --git a/source-mailchimp/metadata.yaml b/source-mailchimp/metadata.yaml deleted file mode 100644 index eb22bc1ef3..0000000000 --- a/source-mailchimp/metadata.yaml +++ /dev/null @@ -1,48 +0,0 @@ -data: - ab_internal: - ql: 200 - sl: 200 - allowedHosts: - hosts: - - "*.api.mailchimp.com" - connectorBuildOptions: - baseImage: docker.io/airbyte/python-connector-base:1.1.0@sha256:bd98f6505c6764b1b5f99d3aedc23dfc9e9af631a62533f60eb32b1d3dbab20c - connectorSubtype: api - connectorType: source - definitionId: b03a9f3e-22a5-11eb-adc1-0242ac120002 - dockerImageTag: 1.2.0 - dockerRepository: airbyte/source-mailchimp - documentationUrl: https://docs.airbyte.com/integrations/sources/mailchimp - githubIssueLabel: source-mailchimp - icon: mailchimp.svg - license: MIT - name: Mailchimp - remoteRegistries: - pypi: - enabled: true - packageName: airbyte-source-mailchimp - registries: - cloud: - enabled: true - oss: - enabled: true - releases: - breakingChanges: - 1.0.0: - message: - Version 1.0.0 introduces schema changes to all incremental streams. - A full schema refresh and data reset are required to upgrade to this version. - For more details, see our migration guide. - upgradeDeadline: "2024-01-10" - releaseStage: generally_available - suggestedStreams: - streams: - - email_activity - - campaigns - - lists - - reports - supportLevel: certified - tags: - - language:python - - cdk:python -metadataSpecVersion: "1.0" diff --git a/source-mailchimp/poetry.lock b/source-mailchimp/poetry.lock index af61bd6aa3..4db7c577e4 100644 --- a/source-mailchimp/poetry.lock +++ b/source-mailchimp/poetry.lock @@ -1,65 +1,178 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. + +[[package]] +name = "aiodns" +version = "3.2.0" +description = "Simple DNS resolver for asyncio" +optional = false +python-versions = "*" +files = [ + {file = "aiodns-3.2.0-py3-none-any.whl", hash = "sha256:e443c0c27b07da3174a109fd9e736d69058d808f144d3c9d56dbd1776964c5f5"}, + {file = "aiodns-3.2.0.tar.gz", hash = "sha256:62869b23409349c21b072883ec8998316b234c9a9e36675756e8e317e8768f72"}, +] + +[package.dependencies] +pycares = ">=4.0.0" + +[[package]] +name = "aiohttp" +version = "3.9.5" +description = "Async http client/server framework (asyncio)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "aiohttp-3.9.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fcde4c397f673fdec23e6b05ebf8d4751314fa7c24f93334bf1f1364c1c69ac7"}, + {file = "aiohttp-3.9.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d6b3f1fabe465e819aed2c421a6743d8debbde79b6a8600739300630a01bf2c"}, + {file = "aiohttp-3.9.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ae79c1bc12c34082d92bf9422764f799aee4746fd7a392db46b7fd357d4a17a"}, + {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d3ebb9e1316ec74277d19c5f482f98cc65a73ccd5430540d6d11682cd857430"}, + {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84dabd95154f43a2ea80deffec9cb44d2e301e38a0c9d331cc4aa0166fe28ae3"}, + {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c8a02fbeca6f63cb1f0475c799679057fc9268b77075ab7cf3f1c600e81dd46b"}, + {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c26959ca7b75ff768e2776d8055bf9582a6267e24556bb7f7bd29e677932be72"}, + {file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:714d4e5231fed4ba2762ed489b4aec07b2b9953cf4ee31e9871caac895a839c0"}, + {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7a6a8354f1b62e15d48e04350f13e726fa08b62c3d7b8401c0a1314f02e3558"}, + {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c413016880e03e69d166efb5a1a95d40f83d5a3a648d16486592c49ffb76d0db"}, + {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ff84aeb864e0fac81f676be9f4685f0527b660f1efdc40dcede3c251ef1e867f"}, + {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ad7f2919d7dac062f24d6f5fe95d401597fbb015a25771f85e692d043c9d7832"}, + {file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:702e2c7c187c1a498a4e2b03155d52658fdd6fda882d3d7fbb891a5cf108bb10"}, + {file = "aiohttp-3.9.5-cp310-cp310-win32.whl", hash = "sha256:67c3119f5ddc7261d47163ed86d760ddf0e625cd6246b4ed852e82159617b5fb"}, + {file = "aiohttp-3.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:471f0ef53ccedec9995287f02caf0c068732f026455f07db3f01a46e49d76bbb"}, + {file = "aiohttp-3.9.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ae53e33ee7476dd3d1132f932eeb39bf6125083820049d06edcdca4381f342"}, + {file = "aiohttp-3.9.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c088c4d70d21f8ca5c0b8b5403fe84a7bc8e024161febdd4ef04575ef35d474d"}, + {file = "aiohttp-3.9.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:639d0042b7670222f33b0028de6b4e2fad6451462ce7df2af8aee37dcac55424"}, + {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f26383adb94da5e7fb388d441bf09c61e5e35f455a3217bfd790c6b6bc64b2ee"}, + {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66331d00fb28dc90aa606d9a54304af76b335ae204d1836f65797d6fe27f1ca2"}, + {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ff550491f5492ab5ed3533e76b8567f4b37bd2995e780a1f46bca2024223233"}, + {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f22eb3a6c1080d862befa0a89c380b4dafce29dc6cd56083f630073d102eb595"}, + {file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a81b1143d42b66ffc40a441379387076243ef7b51019204fd3ec36b9f69e77d6"}, + {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f64fd07515dad67f24b6ea4a66ae2876c01031de91c93075b8093f07c0a2d93d"}, + {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:93e22add827447d2e26d67c9ac0161756007f152fdc5210277d00a85f6c92323"}, + {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:55b39c8684a46e56ef8c8d24faf02de4a2b2ac60d26cee93bc595651ff545de9"}, + {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4715a9b778f4293b9f8ae7a0a7cef9829f02ff8d6277a39d7f40565c737d3771"}, + {file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:afc52b8d969eff14e069a710057d15ab9ac17cd4b6753042c407dcea0e40bf75"}, + {file = "aiohttp-3.9.5-cp311-cp311-win32.whl", hash = "sha256:b3df71da99c98534be076196791adca8819761f0bf6e08e07fd7da25127150d6"}, + {file = "aiohttp-3.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:88e311d98cc0bf45b62fc46c66753a83445f5ab20038bcc1b8a1cc05666f428a"}, + {file = "aiohttp-3.9.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:c7a4b7a6cf5b6eb11e109a9755fd4fda7d57395f8c575e166d363b9fc3ec4678"}, + {file = "aiohttp-3.9.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0a158704edf0abcac8ac371fbb54044f3270bdbc93e254a82b6c82be1ef08f3c"}, + {file = "aiohttp-3.9.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d153f652a687a8e95ad367a86a61e8d53d528b0530ef382ec5aaf533140ed00f"}, + {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82a6a97d9771cb48ae16979c3a3a9a18b600a8505b1115cfe354dfb2054468b4"}, + {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60cdbd56f4cad9f69c35eaac0fbbdf1f77b0ff9456cebd4902f3dd1cf096464c"}, + {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8676e8fd73141ded15ea586de0b7cda1542960a7b9ad89b2b06428e97125d4fa"}, + {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da00da442a0e31f1c69d26d224e1efd3a1ca5bcbf210978a2ca7426dfcae9f58"}, + {file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18f634d540dd099c262e9f887c8bbacc959847cfe5da7a0e2e1cf3f14dbf2daf"}, + {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:320e8618eda64e19d11bdb3bd04ccc0a816c17eaecb7e4945d01deee2a22f95f"}, + {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:2faa61a904b83142747fc6a6d7ad8fccff898c849123030f8e75d5d967fd4a81"}, + {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:8c64a6dc3fe5db7b1b4d2b5cb84c4f677768bdc340611eca673afb7cf416ef5a"}, + {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:393c7aba2b55559ef7ab791c94b44f7482a07bf7640d17b341b79081f5e5cd1a"}, + {file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c671dc117c2c21a1ca10c116cfcd6e3e44da7fcde37bf83b2be485ab377b25da"}, + {file = "aiohttp-3.9.5-cp312-cp312-win32.whl", hash = "sha256:5a7ee16aab26e76add4afc45e8f8206c95d1d75540f1039b84a03c3b3800dd59"}, + {file = "aiohttp-3.9.5-cp312-cp312-win_amd64.whl", hash = "sha256:5ca51eadbd67045396bc92a4345d1790b7301c14d1848feaac1d6a6c9289e888"}, + {file = "aiohttp-3.9.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:694d828b5c41255e54bc2dddb51a9f5150b4eefa9886e38b52605a05d96566e8"}, + {file = "aiohttp-3.9.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0605cc2c0088fcaae79f01c913a38611ad09ba68ff482402d3410bf59039bfb8"}, + {file = "aiohttp-3.9.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4558e5012ee03d2638c681e156461d37b7a113fe13970d438d95d10173d25f78"}, + {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dbc053ac75ccc63dc3a3cc547b98c7258ec35a215a92bd9f983e0aac95d3d5b"}, + {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4109adee842b90671f1b689901b948f347325045c15f46b39797ae1bf17019de"}, + {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6ea1a5b409a85477fd8e5ee6ad8f0e40bf2844c270955e09360418cfd09abac"}, + {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3c2890ca8c59ee683fd09adf32321a40fe1cf164e3387799efb2acebf090c11"}, + {file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3916c8692dbd9d55c523374a3b8213e628424d19116ac4308e434dbf6d95bbdd"}, + {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8d1964eb7617907c792ca00b341b5ec3e01ae8c280825deadbbd678447b127e1"}, + {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d5ab8e1f6bee051a4bf6195e38a5c13e5e161cb7bad83d8854524798bd9fcd6e"}, + {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:52c27110f3862a1afbcb2af4281fc9fdc40327fa286c4625dfee247c3ba90156"}, + {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:7f64cbd44443e80094309875d4f9c71d0401e966d191c3d469cde4642bc2e031"}, + {file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8b4f72fbb66279624bfe83fd5eb6aea0022dad8eec62b71e7bf63ee1caadeafe"}, + {file = "aiohttp-3.9.5-cp38-cp38-win32.whl", hash = "sha256:6380c039ec52866c06d69b5c7aad5478b24ed11696f0e72f6b807cfb261453da"}, + {file = "aiohttp-3.9.5-cp38-cp38-win_amd64.whl", hash = "sha256:da22dab31d7180f8c3ac7c7635f3bcd53808f374f6aa333fe0b0b9e14b01f91a"}, + {file = "aiohttp-3.9.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1732102949ff6087589408d76cd6dea656b93c896b011ecafff418c9661dc4ed"}, + {file = "aiohttp-3.9.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c6021d296318cb6f9414b48e6a439a7f5d1f665464da507e8ff640848ee2a58a"}, + {file = "aiohttp-3.9.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:239f975589a944eeb1bad26b8b140a59a3a320067fb3cd10b75c3092405a1372"}, + {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b7b30258348082826d274504fbc7c849959f1989d86c29bc355107accec6cfb"}, + {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd2adf5c87ff6d8b277814a28a535b59e20bfea40a101db6b3bdca7e9926bc24"}, + {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a3d838441bebcf5cf442700e3963f58b5c33f015341f9ea86dcd7d503c07e2"}, + {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e3a1ae66e3d0c17cf65c08968a5ee3180c5a95920ec2731f53343fac9bad106"}, + {file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9c69e77370cce2d6df5d12b4e12bdcca60c47ba13d1cbbc8645dd005a20b738b"}, + {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0cbf56238f4bbf49dab8c2dc2e6b1b68502b1e88d335bea59b3f5b9f4c001475"}, + {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d1469f228cd9ffddd396d9948b8c9cd8022b6d1bf1e40c6f25b0fb90b4f893ed"}, + {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:45731330e754f5811c314901cebdf19dd776a44b31927fa4b4dbecab9e457b0c"}, + {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:3fcb4046d2904378e3aeea1df51f697b0467f2aac55d232c87ba162709478c46"}, + {file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8cf142aa6c1a751fcb364158fd710b8a9be874b81889c2bd13aa8893197455e2"}, + {file = "aiohttp-3.9.5-cp39-cp39-win32.whl", hash = "sha256:7b179eea70833c8dee51ec42f3b4097bd6370892fa93f510f76762105568cf09"}, + {file = "aiohttp-3.9.5-cp39-cp39-win_amd64.whl", hash = "sha256:38d80498e2e169bc61418ff36170e0aad0cd268da8b38a17c4cf29d254a8b3f1"}, + {file = "aiohttp-3.9.5.tar.gz", hash = "sha256:edea7d15772ceeb29db4aff55e482d4bcfb6ae160ce144f2682de02f6d693551"}, +] + +[package.dependencies] +aiosignal = ">=1.1.2" +attrs = ">=17.3.0" +frozenlist = ">=1.1.1" +multidict = ">=4.5,<7.0" +yarl = ">=1.0,<2.0" + +[package.extras] +speedups = ["Brotli", "aiodns", "brotlicffi"] + +[[package]] +name = "aiosignal" +version = "1.3.1" +description = "aiosignal: a list of registered asynchronous callbacks" +optional = false +python-versions = ">=3.7" +files = [ + {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, + {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, +] + +[package.dependencies] +frozenlist = ">=1.1.0" [[package]] name = "airbyte-cdk" -version = "0.77.2" +version = "0.52.10" description = "A framework for writing Airbyte Connectors." optional = false -python-versions = "<4.0,>=3.9" +python-versions = ">=3.8" files = [ - {file = "airbyte_cdk-0.77.2-py3-none-any.whl", hash = "sha256:6dffbe0c4b3454a5cdd20525b4f1e9cfef2e80c005b6b30473fc5bf6f75af64e"}, - {file = "airbyte_cdk-0.77.2.tar.gz", hash = "sha256:84aeb27862a18e135c7bc3a5dfc363037665d428e7495e8824673f853adcca70"}, + {file = "airbyte-cdk-0.52.10.tar.gz", hash = "sha256:0daee950fe0d4453e6ceea2633090fc1d2144224e6f170b3c6cb4c6392811b47"}, + {file = "airbyte_cdk-0.52.10-py3-none-any.whl", hash = "sha256:366fd7bbbba317223edc1571d22b91c6f5bcff4ba65b3131e42f9b37e29932f4"}, ] [package.dependencies] -airbyte-protocol-models = "0.5.1" +airbyte-protocol-models = "0.4.2" backoff = "*" cachetools = "*" -Deprecated = ">=1.2,<1.3" +Deprecated = ">=1.2,<2.0" dpath = ">=2.0.1,<2.1.0" genson = "1.2.2" isodate = ">=0.6.1,<0.7.0" Jinja2 = ">=3.1.2,<3.2.0" -jsonref = ">=0.2,<0.3" +jsonref = ">=0.2,<1.0" jsonschema = ">=3.2.0,<3.3.0" -pendulum = "<3.0.0" +pendulum = "*" pydantic = ">=1.10.8,<2.0.0" -pyrate-limiter = ">=3.1.0,<3.2.0" python-dateutil = "*" -PyYAML = ">=6.0.1,<7.0.0" +PyYAML = ">=6.0.1" requests = "*" -requests_cache = "*" +requests-cache = "*" wcmatch = "8.4" [package.extras] -file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pyarrow (>=15.0.0,<15.1.0)", "pytesseract (==0.3.10)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.27)"] -sphinx-docs = ["Sphinx (>=4.2,<4.3)", "sphinx-rtd-theme (>=1.0,<1.1)"] +dev = ["avro (>=1.11.2,<1.12.0)", "cohere (==4.21)", "fastavro (>=1.8.0,<1.9.0)", "freezegun", "langchain (==0.0.271)", "markdown", "mypy", "openai[embeddings] (==0.27.9)", "pandas (==2.0.3)", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (==12.0.1)", "pytesseract (==0.3.10)", "pytest", "pytest-cov", "pytest-httpserver", "pytest-mock", "requests-mock", "tiktoken (==0.4.0)", "unstructured (==0.10.19)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.19)"] +file-based = ["avro (>=1.11.2,<1.12.0)", "fastavro (>=1.8.0,<1.9.0)", "markdown", "pdf2image (==1.16.3)", "pdfminer.six (==20221105)", "pyarrow (==12.0.1)", "pytesseract (==0.3.10)", "unstructured (==0.10.19)", "unstructured.pytesseract (>=0.3.12)", "unstructured[docx,pptx] (==0.10.19)"] +sphinx-docs = ["Sphinx (>=4.2,<5.0)", "sphinx-rtd-theme (>=1.0,<2.0)"] vector-db-based = ["cohere (==4.21)", "langchain (==0.0.271)", "openai[embeddings] (==0.27.9)", "tiktoken (==0.4.0)"] [[package]] name = "airbyte-protocol-models" -version = "0.5.1" +version = "0.4.2" description = "Declares the Airbyte Protocol." optional = false python-versions = ">=3.8" files = [ - {file = "airbyte_protocol_models-0.5.1-py3-none-any.whl", hash = "sha256:dfe84e130e51ce2ae81a06d5aa36f6c5ce3152b9e36e6f0195fad6c3dab0927e"}, - {file = "airbyte_protocol_models-0.5.1.tar.gz", hash = "sha256:7c8b16c7c1c7956b1996052e40585a3a93b1e44cb509c4e97c1ee4fe507ea086"}, + {file = "airbyte_protocol_models-0.4.2-py3-none-any.whl", hash = "sha256:d3bbb14d4af9483bd7b08f5eb06f87e7113553bf4baed3998af95be873a0d821"}, + {file = "airbyte_protocol_models-0.4.2.tar.gz", hash = "sha256:67b149d4812f8fdb88396b161274aa73cf0e16f22e35ce44f2bfc4d47e51915c"}, ] [package.dependencies] pydantic = ">=1.9.2,<2.0.0" -[[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, -] - [[package]] name = "attrs" version = "23.2.0" @@ -125,8 +238,6 @@ files = [ [package.dependencies] attrs = ">=23.1.0" -exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} [package.extras] bson = ["pymongo (>=4.4.0)"] @@ -148,6 +259,70 @@ files = [ {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, ] +[[package]] +name = "cffi" +version = "1.16.0" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, + {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, + {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, + {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, + {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, + {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, + {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, + {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, + {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, + {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, + {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, + {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, + {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, + {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, +] + +[package.dependencies] +pycparser = "*" + [[package]] name = "charset-normalizer" version = "3.3.2" @@ -258,6 +433,37 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "debugpy" +version = "1.8.1" +description = "An implementation of the Debug Adapter Protocol for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "debugpy-1.8.1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:3bda0f1e943d386cc7a0e71bfa59f4137909e2ed947fb3946c506e113000f741"}, + {file = "debugpy-1.8.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dda73bf69ea479c8577a0448f8c707691152e6c4de7f0c4dec5a4bc11dee516e"}, + {file = "debugpy-1.8.1-cp310-cp310-win32.whl", hash = "sha256:3a79c6f62adef994b2dbe9fc2cc9cc3864a23575b6e387339ab739873bea53d0"}, + {file = "debugpy-1.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:7eb7bd2b56ea3bedb009616d9e2f64aab8fc7000d481faec3cd26c98a964bcdd"}, + {file = "debugpy-1.8.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:016a9fcfc2c6b57f939673c874310d8581d51a0fe0858e7fac4e240c5eb743cb"}, + {file = "debugpy-1.8.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd97ed11a4c7f6d042d320ce03d83b20c3fb40da892f994bc041bbc415d7a099"}, + {file = "debugpy-1.8.1-cp311-cp311-win32.whl", hash = "sha256:0de56aba8249c28a300bdb0672a9b94785074eb82eb672db66c8144fff673146"}, + {file = "debugpy-1.8.1-cp311-cp311-win_amd64.whl", hash = "sha256:1a9fe0829c2b854757b4fd0a338d93bc17249a3bf69ecf765c61d4c522bb92a8"}, + {file = "debugpy-1.8.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3ebb70ba1a6524d19fa7bb122f44b74170c447d5746a503e36adc244a20ac539"}, + {file = "debugpy-1.8.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2e658a9630f27534e63922ebf655a6ab60c370f4d2fc5c02a5b19baf4410ace"}, + {file = "debugpy-1.8.1-cp312-cp312-win32.whl", hash = "sha256:caad2846e21188797a1f17fc09c31b84c7c3c23baf2516fed5b40b378515bbf0"}, + {file = "debugpy-1.8.1-cp312-cp312-win_amd64.whl", hash = "sha256:edcc9f58ec0fd121a25bc950d4578df47428d72e1a0d66c07403b04eb93bcf98"}, + {file = "debugpy-1.8.1-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:7a3afa222f6fd3d9dfecd52729bc2e12c93e22a7491405a0ecbf9e1d32d45b39"}, + {file = "debugpy-1.8.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d915a18f0597ef685e88bb35e5d7ab968964b7befefe1aaea1eb5b2640b586c7"}, + {file = "debugpy-1.8.1-cp38-cp38-win32.whl", hash = "sha256:92116039b5500633cc8d44ecc187abe2dfa9b90f7a82bbf81d079fcdd506bae9"}, + {file = "debugpy-1.8.1-cp38-cp38-win_amd64.whl", hash = "sha256:e38beb7992b5afd9d5244e96ad5fa9135e94993b0c551ceebf3fe1a5d9beb234"}, + {file = "debugpy-1.8.1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:bfb20cb57486c8e4793d41996652e5a6a885b4d9175dd369045dad59eaacea42"}, + {file = "debugpy-1.8.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efd3fdd3f67a7e576dd869c184c5dd71d9aaa36ded271939da352880c012e703"}, + {file = "debugpy-1.8.1-cp39-cp39-win32.whl", hash = "sha256:58911e8521ca0c785ac7a0539f1e77e0ce2df753f786188f382229278b4cdf23"}, + {file = "debugpy-1.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:6df9aa9599eb05ca179fb0b810282255202a66835c6efb1d112d21ecb830ddd3"}, + {file = "debugpy-1.8.1-py2.py3-none-any.whl", hash = "sha256:28acbe2241222b87e255260c76741e1fbf04fdc3b6d094fcf57b6c6f75ce1242"}, + {file = "debugpy-1.8.1.zip", hash = "sha256:f696d6be15be87aef621917585f9bb94b1dc9e8aced570db1b8a6fc14e8f9b42"}, +] + [[package]] name = "deprecated" version = "1.2.14" @@ -287,18 +493,124 @@ files = [ ] [[package]] -name = "exceptiongroup" -version = "1.2.0" -description = "Backport of PEP 654 (exception groups)" +name = "estuary-cdk" +version = "0.2.0" +description = "Estuary Connector Development Kit" +optional = false +python-versions = "^3.11" +files = [] +develop = true + +[package.dependencies] +aiodns = "^3.1.1" +aiohttp = "^3.9.3" +orjson = "^3.9.15" +pydantic = ">1.10,<3" +xxhash = "^3.4.1" + +[package.source] +type = "directory" +url = "../estuary-cdk" + +[[package]] +name = "freezegun" +version = "1.5.0" +description = "Let your Python tests travel through time" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, - {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, + {file = "freezegun-1.5.0-py3-none-any.whl", hash = "sha256:ec3f4ba030e34eb6cf7e1e257308aee2c60c3d038ff35996d7475760c9ff3719"}, + {file = "freezegun-1.5.0.tar.gz", hash = "sha256:200a64359b363aa3653d8aac289584078386c7c3da77339d257e46a01fb5c77c"}, ] -[package.extras] -test = ["pytest (>=6)"] +[package.dependencies] +python-dateutil = ">=2.7" + +[[package]] +name = "frozenlist" +version = "1.4.1" +description = "A list-like structure which implements collections.abc.MutableSequence" +optional = false +python-versions = ">=3.8" +files = [ + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc"}, + {file = "frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1"}, + {file = "frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2"}, + {file = "frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17"}, + {file = "frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8"}, + {file = "frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89"}, + {file = "frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7"}, + {file = "frozenlist-1.4.1-cp38-cp38-win32.whl", hash = "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497"}, + {file = "frozenlist-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6"}, + {file = "frozenlist-1.4.1-cp39-cp39-win32.whl", hash = "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932"}, + {file = "frozenlist-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0"}, + {file = "frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7"}, + {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, +] [[package]] name = "genson" @@ -312,13 +624,13 @@ files = [ [[package]] name = "idna" -version = "3.6" +version = "3.7" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, - {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, ] [[package]] @@ -365,13 +677,13 @@ i18n = ["Babel (>=2.7)"] [[package]] name = "jsonref" -version = "0.2" -description = "An implementation of JSON Reference for Python" +version = "0.3.0" +description = "jsonref is a library for automatic dereferencing of JSON Reference objects for Python." optional = false -python-versions = "*" +python-versions = ">=3.3,<4.0" files = [ - {file = "jsonref-0.2-py3-none-any.whl", hash = "sha256:b1e82fa0b62e2c2796a13e5401fe51790b248f6d9bf9d7212a3e31a3501b291f"}, - {file = "jsonref-0.2.tar.gz", hash = "sha256:f3c45b121cf6257eafabdc3a8008763aed1cd7da06dbabc59a9e4d2a5e4e6697"}, + {file = "jsonref-0.3.0-py3-none-any.whl", hash = "sha256:9480ad1b500f7e795daeb0ef29f9c55ae3a9ab38fb8d6659b6f4868acb5a5bc8"}, + {file = "jsonref-0.3.0.tar.gz", hash = "sha256:68b330c6815dc0d490dbb3d65ccda265ddde9f7856fd2f3322f971d456ea7549"}, ] [[package]] @@ -464,6 +776,238 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] +[[package]] +name = "mock" +version = "5.1.0" +description = "Rolling backport of unittest.mock for all Pythons" +optional = false +python-versions = ">=3.6" +files = [ + {file = "mock-5.1.0-py3-none-any.whl", hash = "sha256:18c694e5ae8a208cdb3d2c20a993ca1a7b0efa258c247a1e565150f477f83744"}, + {file = "mock-5.1.0.tar.gz", hash = "sha256:5e96aad5ccda4718e0a229ed94b2024df75cc2d55575ba5762d31f5767b8767d"}, +] + +[package.extras] +build = ["blurb", "twine", "wheel"] +docs = ["sphinx"] +test = ["pytest", "pytest-cov"] + +[[package]] +name = "multidict" +version = "6.0.5" +description = "multidict implementation" +optional = false +python-versions = ">=3.7" +files = [ + {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9"}, + {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604"}, + {file = "multidict-6.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc"}, + {file = "multidict-6.0.5-cp310-cp310-win32.whl", hash = "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319"}, + {file = "multidict-6.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e"}, + {file = "multidict-6.0.5-cp311-cp311-win32.whl", hash = "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c"}, + {file = "multidict-6.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda"}, + {file = "multidict-6.0.5-cp312-cp312-win32.whl", hash = "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5"}, + {file = "multidict-6.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556"}, + {file = "multidict-6.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:19fe01cea168585ba0f678cad6f58133db2aa14eccaf22f88e4a6dccadfad8b3"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bf7a982604375a8d49b6cc1b781c1747f243d91b81035a9b43a2126c04766f5"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:107c0cdefe028703fb5dafe640a409cb146d44a6ae201e55b35a4af8e95457dd"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:403c0911cd5d5791605808b942c88a8155c2592e05332d2bf78f18697a5fa15e"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aeaf541ddbad8311a87dd695ed9642401131ea39ad7bc8cf3ef3967fd093b626"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4972624066095e52b569e02b5ca97dbd7a7ddd4294bf4e7247d52635630dd83"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d946b0a9eb8aaa590df1fe082cee553ceab173e6cb5b03239716338629c50c7a"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b55358304d7a73d7bdf5de62494aaf70bd33015831ffd98bc498b433dfe5b10c"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:a3145cb08d8625b2d3fee1b2d596a8766352979c9bffe5d7833e0503d0f0b5e5"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d65f25da8e248202bd47445cec78e0025c0fe7582b23ec69c3b27a640dd7a8e3"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c9bf56195c6bbd293340ea82eafd0071cb3d450c703d2c93afb89f93b8386ccc"}, + {file = "multidict-6.0.5-cp37-cp37m-win32.whl", hash = "sha256:69db76c09796b313331bb7048229e3bee7928eb62bab5e071e9f7fcc4879caee"}, + {file = "multidict-6.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:76f067f5121dcecf0d63a67f29080b26c43c71a98b10c701b0677e4a065fbd54"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b82cc8ace10ab5bd93235dfaab2021c70637005e1ac787031f4d1da63d493c1d"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5cb241881eefd96b46f89b1a056187ea8e9ba14ab88ba632e68d7a2ecb7aadf7"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8e94e6912639a02ce173341ff62cc1201232ab86b8a8fcc05572741a5dc7d93"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09a892e4a9fb47331da06948690ae38eaa2426de97b4ccbfafbdcbe5c8f37ff8"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55205d03e8a598cfc688c71ca8ea5f66447164efff8869517f175ea632c7cb7b"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37b15024f864916b4951adb95d3a80c9431299080341ab9544ed148091b53f50"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2a1dee728b52b33eebff5072817176c172050d44d67befd681609b4746e1c2e"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:edd08e6f2f1a390bf137080507e44ccc086353c8e98c657e666c017718561b89"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:60d698e8179a42ec85172d12f50b1668254628425a6bd611aba022257cac1386"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3d25f19500588cbc47dc19081d78131c32637c25804df8414463ec908631e453"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4cc0ef8b962ac7a5e62b9e826bd0cd5040e7d401bc45a6835910ed699037a461"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:eca2e9d0cc5a889850e9bbd68e98314ada174ff6ccd1129500103df7a94a7a44"}, + {file = "multidict-6.0.5-cp38-cp38-win32.whl", hash = "sha256:4a6a4f196f08c58c59e0b8ef8ec441d12aee4125a7d4f4fef000ccb22f8d7241"}, + {file = "multidict-6.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e7be68734bd8c9a513f2b0cfd508802d6609da068f40dc57d4e3494cefc92929"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1d9ea7a7e779d7a3561aade7d596649fbecfa5c08a7674b11b423783217933f9"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ea1456df2a27c73ce51120fa2f519f1bea2f4a03a917f4a43c8707cf4cbbae1a"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf590b134eb70629e350691ecca88eac3e3b8b3c86992042fb82e3cb1830d5e1"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c0631926c4f58e9a5ccce555ad7747d9a9f8b10619621f22f9635f069f6233e"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1c6912ab9ff5f179eaf6efe7365c1f425ed690b03341911bf4939ef2f3046"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0868d64af83169e4d4152ec612637a543f7a336e4a307b119e98042e852ad9c"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:141b43360bfd3bdd75f15ed811850763555a251e38b2405967f8e25fb43f7d40"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7df704ca8cf4a073334e0427ae2345323613e4df18cc224f647f251e5e75a527"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6214c5a5571802c33f80e6c84713b2c79e024995b9c5897f794b43e714daeec9"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:cd6c8fca38178e12c00418de737aef1261576bd1b6e8c6134d3e729a4e858b38"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:e02021f87a5b6932fa6ce916ca004c4d441509d33bbdbeca70d05dff5e9d2479"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ebd8d160f91a764652d3e51ce0d2956b38efe37c9231cd82cfc0bed2e40b581c"}, + {file = "multidict-6.0.5-cp39-cp39-win32.whl", hash = "sha256:04da1bb8c8dbadf2a18a452639771951c662c5ad03aefe4884775454be322c9b"}, + {file = "multidict-6.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:d6f6d4f185481c9669b9447bf9d9cf3b95a0e9df9d169bbc17e363b7d5487755"}, + {file = "multidict-6.0.5-py3-none-any.whl", hash = "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7"}, + {file = "multidict-6.0.5.tar.gz", hash = "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da"}, +] + +[[package]] +name = "mypy" +version = "1.10.0" +description = "Optional static typing for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, + {file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, + {file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, + {file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, + {file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, + {file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, + {file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, + {file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, + {file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, + {file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, + {file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, + {file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, + {file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, + {file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, + {file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, + {file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, + {file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, + {file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, + {file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, + {file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, + {file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, + {file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, + {file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, + {file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, + {file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, + {file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, + {file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, +] + +[package.dependencies] +mypy-extensions = ">=1.0.0" +typing-extensions = ">=4.1.0" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +install-types = ["pip"] +mypyc = ["setuptools (>=50)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "orjson" +version = "3.10.1" +description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" +optional = false +python-versions = ">=3.8" +files = [ + {file = "orjson-3.10.1-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:8ec2fc456d53ea4a47768f622bb709be68acd455b0c6be57e91462259741c4f3"}, + {file = "orjson-3.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e900863691d327758be14e2a491931605bd0aded3a21beb6ce133889830b659"}, + {file = "orjson-3.10.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ab6ecbd6fe57785ebc86ee49e183f37d45f91b46fc601380c67c5c5e9c0014a2"}, + {file = "orjson-3.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8af7c68b01b876335cccfb4eee0beef2b5b6eae1945d46a09a7c24c9faac7a77"}, + {file = "orjson-3.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:915abfb2e528677b488a06eba173e9d7706a20fdfe9cdb15890b74ef9791b85e"}, + {file = "orjson-3.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe3fd4a36eff9c63d25503b439531d21828da9def0059c4f472e3845a081aa0b"}, + {file = "orjson-3.10.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d229564e72cfc062e6481a91977a5165c5a0fdce11ddc19ced8471847a67c517"}, + {file = "orjson-3.10.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9e00495b18304173ac843b5c5fbea7b6f7968564d0d49bef06bfaeca4b656f4e"}, + {file = "orjson-3.10.1-cp310-none-win32.whl", hash = "sha256:fd78ec55179545c108174ba19c1795ced548d6cac4d80d014163033c047ca4ea"}, + {file = "orjson-3.10.1-cp310-none-win_amd64.whl", hash = "sha256:50ca42b40d5a442a9e22eece8cf42ba3d7cd4cd0f2f20184b4d7682894f05eec"}, + {file = "orjson-3.10.1-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b345a3d6953628df2f42502297f6c1e1b475cfbf6268013c94c5ac80e8abc04c"}, + {file = "orjson-3.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:caa7395ef51af4190d2c70a364e2f42138e0e5fcb4bc08bc9b76997659b27dab"}, + {file = "orjson-3.10.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b01d701decd75ae092e5f36f7b88a1e7a1d3bb7c9b9d7694de850fb155578d5a"}, + {file = "orjson-3.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b5028981ba393f443d8fed9049211b979cadc9d0afecf162832f5a5b152c6297"}, + {file = "orjson-3.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:31ff6a222ea362b87bf21ff619598a4dc1106aaafaea32b1c4876d692891ec27"}, + {file = "orjson-3.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e852a83d7803d3406135fb7a57cf0c1e4a3e73bac80ec621bd32f01c653849c5"}, + {file = "orjson-3.10.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2567bc928ed3c3fcd90998009e8835de7c7dc59aabcf764b8374d36044864f3b"}, + {file = "orjson-3.10.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4ce98cac60b7bb56457bdd2ed7f0d5d7f242d291fdc0ca566c83fa721b52e92d"}, + {file = "orjson-3.10.1-cp311-none-win32.whl", hash = "sha256:813905e111318acb356bb8029014c77b4c647f8b03f314e7b475bd9ce6d1a8ce"}, + {file = "orjson-3.10.1-cp311-none-win_amd64.whl", hash = "sha256:03a3ca0b3ed52bed1a869163a4284e8a7b0be6a0359d521e467cdef7e8e8a3ee"}, + {file = "orjson-3.10.1-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f02c06cee680b1b3a8727ec26c36f4b3c0c9e2b26339d64471034d16f74f4ef5"}, + {file = "orjson-3.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1aa2f127ac546e123283e437cc90b5ecce754a22306c7700b11035dad4ccf85"}, + {file = "orjson-3.10.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2cf29b4b74f585225196944dffdebd549ad2af6da9e80db7115984103fb18a96"}, + {file = "orjson-3.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1b130c20b116f413caf6059c651ad32215c28500dce9cd029a334a2d84aa66f"}, + {file = "orjson-3.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d31f9a709e6114492136e87c7c6da5e21dfedebefa03af85f3ad72656c493ae9"}, + {file = "orjson-3.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d1d169461726f271ab31633cf0e7e7353417e16fb69256a4f8ecb3246a78d6e"}, + {file = "orjson-3.10.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:57c294d73825c6b7f30d11c9e5900cfec9a814893af7f14efbe06b8d0f25fba9"}, + {file = "orjson-3.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d7f11dbacfa9265ec76b4019efffabaabba7a7ebf14078f6b4df9b51c3c9a8ea"}, + {file = "orjson-3.10.1-cp312-none-win32.whl", hash = "sha256:d89e5ed68593226c31c76ab4de3e0d35c760bfd3fbf0a74c4b2be1383a1bf123"}, + {file = "orjson-3.10.1-cp312-none-win_amd64.whl", hash = "sha256:aa76c4fe147fd162107ce1692c39f7189180cfd3a27cfbc2ab5643422812da8e"}, + {file = "orjson-3.10.1-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a2c6a85c92d0e494c1ae117befc93cf8e7bca2075f7fe52e32698da650b2c6d1"}, + {file = "orjson-3.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9813f43da955197d36a7365eb99bed42b83680801729ab2487fef305b9ced866"}, + {file = "orjson-3.10.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ec917b768e2b34b7084cb6c68941f6de5812cc26c6f1a9fecb728e36a3deb9e8"}, + {file = "orjson-3.10.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5252146b3172d75c8a6d27ebca59c9ee066ffc5a277050ccec24821e68742fdf"}, + {file = "orjson-3.10.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:536429bb02791a199d976118b95014ad66f74c58b7644d21061c54ad284e00f4"}, + {file = "orjson-3.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7dfed3c3e9b9199fb9c3355b9c7e4649b65f639e50ddf50efdf86b45c6de04b5"}, + {file = "orjson-3.10.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2b230ec35f188f003f5b543644ae486b2998f6afa74ee3a98fc8ed2e45960afc"}, + {file = "orjson-3.10.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:01234249ba19c6ab1eb0b8be89f13ea21218b2d72d496ef085cfd37e1bae9dd8"}, + {file = "orjson-3.10.1-cp38-none-win32.whl", hash = "sha256:8a884fbf81a3cc22d264ba780920d4885442144e6acaa1411921260416ac9a54"}, + {file = "orjson-3.10.1-cp38-none-win_amd64.whl", hash = "sha256:dab5f802d52b182163f307d2b1f727d30b1762e1923c64c9c56dd853f9671a49"}, + {file = "orjson-3.10.1-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a51fd55d4486bc5293b7a400f9acd55a2dc3b5fc8420d5ffe9b1d6bb1a056a5e"}, + {file = "orjson-3.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53521542a6db1411b3bfa1b24ddce18605a3abdc95a28a67b33f9145f26aa8f2"}, + {file = "orjson-3.10.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:27d610df96ac18ace4931411d489637d20ab3b8f63562b0531bba16011998db0"}, + {file = "orjson-3.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79244b1456e5846d44e9846534bd9e3206712936d026ea8e6a55a7374d2c0694"}, + {file = "orjson-3.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d751efaa8a49ae15cbebdda747a62a9ae521126e396fda8143858419f3b03610"}, + {file = "orjson-3.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27ff69c620a4fff33267df70cfd21e0097c2a14216e72943bd5414943e376d77"}, + {file = "orjson-3.10.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ebc58693464146506fde0c4eb1216ff6d4e40213e61f7d40e2f0dde9b2f21650"}, + {file = "orjson-3.10.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5be608c3972ed902e0143a5b8776d81ac1059436915d42defe5c6ae97b3137a4"}, + {file = "orjson-3.10.1-cp39-none-win32.whl", hash = "sha256:4ae10753e7511d359405aadcbf96556c86e9dbf3a948d26c2c9f9a150c52b091"}, + {file = "orjson-3.10.1-cp39-none-win_amd64.whl", hash = "sha256:fb5bc4caa2c192077fdb02dce4e5ef8639e7f20bec4e3a834346693907362932"}, + {file = "orjson-3.10.1.tar.gz", hash = "sha256:a883b28d73370df23ed995c466b4f6c708c1f7a9bdc400fe89165c96c7603204"}, +] + [[package]] name = "packaging" version = "24.0" @@ -477,62 +1021,128 @@ files = [ [[package]] name = "pendulum" -version = "2.1.2" +version = "3.0.0" description = "Python datetimes made easy" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.8" files = [ - {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, - {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, - {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, - {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, - {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, - {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, - {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, - {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, - {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, - {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, - {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, - {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, - {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, - {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, - {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, - {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, + {file = "pendulum-3.0.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2cf9e53ef11668e07f73190c805dbdf07a1939c3298b78d5a9203a86775d1bfd"}, + {file = "pendulum-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fb551b9b5e6059377889d2d878d940fd0bbb80ae4810543db18e6f77b02c5ef6"}, + {file = "pendulum-3.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c58227ac260d5b01fc1025176d7b31858c9f62595737f350d22124a9a3ad82d"}, + {file = "pendulum-3.0.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60fb6f415fea93a11c52578eaa10594568a6716602be8430b167eb0d730f3332"}, + {file = "pendulum-3.0.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b69f6b4dbcb86f2c2fe696ba991e67347bcf87fe601362a1aba6431454b46bde"}, + {file = "pendulum-3.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:138afa9c373ee450ede206db5a5e9004fd3011b3c6bbe1e57015395cd076a09f"}, + {file = "pendulum-3.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:83d9031f39c6da9677164241fd0d37fbfc9dc8ade7043b5d6d62f56e81af8ad2"}, + {file = "pendulum-3.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0c2308af4033fa534f089595bcd40a95a39988ce4059ccd3dc6acb9ef14ca44a"}, + {file = "pendulum-3.0.0-cp310-none-win_amd64.whl", hash = "sha256:9a59637cdb8462bdf2dbcb9d389518c0263799189d773ad5c11db6b13064fa79"}, + {file = "pendulum-3.0.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3725245c0352c95d6ca297193192020d1b0c0f83d5ee6bb09964edc2b5a2d508"}, + {file = "pendulum-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6c035f03a3e565ed132927e2c1b691de0dbf4eb53b02a5a3c5a97e1a64e17bec"}, + {file = "pendulum-3.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:597e66e63cbd68dd6d58ac46cb7a92363d2088d37ccde2dae4332ef23e95cd00"}, + {file = "pendulum-3.0.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99a0f8172e19f3f0c0e4ace0ad1595134d5243cf75985dc2233e8f9e8de263ca"}, + {file = "pendulum-3.0.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:77d8839e20f54706aed425bec82a83b4aec74db07f26acd039905d1237a5e1d4"}, + {file = "pendulum-3.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afde30e8146292b059020fbc8b6f8fd4a60ae7c5e6f0afef937bbb24880bdf01"}, + {file = "pendulum-3.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:660434a6fcf6303c4efd36713ca9212c753140107ee169a3fc6c49c4711c2a05"}, + {file = "pendulum-3.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dee9e5a48c6999dc1106eb7eea3e3a50e98a50651b72c08a87ee2154e544b33e"}, + {file = "pendulum-3.0.0-cp311-none-win_amd64.whl", hash = "sha256:d4cdecde90aec2d67cebe4042fd2a87a4441cc02152ed7ed8fb3ebb110b94ec4"}, + {file = "pendulum-3.0.0-cp311-none-win_arm64.whl", hash = "sha256:773c3bc4ddda2dda9f1b9d51fe06762f9200f3293d75c4660c19b2614b991d83"}, + {file = "pendulum-3.0.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:409e64e41418c49f973d43a28afe5df1df4f1dd87c41c7c90f1a63f61ae0f1f7"}, + {file = "pendulum-3.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a38ad2121c5ec7c4c190c7334e789c3b4624798859156b138fcc4d92295835dc"}, + {file = "pendulum-3.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fde4d0b2024b9785f66b7f30ed59281bd60d63d9213cda0eb0910ead777f6d37"}, + {file = "pendulum-3.0.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b2c5675769fb6d4c11238132962939b960fcb365436b6d623c5864287faa319"}, + {file = "pendulum-3.0.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8af95e03e066826f0f4c65811cbee1b3123d4a45a1c3a2b4fc23c4b0dff893b5"}, + {file = "pendulum-3.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2165a8f33cb15e06c67070b8afc87a62b85c5a273e3aaa6bc9d15c93a4920d6f"}, + {file = "pendulum-3.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ad5e65b874b5e56bd942546ea7ba9dd1d6a25121db1c517700f1c9de91b28518"}, + {file = "pendulum-3.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17fe4b2c844bbf5f0ece69cfd959fa02957c61317b2161763950d88fed8e13b9"}, + {file = "pendulum-3.0.0-cp312-none-win_amd64.whl", hash = "sha256:78f8f4e7efe5066aca24a7a57511b9c2119f5c2b5eb81c46ff9222ce11e0a7a5"}, + {file = "pendulum-3.0.0-cp312-none-win_arm64.whl", hash = "sha256:28f49d8d1e32aae9c284a90b6bb3873eee15ec6e1d9042edd611b22a94ac462f"}, + {file = "pendulum-3.0.0-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:d4e2512f4e1a4670284a153b214db9719eb5d14ac55ada5b76cbdb8c5c00399d"}, + {file = "pendulum-3.0.0-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:3d897eb50883cc58d9b92f6405245f84b9286cd2de6e8694cb9ea5cb15195a32"}, + {file = "pendulum-3.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e169cc2ca419517f397811bbe4589cf3cd13fca6dc38bb352ba15ea90739ebb"}, + {file = "pendulum-3.0.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f17c3084a4524ebefd9255513692f7e7360e23c8853dc6f10c64cc184e1217ab"}, + {file = "pendulum-3.0.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:826d6e258052715f64d05ae0fc9040c0151e6a87aae7c109ba9a0ed930ce4000"}, + {file = "pendulum-3.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2aae97087872ef152a0c40e06100b3665d8cb86b59bc8471ca7c26132fccd0f"}, + {file = "pendulum-3.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ac65eeec2250d03106b5e81284ad47f0d417ca299a45e89ccc69e36130ca8bc7"}, + {file = "pendulum-3.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a5346d08f3f4a6e9e672187faa179c7bf9227897081d7121866358af369f44f9"}, + {file = "pendulum-3.0.0-cp37-none-win_amd64.whl", hash = "sha256:235d64e87946d8f95c796af34818c76e0f88c94d624c268693c85b723b698aa9"}, + {file = "pendulum-3.0.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:6a881d9c2a7f85bc9adafcfe671df5207f51f5715ae61f5d838b77a1356e8b7b"}, + {file = "pendulum-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d7762d2076b9b1cb718a6631ad6c16c23fc3fac76cbb8c454e81e80be98daa34"}, + {file = "pendulum-3.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e8e36a8130819d97a479a0e7bf379b66b3b1b520e5dc46bd7eb14634338df8c"}, + {file = "pendulum-3.0.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7dc843253ac373358ffc0711960e2dd5b94ab67530a3e204d85c6e8cb2c5fa10"}, + {file = "pendulum-3.0.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a78ad3635d609ceb1e97d6aedef6a6a6f93433ddb2312888e668365908c7120"}, + {file = "pendulum-3.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b30a137e9e0d1f751e60e67d11fc67781a572db76b2296f7b4d44554761049d6"}, + {file = "pendulum-3.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c95984037987f4a457bb760455d9ca80467be792236b69d0084f228a8ada0162"}, + {file = "pendulum-3.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d29c6e578fe0f893766c0d286adbf0b3c726a4e2341eba0917ec79c50274ec16"}, + {file = "pendulum-3.0.0-cp38-none-win_amd64.whl", hash = "sha256:deaba8e16dbfcb3d7a6b5fabdd5a38b7c982809567479987b9c89572df62e027"}, + {file = "pendulum-3.0.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b11aceea5b20b4b5382962b321dbc354af0defe35daa84e9ff3aae3c230df694"}, + {file = "pendulum-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a90d4d504e82ad236afac9adca4d6a19e4865f717034fc69bafb112c320dcc8f"}, + {file = "pendulum-3.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:825799c6b66e3734227756fa746cc34b3549c48693325b8b9f823cb7d21b19ac"}, + {file = "pendulum-3.0.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad769e98dc07972e24afe0cff8d365cb6f0ebc7e65620aa1976fcfbcadc4c6f3"}, + {file = "pendulum-3.0.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6fc26907eb5fb8cc6188cc620bc2075a6c534d981a2f045daa5f79dfe50d512"}, + {file = "pendulum-3.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c717eab1b6d898c00a3e0fa7781d615b5c5136bbd40abe82be100bb06df7a56"}, + {file = "pendulum-3.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3ddd1d66d1a714ce43acfe337190be055cdc221d911fc886d5a3aae28e14b76d"}, + {file = "pendulum-3.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:822172853d7a9cf6da95d7b66a16c7160cb99ae6df55d44373888181d7a06edc"}, + {file = "pendulum-3.0.0-cp39-none-win_amd64.whl", hash = "sha256:840de1b49cf1ec54c225a2a6f4f0784d50bd47f68e41dc005b7f67c7d5b5f3ae"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3b1f74d1e6ffe5d01d6023870e2ce5c2191486928823196f8575dcc786e107b1"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:729e9f93756a2cdfa77d0fc82068346e9731c7e884097160603872686e570f07"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e586acc0b450cd21cbf0db6bae386237011b75260a3adceddc4be15334689a9a"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22e7944ffc1f0099a79ff468ee9630c73f8c7835cd76fdb57ef7320e6a409df4"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fa30af36bd8e50686846bdace37cf6707bdd044e5cb6e1109acbad3277232e04"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:440215347b11914ae707981b9a57ab9c7b6983ab0babde07063c6ee75c0dc6e7"}, + {file = "pendulum-3.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:314c4038dc5e6a52991570f50edb2f08c339debdf8cea68ac355b32c4174e820"}, + {file = "pendulum-3.0.0-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5acb1d386337415f74f4d1955c4ce8d0201978c162927d07df8eb0692b2d8533"}, + {file = "pendulum-3.0.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a789e12fbdefaffb7b8ac67f9d8f22ba17a3050ceaaa635cd1cc4645773a4b1e"}, + {file = "pendulum-3.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:860aa9b8a888e5913bd70d819306749e5eb488e6b99cd6c47beb701b22bdecf5"}, + {file = "pendulum-3.0.0-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:5ebc65ea033ef0281368217fbf59f5cb05b338ac4dd23d60959c7afcd79a60a0"}, + {file = "pendulum-3.0.0-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d9fef18ab0386ef6a9ac7bad7e43ded42c83ff7ad412f950633854f90d59afa8"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:1c134ba2f0571d0b68b83f6972e2307a55a5a849e7dac8505c715c531d2a8795"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:385680812e7e18af200bb9b4a49777418c32422d05ad5a8eb85144c4a285907b"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eec91cd87c59fb32ec49eb722f375bd58f4be790cae11c1b70fac3ee4f00da0"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4386bffeca23c4b69ad50a36211f75b35a4deb6210bdca112ac3043deb7e494a"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:dfbcf1661d7146d7698da4b86e7f04814221081e9fe154183e34f4c5f5fa3bf8"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:04a1094a5aa1daa34a6b57c865b25f691848c61583fb22722a4df5699f6bf74c"}, + {file = "pendulum-3.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5b0ec85b9045bd49dd3a3493a5e7ddfd31c36a2a60da387c419fa04abcaecb23"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0a15b90129765b705eb2039062a6daf4d22c4e28d1a54fa260892e8c3ae6e157"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:bb8f6d7acd67a67d6fedd361ad2958ff0539445ef51cbe8cd288db4306503cd0"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd69b15374bef7e4b4440612915315cc42e8575fcda2a3d7586a0d88192d0c88"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc00f8110db6898360c53c812872662e077eaf9c75515d53ecc65d886eec209a"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:83a44e8b40655d0ba565a5c3d1365d27e3e6778ae2a05b69124db9e471255c4a"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:1a3604e9fbc06b788041b2a8b78f75c243021e0f512447806a6d37ee5214905d"}, + {file = "pendulum-3.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:92c307ae7accebd06cbae4729f0ba9fa724df5f7d91a0964b1b972a22baa482b"}, + {file = "pendulum-3.0.0.tar.gz", hash = "sha256:5d034998dea404ec31fae27af6b22cff1708f830a1ed7353be4d1019bb9f584e"}, ] [package.dependencies] -python-dateutil = ">=2.6,<3.0" -pytzdata = ">=2020.1" +python-dateutil = ">=2.6" +tzdata = ">=2020.1" + +[package.extras] +test = ["time-machine (>=2.6.0)"] [[package]] name = "platformdirs" -version = "4.2.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +version = "4.2.1" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, - {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, + {file = "platformdirs-4.2.1-py3-none-any.whl", hash = "sha256:17d5a1161b3fd67b390023cb2d3b026bbd40abde6fdb052dfbd3a29c3ba22ee1"}, + {file = "platformdirs-4.2.1.tar.gz", hash = "sha256:031cd18d4ec63ec53e82dceaac0417d218a6863f7745dfcc9efe7793b7039bdf"}, ] [package.extras] docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] [[package]] name = "pluggy" -version = "1.4.0" +version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" files = [ - {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, - {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, ] [package.extras] @@ -540,14 +1150,80 @@ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] [[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" +name = "pycares" +version = "4.4.0" +description = "Python interface for c-ares" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pycares-4.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:24da119850841d16996713d9c3374ca28a21deee056d609fbbed29065d17e1f6"}, + {file = "pycares-4.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8f64cb58729689d4d0e78f0bfb4c25ce2f851d0274c0273ac751795c04b8798a"}, + {file = "pycares-4.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d33e2a1120887e89075f7f814ec144f66a6ce06a54f5722ccefc62fbeda83cff"}, + {file = "pycares-4.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c680fef1b502ee680f8f0b95a41af4ec2c234e50e16c0af5bbda31999d3584bd"}, + {file = "pycares-4.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fff16b09042ba077f7b8aa5868d1d22456f0002574d0ba43462b10a009331677"}, + {file = "pycares-4.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:229a1675eb33bc9afb1fc463e73ee334950ccc485bc83a43f6ae5839fb4d5fa3"}, + {file = "pycares-4.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3aebc73e5ad70464f998f77f2da2063aa617cbd8d3e8174dd7c5b4518f967153"}, + {file = "pycares-4.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6ef64649eba56448f65e26546d85c860709844d2fc22ef14d324fe0b27f761a9"}, + {file = "pycares-4.4.0-cp310-cp310-win32.whl", hash = "sha256:4afc2644423f4eef97857a9fd61be9758ce5e336b4b0bd3d591238bb4b8b03e0"}, + {file = "pycares-4.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:5ed4e04af4012f875b78219d34434a6d08a67175150ac1b79eb70ab585d4ba8c"}, + {file = "pycares-4.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bce8db2fc6f3174bd39b81405210b9b88d7b607d33e56a970c34a0c190da0490"}, + {file = "pycares-4.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9a0303428d013ccf5c51de59c83f9127aba6200adb7fd4be57eddb432a1edd2a"}, + {file = "pycares-4.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afb91792f1556f97be7f7acb57dc7756d89c5a87bd8b90363a77dbf9ea653817"}, + {file = "pycares-4.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b61579cecf1f4d616e5ea31a6e423a16680ab0d3a24a2ffe7bb1d4ee162477ff"}, + {file = "pycares-4.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7af06968cbf6851566e806bf3e72825b0e6671832a2cbe840be1d2d65350710"}, + {file = "pycares-4.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ceb12974367b0a68a05d52f4162b29f575d241bd53de155efe632bf2c943c7f6"}, + {file = "pycares-4.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:2eeec144bcf6a7b6f2d74d6e70cbba7886a84dd373c886f06cb137a07de4954c"}, + {file = "pycares-4.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e3a6f7cfdfd11eb5493d6d632e582408c8f3b429f295f8799c584c108b28db6f"}, + {file = "pycares-4.4.0-cp311-cp311-win32.whl", hash = "sha256:34736a2ffaa9c08ca9c707011a2d7b69074bbf82d645d8138bba771479b2362f"}, + {file = "pycares-4.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:eb66c30eb11e877976b7ead13632082a8621df648c408b8e15cdb91a452dd502"}, + {file = "pycares-4.4.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:fd644505a8cfd7f6584d33a9066d4e3d47700f050ef1490230c962de5dfb28c6"}, + {file = "pycares-4.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:52084961262232ec04bd75f5043aed7e5d8d9695e542ff691dfef0110209f2d4"}, + {file = "pycares-4.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0c5368206057884cde18602580083aeaad9b860e2eac14fd253543158ce1e93"}, + {file = "pycares-4.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:112a4979c695b1c86f6782163d7dec58d57a3b9510536dcf4826550f9053dd9a"}, + {file = "pycares-4.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d186dafccdaa3409194c0f94db93c1a5d191145a275f19da6591f9499b8e7b8"}, + {file = "pycares-4.4.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:64965dc19c578a683ea73487a215a8897276224e004d50eeb21f0bc7a0b63c88"}, + {file = "pycares-4.4.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ed2a38e34bec6f2586435f6ff0bc5fe11d14bebd7ed492cf739a424e81681540"}, + {file = "pycares-4.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:94d6962db81541eb0396d2f0dfcbb18cdb8c8b251d165efc2d974ae652c547d4"}, + {file = "pycares-4.4.0-cp312-cp312-win32.whl", hash = "sha256:1168a48a834813aa80f412be2df4abaf630528a58d15c704857448b20b1675c0"}, + {file = "pycares-4.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:db24c4e7fea4a052c6e869cbf387dd85d53b9736cfe1ef5d8d568d1ca925e977"}, + {file = "pycares-4.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:21a5a0468861ec7df7befa69050f952da13db5427ae41ffe4713bc96291d1d95"}, + {file = "pycares-4.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:22c00bf659a9fa44d7b405cf1cd69b68b9d37537899898d8cbe5dffa4016b273"}, + {file = "pycares-4.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23aa3993a352491a47fcf17867f61472f32f874df4adcbb486294bd9fbe8abee"}, + {file = "pycares-4.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:813d661cbe2e37d87da2d16b7110a6860e93ddb11735c6919c8a3545c7b9c8d8"}, + {file = "pycares-4.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:77cf5a2fd5583c670de41a7f4a7b46e5cbabe7180d8029f728571f4d2e864084"}, + {file = "pycares-4.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3eaa6681c0a3e3f3868c77aca14b7760fed35fdfda2fe587e15c701950e7bc69"}, + {file = "pycares-4.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ad58e284a658a8a6a84af2e0b62f2f961f303cedfe551854d7bd40c3cbb61912"}, + {file = "pycares-4.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bfb89ca9e3d0a9b5332deeb666b2ede9d3469107742158f4aeda5ce032d003f4"}, + {file = "pycares-4.4.0-cp38-cp38-win32.whl", hash = "sha256:f36bdc1562142e3695555d2f4ac0cb69af165eddcefa98efc1c79495b533481f"}, + {file = "pycares-4.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:902461a92b6a80fd5041a2ec5235680c7cc35e43615639ec2a40e63fca2dfb51"}, + {file = "pycares-4.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7bddc6adba8f699728f7fc1c9ce8cef359817ad78e2ed52b9502cb5f8dc7f741"}, + {file = "pycares-4.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cb49d5805cd347c404f928c5ae7c35e86ba0c58ffa701dbe905365e77ce7d641"}, + {file = "pycares-4.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56cf3349fa3a2e67ed387a7974c11d233734636fe19facfcda261b411af14d80"}, + {file = "pycares-4.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bf2eaa83a5987e48fa63302f0fe7ce3275cfda87b34d40fef9ce703fb3ac002"}, + {file = "pycares-4.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82bba2ab77eb5addbf9758d514d9bdef3c1bfe7d1649a47bd9a0d55a23ef478b"}, + {file = "pycares-4.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c6a8bde63106f162fca736e842a916853cad3c8d9d137e11c9ffa37efa818b02"}, + {file = "pycares-4.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f5f646eec041db6ffdbcaf3e0756fb92018f7af3266138c756bb09d2b5baadec"}, + {file = "pycares-4.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9dc04c54c6ea615210c1b9e803d0e2d2255f87a3d5d119b6482c8f0dfa15b26b"}, + {file = "pycares-4.4.0-cp39-cp39-win32.whl", hash = "sha256:97892cced5794d721fb4ff8765764aa4ea48fe8b2c3820677505b96b83d4ef47"}, + {file = "pycares-4.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:917f08f0b5d9324e9a34211e68d27447c552b50ab967044776bbab7e42a553a2"}, + {file = "pycares-4.4.0.tar.gz", hash = "sha256:f47579d508f2f56eddd16ce72045782ad3b1b3b678098699e2b6a1b30733e1c2"}, +] + +[package.dependencies] +cffi = ">=1.5.0" + +[package.extras] +idna = ["idna (>=2.1)"] + +[[package]] +name = "pycparser" +version = "2.22" +description = "C parser in Python" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.8" files = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, ] [[package]] @@ -602,21 +1278,6 @@ typing-extensions = ">=4.2.0" dotenv = ["python-dotenv (>=0.10.4)"] email = ["email-validator (>=1.0.3)"] -[[package]] -name = "pyrate-limiter" -version = "3.1.1" -description = "Python Rate-Limiter using Leaky-Bucket Algorithm" -optional = false -python-versions = ">=3.8,<4.0" -files = [ - {file = "pyrate_limiter-3.1.1-py3-none-any.whl", hash = "sha256:c51906f1d51d56dc992ff6c26e8300e32151bc6cfa3e6559792e31971dfd4e2b"}, - {file = "pyrate_limiter-3.1.1.tar.gz", hash = "sha256:2f57eda712687e6eccddf6afe8f8a15b409b97ed675fe64a626058f12863b7b7"}, -] - -[package.extras] -all = ["filelock (>=3.0)", "redis (>=5.0.0,<6.0.0)"] -docs = ["furo (>=2022.3.4,<2023.0.0)", "myst-parser (>=0.17)", "sphinx (>=4.3.0,<5.0.0)", "sphinx-autodoc-typehints (>=1.17,<2.0)", "sphinx-copybutton (>=0.5)", "sphinxcontrib-apidoc (>=0.3,<0.4)"] - [[package]] name = "pyrsistent" version = "0.20.0" @@ -660,27 +1321,38 @@ files = [ [[package]] name = "pytest" -version = "6.2.5" +version = "7.4.4" description = "pytest: simple powerful testing with Python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, ] [package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-insta" +version = "0.3.0" +description = "A practical snapshot testing plugin for pytest" +optional = false +python-versions = ">=3.10,<4.0" +files = [ + {file = "pytest_insta-0.3.0-py3-none-any.whl", hash = "sha256:93a105e3850f2887b120a581923b10bb313d722e00d369377a1d91aa535df704"}, + {file = "pytest_insta-0.3.0.tar.gz", hash = "sha256:9e6e1c70a021f68ccc4643360b2c2f8326cf3befba85f942c1da17b9caf713f7"}, +] + +[package.dependencies] +pytest = ">=7.2.0,<9.0.0" +wrapt = ">=1.14.1,<2.0.0" [[package]] name = "pytest-mock" @@ -713,17 +1385,6 @@ files = [ [package.dependencies] six = ">=1.5" -[[package]] -name = "pytzdata" -version = "2020.1" -description = "The Olson timezone database for Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -files = [ - {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, - {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, -] - [[package]] name = "pyyaml" version = "6.0.1" @@ -837,13 +1498,13 @@ yaml = ["pyyaml (>=6.0.1)"] [[package]] name = "requests-mock" -version = "1.12.0" +version = "1.12.1" description = "Mock out responses from the requests package" optional = false -python-versions = "*" +python-versions = ">=3.5" files = [ - {file = "requests-mock-1.12.0.tar.gz", hash = "sha256:4e34f2a2752f0b78397fb414526605d95fcdeab021ac1f26d18960e7eb41f6a8"}, - {file = "requests_mock-1.12.0-py2.py3-none-any.whl", hash = "sha256:4f6fdf956de568e0bac99eee4ad96b391c602e614cc0ad33e7f5c72edd699e70"}, + {file = "requests-mock-1.12.1.tar.gz", hash = "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401"}, + {file = "requests_mock-1.12.1-py2.py3-none-any.whl", hash = "sha256:b1e37054004cdd5e56c84454cc7df12b25f90f382159087f4b6915aaeef39563"}, ] [package.dependencies] @@ -854,36 +1515,37 @@ fixture = ["fixtures"] [[package]] name = "responses" -version = "0.19.0" +version = "0.25.0" description = "A utility library for mocking out the `requests` Python library." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "responses-0.19.0-py3-none-any.whl", hash = "sha256:53354b5de163aa2074312c71d8ebccb8bd1ab336cff7053abb75e84dc5637abe"}, - {file = "responses-0.19.0.tar.gz", hash = "sha256:3fc29c3117e14136b833a0a6d4e7f1217c6301bf08b6086db468e12f1e3290e2"}, + {file = "responses-0.25.0-py3-none-any.whl", hash = "sha256:2f0b9c2b6437db4b528619a77e5d565e4ec2a9532162ac1a131a83529db7be1a"}, + {file = "responses-0.25.0.tar.gz", hash = "sha256:01ae6a02b4f34e39bffceb0fc6786b67a25eae919c6368d05eabc8d9576c2a66"}, ] [package.dependencies] -requests = ">=2.0,<3.0" -urllib3 = ">=1.25.10" +pyyaml = "*" +requests = ">=2.30.0,<3.0" +urllib3 = ">=1.25.10,<3.0" [package.extras] -tests = ["coverage (>=6.0.0)", "flake8", "mypy", "pytest (>=7.0.0)", "pytest-asyncio", "pytest-cov", "pytest-localserver", "types-mock", "types-requests"] +tests = ["coverage (>=6.0.0)", "flake8", "mypy", "pytest (>=7.0.0)", "pytest-asyncio", "pytest-cov", "pytest-httpserver", "tomli", "tomli-w", "types-PyYAML", "types-requests"] [[package]] name = "setuptools" -version = "69.2.0" +version = "69.5.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.2.0-py3-none-any.whl", hash = "sha256:c21c49fb1042386df081cb5d86759792ab89efca84cf114889191cd09aacc80c"}, - {file = "setuptools-69.2.0.tar.gz", hash = "sha256:0ff4183f8f42cd8fa3acea16c45205521a4ef28f73c6391d8a25e92893134f2e"}, + {file = "setuptools-69.5.1-py3-none-any.whl", hash = "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32"}, + {file = "setuptools-69.5.1.tar.gz", hash = "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] @@ -898,25 +1560,25 @@ files = [ ] [[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" +name = "typing-extensions" +version = "4.11.0" +description = "Backported and Experimental Type Hints for Python 3.8+" optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +python-versions = ">=3.8" files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, + {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"}, + {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"}, ] [[package]] -name = "typing-extensions" -version = "4.10.0" -description = "Backported and Experimental Type Hints for Python 3.8+" +name = "tzdata" +version = "2024.1" +description = "Provider of IANA time zone data" optional = false -python-versions = ">=3.8" +python-versions = ">=2" files = [ - {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, - {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, + {file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"}, + {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, ] [[package]] @@ -1043,7 +1705,227 @@ files = [ {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, ] +[[package]] +name = "xxhash" +version = "3.4.1" +description = "Python binding for xxHash" +optional = false +python-versions = ">=3.7" +files = [ + {file = "xxhash-3.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:91dbfa55346ad3e18e738742236554531a621042e419b70ad8f3c1d9c7a16e7f"}, + {file = "xxhash-3.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:665a65c2a48a72068fcc4d21721510df5f51f1142541c890491afc80451636d2"}, + {file = "xxhash-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb11628470a6004dc71a09fe90c2f459ff03d611376c1debeec2d648f44cb693"}, + {file = "xxhash-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5bef2a7dc7b4f4beb45a1edbba9b9194c60a43a89598a87f1a0226d183764189"}, + {file = "xxhash-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c0f7b2d547d72c7eda7aa817acf8791f0146b12b9eba1d4432c531fb0352228"}, + {file = "xxhash-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00f2fdef6b41c9db3d2fc0e7f94cb3db86693e5c45d6de09625caad9a469635b"}, + {file = "xxhash-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23cfd9ca09acaf07a43e5a695143d9a21bf00f5b49b15c07d5388cadf1f9ce11"}, + {file = "xxhash-3.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6a9ff50a3cf88355ca4731682c168049af1ca222d1d2925ef7119c1a78e95b3b"}, + {file = "xxhash-3.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f1d7c69a1e9ca5faa75546fdd267f214f63f52f12692f9b3a2f6467c9e67d5e7"}, + {file = "xxhash-3.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:672b273040d5d5a6864a36287f3514efcd1d4b1b6a7480f294c4b1d1ee1b8de0"}, + {file = "xxhash-3.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4178f78d70e88f1c4a89ff1ffe9f43147185930bb962ee3979dba15f2b1cc799"}, + {file = "xxhash-3.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9804b9eb254d4b8cc83ab5a2002128f7d631dd427aa873c8727dba7f1f0d1c2b"}, + {file = "xxhash-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c09c49473212d9c87261d22c74370457cfff5db2ddfc7fd1e35c80c31a8c14ce"}, + {file = "xxhash-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:ebbb1616435b4a194ce3466d7247df23499475c7ed4eb2681a1fa42ff766aff6"}, + {file = "xxhash-3.4.1-cp310-cp310-win_arm64.whl", hash = "sha256:25dc66be3db54f8a2d136f695b00cfe88018e59ccff0f3b8f545869f376a8a46"}, + {file = "xxhash-3.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:58c49083801885273e262c0f5bbeac23e520564b8357fbb18fb94ff09d3d3ea5"}, + {file = "xxhash-3.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b526015a973bfbe81e804a586b703f163861da36d186627e27524f5427b0d520"}, + {file = "xxhash-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36ad4457644c91a966f6fe137d7467636bdc51a6ce10a1d04f365c70d6a16d7e"}, + {file = "xxhash-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:248d3e83d119770f96003271fe41e049dd4ae52da2feb8f832b7a20e791d2920"}, + {file = "xxhash-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2070b6d5bbef5ee031666cf21d4953c16e92c2f8a24a94b5c240f8995ba3b1d0"}, + {file = "xxhash-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2746035f518f0410915e247877f7df43ef3372bf36cfa52cc4bc33e85242641"}, + {file = "xxhash-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a8ba6181514681c2591840d5632fcf7356ab287d4aff1c8dea20f3c78097088"}, + {file = "xxhash-3.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0aac5010869240e95f740de43cd6a05eae180c59edd182ad93bf12ee289484fa"}, + {file = "xxhash-3.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4cb11d8debab1626181633d184b2372aaa09825bde709bf927704ed72765bed1"}, + {file = "xxhash-3.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:b29728cff2c12f3d9f1d940528ee83918d803c0567866e062683f300d1d2eff3"}, + {file = "xxhash-3.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:a15cbf3a9c40672523bdb6ea97ff74b443406ba0ab9bca10ceccd9546414bd84"}, + {file = "xxhash-3.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6e66df260fed01ed8ea790c2913271641c58481e807790d9fca8bfd5a3c13844"}, + {file = "xxhash-3.4.1-cp311-cp311-win32.whl", hash = "sha256:e867f68a8f381ea12858e6d67378c05359d3a53a888913b5f7d35fbf68939d5f"}, + {file = "xxhash-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:200a5a3ad9c7c0c02ed1484a1d838b63edcf92ff538770ea07456a3732c577f4"}, + {file = "xxhash-3.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:1d03f1c0d16d24ea032e99f61c552cb2b77d502e545187338bea461fde253583"}, + {file = "xxhash-3.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c4bbba9b182697a52bc0c9f8ec0ba1acb914b4937cd4a877ad78a3b3eeabefb3"}, + {file = "xxhash-3.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9fd28a9da300e64e434cfc96567a8387d9a96e824a9be1452a1e7248b7763b78"}, + {file = "xxhash-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6066d88c9329ab230e18998daec53d819daeee99d003955c8db6fc4971b45ca3"}, + {file = "xxhash-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93805bc3233ad89abf51772f2ed3355097a5dc74e6080de19706fc447da99cd3"}, + {file = "xxhash-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64da57d5ed586ebb2ecdde1e997fa37c27fe32fe61a656b77fabbc58e6fbff6e"}, + {file = "xxhash-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a97322e9a7440bf3c9805cbaac090358b43f650516486746f7fa482672593df"}, + {file = "xxhash-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bbe750d512982ee7d831838a5dee9e9848f3fb440e4734cca3f298228cc957a6"}, + {file = "xxhash-3.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:fd79d4087727daf4d5b8afe594b37d611ab95dc8e29fe1a7517320794837eb7d"}, + {file = "xxhash-3.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:743612da4071ff9aa4d055f3f111ae5247342931dedb955268954ef7201a71ff"}, + {file = "xxhash-3.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:b41edaf05734092f24f48c0958b3c6cbaaa5b7e024880692078c6b1f8247e2fc"}, + {file = "xxhash-3.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:a90356ead70d715fe64c30cd0969072de1860e56b78adf7c69d954b43e29d9fa"}, + {file = "xxhash-3.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ac56eebb364e44c85e1d9e9cc5f6031d78a34f0092fea7fc80478139369a8b4a"}, + {file = "xxhash-3.4.1-cp312-cp312-win32.whl", hash = "sha256:911035345932a153c427107397c1518f8ce456f93c618dd1c5b54ebb22e73747"}, + {file = "xxhash-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:f31ce76489f8601cc7b8713201ce94b4bd7b7ce90ba3353dccce7e9e1fee71fa"}, + {file = "xxhash-3.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:b5beb1c6a72fdc7584102f42c4d9df232ee018ddf806e8c90906547dfb43b2da"}, + {file = "xxhash-3.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6d42b24d1496deb05dee5a24ed510b16de1d6c866c626c2beb11aebf3be278b9"}, + {file = "xxhash-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b685fab18876b14a8f94813fa2ca80cfb5ab6a85d31d5539b7cd749ce9e3624"}, + {file = "xxhash-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:419ffe34c17ae2df019a4685e8d3934d46b2e0bbe46221ab40b7e04ed9f11137"}, + {file = "xxhash-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e041ce5714f95251a88670c114b748bca3bf80cc72400e9f23e6d0d59cf2681"}, + {file = "xxhash-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc860d887c5cb2f524899fb8338e1bb3d5789f75fac179101920d9afddef284b"}, + {file = "xxhash-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:312eba88ffe0a05e332e3a6f9788b73883752be63f8588a6dc1261a3eaaaf2b2"}, + {file = "xxhash-3.4.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:e01226b6b6a1ffe4e6bd6d08cfcb3ca708b16f02eb06dd44f3c6e53285f03e4f"}, + {file = "xxhash-3.4.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9f3025a0d5d8cf406a9313cd0d5789c77433ba2004b1c75439b67678e5136537"}, + {file = "xxhash-3.4.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:6d3472fd4afef2a567d5f14411d94060099901cd8ce9788b22b8c6f13c606a93"}, + {file = "xxhash-3.4.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:43984c0a92f06cac434ad181f329a1445017c33807b7ae4f033878d860a4b0f2"}, + {file = "xxhash-3.4.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a55e0506fdb09640a82ec4f44171273eeabf6f371a4ec605633adb2837b5d9d5"}, + {file = "xxhash-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:faec30437919555b039a8bdbaba49c013043e8f76c999670aef146d33e05b3a0"}, + {file = "xxhash-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:c9e1b646af61f1fc7083bb7b40536be944f1ac67ef5e360bca2d73430186971a"}, + {file = "xxhash-3.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:961d948b7b1c1b6c08484bbce3d489cdf153e4122c3dfb07c2039621243d8795"}, + {file = "xxhash-3.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:719a378930504ab159f7b8e20fa2aa1896cde050011af838af7e7e3518dd82de"}, + {file = "xxhash-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74fb5cb9406ccd7c4dd917f16630d2e5e8cbbb02fc2fca4e559b2a47a64f4940"}, + {file = "xxhash-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5dab508ac39e0ab988039bc7f962c6ad021acd81fd29145962b068df4148c476"}, + {file = "xxhash-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c59f3e46e7daf4c589e8e853d700ef6607afa037bfad32c390175da28127e8c"}, + {file = "xxhash-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cc07256eff0795e0f642df74ad096f8c5d23fe66bc138b83970b50fc7f7f6c5"}, + {file = "xxhash-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e9f749999ed80f3955a4af0eb18bb43993f04939350b07b8dd2f44edc98ffee9"}, + {file = "xxhash-3.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7688d7c02149a90a3d46d55b341ab7ad1b4a3f767be2357e211b4e893efbaaf6"}, + {file = "xxhash-3.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a8b4977963926f60b0d4f830941c864bed16aa151206c01ad5c531636da5708e"}, + {file = "xxhash-3.4.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:8106d88da330f6535a58a8195aa463ef5281a9aa23b04af1848ff715c4398fb4"}, + {file = "xxhash-3.4.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4c76a77dbd169450b61c06fd2d5d436189fc8ab7c1571d39265d4822da16df22"}, + {file = "xxhash-3.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:11f11357c86d83e53719c592021fd524efa9cf024dc7cb1dfb57bbbd0d8713f2"}, + {file = "xxhash-3.4.1-cp38-cp38-win32.whl", hash = "sha256:0c786a6cd74e8765c6809892a0d45886e7c3dc54de4985b4a5eb8b630f3b8e3b"}, + {file = "xxhash-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:aabf37fb8fa27430d50507deeab2ee7b1bcce89910dd10657c38e71fee835594"}, + {file = "xxhash-3.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6127813abc1477f3a83529b6bbcfeddc23162cece76fa69aee8f6a8a97720562"}, + {file = "xxhash-3.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ef2e194262f5db16075caea7b3f7f49392242c688412f386d3c7b07c7733a70a"}, + {file = "xxhash-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71be94265b6c6590f0018bbf73759d21a41c6bda20409782d8117e76cd0dfa8b"}, + {file = "xxhash-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10e0a619cdd1c0980e25eb04e30fe96cf8f4324758fa497080af9c21a6de573f"}, + {file = "xxhash-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa122124d2e3bd36581dd78c0efa5f429f5220313479fb1072858188bc2d5ff1"}, + {file = "xxhash-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17032f5a4fea0a074717fe33477cb5ee723a5f428de7563e75af64bfc1b1e10"}, + {file = "xxhash-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca7783b20e3e4f3f52f093538895863f21d18598f9a48211ad757680c3bd006f"}, + {file = "xxhash-3.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d77d09a1113899fad5f354a1eb4f0a9afcf58cefff51082c8ad643ff890e30cf"}, + {file = "xxhash-3.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:21287bcdd299fdc3328cc0fbbdeaa46838a1c05391264e51ddb38a3f5b09611f"}, + {file = "xxhash-3.4.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:dfd7a6cc483e20b4ad90224aeb589e64ec0f31e5610ab9957ff4314270b2bf31"}, + {file = "xxhash-3.4.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:543c7fcbc02bbb4840ea9915134e14dc3dc15cbd5a30873a7a5bf66039db97ec"}, + {file = "xxhash-3.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fe0a98d990e433013f41827b62be9ab43e3cf18e08b1483fcc343bda0d691182"}, + {file = "xxhash-3.4.1-cp39-cp39-win32.whl", hash = "sha256:b9097af00ebf429cc7c0e7d2fdf28384e4e2e91008130ccda8d5ae653db71e54"}, + {file = "xxhash-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:d699b921af0dcde50ab18be76c0d832f803034d80470703700cb7df0fbec2832"}, + {file = "xxhash-3.4.1-cp39-cp39-win_arm64.whl", hash = "sha256:2be491723405e15cc099ade1280133ccfbf6322d2ef568494fb7d07d280e7eee"}, + {file = "xxhash-3.4.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:431625fad7ab5649368c4849d2b49a83dc711b1f20e1f7f04955aab86cd307bc"}, + {file = "xxhash-3.4.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc6dbd5fc3c9886a9e041848508b7fb65fd82f94cc793253990f81617b61fe49"}, + {file = "xxhash-3.4.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3ff8dbd0ec97aec842476cb8ccc3e17dd288cd6ce3c8ef38bff83d6eb927817"}, + {file = "xxhash-3.4.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef73a53fe90558a4096e3256752268a8bdc0322f4692ed928b6cd7ce06ad4fe3"}, + {file = "xxhash-3.4.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:450401f42bbd274b519d3d8dcf3c57166913381a3d2664d6609004685039f9d3"}, + {file = "xxhash-3.4.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:a162840cf4de8a7cd8720ff3b4417fbc10001eefdd2d21541a8226bb5556e3bb"}, + {file = "xxhash-3.4.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b736a2a2728ba45017cb67785e03125a79d246462dfa892d023b827007412c52"}, + {file = "xxhash-3.4.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d0ae4c2e7698adef58710d6e7a32ff518b66b98854b1c68e70eee504ad061d8"}, + {file = "xxhash-3.4.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6322c4291c3ff174dcd104fae41500e75dad12be6f3085d119c2c8a80956c51"}, + {file = "xxhash-3.4.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:dd59ed668801c3fae282f8f4edadf6dc7784db6d18139b584b6d9677ddde1b6b"}, + {file = "xxhash-3.4.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:92693c487e39523a80474b0394645b393f0ae781d8db3474ccdcead0559ccf45"}, + {file = "xxhash-3.4.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4603a0f642a1e8d7f3ba5c4c25509aca6a9c1cc16f85091004a7028607ead663"}, + {file = "xxhash-3.4.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fa45e8cbfbadb40a920fe9ca40c34b393e0b067082d94006f7f64e70c7490a6"}, + {file = "xxhash-3.4.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:595b252943b3552de491ff51e5bb79660f84f033977f88f6ca1605846637b7c6"}, + {file = "xxhash-3.4.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:562d8b8f783c6af969806aaacf95b6c7b776929ae26c0cd941d54644ea7ef51e"}, + {file = "xxhash-3.4.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:41ddeae47cf2828335d8d991f2d2b03b0bdc89289dc64349d712ff8ce59d0647"}, + {file = "xxhash-3.4.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c44d584afdf3c4dbb3277e32321d1a7b01d6071c1992524b6543025fb8f4206f"}, + {file = "xxhash-3.4.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd7bddb3a5b86213cc3f2c61500c16945a1b80ecd572f3078ddbbe68f9dabdfb"}, + {file = "xxhash-3.4.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ecb6c987b62437c2f99c01e97caf8d25660bf541fe79a481d05732e5236719c"}, + {file = "xxhash-3.4.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:696b4e18b7023527d5c50ed0626ac0520edac45a50ec7cf3fc265cd08b1f4c03"}, + {file = "xxhash-3.4.1.tar.gz", hash = "sha256:0379d6cf1ff987cd421609a264ce025e74f346e3e145dd106c0cc2e3ec3f99a9"}, +] + +[[package]] +name = "yarl" +version = "1.9.4" +description = "Yet another URL library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"}, + {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"}, + {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"}, + {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"}, + {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"}, + {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"}, + {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"}, + {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"}, + {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"}, + {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"}, + {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"}, + {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"}, + {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"}, + {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"}, + {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"}, + {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"}, +] + +[package.dependencies] +idna = ">=2.0" +multidict = ">=4.0" + [metadata] lock-version = "2.0" -python-versions = "^3.9,<3.12" -content-hash = "fe4e36826d87d9a7d36cd58f7f2ede200bffa315a42b37cf046fc495a689984c" +python-versions = "^3.12" +content-hash = "430808daa3ca3ed673e8b6735cd955fc7413cd9c2d1644656416dc5c24789f00" diff --git a/source-mailchimp/pyproject.toml b/source-mailchimp/pyproject.toml index c3a68b066b..2d7f7f6f28 100644 --- a/source-mailchimp/pyproject.toml +++ b/source-mailchimp/pyproject.toml @@ -1,29 +1,26 @@ -[build-system] -requires = [ "poetry-core>=1.0.0",] -build-backend = "poetry.core.masonry.api" - [tool.poetry] -version = "1.2.0" name = "source-mailchimp" -description = "Source implementation for Mailchimp." -authors = [ "Airbyte ",] -license = "MIT" -readme = "README.md" -documentation = "https://docs.airbyte.com/integrations/sources/mailchimp" -homepage = "https://airbyte.com" -repository = "https://github.com/airbytehq/airbyte" -[[tool.poetry.packages]] -include = "source_mailchimp" +version = "0.1.0" +description = "" +authors = ["Luishfs "] [tool.poetry.dependencies] -python = "^3.9,<3.12" -airbyte-cdk = "^0" -pytest = "==6.2.5" - -[tool.poetry.scripts] -source-mailchimp = "source_mailchimp.run:run" +python = "^3.12" +airbyte-cdk = "^0.52" +estuary-cdk = {path="../estuary-cdk", develop = true} +pydantic = "==1.10.14" [tool.poetry.group.dev.dependencies] +debugpy = "^1.8.0" +mypy = "^1.8.0" +pytest = "^7.4.3" +pytest-insta = "^0.3.0" +mock = "^5.1.0" pytest-mock = "^3.6.1" -responses = "^0.19.0" requests-mock = "^1.9.3" +freezegun = "^1.4.0" +responses = "==0.25" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/source-mailchimp/sample_files/catalog.json b/source-mailchimp/sample_files/catalog.json deleted file mode 100644 index 46dba2fd85..0000000000 --- a/source-mailchimp/sample_files/catalog.json +++ /dev/null @@ -1,1370 +0,0 @@ -{ - "streams": [ - { - "name": "Campaigns", - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": "create_time", - "json_schema": { - "type": "object", - "title": "Campaign", - "description": "A summary of an individual campaign's settings and content.", - "properties": { - "id": { - "type": "string", - "title": "Campaign ID", - "description": "A string that uniquely identifies this campaign.", - "readOnly": true - }, - "web_id": { - "type": "integer", - "title": "Campaign Web ID", - "description": "The ID used in the Mailchimp web application. View this campaign in your Mailchimp account at `https://{dc}.admin.mailchimp.com/campaigns/show/?id={web_id}`.", - "readOnly": true - }, - "parent_campaign_id": { - "type": "string", - "title": "Parent Campaign ID", - "description": "If this campaign is the child of another campaign, this identifies the parent campaign. For Example, for RSS or Automation children.", - "readOnly": true - }, - "type": { - "$ref": "https://us1.api.mailchimp.com/schema/3.0/Definitions/CampaignType.json" - }, - "create_time": { - "type": "string", - "format": "date-time", - "title": "Create Time", - "description": "The date and time the campaign was created in ISO 8601 format.", - "readOnly": true - }, - "archive_url": { - "type": "string", - "title": "Archive URL", - "description": "The link to the campaign's archive version in ISO 8601 format.", - "readOnly": true - }, - "long_archive_url": { - "type": "string", - "title": "Long Archive URL", - "description": "The original link to the campaign's archive version.", - "readOnly": true - }, - "status": { - "$ref": "https://us1.api.mailchimp.com/schema/3.0/Definitions/CampaignStatus.json" - }, - "emails_sent": { - "type": "integer", - "title": "Emails Sent", - "description": "The total number of emails sent for this campaign.", - "readOnly": true - }, - "send_time": { - "type": "string", - "format": "date-time", - "title": "Send Time", - "description": "The date and time a campaign was sent.", - "readOnly": true - }, - "content_type": { - "type": "string", - "title": "Content Type", - "description": "How the campaign's content is put together.", - "enum": ["template", "html", "url", "multichannel"] - }, - "needs_block_refresh": { - "type": "boolean", - "title": "Needs Block Refresh", - "description": "Determines if the campaign needs its blocks refreshed by opening the web-based campaign editor. Deprecated and will always return false.", - "readOnly": true - }, - "resendable": { - "type": "boolean", - "title": "Resendable", - "description": "Determines if the campaign qualifies to be resent to non-openers.", - "readOnly": true - }, - "recipients": { - "type": "object", - "title": "List", - "description": "List settings for the campaign.", - "properties": { - "list_id": { - "type": "string", - "title": "List ID", - "description": "The unique list id." - }, - "list_is_active": { - "type": "boolean", - "title": "List Status", - "description": "The status of the list used, namely if it's deleted or disabled.", - "readOnly": true - }, - "list_name": { - "type": "string", - "title": "List Name", - "description": "The name of the list.", - "readOnly": true - }, - "segment_text": { - "type": "string", - "title": "Segment Text", - "description": "A description of the [segment](https://mailchimp.com/help/create-and-send-to-a-segment/) used for the campaign. Formatted as a string marked up with HTML.", - "readOnly": true - }, - "recipient_count": { - "type": "integer", - "title": "Recipient Count", - "description": "Count of the recipients on the associated list. Formatted as an integer.", - "readOnly": true - }, - "segment_opts": { - "$ref": "https://us1.api.mailchimp.com/schema/3.0/Definitions/SegmentationOptions.json" - } - } - }, - "settings": { - "type": "object", - "title": "Campaign Settings", - "description": "The settings for your campaign, including subject, from name, reply-to address, and more.", - "properties": { - "subject_line": { - "type": "string", - "title": "Campaign Subject Line", - "description": "The subject line for the campaign." - }, - "preview_text": { - "type": "string", - "title": "Campaign Preview Text", - "description": "The preview text for the campaign." - }, - "title": { - "type": "string", - "title": "Campaign Title", - "description": "The title of the campaign." - }, - "from_name": { - "type": "string", - "title": "From Name", - "description": "The 'from' name on the campaign (not an email address)." - }, - "reply_to": { - "type": "string", - "title": "Reply To Address", - "description": "The reply-to email address for the campaign." - }, - "use_conversation": { - "type": "boolean", - "title": "Conversation", - "description": "Use Mailchimp Conversation feature to manage out-of-office replies." - }, - "to_name": { - "type": "string", - "title": "To Name", - "description": "The campaign's custom 'To' name. Typically the first name [merge field](https://mailchimp.com/help/getting-started-with-merge-tags/)." - }, - "folder_id": { - "type": "string", - "title": "Folder ID", - "description": "If the campaign is listed in a folder, the id for that folder." - }, - "authenticate": { - "type": "boolean", - "title": "Authentication", - "description": "Whether Mailchimp [authenticated](https://mailchimp.com/help/about-email-authentication/) the campaign. Defaults to `true`." - }, - "auto_footer": { - "type": "boolean", - "title": "Auto-Footer", - "description": "Automatically append Mailchimp's [default footer](https://mailchimp.com/help/about-campaign-footers/) to the campaign." - }, - "inline_css": { - "type": "boolean", - "title": "Inline CSS", - "description": "Automatically inline the CSS included with the campaign content." - }, - "auto_tweet": { - "type": "boolean", - "title": "Auto-Tweet", - "description": "Automatically tweet a link to the [campaign archive](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) page when the campaign is sent." - }, - "auto_fb_post": { - "type": "array", - "title": "Auto Post to Facebook", - "description": "An array of [Facebook](https://mailchimp.com/help/connect-or-disconnect-the-facebook-integration/) page ids to auto-post to.", - "items": { - "type": "string" - } - }, - "fb_comments": { - "type": "boolean", - "title": "Facebook Comments", - "description": "Allows Facebook comments on the campaign (also force-enables the Campaign Archive toolbar). Defaults to `true`." - }, - "timewarp": { - "type": "boolean", - "title": "Timewarp Send", - "description": "Send this campaign using [Timewarp](https://mailchimp.com/help/use-timewarp/).", - "readOnly": true - }, - "template_id": { - "type": "integer", - "title": "Template ID", - "description": "The id for the template used in this campaign.", - "readOnly": false - }, - "drag_and_drop": { - "type": "boolean", - "title": "Drag And Drop Campaign", - "description": "Whether the campaign uses the drag-and-drop editor.", - "readOnly": true - } - } - }, - "variate_settings": { - "type": "object", - "title": "A/B Test Options", - "description": "The settings specific to A/B test campaigns.", - "properties": { - "winning_combination_id": { - "type": "string", - "title": "Winning Combination ID", - "description": "ID for the winning combination.", - "readOnly": true - }, - "winning_campaign_id": { - "type": "string", - "title": "Winning Campaign ID", - "description": "ID of the campaign that was sent to the remaining recipients based on the winning combination.", - "readOnly": true - }, - "winner_criteria": { - "type": "string", - "title": "Winning Criteria", - "description": "The combination that performs the best. This may be determined automatically by click rate, open rate, or total revenue -- or you may choose manually based on the reporting data you find the most valuable. For Multivariate Campaigns testing send_time, winner_criteria is ignored. For Multivariate Campaigns with 'manual' as the winner_criteria, the winner must be chosen in the Mailchimp web application.", - "enum": ["opens", "clicks", "manual", "total_revenue"] - }, - "wait_time": { - "type": "integer", - "title": "Wait Time", - "description": "The number of minutes to wait before choosing the winning campaign. The value of wait_time must be greater than 0 and in whole hours, specified in minutes." - }, - "test_size": { - "type": "integer", - "title": "Test Size", - "description": "The percentage of recipients to send the test combinations to, must be a value between 10 and 100." - }, - "subject_lines": { - "type": "array", - "title": "Subject Lines", - "description": "The possible subject lines to test. If no subject lines are provided, settings.subject_line will be used.", - "items": { - "type": "string" - } - }, - "send_times": { - "type": "array", - "title": "Send Times", - "description": "The possible send times to test. The times provided should be in the format YYYY-MM-DD HH:MM:SS. If send_times are provided to test, the test_size will be set to 100% and winner_criteria will be ignored.", - "items": { - "type": "string", - "format": "date-time" - } - }, - "from_names": { - "type": "array", - "title": "From Names", - "description": "The possible from names. The number of from_names provided must match the number of reply_to_addresses. If no from_names are provided, settings.from_name will be used.", - "items": { - "type": "string" - } - }, - "reply_to_addresses": { - "type": "array", - "title": "Reply To Addresses", - "description": "The possible reply-to addresses. The number of reply_to_addresses provided must match the number of from_names. If no reply_to_addresses are provided, settings.reply_to will be used.", - "items": { - "type": "string" - } - }, - "contents": { - "type": "array", - "title": "Content Descriptions", - "description": "Descriptions of possible email contents. To set campaign contents, make a PUT request to /campaigns/{campaign_id}/content with the field 'variate_contents'.", - "items": { - "type": "string" - }, - "readOnly": true - }, - "combinations": { - "type": "array", - "title": "Combinations", - "description": "Combinations of possible variables used to build emails.", - "readOnly": true, - "items": { - "type": "object", - "properties": { - "id": { - "type": "string", - "title": "ID", - "description": "Unique ID for the combination." - }, - "subject_line": { - "type": "integer", - "title": "Subject Line", - "description": "The index of `variate_settings.subject_lines` used." - }, - "send_time": { - "type": "integer", - "title": "Send Time", - "description": "The index of `variate_settings.send_times` used." - }, - "from_name": { - "type": "integer", - "title": "From Name", - "description": "The index of `variate_settings.from_names` used." - }, - "reply_to": { - "type": "integer", - "title": "Reply To", - "description": "The index of `variate_settings.reply_to_addresses` used." - }, - "content_description": { - "type": "integer", - "title": "Content Description", - "description": "The index of `variate_settings.contents` used." - }, - "recipients": { - "type": "integer", - "title": "Recipients", - "description": "The number of recipients for this combination." - } - } - } - } - } - }, - "tracking": { - "type": "object", - "title": "Campaign Tracking Options", - "description": "The tracking options for a campaign.", - "properties": { - "opens": { - "type": "boolean", - "title": "Opens", - "description": "Whether to [track opens](https://mailchimp.com/help/about-open-tracking/). Defaults to `true`. Cannot be set to false for variate campaigns." - }, - "html_clicks": { - "type": "boolean", - "title": "HTML Click Tracking", - "description": "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the HTML version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns." - }, - "text_clicks": { - "type": "boolean", - "title": "Plain-Text Click Tracking", - "description": "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the plain-text version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns." - }, - "goal_tracking": { - "type": "boolean", - "title": "Mailchimp Goal Tracking", - "description": "Whether to enable [Goal](https://mailchimp.com/help/about-connected-sites/) tracking." - }, - "ecomm360": { - "type": "boolean", - "title": "E-commerce Tracking", - "description": "Whether to enable [eCommerce360](https://mailchimp.com/help/connect-your-online-store-to-mailchimp/) tracking." - }, - "google_analytics": { - "type": "string", - "title": "Google Analytics Tracking", - "description": "The custom slug for [Google Analytics](https://mailchimp.com/help/integrate-google-analytics-with-mailchimp/) tracking (max of 50 bytes)." - }, - "clicktale": { - "type": "string", - "title": "ClickTale Analytics Tracking", - "description": "The custom slug for [ClickTale](https://mailchimp.com/help/additional-tracking-options-for-campaigns/) tracking (max of 50 bytes)." - }, - "salesforce": { - "type": "object", - "title": "Salesforce CRM Tracking", - "description": "Salesforce tracking options for a campaign. Must be using Mailchimp's built-in [Salesforce integration](https://mailchimp.com/help/integrate-salesforce-with-mailchimp/).", - "properties": { - "campaign": { - "type": "boolean", - "title": "Salesforce Campaign", - "description": "Create a campaign in a connected Salesforce account." - }, - "notes": { - "type": "boolean", - "title": "Salesforce Note", - "description": "Update contact notes for a campaign based on subscriber email addresses." - } - } - }, - "capsule": { - "type": "object", - "title": "Capsule CRM Tracking", - "description": "Capsule tracking options for a campaign. Must be using Mailchimp's built-in Capsule integration.", - "properties": { - "notes": { - "type": "boolean", - "title": "Capsule Note", - "description": "Update contact notes for a campaign based on subscriber email addresses." - } - } - } - } - }, - "rss_opts": { - "type": "object", - "title": "RSS Options", - "description": "[RSS](https://mailchimp.com/help/share-your-blog-posts-with-mailchimp/) options for a campaign.", - "properties": { - "feed_url": { - "type": "string", - "title": "Feed URL", - "format": "uri", - "description": "The URL for the RSS feed." - }, - "frequency": { - "type": "string", - "title": "Frequency", - "description": "The frequency of the RSS Campaign.", - "enum": ["daily", "weekly", "monthly"] - }, - "schedule": { - "type": "object", - "title": "Sending Schedule", - "description": "The schedule for sending the RSS Campaign.", - "properties": { - "hour": { - "type": "integer", - "minimum": 0, - "maximum": 23, - "title": "Sending Hour", - "description": "The hour to send the campaign in local time. Acceptable hours are 0-23. For example, '4' would be 4am in [your account's default time zone](https://mailchimp.com/help/set-account-defaults/)." - }, - "daily_send": { - "type": "object", - "title": "Daily Sending Days", - "description": "The days of the week to send a daily RSS Campaign.", - "properties": { - "sunday": { - "type": "boolean", - "title": "Sunday", - "description": "Sends the daily RSS Campaign on Sundays." - }, - "monday": { - "type": "boolean", - "title": "Monday", - "description": "Sends the daily RSS Campaign on Mondays." - }, - "tuesday": { - "type": "boolean", - "title": "tuesday", - "description": "Sends the daily RSS Campaign on Tuesdays." - }, - "wednesday": { - "type": "boolean", - "title": "Monday", - "description": "Sends the daily RSS Campaign on Wednesdays." - }, - "thursday": { - "type": "boolean", - "title": "Thursday", - "description": "Sends the daily RSS Campaign on Thursdays." - }, - "friday": { - "type": "boolean", - "title": "Friday", - "description": "Sends the daily RSS Campaign on Fridays." - }, - "saturday": { - "type": "boolean", - "title": "Saturday", - "description": "Sends the daily RSS Campaign on Saturdays." - } - } - }, - "weekly_send_day": { - "type": "string", - "enum": [ - "sunday", - "monday", - "tuesday", - "wednesday", - "thursday", - "friday", - "saturday" - ], - "title": "Weekly Sending Day", - "description": "The day of the week to send a weekly RSS Campaign." - }, - "monthly_send_date": { - "type": "number", - "minimum": 0, - "maximum": 31, - "title": "Monthly Sending Day", - "description": "The day of the month to send a monthly RSS Campaign. Acceptable days are 0-31, where '0' is always the last day of a month. Months with fewer than the selected number of days will not have an RSS campaign sent out that day. For example, RSS Campaigns set to send on the 30th will not go out in February." - } - } - }, - "last_sent": { - "type": "string", - "format": "date-time", - "title": "Last Sent", - "description": "The date the campaign was last sent.", - "readOnly": true - }, - "constrain_rss_img": { - "type": "boolean", - "title": "Constrain RSS Images", - "description": "Whether to add CSS to images in the RSS feed to constrain their width in campaigns." - } - } - }, - "ab_split_opts": { - "type": "object", - "title": "A/B Testing Options", - "description": "[A/B Testing](https://mailchimp.com/help/about-ab-testing-campaigns/) options for a campaign.", - "readOnly": true, - "properties": { - "split_test": { - "type": "string", - "title": "Split Test", - "description": "The type of AB split to run.", - "enum": ["subject", "from_name", "schedule"] - }, - "pick_winner": { - "type": "string", - "title": "Pick Winner", - "description": "How we should evaluate a winner. Based on 'opens', 'clicks', or 'manual'.", - "enum": ["opens", "clicks", "manual"] - }, - "wait_units": { - "type": "string", - "title": "Wait Time", - "description": "How unit of time for measuring the winner ('hours' or 'days'). This cannot be changed after a campaign is sent.", - "enum": ["hours", "days"] - }, - "wait_time": { - "type": "integer", - "title": "Wait Time", - "description": "The amount of time to wait before picking a winner. This cannot be changed after a campaign is sent." - }, - "split_size": { - "type": "integer", - "minimum": 1, - "maximum": 50, - "title": "Split Size", - "description": "The size of the split groups. Campaigns split based on 'schedule' are forced to have a 50/50 split. Valid split integers are between 1-50." - }, - "from_name_a": { - "type": "string", - "title": "From Name Group A", - "description": "For campaigns split on 'From Name', the name for Group A." - }, - "from_name_b": { - "type": "string", - "title": "From Name Group B", - "description": "For campaigns split on 'From Name', the name for Group B." - }, - "reply_email_a": { - "type": "string", - "title": "Reply Email Group A", - "description": "For campaigns split on 'From Name', the reply-to address for Group A." - }, - "reply_email_b": { - "type": "string", - "title": "Reply Email Group B", - "description": "For campaigns split on 'From Name', the reply-to address for Group B." - }, - "subject_a": { - "type": "string", - "title": "Subject Line Group A", - "description": "For campaigns split on 'Subject Line', the subject line for Group A." - }, - "subject_b": { - "type": "string", - "title": "Subject Line Group B", - "description": "For campaigns split on 'Subject Line', the subject line for Group B." - }, - "send_time_a": { - "type": "string", - "format": "date-time", - "title": "Send Time Group A", - "description": "The send time for Group A." - }, - "send_time_b": { - "type": "string", - "format": "date-time", - "title": "Send Time Group B", - "description": "The send time for Group B." - }, - "send_time_winner": { - "type": "string", - "title": "Send Time Winner", - "description": "The send time for the winning version." - } - } - }, - "social_card": { - "type": "object", - "title": "Campaign Social Card", - "description": "The preview for the campaign, rendered by social networks like Facebook and Twitter. [Learn more](https://mailchimp.com/help/enable-and-customize-social-cards/).", - "properties": { - "image_url": { - "type": "string", - "title": "Image URL", - "description": "The url for the header image for the card." - }, - "description": { - "type": "string", - "title": "Campaign Description", - "description": "A short summary of the campaign to display." - }, - "title": { - "type": "string", - "title": "Title", - "description": "The title for the card. Typically the subject line of the campaign." - } - } - }, - "report_summary": { - "type": "object", - "title": "Campaign Report Summary", - "description": "For sent campaigns, a summary of opens, clicks, and e-commerce data.", - "properties": { - "opens": { - "type": "integer", - "title": "Automation Opens", - "description": "The total number of opens for a campaign.", - "readOnly": true - }, - "unique_opens": { - "type": "integer", - "title": "Unique Opens", - "description": "The number of unique opens.", - "readOnly": true - }, - "open_rate": { - "type": "number", - "title": "Open Rate", - "description": "The number of unique opens divided by the total number of successful deliveries.", - "readOnly": true - }, - "clicks": { - "type": "integer", - "title": "Total Clicks", - "description": "The total number of clicks for an campaign.", - "readOnly": true - }, - "subscriber_clicks": { - "type": "integer", - "title": "Unique Subscriber Clicks", - "description": "The number of unique clicks.", - "readOnly": true - }, - "click_rate": { - "type": "number", - "title": "Click Rate", - "description": "The number of unique clicks divided by the total number of successful deliveries.", - "readOnly": true - }, - "ecommerce": { - "type": "object", - "title": "E-Commerce Report", - "description": "E-Commerce stats for a campaign.", - "properties": { - "total_orders": { - "type": "integer", - "title": "Total Orders", - "description": "The total orders for a campaign.", - "readOnly": true - }, - "total_spent": { - "type": "number", - "title": "Total Spent", - "description": "The total spent for a campaign. Calculated as the sum of all order totals with no deductions.", - "readOnly": true - }, - "total_revenue": { - "type": "number", - "title": "Total Revenue", - "description": "The total revenue for a campaign. Calculated as the sum of all order totals minus shipping and tax totals.", - "readOnly": true - } - } - } - } - }, - "delivery_status": { - "type": "object", - "title": "Campaign Delivery Status", - "description": "Updates on campaigns in the process of sending.", - "properties": { - "enabled": { - "type": "boolean", - "title": "Delivery Status Enabled", - "description": "Whether Campaign Delivery Status is enabled for this account and campaign.", - "readOnly": true - }, - "can_cancel": { - "type": "boolean", - "title": "Campaign Cancelable", - "description": "Whether a campaign send can be canceled.", - "readOnly": true - }, - "status": { - "type": "string", - "title": "Campaign Delivery Status", - "description": "The current state of a campaign delivery.", - "enum": ["delivering", "delivered", "canceling", "canceled"], - "readOnly": true - }, - "emails_sent": { - "type": "integer", - "title": "Emails Sent", - "description": "The total number of emails confirmed sent for this campaign so far.", - "readOnly": true - }, - "emails_canceled": { - "type": "integer", - "title": "Emails Canceled", - "description": "The total number of emails canceled for this campaign.", - "readOnly": true - } - } - }, - "_links": { - "title": "Links", - "description": "A list of link types and descriptions for the API schema documents.", - "type": "array", - "items": { - "type": "object", - "title": "Resource Link", - "description": "This object represents a link from the resource where it is found to another resource or action that may be performed.", - "properties": { - "rel": { - "type": "string", - "title": "Rel", - "description": "As with an HTML 'rel' attribute, this describes the type of link.", - "readOnly": true - }, - "href": { - "type": "string", - "title": "Href", - "description": "This property contains a fully-qualified URL that can be called to retrieve the linked resource or perform the linked action.", - "readOnly": true - }, - "method": { - "type": "string", - "title": "Method", - "description": "The HTTP method that should be used when accessing the URL defined in 'href'.", - "enum": [ - "GET", - "POST", - "PUT", - "PATCH", - "DELETE", - "OPTIONS", - "HEAD" - ], - "readOnly": true - }, - "targetSchema": { - "type": "string", - "title": "Target Schema", - "description": "For GETs, this is a URL representing the schema that the response should conform to.", - "readOnly": true - }, - "schema": { - "type": "string", - "title": "Schema", - "description": "For HTTP methods that can receive bodies (POST and PUT), this is a URL representing the schema that the body should conform to.", - "readOnly": true - } - } - }, - "readOnly": true - } - } - } - }, - { - "name": "Automations", - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": "create_time", - "json_schema": { - "type": "object", - "title": "Automation", - "description": "A summary of an individual automation's settings and content.", - "properties": { - "id": { - "type": ["null", "string"] - }, - "create_time": { - "type": ["null", "string"] - }, - "start_time": { - "type": ["null", "string"] - }, - "status": { - "type": ["null", "string"] - }, - "emails_sent": { - "type": ["null", "number"] - }, - "recipients": { - "type": ["null", "object"], - "properties": { - "list_id": { - "type": ["null", "string"] - }, - "list_is_active": { - "type": ["null", "boolean"] - }, - "list_name": { - "type": ["null", "string"] - }, - "segment_opts": { - "type": ["null", "object"], - "properties": { - "saved_segment_id": { - "type": ["null", "number"] - }, - "match": { - "type": ["null", "string"] - }, - "conditions": { - "type": ["null", "array"], - "items": {} - } - } - }, - "store_id": { - "type": ["null", "string"] - } - } - }, - "settings": { - "type": ["null", "object"], - "properties": { - "title": { - "type": ["null", "string"] - }, - "from_name": { - "type": ["null", "string"] - }, - "reply_to": { - "type": ["null", "string"] - }, - "use_conversation": { - "type": ["null", "boolean"] - }, - "to_name": { - "type": ["null", "string"] - }, - "authenticate": { - "type": ["null", "boolean"] - }, - "auto_footer": { - "type": ["null", "boolean"] - }, - "inline_css": { - "type": ["null", "boolean"] - } - } - }, - "tracking": { - "type": ["null", "object"], - "properties": { - "opens": { - "type": ["null", "boolean"] - }, - "html_clicks": { - "type": ["null", "boolean"] - }, - "text_clicks": { - "type": ["null", "boolean"] - }, - "goal_tracking": { - "type": ["null", "boolean"] - }, - "ecomm360": { - "type": ["null", "boolean"] - }, - "google_analytics": { - "type": ["null", "string"] - }, - "clicktale": { - "type": ["null", "string"] - }, - "salesforce": { - "type": ["null", "object"], - "properties": { - "campaign": { - "type": ["null", "boolean"] - }, - "notes": { - "type": ["null", "boolean"] - } - } - }, - "capsule": { - "type": ["null", "object"], - "properties": { - "notes": { - "type": ["null", "boolean"] - } - } - } - } - }, - "trigger_settings": { - "type": ["null", "object"], - "properties": { - "workflow_type": { - "type": ["null", "string"] - }, - "workflow_title": { - "type": ["null", "string"] - }, - "runtime": { - "type": ["null", "object"], - "properties": { - "days": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "hours": { - "type": ["null", "object"], - "properties": { - "type": { - "type": ["null", "string"] - } - } - } - } - }, - "workflow_emails_count": { - "type": ["null", "number"] - } - } - }, - "report_summary": { - "type": ["null", "object"], - "properties": { - "opens": { - "type": ["null", "number"] - }, - "unique_opens": { - "type": ["null", "number"] - }, - "open_rate": { - "type": ["null", "number"] - }, - "clicks": { - "type": ["null", "number"] - }, - "subscriber_clicks": { - "type": ["null", "number"] - }, - "click_rate": { - "type": ["null", "number"] - } - } - }, - "_links": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "rel": { - "type": ["null", "string"] - }, - "href": { - "type": ["null", "string"] - }, - "method": { - "type": ["null", "string"] - }, - "targetSchema": { - "type": ["null", "string"] - }, - "schema": { - "type": ["null", "string"] - } - } - } - } - } - } - }, - { - "name": "Lists", - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": "date_created", - "json_schema": { - "type": "object", - "title": "Subscriber List", - "description": "Information about a specific list.", - "properties": { - "id": { - "type": "string", - "title": "List ID", - "description": "A string that uniquely identifies this list.", - "readOnly": true - }, - "web_id": { - "type": "integer", - "title": "List Web ID", - "description": "The ID used in the Mailchimp web application. View this list in your Mailchimp account at `https://{dc}.admin.mailchimp.com/lists/members/?id={web_id}`.", - "readOnly": true - }, - "name": { - "type": "string", - "title": "List Name", - "description": "The name of the list." - }, - "contact": { - "type": "object", - "title": "List Contact", - "description": "[Contact information displayed in campaign footers](https://mailchimp.com/help/about-campaign-footers/) to comply with international spam laws.", - "properties": { - "company": { - "type": "string", - "title": "Company Name", - "description": "The company name for the list." - }, - "address1": { - "type": "string", - "title": "Address", - "description": "The street address for the list contact." - }, - "address2": { - "type": "string", - "title": "Address", - "description": "The street address for the list contact." - }, - "city": { - "type": "string", - "title": "City", - "description": "The city for the list contact." - }, - "state": { - "type": "string", - "title": "State", - "description": "The state for the list contact." - }, - "zip": { - "type": "string", - "title": "Postal Code", - "description": "The postal or zip code for the list contact." - }, - "country": { - "type": "string", - "title": "Country Code", - "description": "A two-character ISO3166 country code. Defaults to US if invalid." - }, - "phone": { - "type": "string", - "title": "Phone Number", - "description": "The phone number for the list contact." - } - } - }, - "permission_reminder": { - "type": "string", - "title": "Permission Reminder", - "description": "The [permission reminder](https://mailchimp.com/help/edit-the-permission-reminder/) for the list." - }, - "use_archive_bar": { - "type": "boolean", - "title": "Use Archive Bar", - "description": "Whether campaigns for this list use the [Archive Bar](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) in archives by default.", - "default": false - }, - "campaign_defaults": { - "type": "object", - "title": "Campaign Defaults", - "description": "[Default values for campaigns](https://mailchimp.com/help/edit-your-emails-subject-preview-text-from-name-or-from-email-address/) created for this list.", - "properties": { - "from_name": { - "type": "string", - "title": "Sender's Name", - "description": "The default from name for campaigns sent to this list." - }, - "from_email": { - "type": "string", - "title": "Sender's Email Address", - "description": "The default from email for campaigns sent to this list." - }, - "subject": { - "type": "string", - "title": "Subject", - "description": "The default subject line for campaigns sent to this list." - }, - "language": { - "type": "string", - "title": "Language", - "description": "The default language for this lists's forms." - } - } - }, - "notify_on_subscribe": { - "type": "string", - "title": "Notify on Subscribe", - "description": "The email address to send [subscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", - "default": false - }, - "notify_on_unsubscribe": { - "type": "string", - "title": "Notify on Unsubscribe", - "description": "The email address to send [unsubscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", - "default": false - }, - "date_created": { - "type": "string", - "title": "Creation Date", - "description": "The date and time that this list was created in ISO 8601 format.", - "format": "date-time", - "readOnly": true - }, - "list_rating": { - "type": "integer", - "title": "List Rating", - "description": "An auto-generated activity score for the list (0-5).", - "readOnly": true - }, - "email_type_option": { - "type": "boolean", - "title": "Email Type Option", - "description": "Whether the list supports [multiple formats for emails](https://mailchimp.com/help/change-list-name-and-defaults/). When set to `true`, subscribers can choose whether they want to receive HTML or plain-text emails. When set to `false`, subscribers will receive HTML emails, with a plain-text alternative backup." - }, - "subscribe_url_short": { - "type": "string", - "title": "Subscribe URL Short", - "description": "Our [EepURL shortened](https://mailchimp.com/help/share-your-signup-form/) version of this list's subscribe form.", - "readOnly": true - }, - "subscribe_url_long": { - "type": "string", - "title": "Subscribe URL Long", - "description": "The full version of this list's subscribe form (host will vary).", - "readOnly": true - }, - "beamer_address": { - "type": "string", - "title": "Beamer Address", - "description": "The list's [Email Beamer](https://mailchimp.com/help/use-email-beamer-to-create-a-campaign/) address.", - "readOnly": true - }, - "visibility": { - "type": "string", - "title": "Visibility", - "enum": ["pub", "prv"], - "description": "Whether this list is [public or private](https://mailchimp.com/help/about-list-publicity/)." - }, - "double_optin": { - "type": "boolean", - "title": "Double Opt In", - "description": "Whether or not to require the subscriber to confirm subscription via email.", - "default": false - }, - "has_welcome": { - "type": "boolean", - "title": "Has Welcome", - "description": "Whether or not this list has a welcome automation connected. Welcome Automations: welcomeSeries, singleWelcome, emailFollowup.", - "default": false, - "example": false - }, - "marketing_permissions": { - "type": "boolean", - "title": "Marketing Permissions", - "description": "Whether or not the list has marketing permissions (eg. GDPR) enabled.", - "default": false - }, - "modules": { - "type": "array", - "title": "Modules", - "description": "Any list-specific modules installed for this list.", - "items": { - "type": "string" - }, - "readOnly": true - }, - "stats": { - "type": "object", - "title": "Statistics", - "description": "Stats for the list. Many of these are cached for at least five minutes.", - "readOnly": true, - "properties": { - "member_count": { - "type": "integer", - "title": "Member Count", - "description": "The number of active members in the list.", - "readOnly": true - }, - "total_contacts": { - "type": "integer", - "title": "Total Contacts", - "description": "The number of contacts in the list, including subscribed, unsubscribed, pending, cleaned, deleted, transactional, and those that need to be reconfirmed.", - "readOnly": true - }, - "unsubscribe_count": { - "type": "integer", - "title": "Unsubscribe Count", - "description": "The number of members who have unsubscribed from the list.", - "readOnly": true - }, - "cleaned_count": { - "type": "integer", - "title": "Cleaned Count", - "description": "The number of members cleaned from the list.", - "readOnly": true - }, - "member_count_since_send": { - "type": "integer", - "title": "Member Count Since Send", - "description": "The number of active members in the list since the last campaign was sent.", - "readOnly": true - }, - "unsubscribe_count_since_send": { - "type": "integer", - "title": "Unsubscribe Count Since Send", - "description": "The number of members who have unsubscribed since the last campaign was sent.", - "readOnly": true - }, - "cleaned_count_since_send": { - "type": "integer", - "title": "Cleaned Count Since Send", - "description": "The number of members cleaned from the list since the last campaign was sent.", - "readOnly": true - }, - "campaign_count": { - "type": "integer", - "title": "Campaign Count", - "description": "The number of campaigns in any status that use this list.", - "readOnly": true - }, - "campaign_last_sent": { - "type": "string", - "format": "date-time", - "title": "Campaign Last Sent", - "description": "The date and time the last campaign was sent to this list in ISO 8601 format. This is updated when a campaign is sent to 10 or more recipients.", - "readOnly": true - }, - "merge_field_count": { - "type": "integer", - "title": "Merge Var Count", - "description": "The number of merge vars for this list (not EMAIL, which is required).", - "readOnly": true - }, - "avg_sub_rate": { - "type": "number", - "title": "Average Subscription Rate", - "description": "The average number of subscriptions per month for the list (not returned if we haven't calculated it yet).", - "readOnly": true - }, - "avg_unsub_rate": { - "type": "number", - "title": "Average Unsubscription Rate", - "description": "The average number of unsubscriptions per month for the list (not returned if we haven't calculated it yet).", - "readOnly": true - }, - "target_sub_rate": { - "type": "number", - "title": "Average Subscription Rate", - "description": "The target number of subscriptions per month for the list to keep it growing (not returned if we haven't calculated it yet).", - "readOnly": true - }, - "open_rate": { - "type": "number", - "title": "Open Rate", - "description": "The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet).", - "readOnly": true - }, - "click_rate": { - "type": "number", - "title": "Click Rate", - "description": "The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet).", - "readOnly": true - }, - "last_sub_date": { - "type": "string", - "format": "date-time", - "title": "Date of Last List Subscribe", - "description": "The date and time of the last time someone subscribed to this list in ISO 8601 format.", - "readOnly": true - }, - "last_unsub_date": { - "type": "string", - "format": "date-time", - "title": "Date of Last List Unsubscribe", - "description": "The date and time of the last time someone unsubscribed from this list in ISO 8601 format.", - "readOnly": true - } - } - }, - "_links": { - "title": "Links", - "description": "A list of link types and descriptions for the API schema documents.", - "type": "array", - "items": { - "type": "object", - "title": "Resource Link", - "description": "This object represents a link from the resource where it is found to another resource or action that may be performed.", - "properties": { - "rel": { - "type": "string", - "title": "Rel", - "description": "As with an HTML 'rel' attribute, this describes the type of link.", - "readOnly": true - }, - "href": { - "type": "string", - "title": "Href", - "description": "This property contains a fully-qualified URL that can be called to retrieve the linked resource or perform the linked action.", - "readOnly": true - }, - "method": { - "type": "string", - "title": "Method", - "description": "The HTTP method that should be used when accessing the URL defined in 'href'.", - "enum": [ - "GET", - "POST", - "PUT", - "PATCH", - "DELETE", - "OPTIONS", - "HEAD" - ], - "readOnly": true - }, - "targetSchema": { - "type": "string", - "title": "Target Schema", - "description": "For GETs, this is a URL representing the schema that the response should conform to.", - "readOnly": true - }, - "schema": { - "type": "string", - "title": "Schema", - "description": "For HTTP methods that can receive bodies (POST and PUT), this is a URL representing the schema that the body should conform to.", - "readOnly": true - } - } - }, - "readOnly": true - } - } - } - } - ] -} diff --git a/source-mailchimp/sample_files/configured_catalog.json b/source-mailchimp/sample_files/configured_catalog.json deleted file mode 100644 index a4cb2fb0af..0000000000 --- a/source-mailchimp/sample_files/configured_catalog.json +++ /dev/null @@ -1,1381 +0,0 @@ -{ - "streams": [ - { - "stream": { - "name": "campaigns", - "json_schema": { - "type": "object", - "title": "Campaign", - "description": "A summary of an individual campaign's settings and content.", - "properties": { - "id": { - "type": "string", - "title": "Campaign ID", - "description": "A string that uniquely identifies this campaign.", - "readOnly": true - }, - "web_id": { - "type": "integer", - "title": "Campaign Web ID", - "description": "The ID used in the Mailchimp web application. View this campaign in your Mailchimp account at `https://{dc}.admin.mailchimp.com/campaigns/show/?id={web_id}`.", - "readOnly": true - }, - "parent_campaign_id": { - "type": "string", - "title": "Parent Campaign ID", - "description": "If this campaign is the child of another campaign, this identifies the parent campaign. For Example, for RSS or Automation children.", - "readOnly": true - }, - "type": { - "$ref": "https://us1.api.mailchimp.com/schema/3.0/Definitions/CampaignType.json" - }, - "create_time": { - "type": "string", - "format": "date-time", - "title": "Create Time", - "description": "The date and time the campaign was created in ISO 8601 format.", - "readOnly": true - }, - "archive_url": { - "type": "string", - "title": "Archive URL", - "description": "The link to the campaign's archive version in ISO 8601 format.", - "readOnly": true - }, - "long_archive_url": { - "type": "string", - "title": "Long Archive URL", - "description": "The original link to the campaign's archive version.", - "readOnly": true - }, - "status": { - "$ref": "https://us1.api.mailchimp.com/schema/3.0/Definitions/CampaignStatus.json" - }, - "emails_sent": { - "type": "integer", - "title": "Emails Sent", - "description": "The total number of emails sent for this campaign.", - "readOnly": true - }, - "send_time": { - "type": "string", - "format": "date-time", - "title": "Send Time", - "description": "The date and time a campaign was sent.", - "readOnly": true - }, - "content_type": { - "type": "string", - "title": "Content Type", - "description": "How the campaign's content is put together.", - "enum": ["template", "html", "url", "multichannel"] - }, - "needs_block_refresh": { - "type": "boolean", - "title": "Needs Block Refresh", - "description": "Determines if the campaign needs its blocks refreshed by opening the web-based campaign editor. Deprecated and will always return false.", - "readOnly": true - }, - "resendable": { - "type": "boolean", - "title": "Resendable", - "description": "Determines if the campaign qualifies to be resent to non-openers.", - "readOnly": true - }, - "recipients": { - "type": "object", - "title": "List", - "description": "List settings for the campaign.", - "properties": { - "list_id": { - "type": "string", - "title": "List ID", - "description": "The unique list id." - }, - "list_is_active": { - "type": "boolean", - "title": "List Status", - "description": "The status of the list used, namely if it's deleted or disabled.", - "readOnly": true - }, - "list_name": { - "type": "string", - "title": "List Name", - "description": "The name of the list.", - "readOnly": true - }, - "segment_text": { - "type": "string", - "title": "Segment Text", - "description": "A description of the [segment](https://mailchimp.com/help/create-and-send-to-a-segment/) used for the campaign. Formatted as a string marked up with HTML.", - "readOnly": true - }, - "recipient_count": { - "type": "integer", - "title": "Recipient Count", - "description": "Count of the recipients on the associated list. Formatted as an integer.", - "readOnly": true - }, - "segment_opts": { - "$ref": "https://us1.api.mailchimp.com/schema/3.0/Definitions/SegmentationOptions.json" - } - } - }, - "settings": { - "type": "object", - "title": "Campaign Settings", - "description": "The settings for your campaign, including subject, from name, reply-to address, and more.", - "properties": { - "subject_line": { - "type": "string", - "title": "Campaign Subject Line", - "description": "The subject line for the campaign." - }, - "preview_text": { - "type": "string", - "title": "Campaign Preview Text", - "description": "The preview text for the campaign." - }, - "title": { - "type": "string", - "title": "Campaign Title", - "description": "The title of the campaign." - }, - "from_name": { - "type": "string", - "title": "From Name", - "description": "The 'from' name on the campaign (not an email address)." - }, - "reply_to": { - "type": "string", - "title": "Reply To Address", - "description": "The reply-to email address for the campaign." - }, - "use_conversation": { - "type": "boolean", - "title": "Conversation", - "description": "Use Mailchimp Conversation feature to manage out-of-office replies." - }, - "to_name": { - "type": "string", - "title": "To Name", - "description": "The campaign's custom 'To' name. Typically the first name [merge field](https://mailchimp.com/help/getting-started-with-merge-tags/)." - }, - "folder_id": { - "type": "string", - "title": "Folder ID", - "description": "If the campaign is listed in a folder, the id for that folder." - }, - "authenticate": { - "type": "boolean", - "title": "Authentication", - "description": "Whether Mailchimp [authenticated](https://mailchimp.com/help/about-email-authentication/) the campaign. Defaults to `true`." - }, - "auto_footer": { - "type": "boolean", - "title": "Auto-Footer", - "description": "Automatically append Mailchimp's [default footer](https://mailchimp.com/help/about-campaign-footers/) to the campaign." - }, - "inline_css": { - "type": "boolean", - "title": "Inline CSS", - "description": "Automatically inline the CSS included with the campaign content." - }, - "auto_tweet": { - "type": "boolean", - "title": "Auto-Tweet", - "description": "Automatically tweet a link to the [campaign archive](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) page when the campaign is sent." - }, - "auto_fb_post": { - "type": "array", - "title": "Auto Post to Facebook", - "description": "An array of [Facebook](https://mailchimp.com/help/connect-or-disconnect-the-facebook-integration/) page ids to auto-post to.", - "items": { - "type": "string" - } - }, - "fb_comments": { - "type": "boolean", - "title": "Facebook Comments", - "description": "Allows Facebook comments on the campaign (also force-enables the Campaign Archive toolbar). Defaults to `true`." - }, - "timewarp": { - "type": "boolean", - "title": "Timewarp Send", - "description": "Send this campaign using [Timewarp](https://mailchimp.com/help/use-timewarp/).", - "readOnly": true - }, - "template_id": { - "type": "integer", - "title": "Template ID", - "description": "The id for the template used in this campaign.", - "readOnly": false - }, - "drag_and_drop": { - "type": "boolean", - "title": "Drag And Drop Campaign", - "description": "Whether the campaign uses the drag-and-drop editor.", - "readOnly": true - } - } - }, - "variate_settings": { - "type": "object", - "title": "A/B Test Options", - "description": "The settings specific to A/B test campaigns.", - "properties": { - "winning_combination_id": { - "type": "string", - "title": "Winning Combination ID", - "description": "ID for the winning combination.", - "readOnly": true - }, - "winning_campaign_id": { - "type": "string", - "title": "Winning Campaign ID", - "description": "ID of the campaign that was sent to the remaining recipients based on the winning combination.", - "readOnly": true - }, - "winner_criteria": { - "type": "string", - "title": "Winning Criteria", - "description": "The combination that performs the best. This may be determined automatically by click rate, open rate, or total revenue -- or you may choose manually based on the reporting data you find the most valuable. For Multivariate Campaigns testing send_time, winner_criteria is ignored. For Multivariate Campaigns with 'manual' as the winner_criteria, the winner must be chosen in the Mailchimp web application.", - "enum": ["opens", "clicks", "manual", "total_revenue"] - }, - "wait_time": { - "type": "integer", - "title": "Wait Time", - "description": "The number of minutes to wait before choosing the winning campaign. The value of wait_time must be greater than 0 and in whole hours, specified in minutes." - }, - "test_size": { - "type": "integer", - "title": "Test Size", - "description": "The percentage of recipients to send the test combinations to, must be a value between 10 and 100." - }, - "subject_lines": { - "type": "array", - "title": "Subject Lines", - "description": "The possible subject lines to test. If no subject lines are provided, settings.subject_line will be used.", - "items": { - "type": "string" - } - }, - "send_times": { - "type": "array", - "title": "Send Times", - "description": "The possible send times to test. The times provided should be in the format YYYY-MM-DD HH:MM:SS. If send_times are provided to test, the test_size will be set to 100% and winner_criteria will be ignored.", - "items": { - "type": "string", - "format": "date-time" - } - }, - "from_names": { - "type": "array", - "title": "From Names", - "description": "The possible from names. The number of from_names provided must match the number of reply_to_addresses. If no from_names are provided, settings.from_name will be used.", - "items": { - "type": "string" - } - }, - "reply_to_addresses": { - "type": "array", - "title": "Reply To Addresses", - "description": "The possible reply-to addresses. The number of reply_to_addresses provided must match the number of from_names. If no reply_to_addresses are provided, settings.reply_to will be used.", - "items": { - "type": "string" - } - }, - "contents": { - "type": "array", - "title": "Content Descriptions", - "description": "Descriptions of possible email contents. To set campaign contents, make a PUT request to /campaigns/{campaign_id}/content with the field 'variate_contents'.", - "items": { - "type": "string" - }, - "readOnly": true - }, - "combinations": { - "type": "array", - "title": "Combinations", - "description": "Combinations of possible variables used to build emails.", - "readOnly": true, - "items": { - "type": "object", - "properties": { - "id": { - "type": "string", - "title": "ID", - "description": "Unique ID for the combination." - }, - "subject_line": { - "type": "integer", - "title": "Subject Line", - "description": "The index of `variate_settings.subject_lines` used." - }, - "send_time": { - "type": "integer", - "title": "Send Time", - "description": "The index of `variate_settings.send_times` used." - }, - "from_name": { - "type": "integer", - "title": "From Name", - "description": "The index of `variate_settings.from_names` used." - }, - "reply_to": { - "type": "integer", - "title": "Reply To", - "description": "The index of `variate_settings.reply_to_addresses` used." - }, - "content_description": { - "type": "integer", - "title": "Content Description", - "description": "The index of `variate_settings.contents` used." - }, - "recipients": { - "type": "integer", - "title": "Recipients", - "description": "The number of recipients for this combination." - } - } - } - } - } - }, - "tracking": { - "type": "object", - "title": "Campaign Tracking Options", - "description": "The tracking options for a campaign.", - "properties": { - "opens": { - "type": "boolean", - "title": "Opens", - "description": "Whether to [track opens](https://mailchimp.com/help/about-open-tracking/). Defaults to `true`. Cannot be set to false for variate campaigns." - }, - "html_clicks": { - "type": "boolean", - "title": "HTML Click Tracking", - "description": "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the HTML version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns." - }, - "text_clicks": { - "type": "boolean", - "title": "Plain-Text Click Tracking", - "description": "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the plain-text version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns." - }, - "goal_tracking": { - "type": "boolean", - "title": "Mailchimp Goal Tracking", - "description": "Whether to enable [Goal](https://mailchimp.com/help/about-connected-sites/) tracking." - }, - "ecomm360": { - "type": "boolean", - "title": "E-commerce Tracking", - "description": "Whether to enable [eCommerce360](https://mailchimp.com/help/connect-your-online-store-to-mailchimp/) tracking." - }, - "google_analytics": { - "type": "string", - "title": "Google Analytics Tracking", - "description": "The custom slug for [Google Analytics](https://mailchimp.com/help/integrate-google-analytics-with-mailchimp/) tracking (max of 50 bytes)." - }, - "clicktale": { - "type": "string", - "title": "ClickTale Analytics Tracking", - "description": "The custom slug for [ClickTale](https://mailchimp.com/help/additional-tracking-options-for-campaigns/) tracking (max of 50 bytes)." - }, - "salesforce": { - "type": "object", - "title": "Salesforce CRM Tracking", - "description": "Salesforce tracking options for a campaign. Must be using Mailchimp's built-in [Salesforce integration](https://mailchimp.com/help/integrate-salesforce-with-mailchimp/).", - "properties": { - "campaign": { - "type": "boolean", - "title": "Salesforce Campaign", - "description": "Create a campaign in a connected Salesforce account." - }, - "notes": { - "type": "boolean", - "title": "Salesforce Note", - "description": "Update contact notes for a campaign based on subscriber email addresses." - } - } - }, - "capsule": { - "type": "object", - "title": "Capsule CRM Tracking", - "description": "Capsule tracking options for a campaign. Must be using Mailchimp's built-in Capsule integration.", - "properties": { - "notes": { - "type": "boolean", - "title": "Capsule Note", - "description": "Update contact notes for a campaign based on subscriber email addresses." - } - } - } - } - }, - "rss_opts": { - "type": "object", - "title": "RSS Options", - "description": "[RSS](https://mailchimp.com/help/share-your-blog-posts-with-mailchimp/) options for a campaign.", - "properties": { - "feed_url": { - "type": "string", - "title": "Feed URL", - "format": "uri", - "description": "The URL for the RSS feed." - }, - "frequency": { - "type": "string", - "title": "Frequency", - "description": "The frequency of the RSS Campaign.", - "enum": ["daily", "weekly", "monthly"] - }, - "schedule": { - "type": "object", - "title": "Sending Schedule", - "description": "The schedule for sending the RSS Campaign.", - "properties": { - "hour": { - "type": "integer", - "minimum": 0, - "maximum": 23, - "title": "Sending Hour", - "description": "The hour to send the campaign in local time. Acceptable hours are 0-23. For example, '4' would be 4am in [your account's default time zone](https://mailchimp.com/help/set-account-defaults/)." - }, - "daily_send": { - "type": "object", - "title": "Daily Sending Days", - "description": "The days of the week to send a daily RSS Campaign.", - "properties": { - "sunday": { - "type": "boolean", - "title": "Sunday", - "description": "Sends the daily RSS Campaign on Sundays." - }, - "monday": { - "type": "boolean", - "title": "Monday", - "description": "Sends the daily RSS Campaign on Mondays." - }, - "tuesday": { - "type": "boolean", - "title": "tuesday", - "description": "Sends the daily RSS Campaign on Tuesdays." - }, - "wednesday": { - "type": "boolean", - "title": "Monday", - "description": "Sends the daily RSS Campaign on Wednesdays." - }, - "thursday": { - "type": "boolean", - "title": "Thursday", - "description": "Sends the daily RSS Campaign on Thursdays." - }, - "friday": { - "type": "boolean", - "title": "Friday", - "description": "Sends the daily RSS Campaign on Fridays." - }, - "saturday": { - "type": "boolean", - "title": "Saturday", - "description": "Sends the daily RSS Campaign on Saturdays." - } - } - }, - "weekly_send_day": { - "type": "string", - "enum": [ - "sunday", - "monday", - "tuesday", - "wednesday", - "thursday", - "friday", - "saturday" - ], - "title": "Weekly Sending Day", - "description": "The day of the week to send a weekly RSS Campaign." - }, - "monthly_send_date": { - "type": "number", - "minimum": 0, - "maximum": 31, - "title": "Monthly Sending Day", - "description": "The day of the month to send a monthly RSS Campaign. Acceptable days are 0-31, where '0' is always the last day of a month. Months with fewer than the selected number of days will not have an RSS campaign sent out that day. For example, RSS Campaigns set to send on the 30th will not go out in February." - } - } - }, - "last_sent": { - "type": "string", - "format": "date-time", - "title": "Last Sent", - "description": "The date the campaign was last sent.", - "readOnly": true - }, - "constrain_rss_img": { - "type": "boolean", - "title": "Constrain RSS Images", - "description": "Whether to add CSS to images in the RSS feed to constrain their width in campaigns." - } - } - }, - "ab_split_opts": { - "type": "object", - "title": "A/B Testing Options", - "description": "[A/B Testing](https://mailchimp.com/help/about-ab-testing-campaigns/) options for a campaign.", - "readOnly": true, - "properties": { - "split_test": { - "type": "string", - "title": "Split Test", - "description": "The type of AB split to run.", - "enum": ["subject", "from_name", "schedule"] - }, - "pick_winner": { - "type": "string", - "title": "Pick Winner", - "description": "How we should evaluate a winner. Based on 'opens', 'clicks', or 'manual'.", - "enum": ["opens", "clicks", "manual"] - }, - "wait_units": { - "type": "string", - "title": "Wait Time", - "description": "How unit of time for measuring the winner ('hours' or 'days'). This cannot be changed after a campaign is sent.", - "enum": ["hours", "days"] - }, - "wait_time": { - "type": "integer", - "title": "Wait Time", - "description": "The amount of time to wait before picking a winner. This cannot be changed after a campaign is sent." - }, - "split_size": { - "type": "integer", - "minimum": 1, - "maximum": 50, - "title": "Split Size", - "description": "The size of the split groups. Campaigns split based on 'schedule' are forced to have a 50/50 split. Valid split integers are between 1-50." - }, - "from_name_a": { - "type": "string", - "title": "From Name Group A", - "description": "For campaigns split on 'From Name', the name for Group A." - }, - "from_name_b": { - "type": "string", - "title": "From Name Group B", - "description": "For campaigns split on 'From Name', the name for Group B." - }, - "reply_email_a": { - "type": "string", - "title": "Reply Email Group A", - "description": "For campaigns split on 'From Name', the reply-to address for Group A." - }, - "reply_email_b": { - "type": "string", - "title": "Reply Email Group B", - "description": "For campaigns split on 'From Name', the reply-to address for Group B." - }, - "subject_a": { - "type": "string", - "title": "Subject Line Group A", - "description": "For campaigns split on 'Subject Line', the subject line for Group A." - }, - "subject_b": { - "type": "string", - "title": "Subject Line Group B", - "description": "For campaigns split on 'Subject Line', the subject line for Group B." - }, - "send_time_a": { - "type": "string", - "format": "date-time", - "title": "Send Time Group A", - "description": "The send time for Group A." - }, - "send_time_b": { - "type": "string", - "format": "date-time", - "title": "Send Time Group B", - "description": "The send time for Group B." - }, - "send_time_winner": { - "type": "string", - "title": "Send Time Winner", - "description": "The send time for the winning version." - } - } - }, - "social_card": { - "type": "object", - "title": "Campaign Social Card", - "description": "The preview for the campaign, rendered by social networks like Facebook and Twitter. [Learn more](https://mailchimp.com/help/enable-and-customize-social-cards/).", - "properties": { - "image_url": { - "type": "string", - "title": "Image URL", - "description": "The url for the header image for the card." - }, - "description": { - "type": "string", - "title": "Campaign Description", - "description": "A short summary of the campaign to display." - }, - "title": { - "type": "string", - "title": "Title", - "description": "The title for the card. Typically the subject line of the campaign." - } - } - }, - "report_summary": { - "type": "object", - "title": "Campaign Report Summary", - "description": "For sent campaigns, a summary of opens, clicks, and e-commerce data.", - "properties": { - "opens": { - "type": "integer", - "title": "Automation Opens", - "description": "The total number of opens for a campaign.", - "readOnly": true - }, - "unique_opens": { - "type": "integer", - "title": "Unique Opens", - "description": "The number of unique opens.", - "readOnly": true - }, - "open_rate": { - "type": "number", - "title": "Open Rate", - "description": "The number of unique opens divided by the total number of successful deliveries.", - "readOnly": true - }, - "clicks": { - "type": "integer", - "title": "Total Clicks", - "description": "The total number of clicks for an campaign.", - "readOnly": true - }, - "subscriber_clicks": { - "type": "integer", - "title": "Unique Subscriber Clicks", - "description": "The number of unique clicks.", - "readOnly": true - }, - "click_rate": { - "type": "number", - "title": "Click Rate", - "description": "The number of unique clicks divided by the total number of successful deliveries.", - "readOnly": true - }, - "ecommerce": { - "type": "object", - "title": "E-Commerce Report", - "description": "E-Commerce stats for a campaign.", - "properties": { - "total_orders": { - "type": "integer", - "title": "Total Orders", - "description": "The total orders for a campaign.", - "readOnly": true - }, - "total_spent": { - "type": "number", - "title": "Total Spent", - "description": "The total spent for a campaign. Calculated as the sum of all order totals with no deductions.", - "readOnly": true - }, - "total_revenue": { - "type": "number", - "title": "Total Revenue", - "description": "The total revenue for a campaign. Calculated as the sum of all order totals minus shipping and tax totals.", - "readOnly": true - } - } - } - } - }, - "delivery_status": { - "type": "object", - "title": "Campaign Delivery Status", - "description": "Updates on campaigns in the process of sending.", - "properties": { - "enabled": { - "type": "boolean", - "title": "Delivery Status Enabled", - "description": "Whether Campaign Delivery Status is enabled for this account and campaign.", - "readOnly": true - }, - "can_cancel": { - "type": "boolean", - "title": "Campaign Cancelable", - "description": "Whether a campaign send can be canceled.", - "readOnly": true - }, - "status": { - "type": "string", - "title": "Campaign Delivery Status", - "description": "The current state of a campaign delivery.", - "enum": ["delivering", "delivered", "canceling", "canceled"], - "readOnly": true - }, - "emails_sent": { - "type": "integer", - "title": "Emails Sent", - "description": "The total number of emails confirmed sent for this campaign so far.", - "readOnly": true - }, - "emails_canceled": { - "type": "integer", - "title": "Emails Canceled", - "description": "The total number of emails canceled for this campaign.", - "readOnly": true - } - } - } - } - }, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["create_time"] - }, - "sync_mode": "incremental", - "cursor_field": ["create_time"], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "automations", - "json_schema": { - "type": "object", - "title": "Automation", - "description": "A summary of an individual campaign's settings and content.", - "properties": { - "id": { - "type": ["null", "string"] - }, - "create_time": { - "type": ["null", "string"] - }, - "start_time": { - "type": ["null", "string"] - }, - "status": { - "type": ["null", "string"] - }, - "emails_sent": { - "type": ["null", "number"] - }, - "recipients": { - "type": ["null", "object"], - "properties": { - "list_id": { - "type": ["null", "string"] - }, - "list_is_active": { - "type": ["null", "boolean"] - }, - "list_name": { - "type": ["null", "string"] - }, - "segment_opts": { - "type": ["null", "object"], - "properties": { - "saved_segment_id": { - "type": ["null", "number"] - }, - "match": { - "type": ["null", "string"] - }, - "conditions": { - "type": ["null", "array"], - "items": {} - } - } - }, - "store_id": { - "type": ["null", "string"] - } - } - }, - "settings": { - "type": ["null", "object"], - "properties": { - "title": { - "type": ["null", "string"] - }, - "from_name": { - "type": ["null", "string"] - }, - "reply_to": { - "type": ["null", "string"] - }, - "use_conversation": { - "type": ["null", "boolean"] - }, - "to_name": { - "type": ["null", "string"] - }, - "authenticate": { - "type": ["null", "boolean"] - }, - "auto_footer": { - "type": ["null", "boolean"] - }, - "inline_css": { - "type": ["null", "boolean"] - } - } - }, - "tracking": { - "type": ["null", "object"], - "properties": { - "opens": { - "type": ["null", "boolean"] - }, - "html_clicks": { - "type": ["null", "boolean"] - }, - "text_clicks": { - "type": ["null", "boolean"] - }, - "goal_tracking": { - "type": ["null", "boolean"] - }, - "ecomm360": { - "type": ["null", "boolean"] - }, - "google_analytics": { - "type": ["null", "string"] - }, - "clicktale": { - "type": ["null", "string"] - }, - "salesforce": { - "type": ["null", "object"], - "properties": { - "campaign": { - "type": ["null", "boolean"] - }, - "notes": { - "type": ["null", "boolean"] - } - } - }, - "capsule": { - "type": ["null", "object"], - "properties": { - "notes": { - "type": ["null", "boolean"] - } - } - } - } - }, - "trigger_settings": { - "type": ["null", "object"], - "properties": { - "workflow_type": { - "type": ["null", "string"] - }, - "workflow_title": { - "type": ["null", "string"] - }, - "runtime": { - "type": ["null", "object"], - "properties": { - "days": { - "type": ["null", "array"], - "items": { - "type": ["null", "string"] - } - }, - "hours": { - "type": ["null", "object"], - "properties": { - "type": { - "type": ["null", "string"] - } - } - } - } - }, - "workflow_emails_count": { - "type": ["null", "number"] - } - } - }, - "report_summary": { - "type": ["null", "object"], - "properties": { - "opens": { - "type": ["null", "number"] - }, - "unique_opens": { - "type": ["null", "number"] - }, - "open_rate": { - "type": ["null", "number"] - }, - "clicks": { - "type": ["null", "number"] - }, - "subscriber_clicks": { - "type": ["null", "number"] - }, - "click_rate": { - "type": ["null", "number"] - } - } - }, - "_links": { - "type": ["null", "array"], - "items": { - "type": ["null", "object"], - "properties": { - "rel": { - "type": ["null", "string"] - }, - "href": { - "type": ["null", "string"] - }, - "method": { - "type": ["null", "string"] - }, - "targetSchema": { - "type": ["null", "string"] - }, - "schema": { - "type": ["null", "string"] - } - } - } - } - } - }, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["create_time"] - }, - "sync_mode": "incremental", - "cursor_field": ["create_time"], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "lists", - "json_schema": { - "type": "object", - "title": "Subscriber List", - "description": "Information about a specific list.", - "properties": { - "id": { - "type": "string", - "title": "List ID", - "description": "A string that uniquely identifies this list.", - "readOnly": true - }, - "web_id": { - "type": "integer", - "title": "List Web ID", - "description": "The ID used in the Mailchimp web application. View this list in your Mailchimp account at `https://{dc}.admin.mailchimp.com/lists/members/?id={web_id}`.", - "readOnly": true - }, - "name": { - "type": "string", - "title": "List Name", - "description": "The name of the list." - }, - "contact": { - "type": "object", - "title": "List Contact", - "description": "[Contact information displayed in campaign footers](https://mailchimp.com/help/about-campaign-footers/) to comply with international spam laws.", - "properties": { - "company": { - "type": "string", - "title": "Company Name", - "description": "The company name for the list." - }, - "address1": { - "type": "string", - "title": "Address", - "description": "The street address for the list contact." - }, - "address2": { - "type": "string", - "title": "Address", - "description": "The street address for the list contact." - }, - "city": { - "type": "string", - "title": "City", - "description": "The city for the list contact." - }, - "state": { - "type": "string", - "title": "State", - "description": "The state for the list contact." - }, - "zip": { - "type": "string", - "title": "Postal Code", - "description": "The postal or zip code for the list contact." - }, - "country": { - "type": "string", - "title": "Country Code", - "description": "A two-character ISO3166 country code. Defaults to US if invalid." - }, - "phone": { - "type": "string", - "title": "Phone Number", - "description": "The phone number for the list contact." - } - } - }, - "permission_reminder": { - "type": "string", - "title": "Permission Reminder", - "description": "The [permission reminder](https://mailchimp.com/help/edit-the-permission-reminder/) for the list." - }, - "use_archive_bar": { - "type": "boolean", - "title": "Use Archive Bar", - "description": "Whether campaigns for this list use the [Archive Bar](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) in archives by default.", - "default": false - }, - "campaign_defaults": { - "type": "object", - "title": "Campaign Defaults", - "description": "[Default values for campaigns](https://mailchimp.com/help/edit-your-emails-subject-preview-text-from-name-or-from-email-address/) created for this list.", - "properties": { - "from_name": { - "type": "string", - "title": "Sender's Name", - "description": "The default from name for campaigns sent to this list." - }, - "from_email": { - "type": "string", - "title": "Sender's Email Address", - "description": "The default from email for campaigns sent to this list." - }, - "subject": { - "type": "string", - "title": "Subject", - "description": "The default subject line for campaigns sent to this list." - }, - "language": { - "type": "string", - "title": "Language", - "description": "The default language for this lists's forms." - } - } - }, - "notify_on_subscribe": { - "type": "string", - "title": "Notify on Subscribe", - "description": "The email address to send [subscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", - "default": false - }, - "notify_on_unsubscribe": { - "type": "string", - "title": "Notify on Unsubscribe", - "description": "The email address to send [unsubscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", - "default": false - }, - "date_created": { - "type": "string", - "title": "Creation Date", - "description": "The date and time that this list was created in ISO 8601 format.", - "format": "date-time", - "readOnly": true - }, - "list_rating": { - "type": "integer", - "title": "List Rating", - "description": "An auto-generated activity score for the list (0-5).", - "readOnly": true - }, - "email_type_option": { - "type": "boolean", - "title": "Email Type Option", - "description": "Whether the list supports [multiple formats for emails](https://mailchimp.com/help/change-list-name-and-defaults/). When set to `true`, subscribers can choose whether they want to receive HTML or plain-text emails. When set to `false`, subscribers will receive HTML emails, with a plain-text alternative backup." - }, - "subscribe_url_short": { - "type": "string", - "title": "Subscribe URL Short", - "description": "Our [EepURL shortened](https://mailchimp.com/help/share-your-signup-form/) version of this list's subscribe form.", - "readOnly": true - }, - "subscribe_url_long": { - "type": "string", - "title": "Subscribe URL Long", - "description": "The full version of this list's subscribe form (host will vary).", - "readOnly": true - }, - "beamer_address": { - "type": "string", - "title": "Beamer Address", - "description": "The list's [Email Beamer](https://mailchimp.com/help/use-email-beamer-to-create-a-campaign/) address.", - "readOnly": true - }, - "visibility": { - "type": "string", - "title": "Visibility", - "enum": ["pub", "prv"], - "description": "Whether this list is [public or private](https://mailchimp.com/help/about-list-publicity/)." - }, - "double_optin": { - "type": "boolean", - "title": "Double Opt In", - "description": "Whether or not to require the subscriber to confirm subscription via email.", - "default": false - }, - "has_welcome": { - "type": "boolean", - "title": "Has Welcome", - "description": "Whether or not this list has a welcome automation connected. Welcome Automations: welcomeSeries, singleWelcome, emailFollowup.", - "default": false, - "example": false - }, - "marketing_permissions": { - "type": "boolean", - "title": "Marketing Permissions", - "description": "Whether or not the list has marketing permissions (eg. GDPR) enabled.", - "default": false - }, - "modules": { - "type": "array", - "title": "Modules", - "description": "Any list-specific modules installed for this list.", - "items": { - "type": "string" - }, - "readOnly": true - }, - "stats": { - "type": "object", - "title": "Statistics", - "description": "Stats for the list. Many of these are cached for at least five minutes.", - "readOnly": true, - "properties": { - "member_count": { - "type": "integer", - "title": "Member Count", - "description": "The number of active members in the list.", - "readOnly": true - }, - "total_contacts": { - "type": "integer", - "title": "Total Contacts", - "description": "The number of contacts in the list, including subscribed, unsubscribed, pending, cleaned, deleted, transactional, and those that need to be reconfirmed.", - "readOnly": true - }, - "unsubscribe_count": { - "type": "integer", - "title": "Unsubscribe Count", - "description": "The number of members who have unsubscribed from the list.", - "readOnly": true - }, - "cleaned_count": { - "type": "integer", - "title": "Cleaned Count", - "description": "The number of members cleaned from the list.", - "readOnly": true - }, - "member_count_since_send": { - "type": "integer", - "title": "Member Count Since Send", - "description": "The number of active members in the list since the last campaign was sent.", - "readOnly": true - }, - "unsubscribe_count_since_send": { - "type": "integer", - "title": "Unsubscribe Count Since Send", - "description": "The number of members who have unsubscribed since the last campaign was sent.", - "readOnly": true - }, - "cleaned_count_since_send": { - "type": "integer", - "title": "Cleaned Count Since Send", - "description": "The number of members cleaned from the list since the last campaign was sent.", - "readOnly": true - }, - "campaign_count": { - "type": "integer", - "title": "Campaign Count", - "description": "The number of campaigns in any status that use this list.", - "readOnly": true - }, - "campaign_last_sent": { - "type": "string", - "format": "date-time", - "title": "Campaign Last Sent", - "description": "The date and time the last campaign was sent to this list in ISO 8601 format. This is updated when a campaign is sent to 10 or more recipients.", - "readOnly": true - }, - "merge_field_count": { - "type": "integer", - "title": "Merge Var Count", - "description": "The number of merge vars for this list (not EMAIL, which is required).", - "readOnly": true - }, - "avg_sub_rate": { - "type": "number", - "title": "Average Subscription Rate", - "description": "The average number of subscriptions per month for the list (not returned if we haven't calculated it yet).", - "readOnly": true - }, - "avg_unsub_rate": { - "type": "number", - "title": "Average Unsubscription Rate", - "description": "The average number of unsubscriptions per month for the list (not returned if we haven't calculated it yet).", - "readOnly": true - }, - "target_sub_rate": { - "type": "number", - "title": "Average Subscription Rate", - "description": "The target number of subscriptions per month for the list to keep it growing (not returned if we haven't calculated it yet).", - "readOnly": true - }, - "open_rate": { - "type": "number", - "title": "Open Rate", - "description": "The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet).", - "readOnly": true - }, - "click_rate": { - "type": "number", - "title": "Click Rate", - "description": "The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet).", - "readOnly": true - }, - "last_sub_date": { - "type": "string", - "format": "date-time", - "title": "Date of Last List Subscribe", - "description": "The date and time of the last time someone subscribed to this list in ISO 8601 format.", - "readOnly": true - }, - "last_unsub_date": { - "type": "string", - "format": "date-time", - "title": "Date of Last List Unsubscribe", - "description": "The date and time of the last time someone unsubscribed from this list in ISO 8601 format.", - "readOnly": true - } - } - } - } - }, - "supported_sync_modes": ["full_refresh", "incremental"], - "source_defined_cursor": true, - "default_cursor_field": ["date_created"] - }, - "sync_mode": "incremental", - "cursor_field": ["date_created"], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "email_activity", - "json_schema": { - "type": "object", - "title": "Email Activity", - "description": "A list of member's subscriber activity in a specific campaign.", - "properties": { - "emails": { - "type": "object", - "title": "List members", - "description": "An array of members that were sent the campaign.", - "properties": { - "campaign_id": { - "type": "string", - "title": "The unique id for the campaign.", - "description": "The unique id for the campaign." - }, - "list_id": { - "type": "string", - "title": "The unique id for the list.", - "description": "The unique id for the list." - }, - "list_is_active": { - "type": "boolean", - "title": "The status of the list used.", - "description": "The status of the list used, namely if it's deleted or disabled." - }, - "email_id": { - "type": "string", - "title": "email MD5 hash.", - "description": "The MD5 hash of the lowercase version of the list member's email address." - }, - "email_address": { - "type": "string", - "title": "Email address for a subscriber.", - "description": "Email address for a subscriber." - }, - "action": { - "type": "string", - "title": "action", - "enum": ["open", "click", "bounce"], - "description": "One of the following actions: 'open', 'click', or 'bounce'" - }, - "type": { - "type": "string", - "title": "Type", - "enum": ["hard", "soft"], - "description": "If the action is a 'bounce', the type of bounce received: 'hard', 'soft'." - }, - "timestamp": { - "type": "string", - "title": "Action date and time", - "description": "The date and time recorded for the action in ISO 8601 format.", - "format": "date-time" - }, - "url": { - "type": "string", - "title": "The IP address.", - "description": "The IP address recorded for the action." - }, - "ip": { - "type": "string", - "title": "Action ip address", - "description": "The IP address recorded for the action." - } - } - }, - "campaign_id": { - "type": "string", - "title": "Campaign ID", - "description": "The unique id for the sent campaign." - }, - "total_items": { - "type": "integer", - "title": "Total amount of items", - "description": "The total number of items matching the query regardless of pagination." - } - } - }, - "supported_sync_modes": ["incremental", "full_refresh"], - "source_defined_cursor": true, - "default_cursor_field": ["timestamp"] - }, - "sync_mode": "incremental", - "cursor_field": ["timestamp"], - "destination_sync_mode": "append" - }, - { - "stream": { - "name": "reports", - "json_schema": {}, - "supported_sync_modes": ["incremental", "full_refresh"], - "source_defined_cursor": true, - "default_cursor_field": ["send_time"] - }, - "sync_mode": "incremental", - "cursor_field": ["send_time"], - "destination_sync_mode": "append" - } - ] -} diff --git a/source-mailchimp/sample_files/state.json b/source-mailchimp/sample_files/state.json deleted file mode 100644 index d01435a925..0000000000 --- a/source-mailchimp/sample_files/state.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "campaigns": { "create_time": "2020-11-23T05:42:11+00:00" }, - "lists": { "date_created": "2020-09-25T04:47:31+00:00" }, - "automations": { "create_time": "2020-11-23T05:42:11+00:00" }, - "email_activity": { - "49d68626f3": { "timestamp": "2020-11-23T05:42:10+00:00" } - }, - "reports": { - "49d68626f3": { "send_time": "2020-11-23T05:42:10+00:00" } - } -} diff --git a/source-mailchimp/source_mailchimp/__main__.py b/source-mailchimp/source_mailchimp/__main__.py new file mode 100644 index 0000000000..973316ee82 --- /dev/null +++ b/source-mailchimp/source_mailchimp/__main__.py @@ -0,0 +1,34 @@ +import estuary_cdk.pydantic_polyfill # Must be first. + +import asyncio +import urllib +from estuary_cdk import shim_airbyte_cdk, flow +from source_mailchimp import SourceMailchimp + +asyncio.run( + shim_airbyte_cdk.CaptureShim( + delegate=SourceMailchimp(), + oauth2=flow.OAuth2Spec( + provider="mailchimp", + authUrlTemplate=( + "https://login.mailchimp.com/oauth2/authorize?response_type=code" + r"&client_id={{#urlencode}}{{{ client_id }}}{{/urlencode}}" + r"&redirect_uri={{#urlencode}}{{{ redirect_uri }}}{{/urlencode}}" + r"&state={{#urlencode}}{{{ state }}}{{/urlencode}}" + ), + accessTokenUrlTemplate="https://login.mailchimp.com/oauth2/token", + accessTokenHeaders={"content-type": "application/x-www-form-urlencoded"}, + accessTokenBody=( + "grant_type=authorization_code" + r"&client_id={{#urlencode}}{{{ client_id }}}{{/urlencode}}" + r"&client_secret={{#urlencode}}{{{ client_secret }}}{{/urlencode}}" + r"&redirect_uri={{#urlencode}}{{{ redirect_uri }}}{{/urlencode}}" + r"&code={{#urlencode}}{{{ code }}}{{/urlencode}}" + ), + accessTokenResponseMap={ + "access_token": "/access_token" + }, + ), + schema_inference=False, + ).serve() +) \ No newline at end of file diff --git a/source-mailchimp/source_mailchimp/schemas/automations.json b/source-mailchimp/source_mailchimp/schemas/automations.json index 27e691cf22..9a172a10df 100644 --- a/source-mailchimp/source_mailchimp/schemas/automations.json +++ b/source-mailchimp/source_mailchimp/schemas/automations.json @@ -3,19 +3,18 @@ "type": "object", "title": "Automations", "additionalProperties": true, + "required": ["id"], "properties": { "id": { - "type": ["null", "string"] + "type": "string" }, "create_time": { "type": ["null", "string"], - "format": "date-time", - "airbyte-type": "timestamp_with_timezone" + "format": "date-time" }, "start_time": { "type": ["null", "string"], - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "status": { "type": ["null", "string"] diff --git a/source-mailchimp/source_mailchimp/schemas/campaigns.json b/source-mailchimp/source_mailchimp/schemas/campaigns.json index 8d058b78e9..113a57e5d5 100644 --- a/source-mailchimp/source_mailchimp/schemas/campaigns.json +++ b/source-mailchimp/source_mailchimp/schemas/campaigns.json @@ -2,6 +2,7 @@ "type": "object", "title": "Campaign", "description": "A summary of an individual campaign's settings and content.", + "required": ["id"], "properties": { "id": { "type": "string", @@ -29,8 +30,7 @@ "title": "Create Time", "description": "The date and time the campaign was created in ISO 8601 format.", "readOnly": true, - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "archive_url": { "type": ["null", "string"], @@ -58,8 +58,7 @@ "title": "Send Time", "description": "The date and time a campaign was sent.", "readOnly": true, - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "content_type": { "type": ["null", "string"], @@ -263,8 +262,7 @@ "description": "The possible send times to test. The times provided should be in the format YYYY-MM-DD HH:MM:SS. If send_times are provided to test, the test_size will be set to 100% and winner_criteria will be ignored.", "items": { "type": ["null", "string"], - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" } }, "from_names": { @@ -510,8 +508,7 @@ "title": "Last Sent", "description": "The date the campaign was last sent.", "readOnly": true, - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "constrain_rss_img": { "type": "boolean", @@ -589,14 +586,12 @@ "send_time_a": { "type": ["null", "string"], "format": "date-time", - "airbyte_type": "timestamp_with_timezone", "title": "Send Time Group A", "description": "The send time for Group A." }, "send_time_b": { "type": ["null", "string"], "format": "date-time", - "airbyte_type": "timestamp_with_timezone", "title": "Send Time Group B", "description": "The send time for Group B." }, diff --git a/source-mailchimp/source_mailchimp/schemas/email_activity.json b/source-mailchimp/source_mailchimp/schemas/email_activity.json index b416956c54..a8f2c115e1 100644 --- a/source-mailchimp/source_mailchimp/schemas/email_activity.json +++ b/source-mailchimp/source_mailchimp/schemas/email_activity.json @@ -2,6 +2,7 @@ "type": "object", "title": "Email Activity", "description": "A list of member's subscriber activity in a specific campaign.", + "required": ["timestamp", "email_id", "action"], "properties": { "campaign_id": { "type": "string", @@ -29,7 +30,7 @@ "description": "Email address for a subscriber." }, "action": { - "type": ["string", "null"], + "type": "string", "title": "action", "enum": ["open", "click", "bounce"], "description": "One of the following actions: 'open', 'click', or 'bounce'" @@ -41,11 +42,10 @@ "description": "If the action is a 'bounce', the type of bounce received: 'hard', 'soft'." }, "timestamp": { - "type": ["string", "null"], + "type": "string", "title": "Action date and time", "description": "The date and time recorded for the action in ISO 8601 format.", - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "url": { "type": ["string", "null"], diff --git a/source-mailchimp/source_mailchimp/schemas/interest_categories.json b/source-mailchimp/source_mailchimp/schemas/interest_categories.json index 7d808ecd6a..621a63ecdc 100644 --- a/source-mailchimp/source_mailchimp/schemas/interest_categories.json +++ b/source-mailchimp/source_mailchimp/schemas/interest_categories.json @@ -1,12 +1,13 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", + "required": ["id"], "properties": { "list_id": { "type": ["null", "string"] }, "id": { - "type": ["null", "string"] + "type": "string" }, "title": { "type": ["null", "string"] diff --git a/source-mailchimp/source_mailchimp/schemas/interests.json b/source-mailchimp/source_mailchimp/schemas/interests.json index b936326faa..84ebf4c9d7 100644 --- a/source-mailchimp/source_mailchimp/schemas/interests.json +++ b/source-mailchimp/source_mailchimp/schemas/interests.json @@ -1,6 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", + "required": ["id"], "properties": { "category_id": { "type": ["null", "string"] @@ -9,7 +10,7 @@ "type": ["null", "string"] }, "id": { - "type": ["null", "string"] + "type": "string" }, "name": { "type": ["null", "string"] diff --git a/source-mailchimp/source_mailchimp/schemas/list_members.json b/source-mailchimp/source_mailchimp/schemas/list_members.json index 50376c80b7..3e369c48e2 100644 --- a/source-mailchimp/source_mailchimp/schemas/list_members.json +++ b/source-mailchimp/source_mailchimp/schemas/list_members.json @@ -2,9 +2,10 @@ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "additionalProperties": true, + "required": ["id"], "properties": { "id": { - "type": ["null", "string"] + "type": "string" }, "email_address": { "type": ["null", "string"] @@ -71,24 +72,21 @@ }, "timestamp_signup": { "type": ["null", "string"], - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "ip_opt": { "type": ["null", "string"] }, "timestamp_opt": { "type": ["null", "string"], - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "member_rating": { "type": ["null", "integer"] }, "last_changed": { "type": ["null", "string"], - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "language": { "type": ["null", "string"] @@ -147,8 +145,7 @@ }, "created_at": { "type": ["null", "string"], - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "created_by": { "type": ["null", "string"] diff --git a/source-mailchimp/source_mailchimp/schemas/lists.json b/source-mailchimp/source_mailchimp/schemas/lists.json index 01cd5b3e18..5343eb9284 100644 --- a/source-mailchimp/source_mailchimp/schemas/lists.json +++ b/source-mailchimp/source_mailchimp/schemas/lists.json @@ -2,6 +2,7 @@ "type": "object", "title": "Subscriber List", "description": "Information about a specific list.", + "required": ["id"], "properties": { "id": { "type": "string", @@ -108,21 +109,17 @@ "notify_on_subscribe": { "type": ["null", "string"], "title": "Notify on Subscribe", - "description": "The email address to send [subscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", - "default": false + "description": "The email address to send [subscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to." }, "notify_on_unsubscribe": { "type": ["null", "string"], "title": "Notify on Unsubscribe", - "description": "The email address to send [unsubscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", - "default": false - }, + "description": "The email address to send [unsubscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to." }, "date_created": { "type": "string", "title": "Creation Date", "description": "The date and time that this list was created in ISO 8601 format.", "format": "date-time", - "airbyte_type": "timestamp_with_timezone", "readOnly": true }, "list_rating": { @@ -247,8 +244,7 @@ "title": "Campaign Last Sent", "description": "The date and time the last campaign was sent to this list in ISO 8601 format. This is updated when a campaign is sent to 10 or more recipients.", "readOnly": true, - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "merge_field_count": { "type": "integer", @@ -291,16 +287,14 @@ "title": "Date of Last List Subscribe", "description": "The date and time of the last time someone subscribed to this list in ISO 8601 format.", "readOnly": true, - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "last_unsub_date": { "type": ["null", "string"], "title": "Date of Last List Unsubscribe", "description": "The date and time of the last time someone unsubscribed from this list in ISO 8601 format.", "readOnly": true, - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" } } } diff --git a/source-mailchimp/source_mailchimp/schemas/reports.json b/source-mailchimp/source_mailchimp/schemas/reports.json index 940b0a8320..f31a2cbda1 100644 --- a/source-mailchimp/source_mailchimp/schemas/reports.json +++ b/source-mailchimp/source_mailchimp/schemas/reports.json @@ -2,6 +2,7 @@ "type": "object", "title": "Campaign Reports", "description": "A list of reports containing campaigns marked as Sent.", + "required": ["id"], "properties": { "id": { "type": "string", @@ -67,7 +68,6 @@ "send_time": { "type": ["null", "string"], "format": "date-time", - "airbyte_type": "timestamp_with_timezone", "title": "Send Time", "description": "The date and time a campaign was sent in ISO 8601 format.", "readOnly": true @@ -75,7 +75,6 @@ "rss_last_send": { "type": ["null", "string"], "format": "date-time", - "airbyte_type": "timestamp_with_timezone", "title": "RSS Last Send", "description": "For RSS campaigns, the date and time of the last send in ISO 8601 format.", "readOnly": true @@ -142,7 +141,6 @@ "last_open": { "type": ["null", "string"], "format": "date-time", - "airbyte_type": "timestamp_with_timezone", "title": "Last Open", "description": "The date and time of the last recorded open in ISO 8601 format." } @@ -176,7 +174,6 @@ "last_click": { "type": ["null", "string"], "format": "date-time", - "airbyte_type": "timestamp_with_timezone", "title": "Last Click", "description": "The date and time of the last recorded click for the campaign in ISO 8601 format." } @@ -326,8 +323,7 @@ "type": ["null", "string"], "title": "Last Open", "description": "The last open for Campaign A.", - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "unique_opens": { "type": "integer", @@ -380,8 +376,7 @@ "type": ["null", "string"], "title": "Last Open", "description": "The last open for Campaign B.", - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "unique_opens": { "type": "integer", @@ -412,7 +407,6 @@ "last_open": { "type": ["null", "string"], "format": "date-time", - "airbyte_type": "timestamp_with_timezone", "title": "Last Open", "description": "The date and time of the last open in ISO 8601 format." }, @@ -429,7 +423,6 @@ "last_click": { "type": ["null", "string"], "format": "date-time", - "airbyte_type": "timestamp_with_timezone", "title": "Last Click", "description": "The date and time of the last click in ISO 8601 format." }, @@ -456,7 +449,6 @@ "timestamp": { "type": ["null", "string"], "format": "date-time", - "airbyte_type": "timestamp_with_timezone", "title": "Timestamp", "description": "The date and time for the series in ISO 8601 format." }, diff --git a/source-mailchimp/source_mailchimp/schemas/segment_members.json b/source-mailchimp/source_mailchimp/schemas/segment_members.json index 8766876fd2..53acc2bdaf 100644 --- a/source-mailchimp/source_mailchimp/schemas/segment_members.json +++ b/source-mailchimp/source_mailchimp/schemas/segment_members.json @@ -2,9 +2,10 @@ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "additionalProperties": true, + "required": ["id"], "properties": { "id": { - "type": ["null", "string"] + "type": "string" }, "email_address": { "type": ["null", "string"] @@ -42,24 +43,21 @@ }, "timestamp_signup": { "type": ["null", "string"], - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "ip_opt": { "type": ["null", "string"] }, "timestamp_opt": { "type": ["null", "string"], - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "member_rating": { "type": ["null", "integer"] }, "last_changed": { "type": ["null", "string"], - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "language": { "type": ["null", "string"] @@ -101,8 +99,7 @@ }, "created_at": { "type": ["null", "string"], - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "created_by": { "type": ["null", "string"] diff --git a/source-mailchimp/source_mailchimp/schemas/segments.json b/source-mailchimp/source_mailchimp/schemas/segments.json index 8840817de2..3806f69a15 100644 --- a/source-mailchimp/source_mailchimp/schemas/segments.json +++ b/source-mailchimp/source_mailchimp/schemas/segments.json @@ -2,9 +2,10 @@ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "additionalProperties": true, + "required": ["id"], "properties": { "id": { - "type": ["null", "integer"] + "type": "integer" }, "name": { "type": ["null", "string"] @@ -17,13 +18,11 @@ }, "created_at": { "type": ["null", "string"], - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "updated_at": { "type": ["null", "string"], - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "format": "date-time" }, "options": { "type": ["null", "object"], diff --git a/source-mailchimp/source_mailchimp/schemas/shared/campaignType.json b/source-mailchimp/source_mailchimp/schemas/shared/campaignType.json index 4e7ad8a597..6784e48359 100644 --- a/source-mailchimp/source_mailchimp/schemas/shared/campaignType.json +++ b/source-mailchimp/source_mailchimp/schemas/shared/campaignType.json @@ -1,13 +1,5 @@ { "type": "string", "title": "Campaign Type", - "description": "There are four types of [campaigns](https://mailchimp.com/help/getting-started-with-campaigns/) you can create in Mailchimp. A/B Split campaigns have been deprecated and variate campaigns should be used instead.", - "enum": [ - "automation-email", - "regular", - "plaintext", - "absplit", - "rss", - "variate" - ] + "description": "There are four types of [campaigns](https://mailchimp.com/help/getting-started-with-campaigns/) you can create in Mailchimp. A/B Split campaigns have been deprecated and variate campaigns should be used instead." } diff --git a/source-mailchimp/source_mailchimp/schemas/tags.json b/source-mailchimp/source_mailchimp/schemas/tags.json index 93e81d28f9..cb86990c71 100644 --- a/source-mailchimp/source_mailchimp/schemas/tags.json +++ b/source-mailchimp/source_mailchimp/schemas/tags.json @@ -1,9 +1,10 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", + "required": ["id"], "properties": { "id": { - "type": ["null", "integer"] + "type": "integer" }, "name": { "type": ["null", "string"] diff --git a/source-mailchimp/source_mailchimp/schemas/unsubscribes.json b/source-mailchimp/source_mailchimp/schemas/unsubscribes.json index ead264a0c1..0ceccd7e2e 100644 --- a/source-mailchimp/source_mailchimp/schemas/unsubscribes.json +++ b/source-mailchimp/source_mailchimp/schemas/unsubscribes.json @@ -2,9 +2,10 @@ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "additionalProperties": true, + "required": ["campaign_id", "email_id", "timestamp"], "properties": { "email_id": { - "type": ["null", "string"] + "type": "string" }, "email_address": { "type": ["null", "string"] @@ -17,15 +18,14 @@ "type": ["null", "boolean"] }, "timestamp": { - "type": ["null", "string"], - "format": "date-time", - "airbyte_type": "timestamp_with_timezone" + "type": "string", + "format": "date-time" }, "reason": { "type": ["null", "string"] }, "campaign_id": { - "type": ["null", "string"] + "type": "string" }, "list_id": { "type": ["null", "string"] diff --git a/source-mailchimp/source_mailchimp/spec.json b/source-mailchimp/source_mailchimp/spec.json index f88649faa1..094e02a377 100644 --- a/source-mailchimp/source_mailchimp/spec.json +++ b/source-mailchimp/source_mailchimp/spec.json @@ -1,24 +1,29 @@ { - "documentationUrl": "https://docs.airbyte.com/integrations/sources/mailchimp", + "documentationUrl": "https://go.estuary.dev/tmiNoF", "connectionSpecification": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "Mailchimp Spec", "type": "object", - "required": [], + "required": ["credentials"], "additionalProperties": true, "properties": { "credentials": { "type": "object", "title": "Authentication", + "discriminator": { + "propertyName": "auth_type" + }, "oneOf": [ { "title": "OAuth2.0", "type": "object", + "x-oauth2-provider": "mailchimp", "required": ["auth_type", "access_token"], "properties": { "auth_type": { "type": "string", "const": "oauth2.0", + "default": "oauth2.0", "order": 0 }, "client_id": { @@ -49,12 +54,13 @@ "auth_type": { "type": "string", "const": "apikey", + "default": "apikey", "order": 1 }, "apikey": { "type": "string", "title": "API Key", - "description": "Mailchimp API Key. See the docs for information on how to generate this key.", + "description": "Mailchimp API Key. See the docs for more information on how to generate this key: https://go.estuary.dev/tmiNoF", "airbyte_secret": true } } @@ -66,14 +72,12 @@ "description": "The date from which you want to start syncing data for Incremental streams. Only records that have been created or modified since this date will be synced. If left blank, all data will by synced.", "type": "string", "format": "date-time", - "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}Z$", - "pattern_descriptor": "YYYY-MM-DDTHH:MM:SS.000Z", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$", "examples": ["2020-01-01T00:00:00.000Z"] }, "campaign_id": { "type": "string", - "title": "ID of a campaign to sync email activities", - "airbyte_hidden": true + "title": "ID of a campaign to sync email activities" } } }, diff --git a/source-mailchimp/test.flow.yaml b/source-mailchimp/test.flow.yaml index 0be6c0a374..e201120069 100644 --- a/source-mailchimp/test.flow.yaml +++ b/source-mailchimp/test.flow.yaml @@ -4,16 +4,19 @@ import: captures: acmeCo/source-mailchimp: endpoint: - connector: - image: "ghcr.io/estuary/source-mailchimp:v2" + local: + command: + - python + - "-m" + - source_mailchimp config: config.yaml bindings: - resource: - stream: lists + stream: automations syncMode: incremental cursorField: - - date_created - target: acmeCo/lists + - create_time + target: acmeCo/automations - resource: stream: campaigns syncMode: incremental @@ -26,9 +29,51 @@ captures: cursorField: - timestamp target: acmeCo/email_activity + - resource: + stream: interest_categories + syncMode: full_refresh + target: acmeCo/interest_categories + - resource: + stream: interests + syncMode: full_refresh + target: acmeCo/interests + - resource: + stream: lists + syncMode: incremental + cursorField: + - date_created + target: acmeCo/lists + - resource: + stream: list_members + syncMode: incremental + cursorField: + - last_changed + target: acmeCo/list_members - resource: stream: reports syncMode: incremental cursorField: - send_time target: acmeCo/reports + - resource: + stream: segment_members + syncMode: incremental + cursorField: + - last_changed + target: acmeCo/segment_members + - resource: + stream: segments + syncMode: incremental + cursorField: + - updated_at + target: acmeCo/segments + - resource: + stream: tags + syncMode: full_refresh + target: acmeCo/tags + - resource: + stream: unsubscribes + syncMode: incremental + cursorField: + - timestamp + target: acmeCo/unsubscribes diff --git a/source-mailchimp/unit_tests/conftest.py b/source-mailchimp/tests/conftest.py similarity index 100% rename from source-mailchimp/unit_tests/conftest.py rename to source-mailchimp/tests/conftest.py diff --git a/source-mailchimp/unit_tests/test_source.py b/source-mailchimp/tests/test_source.py similarity index 100% rename from source-mailchimp/unit_tests/test_source.py rename to source-mailchimp/tests/test_source.py diff --git a/source-mailchimp/unit_tests/test_streams.py b/source-mailchimp/tests/test_streams.py similarity index 99% rename from source-mailchimp/unit_tests/test_streams.py rename to source-mailchimp/tests/test_streams.py index b441fe26f7..60c22963d1 100644 --- a/source-mailchimp/unit_tests/test_streams.py +++ b/source-mailchimp/tests/test_streams.py @@ -24,7 +24,7 @@ Tags, Unsubscribes, ) -from utils import read_full_refresh, read_incremental +from .utils import read_full_refresh, read_incremental @pytest.mark.parametrize( diff --git a/source-mailchimp/unit_tests/unit_test.py b/source-mailchimp/tests/unit_test.py similarity index 100% rename from source-mailchimp/unit_tests/unit_test.py rename to source-mailchimp/tests/unit_test.py diff --git a/source-mailchimp/unit_tests/utils.py b/source-mailchimp/tests/utils.py similarity index 100% rename from source-mailchimp/unit_tests/utils.py rename to source-mailchimp/tests/utils.py From b674a2967ffc7a953d8075943df127c87e5fe70c Mon Sep 17 00:00:00 2001 From: Luishfs Date: Fri, 26 Apr 2024 16:08:45 -0300 Subject: [PATCH 4/5] Added new snapshots --- .../snapshots__capture__capture.stdout.json | 442 ++- .../snapshots__discover__capture.stdout.json | 3295 +++++++++++++---- .../snapshots__spec__capture.stdout.json | 40 +- source-mailchimp/tests/test_snapshots.py | 3 + 4 files changed, 2879 insertions(+), 901 deletions(-) diff --git a/source-mailchimp/tests/snapshots/snapshots__capture__capture.stdout.json b/source-mailchimp/tests/snapshots/snapshots__capture__capture.stdout.json index 2bed8b8b8d..b603d97a5d 100644 --- a/source-mailchimp/tests/snapshots/snapshots__capture__capture.stdout.json +++ b/source-mailchimp/tests/snapshots/snapshots__capture__capture.stdout.json @@ -1,122 +1,88 @@ [ [ - "acmeCo/lists", + "acmeCo/campaigns", { - "_links": [ - { - "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72", - "method": "GET", - "rel": "self", - "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Response.json" - }, - { - "href": "https://us22.api.mailchimp.com/3.0/lists", - "method": "GET", - "rel": "parent", - "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/Collection.json", - "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/CollectionResponse.json" - }, - { - "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72", - "method": "PATCH", - "rel": "update", - "schema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/PATCH.json", - "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Response.json" - }, - { - "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72", - "method": "POST", - "rel": "batch-sub-unsub-members", - "schema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/BatchPOST.json", - "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/BatchPOST-Response.json" - }, - { - "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72", - "method": "DELETE", - "rel": "delete" - }, - { - "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/abuse-reports", - "method": "GET", - "rel": "abuse-reports", - "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/Abuse/Collection.json", - "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Abuse/CollectionResponse.json" - }, - { - "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/activity", - "method": "GET", - "rel": "activity", - "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Activity/Response.json" - }, - { - "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/clients", - "method": "GET", - "rel": "clients", - "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Clients/Response.json" - }, - { - "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/growth-history", - "method": "GET", - "rel": "growth-history", - "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/Growth/Collection.json", - "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Growth/CollectionResponse.json" - }, - { - "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/interest-categories", - "method": "GET", - "rel": "interest-categories", - "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/InterestCategories/Collection.json", - "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/InterestCategories/CollectionResponse.json" - }, - { - "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/members", - "method": "GET", - "rel": "members", - "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/Members/Collection.json", - "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Members/CollectionResponse.json" - }, - { - "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/merge-fields", - "method": "GET", - "rel": "merge-fields", - "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/MergeFields/Collection.json", - "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/MergeFields/CollectionResponse.json" - }, - { - "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/segments", - "method": "GET", - "rel": "segments", - "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/Segments/Collection.json", - "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Segments/CollectionResponse.json" - }, - { - "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/webhooks", - "method": "GET", - "rel": "webhooks", - "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/Webhooks/Collection.json", - "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Webhooks/CollectionResponse.json" - }, - { - "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/signup-forms", - "method": "GET", - "rel": "signup-forms", - "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/SignupForms/Collection.json", - "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/SignupForms/CollectionResponse.json" + "_meta": { + "op": "u", + "row_id": 0 + }, + "archive_url": "http://eepurl.com/iO2fCY", + "content_type": "multichannel", + "create_time": "2024-04-29T14:56:01+00:00", + "delivery_status": { + "enabled": false + }, + "emails_sent": 2, + "id": "52b74e95ee", + "long_archive_url": "https://mailchi.mp/30fdc4b30708/teste", + "needs_block_refresh": false, + "recipients": { + "list_id": "7a1cbe4b72", + "list_is_active": true, + "list_name": "Penguins", + "recipient_count": 2, + "segment_text": null + }, + "report_summary": { + "click_rate": 0, + "clicks": 0, + "ecommerce": { + "total_orders": 0, + "total_revenue": 0, + "total_spent": 0 }, - { - "href": "https://us22.api.mailchimp.com/3.0/lists/7a1cbe4b72/locations", - "method": "GET", - "rel": "locations", - "schema": "https://us22.api.mailchimp.com/schema/3.0/Paths/Lists/Locations/Collection.json", - "targetSchema": "https://us22.api.mailchimp.com/schema/3.0/Definitions/Lists/Locations/CollectionResponse.json" - } - ], + "open_rate": 0, + "opens": 0, + "subscriber_clicks": 0, + "unique_opens": 0 + }, + "resendable": true, + "send_time": "2024-04-29T14:57:00+00:00", + "settings": { + "authenticate": true, + "auto_footer": false, + "auto_tweet": false, + "drag_and_drop": false, + "fb_comments": true, + "folder_id": null, + "from_name": "Estu", + "inline_css": false, + "preview_text": "Teste", + "reply_to": "leofs123@gmail.com", + "subject_line": "Teste", + "template_id": 13, + "timewarp": false, + "title": null, + "to_name": null, + "use_conversation": false + }, + "status": "sent", + "tracking": { + "clicktale": null, + "ecomm360": false, + "goal_tracking": false, + "google_analytics": null, + "html_clicks": true, + "opens": true, + "text_clicks": false + }, + "type": "regular", + "web_id": 6290 + } + ], + [ + "acmeCo/lists", + { + "_meta": { + "op": "u", + "row_id": 0 + }, "beamer_address": "us22-eb203924dd-18076968e2@inbound.mailchimp.com", "campaign_defaults": { "from_email": "leofs123@gmail.com", "from_name": "Estu", "language": "en", - "subject": "" + "subject": null }, "contact": "redacted", "date_created": "2024-03-22T20:01:48+00:00", @@ -128,21 +94,21 @@ "marketing_permissions": false, "modules": [], "name": "Penguins", - "notify_on_subscribe": "", - "notify_on_unsubscribe": "", + "notify_on_subscribe": null, + "notify_on_unsubscribe": null, "permission_reminder": "Voc\u00ea est\u00e1 recebendo este e-mail porque se inscreveu em nosso site.", "stats": { "avg_sub_rate": 0, "avg_unsub_rate": 0, - "campaign_count": 0, - "campaign_last_sent": "", + "campaign_count": 1, + "campaign_last_sent": null, "cleaned_count": 0, "cleaned_count_since_send": 0, "click_rate": 0, "last_sub_date": "redacted", - "last_unsub_date": "", + "last_unsub_date": null, "member_count": 2, - "member_count_since_send": 2, + "member_count_since_send": 0, "merge_field_count": 5, "open_rate": 0, "target_sub_rate": 0, @@ -155,5 +121,249 @@ "visibility": "prv", "web_id": 1174 } + ], + [ + "acmeCo/list_members", + { + "_meta": { + "op": "u", + "row_id": 0 + }, + "consents_to_one_to_one_messaging": true, + "contact_id": "857bca141e5cc997988fa0ce172ece26", + "email_address": "leofs123@gmail.com", + "email_client": null, + "email_type": "html", + "full_name": "Estu", + "id": "65eb1560cc6c0c8156369f06e143f3db", + "ip_opt": "177.34.243.176", + "ip_signup": null, + "language": null, + "last_changed": "2024-03-22T20:01:48+00:00", + "list_id": "7a1cbe4b72", + "location": { + "country_code": null, + "dstoff": 0, + "gmtoff": 0, + "latitude": 0, + "longitude": 0, + "region": null, + "timezone": null + }, + "member_rating": 2, + "merge_fields": { + "ADDRESS": { + "addr1": "Penguins\nRua Neo Alves Martins, 1552\nMaringa, PR 87013-060\nBrazil", + "addr2": null, + "city": null, + "country": "US", + "state": null, + "zip": null + }, + "BIRTHDAY": null, + "FNAME": "Estu", + "LNAME": "Ary", + "PHONE": null + }, + "sms_phone_number": null, + "sms_subscription_last_updated": null, + "sms_subscription_status": null, + "source": "Admin Add", + "stats": { + "avg_click_rate": 0, + "avg_open_rate": 0 + }, + "status": "subscribed", + "tags": [], + "tags_count": 0, + "timestamp_opt": "2024-03-22T20:01:48+00:00", + "timestamp_signup": null, + "unique_email_id": "024245a424", + "vip": false, + "web_id": 557562 + } + ], + [ + "acmeCo/list_members", + { + "_meta": { + "op": "u", + "row_id": 1 + }, + "consents_to_one_to_one_messaging": true, + "contact_id": "354277a363e306205348a85112c500bc", + "email_address": "luish1980@hotmail.com", + "email_client": null, + "email_type": "html", + "full_name": "Luis", + "id": "8b04baf128b1c48ff4bb18dbb6bba2ce", + "ip_opt": "177.34.243.176", + "ip_signup": null, + "language": null, + "last_changed": "2024-04-26T02:19:01+00:00", + "list_id": "7a1cbe4b72", + "location": { + "country_code": null, + "dstoff": 0, + "gmtoff": 0, + "latitude": 0, + "longitude": 0, + "region": null, + "timezone": null + }, + "member_rating": 2, + "merge_fields": { + "ADDRESS": null, + "BIRTHDAY": "11/23", + "FNAME": "Luis", + "LNAME": "Salomao", + "PHONE": "+55 44 0000-0000" + }, + "sms_phone_number": null, + "sms_subscription_last_updated": null, + "sms_subscription_status": null, + "source": "Admin Add", + "stats": { + "avg_click_rate": 0, + "avg_open_rate": 0 + }, + "status": "subscribed", + "tags": [ + { + "id": 3389, + "name": "test_tag" + } + ], + "tags_count": 1, + "timestamp_opt": "2024-04-26T02:19:01+00:00", + "timestamp_signup": null, + "unique_email_id": "3942f2eb78", + "vip": false, + "web_id": 1970495 + } + ], + [ + "acmeCo/reports", + { + "_meta": { + "op": "u", + "row_id": 0 + }, + "abuse_reports": 0, + "bounces": { + "hard_bounces": 0, + "soft_bounces": 0, + "syntax_errors": 0 + }, + "campaign_title": null, + "clicks": { + "click_rate": 0, + "clicks_total": 0, + "last_click": null, + "unique_clicks": 0, + "unique_subscriber_clicks": 0 + }, + "delivery_status": { + "enabled": false + }, + "ecommerce": { + "currency_code": "USD", + "total_orders": 0, + "total_revenue": 0, + "total_spent": 0 + }, + "emails_sent": 2, + "facebook_likes": { + "facebook_likes": 0, + "recipient_likes": 0, + "unique_likes": 0 + }, + "forwards": { + "forwards_count": 0, + "forwards_opens": 0 + }, + "id": "52b74e95ee", + "list_id": "7a1cbe4b72", + "list_is_active": true, + "list_name": "Penguins", + "list_stats": { + "click_rate": 0, + "open_rate": 0, + "sub_rate": 0, + "unsub_rate": 0 + }, + "opens": { + "last_open": null, + "open_rate": 0, + "opens_total": 0, + "unique_opens": 0 + }, + "preview_text": "Teste", + "send_time": "2024-04-29T14:57:00+00:00", + "subject_line": "Teste", + "timeseries": "redacted", + "type": "regular", + "unsubscribed": 0 + } + ], + [ + "acmeCo/segment_members", + { + "_meta": { + "op": "u", + "row_id": 0 + }, + "email_address": "luish1980@hotmail.com", + "email_client": null, + "email_type": "html", + "id": "8b04baf128b1c48ff4bb18dbb6bba2ce", + "ip_opt": "redacted", + "ip_signup": null, + "language": null, + "last_changed": "2024-04-26T02:19:01+00:00", + "list_id": "7a1cbe4b72", + "location": { + "country_code": null, + "dstoff": 0, + "gmtoff": 0, + "latitude": 0, + "longitude": 0, + "timezone": null + }, + "member_rating": 2, + "merge_fields": { + "ADDRESS": null, + "BIRTHDAY": "11/23", + "FNAME": "Luis", + "LNAME": "Salomao", + "PHONE": "+55 44 0000-0000" + }, + "segment_id": 3389, + "stats": { + "avg_click_rate": 0, + "avg_open_rate": 0 + }, + "status": "subscribed", + "timestamp_opt": "2024-04-26T02:19:01+00:00", + "timestamp_signup": null, + "unique_email_id": "3942f2eb78", + "vip": false + } + ], + [ + "acmeCo/segments", + { + "_meta": { + "op": "u", + "row_id": 0 + }, + "created_at": "2024-04-26T02:17:50+00:00", + "id": 3389, + "list_id": "7a1cbe4b72", + "member_count": 1, + "name": "test_tag", + "type": "static", + "updated_at": "2024-04-26T02:17:50+00:00" + } ] ] diff --git a/source-mailchimp/tests/snapshots/snapshots__discover__capture.stdout.json b/source-mailchimp/tests/snapshots/snapshots__discover__capture.stdout.json index 6709ff686f..bffe659c39 100644 --- a/source-mailchimp/tests/snapshots/snapshots__discover__capture.stdout.json +++ b/source-mailchimp/tests/snapshots/snapshots__discover__capture.stdout.json @@ -1,317 +1,374 @@ [ { "documentSchema": { - "description": "Information about a specific list.", + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, "properties": { - "beamer_address": { - "description": "The list's [Email Beamer](https://mailchimp.com/help/use-email-beamer-to-create-a-campaign/) address.", - "readOnly": true, - "title": "Beamer Address", + "_meta": { + "properties": { + "row_id": { + "type": "integer" + } + }, + "required": [ + "row_id" + ], + "type": "object" + }, + "create_time": { + "format": "date-time", + "type": [ + "null", + "string" + ] + }, + "emails_sent": { + "type": [ + "null", + "number" + ] + }, + "id": { "type": "string" }, - "campaign_defaults": { - "description": "[Default values for campaigns](https://mailchimp.com/help/edit-your-emails-subject-preview-text-from-name-or-from-email-address/) created for this list.", + "recipients": { "properties": { - "from_email": { - "description": "The default from email for campaigns sent to this list.", - "title": "Sender's Email Address", - "type": "string" + "list_id": { + "type": [ + "null", + "string" + ] }, - "from_name": { - "description": "The default from name for campaigns sent to this list.", - "title": "Sender's Name", - "type": "string" + "list_is_active": { + "type": [ + "null", + "boolean" + ] }, - "language": { - "description": "The default language for this lists's forms.", - "title": "Language", - "type": "string" + "list_name": { + "type": [ + "null", + "string" + ] }, - "subject": { - "description": "The default subject line for campaigns sent to this list.", - "title": "Subject", - "type": "string" + "segment_opts": { + "properties": { + "conditions": { + "items": { + "additionalProperties": true, + "type": [ + "null", + "object" + ] + }, + "type": [ + "null", + "array" + ] + }, + "match": { + "type": [ + "null", + "string" + ] + }, + "saved_segment_id": { + "type": [ + "null", + "number" + ] + } + }, + "type": [ + "null", + "object" + ] + }, + "store_id": { + "type": [ + "null", + "string" + ] } }, - "title": "Campaign Defaults", - "type": "object" + "type": [ + "null", + "object" + ] }, - "contact": { - "description": "[Contact information displayed in campaign footers](https://mailchimp.com/help/about-campaign-footers/) to comply with international spam laws.", + "report_summary": { "properties": { - "address1": { - "description": "The street address for the list contact.", - "title": "Address", - "type": "string" + "click_rate": { + "type": [ + "null", + "number" + ] }, - "address2": { - "description": "The street address for the list contact.", - "title": "Address", - "type": "string" + "clicks": { + "type": [ + "null", + "number" + ] }, - "city": { - "description": "The city for the list contact.", - "title": "City", - "type": "string" + "open_rate": { + "type": [ + "null", + "number" + ] }, - "company": { - "description": "The company name for the list.", - "title": "Company Name", - "type": "string" + "opens": { + "type": [ + "null", + "number" + ] }, - "country": { - "description": "A two-character ISO3166 country code. Defaults to US if invalid.", - "title": "Country Code", - "type": "string" + "subscriber_clicks": { + "type": [ + "null", + "number" + ] }, - "phone": { - "description": "The phone number for the list contact.", - "title": "Phone Number", - "type": "string" + "unique_opens": { + "type": [ + "null", + "number" + ] + } + }, + "type": [ + "null", + "object" + ] + }, + "settings": { + "properties": { + "authenticate": { + "type": [ + "null", + "boolean" + ] }, - "state": { - "description": "The state for the list contact.", - "title": "State", - "type": "string" + "auto_footer": { + "type": [ + "null", + "boolean" + ] }, - "zip": { - "description": "The postal or zip code for the list contact.", - "title": "Postal Code", - "type": "string" + "from_name": { + "type": [ + "null", + "string" + ] + }, + "inline_css": { + "type": [ + "null", + "boolean" + ] + }, + "reply_to": { + "type": [ + "null", + "string" + ] + }, + "title": { + "type": [ + "null", + "string" + ] + }, + "to_name": { + "type": [ + "null", + "string" + ] + }, + "use_conversation": { + "type": [ + "null", + "boolean" + ] } }, - "title": "List Contact", - "type": "object" + "type": [ + "null", + "object" + ] }, - "date_created": { - "description": "The date and time that this list was created in ISO 8601 format.", + "start_time": { "format": "date-time", - "readOnly": true, - "title": "Creation Date", - "type": "string" - }, - "double_optin": { - "default": false, - "description": "Whether or not to require the subscriber to confirm subscription via email.", - "title": "Double Opt In", - "type": "boolean" - }, - "email_type_option": { - "description": "Whether the list supports [multiple formats for emails](https://mailchimp.com/help/change-list-name-and-defaults/). When set to `true`, subscribers can choose whether they want to receive HTML or plain-text emails. When set to `false`, subscribers will receive HTML emails, with a plain-text alternative backup.", - "title": "Email Type Option", - "type": "boolean" - }, - "has_welcome": { - "default": false, - "description": "Whether or not this list has a welcome automation connected. Welcome Automations: welcomeSeries, singleWelcome, emailFollowup.", - "example": false, - "title": "Has Welcome", - "type": "boolean" - }, - "id": { - "description": "A string that uniquely identifies this list.", - "readOnly": true, - "title": "List ID", - "type": "string" - }, - "list_rating": { - "description": "An auto-generated activity score for the list (0-5).", - "readOnly": true, - "title": "List Rating", - "type": "integer" - }, - "marketing_permissions": { - "default": false, - "description": "Whether or not the list has marketing permissions (eg. GDPR) enabled.", - "title": "Marketing Permissions", - "type": "boolean" - }, - "modules": { - "description": "Any list-specific modules installed for this list.", - "items": { - "type": "string" - }, - "readOnly": true, - "title": "Modules", - "type": "array" - }, - "name": { - "description": "The name of the list.", - "title": "List Name", - "type": "string" - }, - "notify_on_subscribe": { - "default": "false", - "description": "The email address to send [subscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", - "title": "Notify on Subscribe", - "type": "string" - }, - "notify_on_unsubscribe": { - "default": "false", - "description": "The email address to send [unsubscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", - "title": "Notify on Unsubscribe", - "type": "string" + "type": [ + "null", + "string" + ] }, - "permission_reminder": { - "description": "The [permission reminder](https://mailchimp.com/help/edit-the-permission-reminder/) for the list.", - "title": "Permission Reminder", - "type": "string" + "status": { + "type": [ + "null", + "string" + ] }, - "stats": { - "description": "Stats for the list. Many of these are cached for at least five minutes.", + "tracking": { "properties": { - "avg_sub_rate": { - "description": "The average number of subscriptions per month for the list (not returned if we haven't calculated it yet).", - "readOnly": true, - "title": "Average Subscription Rate", - "type": "number" - }, - "avg_unsub_rate": { - "description": "The average number of unsubscriptions per month for the list (not returned if we haven't calculated it yet).", - "readOnly": true, - "title": "Average Unsubscription Rate", - "type": "number" - }, - "campaign_count": { - "description": "The number of campaigns in any status that use this list.", - "readOnly": true, - "title": "Campaign Count", - "type": "integer" + "capsule": { + "properties": { + "notes": { + "type": [ + "null", + "boolean" + ] + } + }, + "type": [ + "null", + "object" + ] }, - "campaign_last_sent": { - "description": "The date and time the last campaign was sent to this list in ISO 8601 format. This is updated when a campaign is sent to 10 or more recipients.", - "readOnly": true, - "title": "Campaign Last Sent", - "type": "string" + "clicktale": { + "type": [ + "null", + "string" + ] }, - "cleaned_count": { - "description": "The number of members cleaned from the list.", - "readOnly": true, - "title": "Cleaned Count", - "type": "integer" + "ecomm360": { + "type": [ + "null", + "boolean" + ] }, - "cleaned_count_since_send": { - "description": "The number of members cleaned from the list since the last campaign was sent.", - "readOnly": true, - "title": "Cleaned Count Since Send", - "type": "integer" + "goal_tracking": { + "type": [ + "null", + "boolean" + ] }, - "click_rate": { - "description": "The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet).", - "readOnly": true, - "title": "Click Rate", - "type": "number" + "google_analytics": { + "type": [ + "null", + "string" + ] }, - "last_sub_date": { - "description": "The date and time of the last time someone subscribed to this list in ISO 8601 format.", - "readOnly": true, - "title": "Date of Last List Subscribe", - "type": "string" + "html_clicks": { + "type": [ + "null", + "boolean" + ] }, - "last_unsub_date": { - "description": "The date and time of the last time someone unsubscribed from this list in ISO 8601 format.", - "readOnly": true, - "title": "Date of Last List Unsubscribe", - "type": "string" + "opens": { + "type": [ + "null", + "boolean" + ] }, - "member_count": { - "description": "The number of active members in the list.", - "readOnly": true, - "title": "Member Count", - "type": "integer" + "salesforce": { + "properties": { + "campaign": { + "type": [ + "null", + "boolean" + ] + }, + "notes": { + "type": [ + "null", + "boolean" + ] + } + }, + "type": [ + "null", + "object" + ] }, - "member_count_since_send": { - "description": "The number of active members in the list since the last campaign was sent.", - "readOnly": true, - "title": "Member Count Since Send", - "type": "integer" - }, - "merge_field_count": { - "description": "The number of merge vars for this list (not EMAIL, which is required).", - "readOnly": true, - "title": "Merge Var Count", - "type": "integer" - }, - "open_rate": { - "description": "The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet).", - "readOnly": true, - "title": "Open Rate", - "type": "number" - }, - "target_sub_rate": { - "description": "The target number of subscriptions per month for the list to keep it growing (not returned if we haven't calculated it yet).", - "readOnly": true, - "title": "Average Subscription Rate", - "type": "number" + "text_clicks": { + "type": [ + "null", + "boolean" + ] + } + }, + "type": [ + "null", + "object" + ] + }, + "trigger_settings": { + "properties": { + "runtime": { + "properties": { + "days": { + "items": { + "type": [ + "null", + "string" + ] + }, + "type": [ + "null", + "array" + ] + }, + "hours": { + "properties": { + "type": { + "type": [ + "null", + "string" + ] + } + }, + "type": [ + "null", + "object" + ] + } + }, + "type": [ + "null", + "object" + ] }, - "total_contacts": { - "description": "The number of contacts in the list, including subscribed, unsubscribed, pending, cleaned, deleted, transactional, and those that need to be reconfirmed.", - "readOnly": true, - "title": "Total Contacts", - "type": "integer" + "workflow_emails_count": { + "type": [ + "null", + "number" + ] }, - "unsubscribe_count": { - "description": "The number of members who have unsubscribed from the list.", - "readOnly": true, - "title": "Unsubscribe Count", - "type": "integer" + "workflow_title": { + "type": [ + "null", + "string" + ] }, - "unsubscribe_count_since_send": { - "description": "The number of members who have unsubscribed since the last campaign was sent.", - "readOnly": true, - "title": "Unsubscribe Count Since Send", - "type": "integer" + "workflow_type": { + "type": [ + "null", + "string" + ] } }, - "readOnly": true, - "title": "Statistics", - "type": "object" - }, - "subscribe_url_long": { - "description": "The full version of this list's subscribe form (host will vary).", - "readOnly": true, - "title": "Subscribe URL Long", - "type": "string" - }, - "subscribe_url_short": { - "description": "Our [EepURL shortened](https://mailchimp.com/help/share-your-signup-form/) version of this list's subscribe form.", - "readOnly": true, - "title": "Subscribe URL Short", - "type": "string" - }, - "use_archive_bar": { - "default": false, - "description": "Whether campaigns for this list use the [Archive Bar](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) in archives by default.", - "title": "Use Archive Bar", - "type": "boolean" - }, - "visibility": { - "description": "Whether this list is [public or private](https://mailchimp.com/help/about-list-publicity/).", - "title": "Visibility", - "type": "string" - }, - "web_id": { - "description": "The ID used in the Mailchimp web application. View this list in your Mailchimp account at `https://{dc}.admin.mailchimp.com/lists/members/?id={web_id}`.", - "readOnly": true, - "title": "List Web ID", - "type": "integer" + "type": [ + "null", + "object" + ] } }, "required": [ "id" ], - "title": "Subscriber List", + "title": "Automations", "type": "object" }, "key": [ "/id" ], - "recommendedName": "lists", + "recommendedName": "automations", "resourceConfig": { "cursorField": [ - "date_created" + "create_time" ], - "stream": "lists", + "stream": "automations", "syncMode": "incremental" } }, @@ -319,48 +376,90 @@ "documentSchema": { "description": "A summary of an individual campaign's settings and content.", "properties": { + "_meta": { + "properties": { + "row_id": { + "type": "integer" + } + }, + "required": [ + "row_id" + ], + "type": "object" + }, "ab_split_opts": { "description": "[A/B Testing](https://mailchimp.com/help/about-ab-testing-campaigns/) options for a campaign.", "properties": { "from_name_a": { "description": "For campaigns split on 'From Name', the name for Group A.", "title": "From Name Group A", - "type": "string" + "type": [ + "null", + "string" + ] }, "from_name_b": { "description": "For campaigns split on 'From Name', the name for Group B.", "title": "From Name Group B", - "type": "string" + "type": [ + "null", + "string" + ] }, "pick_winner": { "description": "How we should evaluate a winner. Based on 'opens', 'clicks', or 'manual'.", + "enum": [ + "opens", + "clicks", + "manual" + ], "title": "Pick Winner", - "type": "string" + "type": [ + "null", + "string" + ] }, "reply_email_a": { "description": "For campaigns split on 'From Name', the reply-to address for Group A.", "title": "Reply Email Group A", - "type": "string" + "type": [ + "null", + "string" + ] }, "reply_email_b": { "description": "For campaigns split on 'From Name', the reply-to address for Group B.", "title": "Reply Email Group B", - "type": "string" + "type": [ + "null", + "string" + ] }, "send_time_a": { "description": "The send time for Group A.", + "format": "date-time", "title": "Send Time Group A", - "type": "string" + "type": [ + "null", + "string" + ] }, "send_time_b": { "description": "The send time for Group B.", + "format": "date-time", "title": "Send Time Group B", - "type": "string" + "type": [ + "null", + "string" + ] }, "send_time_winner": { "description": "The send time for the winning version.", "title": "Send Time Winner", - "type": "string" + "type": [ + "null", + "string" + ] }, "split_size": { "description": "The size of the split groups. Campaigns split based on 'schedule' are forced to have a 50/50 split. Valid split integers are between 1-50.", @@ -371,18 +470,32 @@ }, "split_test": { "description": "The type of AB split to run.", + "enum": [ + "subject", + "from_name", + "schedule" + ], "title": "Split Test", - "type": "string" + "type": [ + "null", + "string" + ] }, "subject_a": { "description": "For campaigns split on 'Subject Line', the subject line for Group A.", "title": "Subject Line Group A", - "type": "string" + "type": [ + "null", + "string" + ] }, "subject_b": { "description": "For campaigns split on 'Subject Line', the subject line for Group B.", "title": "Subject Line Group B", - "type": "string" + "type": [ + "null", + "string" + ] }, "wait_time": { "description": "The amount of time to wait before picking a winner. This cannot be changed after a campaign is sent.", @@ -391,8 +504,15 @@ }, "wait_units": { "description": "How unit of time for measuring the winner ('hours' or 'days'). This cannot be changed after a campaign is sent.", + "enum": [ + "hours", + "days" + ], "title": "Wait Time", - "type": "string" + "type": [ + "null", + "string" + ] } }, "readOnly": true, @@ -403,15 +523,28 @@ "description": "The link to the campaign's archive version in ISO 8601 format.", "readOnly": true, "title": "Archive URL", - "type": "string" + "type": [ + "null", + "string" + ] }, "content_type": { "description": "How the campaign's content is put together.", + "enum": [ + "template", + "html", + "url", + "multichannel" + ], "title": "Content Type", - "type": "string" + "type": [ + "null", + "string" + ] }, "create_time": { "description": "The date and time the campaign was created in ISO 8601 format.", + "format": "date-time", "readOnly": true, "title": "Create Time", "type": "string" @@ -445,9 +578,18 @@ }, "status": { "description": "The current state of a campaign delivery.", + "enum": [ + "delivering", + "delivered", + "canceling", + "canceled" + ], "readOnly": true, "title": "Campaign Delivery Status", - "type": "string" + "type": [ + "null", + "string" + ] } }, "title": "Campaign Delivery Status", @@ -469,7 +611,10 @@ "description": "The original link to the campaign's archive version.", "readOnly": true, "title": "Long Archive URL", - "type": "string" + "type": [ + "null", + "string" + ] }, "needs_block_refresh": { "description": "Determines if the campaign needs its blocks refreshed by opening the web-based campaign editor. Deprecated and will always return false.", @@ -481,7 +626,10 @@ "description": "If this campaign is the child of another campaign, this identifies the parent campaign. For Example, for RSS or Automation children.", "readOnly": true, "title": "Parent Campaign ID", - "type": "string" + "type": [ + "null", + "string" + ] }, "recipients": { "description": "List settings for the campaign.", @@ -489,7 +637,10 @@ "list_id": { "description": "The unique list id.", "title": "List ID", - "type": "string" + "type": [ + "null", + "string" + ] }, "list_is_active": { "description": "The status of the list used, namely if it's deleted or disabled.", @@ -501,7 +652,10 @@ "description": "The name of the list.", "readOnly": true, "title": "List Name", - "type": "string" + "type": [ + "null", + "string" + ] }, "recipient_count": { "description": "Count of the recipients on the associated list. Formatted as an integer.", @@ -2388,6 +2542,10 @@ }, "match": { "description": "Segment match type.", + "enum": [ + "any", + "all" + ], "title": "Match Type", "type": "string" }, @@ -2410,7 +2568,10 @@ "description": "A description of the [segment](https://mailchimp.com/help/create-and-send-to-a-segment/) used for the campaign. Formatted as a string marked up with HTML.", "readOnly": true, "title": "Segment Text", - "type": "string" + "type": [ + "null", + "string" + ] } }, "title": "List", @@ -2502,18 +2663,33 @@ "description": "The URL for the RSS feed.", "format": "uri", "title": "Feed URL", - "type": "string" + "type": [ + "null", + "string" + ] }, "frequency": { "description": "The frequency of the RSS Campaign.", + "enum": [ + "daily", + "weekly", + "monthly" + ], "title": "Frequency", - "type": "string" + "type": [ + "null", + "string" + ] }, "last_sent": { "description": "The date the campaign was last sent.", + "format": "date-time", "readOnly": true, "title": "Last Sent", - "type": "string" + "type": [ + "null", + "string" + ] }, "schedule": { "description": "The schedule for sending the RSS Campaign.", @@ -2576,8 +2752,20 @@ }, "weekly_send_day": { "description": "The day of the week to send a weekly RSS Campaign.", + "enum": [ + "sunday", + "monday", + "tuesday", + "wednesday", + "thursday", + "friday", + "saturday" + ], "title": "Weekly Sending Day", - "type": "string" + "type": [ + "null", + "string" + ] } }, "title": "Sending Schedule", @@ -2589,9 +2777,13 @@ }, "send_time": { "description": "The date and time a campaign was sent.", + "format": "date-time", "readOnly": true, "title": "Send Time", - "type": "string" + "type": [ + "null", + "string" + ] }, "settings": { "description": "The settings for your campaign, including subject, from name, reply-to address, and more.", @@ -2604,7 +2796,10 @@ "auto_fb_post": { "description": "An array of [Facebook](https://mailchimp.com/help/connect-or-disconnect-the-facebook-integration/) page ids to auto-post to.", "items": { - "type": "string" + "type": [ + "null", + "string" + ] }, "title": "Auto Post to Facebook", "type": "array" @@ -2633,12 +2828,18 @@ "folder_id": { "description": "If the campaign is listed in a folder, the id for that folder.", "title": "Folder ID", - "type": "string" + "type": [ + "null", + "string" + ] }, "from_name": { "description": "The 'from' name on the campaign (not an email address).", "title": "From Name", - "type": "string" + "type": [ + "null", + "string" + ] }, "inline_css": { "description": "Automatically inline the CSS included with the campaign content.", @@ -2648,17 +2849,26 @@ "preview_text": { "description": "The preview text for the campaign.", "title": "Campaign Preview Text", - "type": "string" + "type": [ + "null", + "string" + ] }, "reply_to": { "description": "The reply-to email address for the campaign.", "title": "Reply To Address", - "type": "string" + "type": [ + "null", + "string" + ] }, "subject_line": { "description": "The subject line for the campaign.", "title": "Campaign Subject Line", - "type": "string" + "type": [ + "null", + "string" + ] }, "template_id": { "description": "The id for the template used in this campaign.", @@ -2675,12 +2885,18 @@ "title": { "description": "The title of the campaign.", "title": "Campaign Title", - "type": "string" + "type": [ + "null", + "string" + ] }, "to_name": { "description": "The campaign's custom 'To' name. Typically the first name [merge field](https://mailchimp.com/help/getting-started-with-merge-tags/).", "title": "To Name", - "type": "string" + "type": [ + "null", + "string" + ] }, "use_conversation": { "description": "Use Mailchimp Conversation feature to manage out-of-office replies.", @@ -2697,17 +2913,26 @@ "description": { "description": "A short summary of the campaign to display.", "title": "Campaign Description", - "type": "string" + "type": [ + "null", + "string" + ] }, "image_url": { "description": "The url for the header image for the card.", "title": "Image URL", - "type": "string" + "type": [ + "null", + "string" + ] }, "title": { "description": "The title for the card. Typically the subject line of the campaign.", "title": "Title", - "type": "string" + "type": [ + "null", + "string" + ] } }, "title": "Campaign Social Card", @@ -2715,6 +2940,16 @@ }, "status": { "description": "The current status of the campaign.", + "enum": [ + "save", + "paused", + "schedule", + "sending", + "sent", + "canceled", + "canceling", + "archived" + ], "readOnly": true, "title": "Campaign Status", "type": "string" @@ -2737,7 +2972,10 @@ "clicktale": { "description": "The custom slug for [ClickTale](https://mailchimp.com/help/additional-tracking-options-for-campaigns/) tracking (max of 50 bytes).", "title": "ClickTale Analytics Tracking", - "type": "string" + "type": [ + "null", + "string" + ] }, "ecomm360": { "description": "Whether to enable [eCommerce360](https://mailchimp.com/help/connect-your-online-store-to-mailchimp/) tracking.", @@ -2752,7 +2990,10 @@ "google_analytics": { "description": "The custom slug for [Google Analytics](https://mailchimp.com/help/integrate-google-analytics-with-mailchimp/) tracking (max of 50 bytes).", "title": "Google Analytics Tracking", - "type": "string" + "type": [ + "null", + "string" + ] }, "html_clicks": { "description": "Whether to [track clicks](https://mailchimp.com/help/enable-and-view-click-tracking/) in the HTML version of the campaign. Defaults to `true`. Cannot be set to false for variate campaigns.", @@ -2815,7 +3056,10 @@ "id": { "description": "Unique ID for the combination.", "title": "ID", - "type": "string" + "type": [ + "null", + "string" + ] }, "recipients": { "description": "The number of recipients for this combination.", @@ -2847,7 +3091,10 @@ "contents": { "description": "Descriptions of possible email contents. To set campaign contents, make a PUT request to /campaigns/{campaign_id}/content with the field 'variate_contents'.", "items": { - "type": "string" + "type": [ + "null", + "string" + ] }, "readOnly": true, "title": "Content Descriptions", @@ -2856,7 +3103,10 @@ "from_names": { "description": "The possible from names. The number of from_names provided must match the number of reply_to_addresses. If no from_names are provided, settings.from_name will be used.", "items": { - "type": "string" + "type": [ + "null", + "string" + ] }, "title": "From Names", "type": "array" @@ -2864,7 +3114,10 @@ "reply_to_addresses": { "description": "The possible reply-to addresses. The number of reply_to_addresses provided must match the number of from_names. If no reply_to_addresses are provided, settings.reply_to will be used.", "items": { - "type": "string" + "type": [ + "null", + "string" + ] }, "title": "Reply To Addresses", "type": "array" @@ -2872,7 +3125,11 @@ "send_times": { "description": "The possible send times to test. The times provided should be in the format YYYY-MM-DD HH:MM:SS. If send_times are provided to test, the test_size will be set to 100% and winner_criteria will be ignored.", "items": { - "type": "string" + "format": "date-time", + "type": [ + "null", + "string" + ] }, "title": "Send Times", "type": "array" @@ -2880,7 +3137,10 @@ "subject_lines": { "description": "The possible subject lines to test. If no subject lines are provided, settings.subject_line will be used.", "items": { - "type": "string" + "type": [ + "null", + "string" + ] }, "title": "Subject Lines", "type": "array" @@ -2897,20 +3157,35 @@ }, "winner_criteria": { "description": "The combination that performs the best. This may be determined automatically by click rate, open rate, or total revenue -- or you may choose manually based on the reporting data you find the most valuable. For Multivariate Campaigns testing send_time, winner_criteria is ignored. For Multivariate Campaigns with 'manual' as the winner_criteria, the winner must be chosen in the Mailchimp web application.", + "enum": [ + "opens", + "clicks", + "manual", + "total_revenue" + ], "title": "Winning Criteria", - "type": "string" + "type": [ + "null", + "string" + ] }, "winning_campaign_id": { "description": "ID of the campaign that was sent to the remaining recipients based on the winning combination.", "readOnly": true, "title": "Winning Campaign ID", - "type": "string" + "type": [ + "null", + "string" + ] }, "winning_combination_id": { "description": "ID for the winning combination.", "readOnly": true, "title": "Winning Combination ID", - "type": "string" + "type": [ + "null", + "string" + ] } }, "title": "A/B Test Options", @@ -2945,8 +3220,24 @@ "documentSchema": { "description": "A list of member's subscriber activity in a specific campaign.", "properties": { + "_meta": { + "properties": { + "row_id": { + "type": "integer" + } + }, + "required": [ + "row_id" + ], + "type": "object" + }, "action": { "description": "One of the following actions: 'open', 'click', or 'bounce'", + "enum": [ + "open", + "click", + "bounce" + ], "title": "action", "type": "string" }, @@ -2991,6 +3282,10 @@ }, "type": { "description": "If the action is a 'bounce', the type of bounce received: 'hard', 'soft'.", + "enum": [ + "hard", + "soft" + ], "title": "Type", "type": [ "string", @@ -3030,575 +3325,2029 @@ }, { "documentSchema": { - "description": "A list of reports containing campaigns marked as Sent.", + "$schema": "http://json-schema.org/draft-07/schema#", "properties": { - "ab_split": { - "description": "General stats about different groups of an A/B Split campaign. Does not return information about Multivariate Campaigns.", + "_meta": { "properties": { - "a": { - "description": "Stats for Campaign A.", - "properties": { - "abuse_reports": { - "description": "Abuse reports for Campaign A.", - "title": "Abuse Reports", - "type": "integer" - }, - "bounces": { - "description": "Bounces for Campaign A.", - "title": "Bounces", - "type": "integer" - }, - "forwards": { - "description": "Forwards for Campaign A.", - "title": "Forwards", - "type": "integer" - }, - "forwards_opens": { - "description": "Opens from forwards for Campaign A.", - "title": "Forward Opens", - "type": "integer" - }, - "last_open": { - "description": "The last open for Campaign A.", - "title": "Last Open", - "type": "string" - }, - "opens": { - "description": "Opens for Campaign A.", - "title": "Opens", - "type": "integer" - }, - "recipient_clicks": { - "description": "Recipient Clicks for Campaign A.", - "title": "Recipient Clicks", - "type": "integer" - }, - "unique_opens": { - "description": "Unique opens for Campaign A.", - "title": "Unique Opens", - "type": "integer" - }, - "unsubs": { - "description": "Unsubscribes for Campaign A.", - "title": "Unsubscribes", - "type": "integer" - } - }, - "title": "Campaign A", - "type": "object" - }, - "b": { - "description": "Stats for Campaign B.", - "properties": { - "abuse_reports": { - "description": "Abuse reports for Campaign B.", - "title": "Abuse Reports", - "type": "integer" - }, - "bounces": { - "description": "Bounces for Campaign B.", - "title": "Bounces", - "type": "integer" - }, - "forwards": { - "description": "Forwards for Campaign B.", - "title": "Forwards", - "type": "integer" - }, - "forwards_opens": { - "description": "Opens for forwards from Campaign B.", - "title": "Forward Opens", - "type": "integer" - }, - "last_open": { - "description": "The last open for Campaign B.", - "title": "Last Open", - "type": "string" - }, - "opens": { - "description": "Opens for Campaign B.", - "title": "Opens", - "type": "integer" - }, - "recipient_clicks": { - "description": "Recipients clicks for Campaign B.", - "title": "Recipient Clicks", - "type": "integer" - }, - "unique_opens": { - "description": "Unique opens for Campaign B.", - "title": "Unique Opens", - "type": "integer" - }, - "unsubs": { - "description": "Unsubscribes for Campaign B.", - "title": "Unsubscribes", - "type": "integer" - } - }, - "title": "Campaign B", - "type": "object" + "row_id": { + "type": "integer" } }, - "title": "A/B Split Stats", + "required": [ + "row_id" + ], "type": "object" }, - "abuse_reports": { - "description": "The number of abuse reports generated for this campaign.", - "title": "Abuse Reports", - "type": "integer" + "display_order": { + "type": [ + "null", + "integer" + ] }, - "bounces": { - "description": "An object describing the bounce summary for the campaign.", - "properties": { - "hard_bounces": { - "description": "The total number of hard bounced email addresses.", - "title": "Hard Bounces", - "type": "integer" - }, - "soft_bounces": { - "description": "The total number of soft bounced email addresses.", - "title": "Soft Bounces", - "type": "integer" - }, - "syntax_errors": { - "description": "The total number of addresses that were syntax-related bounces.", - "title": "Syntax Errors", + "id": { + "type": "string" + }, + "list_id": { + "type": [ + "null", + "string" + ] + }, + "title": { + "type": [ + "null", + "string" + ] + }, + "type": { + "type": [ + "null", + "string" + ] + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "key": [ + "/id" + ], + "recommendedName": "interest_categories", + "resourceConfig": { + "stream": "interest_categories", + "syncMode": "full_refresh" + } + }, + { + "documentSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "_meta": { + "properties": { + "row_id": { "type": "integer" } }, - "title": "Bounces", + "required": [ + "row_id" + ], "type": "object" }, - "campaign_title": { - "description": "The title of the campaign.", - "readOnly": true, - "title": "Campaign Title", + "category_id": { + "type": [ + "null", + "string" + ] + }, + "display_order": { + "type": [ + "null", + "integer" + ] + }, + "id": { "type": "string" }, - "clicks": { - "description": "An object describing the click activity for the campaign.", + "list_id": { + "type": [ + "null", + "string" + ] + }, + "name": { + "type": [ + "null", + "string" + ] + }, + "subscriber_count": { + "type": [ + "null", + "string" + ] + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "key": [ + "/id" + ], + "recommendedName": "interests", + "resourceConfig": { + "stream": "interests", + "syncMode": "full_refresh" + } + }, + { + "documentSchema": { + "description": "Information about a specific list.", + "properties": { + "_meta": { "properties": { - "click_rate": { - "description": "The number of unique clicks divided by the total number of successful deliveries.", - "title": "Click Rate", - "type": "number" - }, - "clicks_total": { - "description": "The total number of clicks for the campaign.", - "title": "Total Clicks", - "type": "integer" - }, - "last_click": { - "description": "The date and time of the last recorded click for the campaign in ISO 8601 format.", - "format": "date-time", - "title": "Last Click", - "type": "string" - }, - "unique_clicks": { - "description": "The total number of unique clicks for links across a campaign.", - "title": "Unique Clicks", - "type": "integer" - }, - "unique_subscriber_clicks": { - "description": "The total number of subscribers who clicked on a campaign.", - "title": "Unique Subscriber Clicks", + "row_id": { "type": "integer" } }, - "title": "Clicks", + "required": [ + "row_id" + ], "type": "object" }, - "delivery_status": { - "description": "Updates on campaigns in the process of sending.", + "beamer_address": { + "description": "The list's [Email Beamer](https://mailchimp.com/help/use-email-beamer-to-create-a-campaign/) address.", + "readOnly": true, + "title": "Beamer Address", + "type": [ + "null", + "string" + ] + }, + "campaign_defaults": { + "description": "[Default values for campaigns](https://mailchimp.com/help/edit-your-emails-subject-preview-text-from-name-or-from-email-address/) created for this list.", "properties": { - "can_cancel": { - "description": "Whether a campaign send can be canceled.", - "readOnly": true, - "title": "Campaign Cancelable", - "type": "boolean" - }, - "emails_canceled": { - "description": "The total number of emails canceled for this campaign.", - "readOnly": true, - "title": "Emails Canceled", - "type": "integer" + "from_email": { + "description": "The default from email for campaigns sent to this list.", + "title": "Sender's Email Address", + "type": [ + "null", + "string" + ] }, - "emails_sent": { - "description": "The total number of emails confirmed sent for this campaign so far.", - "readOnly": true, - "title": "Emails Sent", - "type": "integer" + "from_name": { + "description": "The default from name for campaigns sent to this list.", + "title": "Sender's Name", + "type": [ + "null", + "string" + ] }, - "enabled": { - "description": "Whether Campaign Delivery Status is enabled for this account and campaign.", - "readOnly": true, - "title": "Delivery Status Enabled", - "type": "boolean" + "language": { + "description": "The default language for this lists's forms.", + "title": "Language", + "type": [ + "null", + "string" + ] }, - "status": { - "description": "The current state of a campaign delivery.", - "readOnly": true, - "title": "Campaign Delivery Status", - "type": "string" + "subject": { + "description": "The default subject line for campaigns sent to this list.", + "title": "Subject", + "type": [ + "null", + "string" + ] } }, - "title": "Campaign Delivery Status", + "title": "Campaign Defaults", "type": "object" }, - "ecommerce": { - "description": "E-Commerce stats for a campaign.", + "contact": { + "description": "[Contact information displayed in campaign footers](https://mailchimp.com/help/about-campaign-footers/) to comply with international spam laws.", "properties": { - "currency_code": { - "example": "USD", - "readOnly": true, - "title": "Three letter currency code for this user", - "type": "string" + "address1": { + "description": "The street address for the list contact.", + "title": "Address", + "type": [ + "null", + "string" + ] }, - "total_orders": { - "description": "The total orders for a campaign.", - "readOnly": true, - "title": "Total Orders", - "type": "integer" + "address2": { + "description": "The street address for the list contact.", + "title": "Address", + "type": [ + "null", + "string" + ] }, - "total_revenue": { - "description": "The total revenue for a campaign. Calculated as the sum of all order totals minus shipping and tax totals.", - "readOnly": true, - "title": "Total Revenue", - "type": "number" + "city": { + "description": "The city for the list contact.", + "title": "City", + "type": [ + "null", + "string" + ] }, - "total_spent": { - "description": "The total spent for a campaign. Calculated as the sum of all order totals with no deductions.", - "readOnly": true, - "title": "Total Spent", - "type": "number" - } - }, - "title": "E-Commerce Report", - "type": "object" - }, - "emails_sent": { - "description": "The total number of emails sent for this campaign.", - "title": "Emails Sent", - "type": "integer" - }, - "facebook_likes": { - "description": "An object describing campaign engagement on Facebook.", - "properties": { - "facebook_likes": { - "description": "The number of Facebook likes for the campaign.", - "title": "Facebook Likes", - "type": "integer" + "company": { + "description": "The company name for the list.", + "title": "Company Name", + "type": [ + "null", + "string" + ] }, - "recipient_likes": { - "description": "The number of recipients who liked the campaign on Facebook.", - "title": "Recipient Likes", - "type": "integer" + "country": { + "description": "A two-character ISO3166 country code. Defaults to US if invalid.", + "title": "Country Code", + "type": [ + "null", + "string" + ] }, - "unique_likes": { - "description": "The number of unique likes.", - "title": "Unique Likes", - "type": "integer" - } - }, - "title": "Facebook Likes", - "type": "object" - }, - "forwards": { - "description": "An object describing the forwards and forward activity for the campaign.", - "properties": { - "forwards_count": { - "description": "How many times the campaign has been forwarded.", - "title": "Total Forwards", - "type": "integer" + "phone": { + "description": "The phone number for the list contact.", + "title": "Phone Number", + "type": [ + "null", + "string" + ] }, - "forwards_opens": { - "description": "How many times the forwarded campaign has been opened.", - "title": "Forward Opens", - "type": "integer" + "state": { + "description": "The state for the list contact.", + "title": "State", + "type": [ + "null", + "string" + ] + }, + "zip": { + "description": "The postal or zip code for the list contact.", + "title": "Postal Code", + "type": [ + "null", + "string" + ] } }, - "title": "Forwards", + "title": "List Contact", "type": "object" }, - "id": { - "description": "A string that uniquely identifies this campaign.", - "title": "Campaign ID", + "date_created": { + "description": "The date and time that this list was created in ISO 8601 format.", + "format": "date-time", + "readOnly": true, + "title": "Creation Date", "type": "string" }, - "industry_stats": { - "description": "The average campaign statistics for your industry.", - "properties": { - "abuse_rate": { - "description": "The industry abuse rate.", - "title": "Abuse Rate", - "type": "number" - }, - "bounce_rate": { - "description": "The industry bounce rate.", - "title": "Bounce Rate", - "type": "number" - }, - "click_rate": { - "description": "The industry click rate.", - "title": "Click Rate", - "type": "number" - }, - "open_rate": { - "description": "The industry open rate.", - "title": "Open Rate", - "type": "number" - }, - "type": { - "description": "The type of business industry associated with your account. For example: retail, education, etc.", - "title": "Industry Type", - "type": "string" - }, - "unopen_rate": { - "description": "The industry unopened rate.", - "title": "Unopened Rate", - "type": "number" - }, - "unsub_rate": { - "description": "The industry unsubscribe rate.", - "title": "Unsubscribe Rate", - "type": "number" - } - }, - "title": "Industry Stats", - "type": "object" + "double_optin": { + "default": false, + "description": "Whether or not to require the subscriber to confirm subscription via email.", + "title": "Double Opt In", + "type": "boolean" }, - "list_id": { - "description": "The unique list id.", + "email_type_option": { + "description": "Whether the list supports [multiple formats for emails](https://mailchimp.com/help/change-list-name-and-defaults/). When set to `true`, subscribers can choose whether they want to receive HTML or plain-text emails. When set to `false`, subscribers will receive HTML emails, with a plain-text alternative backup.", + "title": "Email Type Option", + "type": "boolean" + }, + "has_welcome": { + "default": false, + "description": "Whether or not this list has a welcome automation connected. Welcome Automations: welcomeSeries, singleWelcome, emailFollowup.", + "example": false, + "title": "Has Welcome", + "type": "boolean" + }, + "id": { + "description": "A string that uniquely identifies this list.", "readOnly": true, "title": "List ID", "type": "string" }, - "list_is_active": { - "description": "The status of the list used, namely if it's deleted or disabled.", + "list_rating": { + "description": "An auto-generated activity score for the list (0-5).", "readOnly": true, - "title": "List Status", + "title": "List Rating", + "type": "integer" + }, + "marketing_permissions": { + "default": false, + "description": "Whether or not the list has marketing permissions (eg. GDPR) enabled.", + "title": "Marketing Permissions", "type": "boolean" }, - "list_name": { - "description": "The name of the list.", + "modules": { + "description": "Any list-specific modules installed for this list.", + "items": { + "type": [ + "null", + "string" + ] + }, "readOnly": true, + "title": "Modules", + "type": "array" + }, + "name": { + "description": "The name of the list.", "title": "List Name", - "type": "string" + "type": [ + "null", + "string" + ] }, - "list_stats": { - "description": "The average campaign statistics for your list. This won't be present if we haven't calculated it yet for this list.", + "notify_on_subscribe": { + "description": "The email address to send [subscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", + "title": "Notify on Subscribe", + "type": [ + "null", + "string" + ] + }, + "notify_on_unsubscribe": { + "description": "The email address to send [unsubscribe notifications](https://mailchimp.com/help/change-subscribe-and-unsubscribe-notifications/) to.", + "title": "Notify on Unsubscribe", + "type": [ + "null", + "string" + ] + }, + "permission_reminder": { + "description": "The [permission reminder](https://mailchimp.com/help/edit-the-permission-reminder/) for the list.", + "title": "Permission Reminder", + "type": [ + "null", + "string" + ] + }, + "stats": { + "description": "Stats for the list. Many of these are cached for at least five minutes.", "properties": { + "avg_sub_rate": { + "description": "The average number of subscriptions per month for the list (not returned if we haven't calculated it yet).", + "readOnly": true, + "title": "Average Subscription Rate", + "type": "number" + }, + "avg_unsub_rate": { + "description": "The average number of unsubscriptions per month for the list (not returned if we haven't calculated it yet).", + "readOnly": true, + "title": "Average Unsubscription Rate", + "type": "number" + }, + "campaign_count": { + "description": "The number of campaigns in any status that use this list.", + "readOnly": true, + "title": "Campaign Count", + "type": "integer" + }, + "campaign_last_sent": { + "description": "The date and time the last campaign was sent to this list in ISO 8601 format. This is updated when a campaign is sent to 10 or more recipients.", + "format": "date-time", + "readOnly": true, + "title": "Campaign Last Sent", + "type": [ + "null", + "string" + ] + }, + "cleaned_count": { + "description": "The number of members cleaned from the list.", + "readOnly": true, + "title": "Cleaned Count", + "type": "integer" + }, + "cleaned_count_since_send": { + "description": "The number of members cleaned from the list since the last campaign was sent.", + "readOnly": true, + "title": "Cleaned Count Since Send", + "type": "integer" + }, "click_rate": { - "description": "The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list.", + "description": "The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet).", "readOnly": true, "title": "Click Rate", "type": "number" }, + "last_sub_date": { + "description": "The date and time of the last time someone subscribed to this list in ISO 8601 format.", + "format": "date-time", + "readOnly": true, + "title": "Date of Last List Subscribe", + "type": [ + "null", + "string" + ] + }, + "last_unsub_date": { + "description": "The date and time of the last time someone unsubscribed from this list in ISO 8601 format.", + "format": "date-time", + "readOnly": true, + "title": "Date of Last List Unsubscribe", + "type": [ + "null", + "string" + ] + }, + "member_count": { + "description": "The number of active members in the list.", + "readOnly": true, + "title": "Member Count", + "type": "integer" + }, + "member_count_since_send": { + "description": "The number of active members in the list since the last campaign was sent.", + "readOnly": true, + "title": "Member Count Since Send", + "type": "integer" + }, + "merge_field_count": { + "description": "The number of merge vars for this list (not EMAIL, which is required).", + "readOnly": true, + "title": "Merge Var Count", + "type": "integer" + }, "open_rate": { - "description": "The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list.", + "description": "The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list (not returned if we haven't calculated it yet).", "readOnly": true, "title": "Open Rate", "type": "number" }, - "sub_rate": { - "description": "The average number of subscriptions per month for the list.", + "target_sub_rate": { + "description": "The target number of subscriptions per month for the list to keep it growing (not returned if we haven't calculated it yet).", "readOnly": true, "title": "Average Subscription Rate", "type": "number" }, - "unsub_rate": { - "description": "The average number of unsubscriptions per month for the list.", + "total_contacts": { + "description": "The number of contacts in the list, including subscribed, unsubscribed, pending, cleaned, deleted, transactional, and those that need to be reconfirmed.", "readOnly": true, - "title": "Average Unsubscription Rate", - "type": "number" + "title": "Total Contacts", + "type": "integer" + }, + "unsubscribe_count": { + "description": "The number of members who have unsubscribed from the list.", + "readOnly": true, + "title": "Unsubscribe Count", + "type": "integer" + }, + "unsubscribe_count_since_send": { + "description": "The number of members who have unsubscribed since the last campaign was sent.", + "readOnly": true, + "title": "Unsubscribe Count Since Send", + "type": "integer" + } + }, + "readOnly": true, + "title": "Statistics", + "type": "object" + }, + "subscribe_url_long": { + "description": "The full version of this list's subscribe form (host will vary).", + "readOnly": true, + "title": "Subscribe URL Long", + "type": [ + "null", + "string" + ] + }, + "subscribe_url_short": { + "description": "Our [EepURL shortened](https://mailchimp.com/help/share-your-signup-form/) version of this list's subscribe form.", + "readOnly": true, + "title": "Subscribe URL Short", + "type": [ + "null", + "string" + ] + }, + "use_archive_bar": { + "default": false, + "description": "Whether campaigns for this list use the [Archive Bar](https://mailchimp.com/help/about-email-campaign-archives-and-pages/) in archives by default.", + "title": "Use Archive Bar", + "type": "boolean" + }, + "visibility": { + "description": "Whether this list is [public or private](https://mailchimp.com/help/about-list-publicity/).", + "enum": [ + "pub", + "prv" + ], + "title": "Visibility", + "type": [ + "null", + "string" + ] + }, + "web_id": { + "description": "The ID used in the Mailchimp web application. View this list in your Mailchimp account at `https://{dc}.admin.mailchimp.com/lists/members/?id={web_id}`.", + "readOnly": true, + "title": "List Web ID", + "type": "integer" + } + }, + "required": [ + "id" + ], + "title": "Subscriber List", + "type": "object" + }, + "key": [ + "/id" + ], + "recommendedName": "lists", + "resourceConfig": { + "cursorField": [ + "date_created" + ], + "stream": "lists", + "syncMode": "incremental" + } + }, + { + "documentSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "_meta": { + "properties": { + "row_id": { + "type": "integer" + } + }, + "required": [ + "row_id" + ], + "type": "object" + }, + "consents_to_one_to_one_messaging": { + "type": [ + "null", + "boolean" + ] + }, + "contact_id": { + "type": [ + "null", + "string" + ] + }, + "email_address": { + "type": [ + "null", + "string" + ] + }, + "email_client": { + "type": [ + "null", + "string" + ] + }, + "email_type": { + "type": [ + "null", + "string" + ] + }, + "full_name": { + "type": [ + "null", + "string" + ] + }, + "id": { + "type": "string" + }, + "interests": { + "additionalProperties": true, + "type": [ + "null", + "object" + ] + }, + "ip_opt": { + "type": [ + "null", + "string" + ] + }, + "ip_signup": { + "type": [ + "null", + "string" + ] + }, + "language": { + "type": [ + "null", + "string" + ] + }, + "last_changed": { + "format": "date-time", + "type": [ + "null", + "string" + ] + }, + "last_note": { + "properties": { + "created_at": { + "format": "date-time", + "type": [ + "null", + "string" + ] + }, + "created_by": { + "type": [ + "null", + "string" + ] + }, + "note": { + "type": [ + "null", + "string" + ] + }, + "note_id": { + "type": [ + "null", + "integer" + ] + } + }, + "type": [ + "null", + "object" + ] + }, + "list_id": { + "type": [ + "null", + "string" + ] + }, + "location": { + "properties": { + "country_code": { + "type": [ + "null", + "string" + ] + }, + "dstoff": { + "type": [ + "null", + "integer" + ] + }, + "gmtoff": { + "type": [ + "null", + "integer" + ] + }, + "latitude": { + "type": [ + "null", + "number" + ] + }, + "longitude": { + "type": [ + "null", + "number" + ] + }, + "region": { + "type": [ + "null", + "string" + ] + }, + "timezone": { + "type": [ + "null", + "string" + ] + } + }, + "type": [ + "null", + "object" + ] + }, + "marketing_permissions": { + "properties": { + "enabled": { + "type": [ + "null", + "boolean" + ] + }, + "marketing_permission_id": { + "type": [ + "null", + "string" + ] + }, + "text": { + "type": [ + "null", + "string" + ] + } + }, + "type": [ + "null", + "object" + ] + }, + "member_rating": { + "type": [ + "null", + "integer" + ] + }, + "merge_fields": { + "additionalProperties": true, + "type": [ + "null", + "object" + ] + }, + "source": { + "type": [ + "null", + "string" + ] + }, + "stats": { + "properties": { + "avg_click_rate": { + "type": [ + "null", + "number" + ] + }, + "avg_open_rate": { + "type": [ + "null", + "number" + ] + }, + "ecommerce_data": { + "properties": { + "currency_code": { + "type": [ + "null", + "string" + ] + }, + "number_of_orders": { + "type": [ + "null", + "number" + ] + }, + "total_revenue": { + "type": [ + "null", + "number" + ] + } + }, + "type": [ + "null", + "object" + ] + } + }, + "type": [ + "null", + "object" + ] + }, + "status": { + "type": [ + "null", + "string" + ] + }, + "tags": { + "items": { + "properties": { + "id": { + "type": [ + "null", + "integer" + ] + }, + "name": { + "type": [ + "null", + "string" + ] + } + }, + "type": [ + "null", + "object" + ] + }, + "type": [ + "null", + "array" + ] + }, + "tags_count": { + "type": [ + "null", + "integer" + ] + }, + "timestamp_opt": { + "format": "date-time", + "type": [ + "null", + "string" + ] + }, + "timestamp_signup": { + "format": "date-time", + "type": [ + "null", + "string" + ] + }, + "unique_email_id": { + "type": [ + "null", + "string" + ] + }, + "unsubscribe_reason": { + "type": [ + "null", + "string" + ] + }, + "vip": { + "type": [ + "null", + "boolean" + ] + }, + "web_id": { + "type": [ + "null", + "integer" + ] + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "key": [ + "/id" + ], + "recommendedName": "list_members", + "resourceConfig": { + "cursorField": [ + "last_changed" + ], + "stream": "list_members", + "syncMode": "incremental" + } + }, + { + "documentSchema": { + "description": "A list of reports containing campaigns marked as Sent.", + "properties": { + "_meta": { + "properties": { + "row_id": { + "type": "integer" + } + }, + "required": [ + "row_id" + ], + "type": "object" + }, + "ab_split": { + "description": "General stats about different groups of an A/B Split campaign. Does not return information about Multivariate Campaigns.", + "properties": { + "a": { + "description": "Stats for Campaign A.", + "properties": { + "abuse_reports": { + "description": "Abuse reports for Campaign A.", + "title": "Abuse Reports", + "type": "integer" + }, + "bounces": { + "description": "Bounces for Campaign A.", + "title": "Bounces", + "type": "integer" + }, + "forwards": { + "description": "Forwards for Campaign A.", + "title": "Forwards", + "type": "integer" + }, + "forwards_opens": { + "description": "Opens from forwards for Campaign A.", + "title": "Forward Opens", + "type": "integer" + }, + "last_open": { + "description": "The last open for Campaign A.", + "format": "date-time", + "title": "Last Open", + "type": [ + "null", + "string" + ] + }, + "opens": { + "description": "Opens for Campaign A.", + "title": "Opens", + "type": "integer" + }, + "recipient_clicks": { + "description": "Recipient Clicks for Campaign A.", + "title": "Recipient Clicks", + "type": "integer" + }, + "unique_opens": { + "description": "Unique opens for Campaign A.", + "title": "Unique Opens", + "type": "integer" + }, + "unsubs": { + "description": "Unsubscribes for Campaign A.", + "title": "Unsubscribes", + "type": "integer" + } + }, + "title": "Campaign A", + "type": "object" + }, + "b": { + "description": "Stats for Campaign B.", + "properties": { + "abuse_reports": { + "description": "Abuse reports for Campaign B.", + "title": "Abuse Reports", + "type": "integer" + }, + "bounces": { + "description": "Bounces for Campaign B.", + "title": "Bounces", + "type": "integer" + }, + "forwards": { + "description": "Forwards for Campaign B.", + "title": "Forwards", + "type": "integer" + }, + "forwards_opens": { + "description": "Opens for forwards from Campaign B.", + "title": "Forward Opens", + "type": "integer" + }, + "last_open": { + "description": "The last open for Campaign B.", + "format": "date-time", + "title": "Last Open", + "type": [ + "null", + "string" + ] + }, + "opens": { + "description": "Opens for Campaign B.", + "title": "Opens", + "type": "integer" + }, + "recipient_clicks": { + "description": "Recipients clicks for Campaign B.", + "title": "Recipient Clicks", + "type": "integer" + }, + "unique_opens": { + "description": "Unique opens for Campaign B.", + "title": "Unique Opens", + "type": "integer" + }, + "unsubs": { + "description": "Unsubscribes for Campaign B.", + "title": "Unsubscribes", + "type": "integer" + } + }, + "title": "Campaign B", + "type": "object" + } + }, + "title": "A/B Split Stats", + "type": "object" + }, + "abuse_reports": { + "description": "The number of abuse reports generated for this campaign.", + "title": "Abuse Reports", + "type": "integer" + }, + "bounces": { + "description": "An object describing the bounce summary for the campaign.", + "properties": { + "hard_bounces": { + "description": "The total number of hard bounced email addresses.", + "title": "Hard Bounces", + "type": "integer" + }, + "soft_bounces": { + "description": "The total number of soft bounced email addresses.", + "title": "Soft Bounces", + "type": "integer" + }, + "syntax_errors": { + "description": "The total number of addresses that were syntax-related bounces.", + "title": "Syntax Errors", + "type": "integer" + } + }, + "title": "Bounces", + "type": "object" + }, + "campaign_title": { + "description": "The title of the campaign.", + "readOnly": true, + "title": "Campaign Title", + "type": [ + "null", + "string" + ] + }, + "clicks": { + "description": "An object describing the click activity for the campaign.", + "properties": { + "click_rate": { + "description": "The number of unique clicks divided by the total number of successful deliveries.", + "title": "Click Rate", + "type": "number" + }, + "clicks_total": { + "description": "The total number of clicks for the campaign.", + "title": "Total Clicks", + "type": "integer" + }, + "last_click": { + "description": "The date and time of the last recorded click for the campaign in ISO 8601 format.", + "format": "date-time", + "title": "Last Click", + "type": [ + "null", + "string" + ] + }, + "unique_clicks": { + "description": "The total number of unique clicks for links across a campaign.", + "title": "Unique Clicks", + "type": "integer" + }, + "unique_subscriber_clicks": { + "description": "The total number of subscribers who clicked on a campaign.", + "title": "Unique Subscriber Clicks", + "type": "integer" + } + }, + "title": "Clicks", + "type": "object" + }, + "delivery_status": { + "description": "Updates on campaigns in the process of sending.", + "properties": { + "can_cancel": { + "description": "Whether a campaign send can be canceled.", + "readOnly": true, + "title": "Campaign Cancelable", + "type": "boolean" + }, + "emails_canceled": { + "description": "The total number of emails canceled for this campaign.", + "readOnly": true, + "title": "Emails Canceled", + "type": "integer" + }, + "emails_sent": { + "description": "The total number of emails confirmed sent for this campaign so far.", + "readOnly": true, + "title": "Emails Sent", + "type": "integer" + }, + "enabled": { + "description": "Whether Campaign Delivery Status is enabled for this account and campaign.", + "readOnly": true, + "title": "Delivery Status Enabled", + "type": "boolean" + }, + "status": { + "description": "The current state of a campaign delivery.", + "enum": [ + "delivering", + "delivered", + "canceling", + "canceled" + ], + "readOnly": true, + "title": "Campaign Delivery Status", + "type": [ + "null", + "string" + ] + } + }, + "title": "Campaign Delivery Status", + "type": "object" + }, + "ecommerce": { + "description": "E-Commerce stats for a campaign.", + "properties": { + "currency_code": { + "example": "USD", + "readOnly": true, + "title": "Three letter currency code for this user", + "type": [ + "null", + "string" + ] + }, + "total_orders": { + "description": "The total orders for a campaign.", + "readOnly": true, + "title": "Total Orders", + "type": "integer" + }, + "total_revenue": { + "description": "The total revenue for a campaign. Calculated as the sum of all order totals minus shipping and tax totals.", + "readOnly": true, + "title": "Total Revenue", + "type": "number" + }, + "total_spent": { + "description": "The total spent for a campaign. Calculated as the sum of all order totals with no deductions.", + "readOnly": true, + "title": "Total Spent", + "type": "number" + } + }, + "title": "E-Commerce Report", + "type": "object" + }, + "emails_sent": { + "description": "The total number of emails sent for this campaign.", + "title": "Emails Sent", + "type": "integer" + }, + "facebook_likes": { + "description": "An object describing campaign engagement on Facebook.", + "properties": { + "facebook_likes": { + "description": "The number of Facebook likes for the campaign.", + "title": "Facebook Likes", + "type": "integer" + }, + "recipient_likes": { + "description": "The number of recipients who liked the campaign on Facebook.", + "title": "Recipient Likes", + "type": "integer" + }, + "unique_likes": { + "description": "The number of unique likes.", + "title": "Unique Likes", + "type": "integer" + } + }, + "title": "Facebook Likes", + "type": "object" + }, + "forwards": { + "description": "An object describing the forwards and forward activity for the campaign.", + "properties": { + "forwards_count": { + "description": "How many times the campaign has been forwarded.", + "title": "Total Forwards", + "type": "integer" + }, + "forwards_opens": { + "description": "How many times the forwarded campaign has been opened.", + "title": "Forward Opens", + "type": "integer" + } + }, + "title": "Forwards", + "type": "object" + }, + "id": { + "description": "A string that uniquely identifies this campaign.", + "title": "Campaign ID", + "type": "string" + }, + "industry_stats": { + "description": "The average campaign statistics for your industry.", + "properties": { + "abuse_rate": { + "description": "The industry abuse rate.", + "title": "Abuse Rate", + "type": "number" + }, + "bounce_rate": { + "description": "The industry bounce rate.", + "title": "Bounce Rate", + "type": "number" + }, + "click_rate": { + "description": "The industry click rate.", + "title": "Click Rate", + "type": "number" + }, + "open_rate": { + "description": "The industry open rate.", + "title": "Open Rate", + "type": "number" + }, + "type": { + "description": "The type of business industry associated with your account. For example: retail, education, etc.", + "title": "Industry Type", + "type": [ + "null", + "string" + ] + }, + "unopen_rate": { + "description": "The industry unopened rate.", + "title": "Unopened Rate", + "type": "number" + }, + "unsub_rate": { + "description": "The industry unsubscribe rate.", + "title": "Unsubscribe Rate", + "type": "number" + } + }, + "title": "Industry Stats", + "type": "object" + }, + "list_id": { + "description": "The unique list id.", + "readOnly": true, + "title": "List ID", + "type": "string" + }, + "list_is_active": { + "description": "The status of the list used, namely if it's deleted or disabled.", + "readOnly": true, + "title": "List Status", + "type": "boolean" + }, + "list_name": { + "description": "The name of the list.", + "readOnly": true, + "title": "List Name", + "type": [ + "null", + "string" + ] + }, + "list_stats": { + "description": "The average campaign statistics for your list. This won't be present if we haven't calculated it yet for this list.", + "properties": { + "click_rate": { + "description": "The average click rate (a percentage represented as a number between 0 and 100) per campaign for the list.", + "readOnly": true, + "title": "Click Rate", + "type": "number" + }, + "open_rate": { + "description": "The average open rate (a percentage represented as a number between 0 and 100) per campaign for the list.", + "readOnly": true, + "title": "Open Rate", + "type": "number" + }, + "sub_rate": { + "description": "The average number of subscriptions per month for the list.", + "readOnly": true, + "title": "Average Subscription Rate", + "type": "number" + }, + "unsub_rate": { + "description": "The average number of unsubscriptions per month for the list.", + "readOnly": true, + "title": "Average Unsubscription Rate", + "type": "number" + } + }, + "title": "List Stats", + "type": "object" + }, + "opens": { + "description": "An object describing the open activity for the campaign.", + "properties": { + "last_open": { + "description": "The date and time of the last recorded open in ISO 8601 format.", + "format": "date-time", + "title": "Last Open", + "type": [ + "null", + "string" + ] + }, + "open_rate": { + "description": "The number of unique opens divided by the total number of successful deliveries.", + "title": "Open Rate", + "type": "number" + }, + "opens_total": { + "description": "The total number of opens for a campaign.", + "title": "Total Opens", + "type": "integer" + }, + "unique_opens": { + "description": "The total number of unique opens.", + "title": "Unique Opens", + "type": "integer" + } + }, + "title": "Opens", + "type": "object" + }, + "preview_text": { + "description": "The preview text for the campaign.", + "title": "Campaign Preview Text", + "type": [ + "null", + "string" + ] + }, + "rss_last_send": { + "description": "For RSS campaigns, the date and time of the last send in ISO 8601 format.", + "format": "date-time", + "readOnly": true, + "title": "RSS Last Send", + "type": [ + "null", + "string" + ] + }, + "send_time": { + "description": "The date and time a campaign was sent in ISO 8601 format.", + "format": "date-time", + "readOnly": true, + "title": "Send Time", + "type": [ + "null", + "string" + ] + }, + "share_report": { + "description": "The url and password for the [VIP report](https://mailchimp.com/help/share-a-campaign-report/).", + "properties": { + "share_password": { + "description": "If password protected, the password for the VIP report.", + "readOnly": true, + "title": "Report Password", + "type": [ + "null", + "string" + ] + }, + "share_url": { + "description": "The URL for the VIP report.", + "readOnly": true, + "title": "Report URL", + "type": [ + "null", + "string" + ] + } + }, + "title": "Share Report", + "type": "object" + }, + "subject_line": { + "description": "The subject line for the campaign.", + "readOnly": true, + "title": "Campaign Subject Line", + "type": [ + "null", + "string" + ] + }, + "timeseries": { + "description": "An hourly breakdown of the performance of the campaign over the first 24 hours.", + "items": { + "properties": { + "emails_sent": { + "description": "The number of emails sent in the timeseries.", + "title": "Emails Sent", + "type": "integer" + }, + "recipients_clicks": { + "description": "The number of clicks in the timeseries.", + "title": "Recipient Clicks", + "type": "integer" + }, + "timestamp": { + "description": "The date and time for the series in ISO 8601 format.", + "format": "date-time", + "title": "Timestamp", + "type": [ + "null", + "string" + ] + }, + "unique_opens": { + "description": "The number of unique opens in the timeseries.", + "title": "Unique Opens", + "type": "integer" + } + }, + "type": "object" + }, + "title": "Timeseries", + "type": "array" + }, + "timewarp": { + "description": "An hourly breakdown of sends, opens, and clicks if a campaign is sent using timewarp.", + "items": { + "properties": { + "bounces": { + "description": "The number of bounces.", + "title": "Bounces", + "type": "integer" + }, + "clicks": { + "description": "The number of clicks.", + "title": "Clicks", + "type": "integer" + }, + "gmt_offset": { + "description": "For campaigns sent with timewarp, the time zone group the member is apart of.", + "title": "GMT Offset", + "type": "integer" + }, + "last_click": { + "description": "The date and time of the last click in ISO 8601 format.", + "format": "date-time", + "title": "Last Click", + "type": [ + "null", + "string" + ] + }, + "last_open": { + "description": "The date and time of the last open in ISO 8601 format.", + "format": "date-time", + "title": "Last Open", + "type": [ + "null", + "string" + ] + }, + "opens": { + "description": "The number of opens.", + "title": "Opens", + "type": "integer" + }, + "unique_clicks": { + "description": "The number of unique clicks.", + "title": "Unique Clicks", + "type": "integer" + }, + "unique_opens": { + "description": "The number of unique opens.", + "title": "Unique Opens", + "type": "integer" + } + }, + "type": "object" + }, + "title": "Timewarp Stats", + "type": "array" + }, + "type": { + "description": "The type of campaign (regular, plain-text, ab_split, rss, automation, variate, or auto).", + "title": "Campaign Type", + "type": [ + "null", + "string" + ] + }, + "unsubscribed": { + "description": "The total number of unsubscribed members for this campaign.", + "readOnly": true, + "title": "Unsubscribe Count", + "type": "integer" + } + }, + "required": [ + "id" + ], + "title": "Campaign Reports", + "type": "object" + }, + "key": [ + "/id" + ], + "recommendedName": "reports", + "resourceConfig": { + "cursorField": [ + "send_time" + ], + "stream": "reports", + "syncMode": "incremental" + } + }, + { + "documentSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "_meta": { + "properties": { + "row_id": { + "type": "integer" + } + }, + "required": [ + "row_id" + ], + "type": "object" + }, + "email_address": { + "type": [ + "null", + "string" + ] + }, + "email_client": { + "type": [ + "null", + "string" + ] + }, + "email_type": { + "type": [ + "null", + "string" + ] + }, + "id": { + "type": "string" + }, + "interests": { + "additionalProperties": true, + "type": [ + "null", + "object" + ] + }, + "ip_opt": { + "type": [ + "null", + "string" + ] + }, + "ip_signup": { + "type": [ + "null", + "string" + ] + }, + "language": { + "type": [ + "null", + "string" + ] + }, + "last_changed": { + "format": "date-time", + "type": [ + "null", + "string" + ] + }, + "last_note": { + "properties": { + "created_at": { + "format": "date-time", + "type": [ + "null", + "string" + ] + }, + "created_by": { + "type": [ + "null", + "string" + ] + }, + "note": { + "type": [ + "null", + "string" + ] + }, + "note_id": { + "type": [ + "null", + "integer" + ] + } + }, + "type": [ + "null", + "object" + ] + }, + "list_id": { + "type": [ + "null", + "string" + ] + }, + "location": { + "properties": { + "country_code": { + "type": [ + "null", + "string" + ] + }, + "dstoff": { + "type": [ + "null", + "integer" + ] + }, + "gmtoff": { + "type": [ + "null", + "integer" + ] + }, + "latitude": { + "type": [ + "null", + "number" + ] + }, + "longitude": { + "type": [ + "null", + "number" + ] + }, + "timezone": { + "type": [ + "null", + "string" + ] + } + }, + "type": [ + "null", + "object" + ] + }, + "member_rating": { + "type": [ + "null", + "integer" + ] + }, + "merge_fields": { + "additionalProperties": true, + "type": [ + "null", + "object" + ] + }, + "segment_id": { + "type": [ + "null", + "integer" + ] + }, + "stats": { + "properties": { + "avg_click_rate": { + "type": [ + "null", + "number" + ] + }, + "avg_open_rate": { + "type": [ + "null", + "number" + ] + } + }, + "type": [ + "null", + "object" + ] + }, + "status": { + "type": [ + "null", + "string" + ] + }, + "timestamp_opt": { + "format": "date-time", + "type": [ + "null", + "string" + ] + }, + "timestamp_signup": { + "format": "date-time", + "type": [ + "null", + "string" + ] + }, + "unique_email_id": { + "type": [ + "null", + "string" + ] + }, + "vip": { + "type": [ + "null", + "boolean" + ] + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "key": [ + "/id" + ], + "recommendedName": "segment_members", + "resourceConfig": { + "cursorField": [ + "last_changed" + ], + "stream": "segment_members", + "syncMode": "incremental" + } + }, + { + "documentSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "_meta": { + "properties": { + "row_id": { + "type": "integer" } }, - "title": "List Stats", + "required": [ + "row_id" + ], "type": "object" }, - "opens": { - "description": "An object describing the open activity for the campaign.", + "created_at": { + "format": "date-time", + "type": [ + "null", + "string" + ] + }, + "id": { + "type": "integer" + }, + "list_id": { + "type": [ + "null", + "string" + ] + }, + "member_count": { + "type": [ + "null", + "integer" + ] + }, + "name": { + "type": [ + "null", + "string" + ] + }, + "options": { "properties": { - "last_open": { - "description": "The date and time of the last recorded open in ISO 8601 format.", - "format": "date-time", - "title": "Last Open", - "type": "string" - }, - "open_rate": { - "description": "The number of unique opens divided by the total number of successful deliveries.", - "title": "Open Rate", - "type": "number" - }, - "opens_total": { - "description": "The total number of opens for a campaign.", - "title": "Total Opens", - "type": "integer" + "conditions": { + "items": { + "additionalProperties": true, + "properties": { + "condition_type": { + "type": [ + "null", + "string" + ] + }, + "field": { + "type": [ + "null", + "string" + ] + }, + "op": { + "type": [ + "null", + "string" + ] + } + }, + "type": [ + "null", + "object" + ] + }, + "type": [ + "null", + "array" + ] }, - "unique_opens": { - "description": "The total number of unique opens.", - "title": "Unique Opens", - "type": "integer" + "match": { + "type": [ + "null", + "string" + ] } }, - "title": "Opens", - "type": "object" + "type": [ + "null", + "object" + ] }, - "preview_text": { - "description": "The preview text for the campaign.", - "title": "Campaign Preview Text", - "type": "string" + "type": { + "type": [ + "null", + "string" + ] }, - "rss_last_send": { - "description": "For RSS campaigns, the date and time of the last send in ISO 8601 format.", + "updated_at": { "format": "date-time", - "readOnly": true, - "title": "RSS Last Send", - "type": "string" + "type": [ + "null", + "string" + ] + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "key": [ + "/id" + ], + "recommendedName": "segments", + "resourceConfig": { + "cursorField": [ + "updated_at" + ], + "stream": "segments", + "syncMode": "incremental" + } + }, + { + "documentSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "properties": { + "_meta": { + "properties": { + "row_id": { + "type": "integer" + } + }, + "required": [ + "row_id" + ], + "type": "object" }, - "send_time": { - "description": "The date and time a campaign was sent in ISO 8601 format.", - "format": "date-time", - "readOnly": true, - "title": "Send Time", - "type": "string" + "id": { + "type": "integer" }, - "share_report": { - "description": "The url and password for the [VIP report](https://mailchimp.com/help/share-a-campaign-report/).", + "list_id": { + "type": [ + "null", + "string" + ] + }, + "name": { + "type": [ + "null", + "string" + ] + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "key": [ + "/id" + ], + "recommendedName": "tags", + "resourceConfig": { + "stream": "tags", + "syncMode": "full_refresh" + } + }, + { + "documentSchema": { + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": true, + "properties": { + "_meta": { "properties": { - "share_password": { - "description": "If password protected, the password for the VIP report.", - "readOnly": true, - "title": "Report Password", - "type": "string" - }, - "share_url": { - "description": "The URL for the VIP report.", - "readOnly": true, - "title": "Report URL", - "type": "string" + "row_id": { + "type": "integer" } }, - "title": "Share Report", + "required": [ + "row_id" + ], "type": "object" }, - "subject_line": { - "description": "The subject line for the campaign.", - "readOnly": true, - "title": "Campaign Subject Line", + "campaign_id": { "type": "string" }, - "timeseries": { - "description": "An hourly breakdown of the performance of the campaign over the first 24 hours.", - "items": { - "properties": { - "emails_sent": { - "description": "The number of emails sent in the timeseries.", - "title": "Emails Sent", - "type": "integer" - }, - "recipients_clicks": { - "description": "The number of clicks in the timeseries.", - "title": "Recipient Clicks", - "type": "integer" - }, - "timestamp": { - "description": "The date and time for the series in ISO 8601 format.", - "format": "date-time", - "title": "Timestamp", - "type": "string" - }, - "unique_opens": { - "description": "The number of unique opens in the timeseries.", - "title": "Unique Opens", - "type": "integer" - } - }, - "type": "object" - }, - "title": "Timeseries", - "type": "array" + "email_address": { + "type": [ + "null", + "string" + ] }, - "timewarp": { - "description": "An hourly breakdown of sends, opens, and clicks if a campaign is sent using timewarp.", - "items": { - "properties": { - "bounces": { - "description": "The number of bounces.", - "title": "Bounces", - "type": "integer" - }, - "clicks": { - "description": "The number of clicks.", - "title": "Clicks", - "type": "integer" - }, - "gmt_offset": { - "description": "For campaigns sent with timewarp, the time zone group the member is apart of.", - "title": "GMT Offset", - "type": "integer" - }, - "last_click": { - "description": "The date and time of the last click in ISO 8601 format.", - "format": "date-time", - "title": "Last Click", - "type": "string" - }, - "last_open": { - "description": "The date and time of the last open in ISO 8601 format.", - "format": "date-time", - "title": "Last Open", - "type": "string" - }, - "opens": { - "description": "The number of opens.", - "title": "Opens", - "type": "integer" - }, - "unique_clicks": { - "description": "The number of unique clicks.", - "title": "Unique Clicks", - "type": "integer" - }, - "unique_opens": { - "description": "The number of unique opens.", - "title": "Unique Opens", - "type": "integer" - } - }, - "type": "object" - }, - "title": "Timewarp Stats", - "type": "array" + "email_id": { + "type": "string" }, - "type": { - "description": "The type of campaign (regular, plain-text, ab_split, rss, automation, variate, or auto).", - "title": "Campaign Type", + "list_id": { + "type": [ + "null", + "string" + ] + }, + "list_is_active": { + "type": [ + "null", + "boolean" + ] + }, + "merge_fields": { + "additionalProperties": true, + "type": [ + "null", + "object" + ] + }, + "reason": { + "type": [ + "null", + "string" + ] + }, + "timestamp": { + "format": "date-time", "type": "string" }, - "unsubscribed": { - "description": "The total number of unsubscribed members for this campaign.", - "readOnly": true, - "title": "Unsubscribe Count", - "type": "integer" + "vip": { + "type": [ + "null", + "boolean" + ] } }, "required": [ - "id" + "campaign_id", + "email_id", + "timestamp" ], - "title": "Campaign Reports", "type": "object" }, "key": [ - "/id" + "/campaign_id", + "/email_id", + "/timestamp" ], - "recommendedName": "reports", + "recommendedName": "unsubscribes", "resourceConfig": { "cursorField": [ - "send_time" + "timestamp" ], - "stream": "reports", + "stream": "unsubscribes", "syncMode": "incremental" } } diff --git a/source-mailchimp/tests/snapshots/snapshots__spec__capture.stdout.json b/source-mailchimp/tests/snapshots/snapshots__spec__capture.stdout.json index 91a1762cb5..fd7e12ee7f 100644 --- a/source-mailchimp/tests/snapshots/snapshots__spec__capture.stdout.json +++ b/source-mailchimp/tests/snapshots/snapshots__spec__capture.stdout.json @@ -4,6 +4,10 @@ "$schema": "http://json-schema.org/draft-07/schema#", "additionalProperties": true, "properties": { + "campaign_id": { + "title": "ID of a campaign to sync email activities", + "type": "string" + }, "credentials": { "discriminator": { "propertyName": "auth_type" @@ -69,6 +73,16 @@ ], "title": "Authentication", "type": "object" + }, + "start_date": { + "description": "The date from which you want to start syncing data for Incremental streams. Only records that have been created or modified since this date will be synced. If left blank, all data will by synced.", + "examples": [ + "2020-01-01T00:00:00.000Z" + ], + "format": "date-time", + "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$", + "title": "Incremental Sync Start Date", + "type": "string" } }, "required": [ @@ -92,31 +106,33 @@ }, "protocol": 3032023, "resourceConfigSchema": { - "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "description": "ResourceConfig encodes a configured resource stream", "properties": { "cursorField": { "items": { "type": "string" }, - "type": [ - "array", - "null" - ] + "title": "Cursor Field", + "type": "array" }, "namespace": { - "type": [ - "string", - "null" - ] + "description": "Enclosing schema namespace of this resource", + "title": "Namespace", + "type": "string" }, "stream": { + "description": "Name of this stream", + "title": "Stream", "type": "string" }, "syncMode": { + "description": "Sync this resource incrementally, or fully refresh it every run", "enum": [ - "incremental", - "full_refresh" + "full_refresh", + "incremental" ], + "title": "Sync Mode", "type": "string" } }, @@ -124,7 +140,7 @@ "stream", "syncMode" ], - "title": "ResourceSpec", + "title": "ResourceConfig", "type": "object" }, "resourcePathPointers": [ diff --git a/source-mailchimp/tests/test_snapshots.py b/source-mailchimp/tests/test_snapshots.py index 9b9d8ece94..d403ae699e 100644 --- a/source-mailchimp/tests/test_snapshots.py +++ b/source-mailchimp/tests/test_snapshots.py @@ -32,6 +32,9 @@ def test_capture(request, snapshot): elif typ == "acmeCo/segment_members": rec["ip_opt"] = "redacted" + elif typ == "acmeCo/reports": + rec["timeseries"] = "redacted" + assert snapshot("capture.stdout.json") == lines def test_discover(request, snapshot): From 8f41f13c131fd0bdbb36851fe5a0c836fa812d12 Mon Sep 17 00:00:00 2001 From: Luishfs Date: Fri, 26 Apr 2024 16:10:55 -0300 Subject: [PATCH 5/5] Adding connector to CI --- .github/workflows/python.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/python.yaml b/.github/workflows/python.yaml index 11d84fc9df..0f5440c4f2 100644 --- a/.github/workflows/python.yaml +++ b/.github/workflows/python.yaml @@ -13,6 +13,7 @@ on: - "source-google-sheets-native/**" - "source-hubspot-native/**" - "source-hubspot/**" + - "source-mailchimp/**" pull_request: branches: [main] paths: @@ -25,6 +26,7 @@ on: - "source-google-sheets-native/**" - "source-hubspot-native/**" - "source-hubspot/**" + - "source-mailchimp/**" concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -72,6 +74,10 @@ jobs: type: capture version: v5 usage_rate: "1.0" + - name: source-mailchimp + type: capture + version: v2 + usage_rate: "1.0" steps: - uses: actions/checkout@v4