diff --git a/CHANGELOG.md b/CHANGELOG.md index cf8e1fc..0a3c1b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.0.0 + +* **Breaking** Library moved to use Patreon API v2 endpoints and calls +* A good part of the code is now generated based on the Platform API's Cartographer schema definition. + # 0.5.1 * Fix test runner to execute tests properly diff --git a/README.md b/README.md index 75042ee..6269126 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,14 @@ # patreon-ruby Interact with the Patreon API via OAuth. +## Important notice about updating to 1.0.0 from earlier versions + +Patreon Ruby library version 1.0.0 moves on to Patreon's v2 API, which is not compatible with old v1 calls. Therefore directly upgrading from older versions to 1.0.0 would break compatibility of your installation. APIv1 will be deprecated some time soon after APIv2 comes out of beta, so it's important to get your integration compatible with API v2. + +For more information on the differences and similarities between v1 and v2, check out: https://docs.patreon.com/#what-39-s-new + +## Getting started + Get the gem from [RubyGems](https://rubygems.org/gems/patreon) Step 1. Get your client_id and client_secret @@ -38,22 +46,71 @@ end Step 3. (Optional) Customize your usage --- -`Patreon::API` instances have four methods: -* `fetch_user(includes=nil, fields=nil)` -* `fetch_campaign(includes=nil, fields=nil)` -* `fetch_campaign_and_patrons(includes=nil, fields=nil)` -* `fetch_page_of_pledges(campaign_id, page_size, cursor=nil, includes=nil, fields=nil)` +`Patreon::API` instances have the following methods: + +* `get_campaigns(opts = { includes: [], fields: [], count: 10, cursor: nil})` +* `get_identity(opts = { includes: [], fields: [], })` +* `get_webhooks(opts = { includes: [], fields: [], count: 10, cursor: nil})` +* `get_campaigns_by_id_members(resource_id, opts = { includes: [], fields: [], count: 10, cursor: nil})` +* `get_campaigns_by_id(resource_id, opts = { includes: [], fields: [], })` +* `get_webhooks_by_id(resource_id, opts = { includes: [], fields: [], })` +* `get_members_by_id(resource_id, opts = { includes: [], fields: [], })` The `includes` and `fields` arguments to these methods specify the [related resources](http://jsonapi.org/format/#fetching-includes) and the [resource attributes](http://jsonapi.org/format/#fetching-sparse-fieldsets) you want returned by our API, as per the [JSON:API specification](http://jsonapi.org/). The lists of valid `includes` and `fields` arguments are provided on `Patreon::Schemas`. -For instance, if you wanted to request the total amount a patron has ever paid to your campaign, -which is not included by default, you could do: + +For instance, if you wanted to request the first name and total amount a patron has ever paid to your campaign, you could do: ```ruby api_client = Patreon::API.new(patron_access_token) -patron_response = api_client.fetch_user(nil, { - 'pledge': Patreon::Schemas::Pledge.default_attributes + [Patreon::Schemas::Pledge::Attributes::TOTAL_HISTORICAL_AMOUNT_CENTS] + +User = Patreon::Schemas::User +Member = Patreon::Schemas::Member + +patron_response = api_client.get_identity({ + includes: [User::Relationships::MEMBERSHIPS], + fields: { + User::Name => User::Attributes::FIRST_NAME, + Member::Name => Member::Attributes::LIFETIME_SUPPORT_CENTS + } }) ``` +Which would return: +```json +{ + "data": { + "attributes": { + "first_name": "Jack" + }, + "id": "1234", + "relationships": { + "memberships": { + "data": [ + { + "id": "960d87e4-49ab-4828-b411-8ba9f91c6d81", + "type": "member" + } + ] + } + }, + "type": "user" + }, + "included": [ + { + "attributes": { + "lifetime_support_cents": 500 + }, + "id": "960d87e4-49ab-4828-b411-8ba9f91c6d81", + "type": "member" + } + ], + "links": { + "self": "https://www.patreon.com/api/oauth2/v2/user/1234" + } +} +``` diff --git a/example/fetch_all_patrons.rb b/example/fetch_all_patrons.rb index bd63866..c5ea062 100644 --- a/example/fetch_all_patrons.rb +++ b/example/fetch_all_patrons.rb @@ -16,15 +16,27 @@ # Fetching basic data api_client = Patreon::API.new(access_token) -campaign_response = api_client.fetch_campaign() +Member = Patreon::Schemas::Member + +campaign_response = api_client.get_campaigns() campaign_id = campaign_response.data[0].id # Fetching all pledges -all_pledges = [] +all_members = [] cursor = nil while true do - page_response = api_client.fetch_page_of_pledges(campaign_id, { :count => 25, :cursor => cursor }) - all_pledges += page_response.data + page_response = api_client.get_campaigns_by_id_members(campaign_id, { + :count => 25, + :cursor => cursor, + # In v2 you need to specify the fields that you are requesting + fields: { + Member::Name => [ + Member::Attributes::FULL_NAME, + Member::Attributes::LIFETIME_SUPPORT_CENTS, + ], + } + }) + all_members += page_response.data next_page_link = page_response.links[page_response.data]['next'] if next_page_link parsed_query = CGI::parse(next_page_link) @@ -35,5 +47,5 @@ end # Mapping to all patrons. Feel free to customize as needed. -# As with all standard Ruby objects, (pledge.methods - Object.methods) will list the available attributes and relationships -puts all_pledges.map{ |pledge| { full_name: pledge.patron.full_name, amount_cents: pledge.amount_cents } } +# As with all standard Ruby objects, (member.methods - Object.methods) will list the available attributes and relationships +puts all_members.map{ |member| { full_name: member.full_name, lifetime_support_cents: member.lifetime_support_cents } } \ No newline at end of file diff --git a/example/sinatra/models/manager/patreon_user_mgr.rb b/example/sinatra/models/manager/patreon_user_mgr.rb index 9297494..0697f3f 100644 --- a/example/sinatra/models/manager/patreon_user_mgr.rb +++ b/example/sinatra/models/manager/patreon_user_mgr.rb @@ -11,30 +11,36 @@ def self.create_or_update_user_with_tokens(patreon_refresh_token, patreon_access api_client = Patreon::API.new(patreon_access_token) # Get the patron's profile info and pledge amount - user_response = api_client.fetch_user() + user_response = api_client.get_identity({ + # In v2 you need to specify the fields that you are requesting + includes: [Patreon::Schemas::User::Relationships::MEMBERSHIPS], + fields: { + Patreon::Schemas::User::Name => [ + Patreon::Schemas::User::Attributes::FULL_NAME, + Patreon::Schemas::User::Attributes::EMAIL, + ], + Patreon::Schemas::Member::Name => [ + Patreon::Schemas::Member::Attributes::LIFETIME_SUPPORT_CENTS + ] + } + }) patreon_user_data = user_response.data return nil unless patreon_user_data # Find or make the user, and set their information using the API response db_user = User.first_or_create({:patreon_user_id => patreon_user_data.id}) - db_user.update({ + update_data = { :full_name => patreon_user_data.full_name, :email => patreon_user_data.email, :patreon_refresh_token => patreon_refresh_token, :patreon_access_token => patreon_access_token - }) - - # Find the user's pledge to us, and if they have one, update their pledge amount in our db - # puts user_response.data.methods - pledges = (user_response.find_all('pledge') || []) - pledge = pledges.find {|obj| - obj.creator.id == MyConfig::PATREON_CREATOR_ID } - if pledge - db_user.update({ - :patreon_pledge_amount_cents => pledge.amount_cents - }) + # If you request `memberships` and DON’T have the `identity.memberships` scope, + # you will receive data about the user’s membership to your campaign. + if patreon_user_data.memberships.length > 0 + update_data[:lifetime_support_cents] = patreon_user_data.memberships[0].lifetime_support_cents end + db_user.update(update_data) # Return the user we've made or updated return db_user diff --git a/example/sinatra/models/table/user.rb b/example/sinatra/models/table/user.rb index 6c3a605..e15e0ef 100644 --- a/example/sinatra/models/table/user.rb +++ b/example/sinatra/models/table/user.rb @@ -6,7 +6,7 @@ class User property :user_id, Serial property :full_name, String property :email, String - property :patreon_pledge_amount_cents, Integer + property :lifetime_support_cents, Integer property :patreon_user_id, String property :patreon_refresh_token, String property :patreon_access_token, String diff --git a/lib/patreon.rb b/lib/patreon.rb index 384c0cc..6dc72cb 100644 --- a/lib/patreon.rb +++ b/lib/patreon.rb @@ -1,3 +1,7 @@ +# This file is auto-generated from the same code that generates +# https://docs.patreon.com. Community pull requests against this +# file may not be accepted. + require 'net/http' require 'json' require 'rack' @@ -8,11 +12,19 @@ require 'patreon/utils/jsonapi/url_util' require 'patreon/utils/enum' require 'patreon/utils/client' +require 'patreon/schemas/address' +require 'patreon/schemas/benefit' require 'patreon/schemas/campaign' +require 'patreon/schemas/deliverable' require 'patreon/schemas/goal' -require 'patreon/schemas/pledge' -require 'patreon/schemas/reward' +require 'patreon/schemas/media' +require 'patreon/schemas/member' +require 'patreon/schemas/oauthclient' +require 'patreon/schemas/pledgeevent' +require 'patreon/schemas/post' +require 'patreon/schemas/tier' require 'patreon/schemas/user' +require 'patreon/schemas/webhook' require 'patreon/version' require 'patreon/oauth' -require 'patreon/api' +require 'patreon/api' \ No newline at end of file diff --git a/lib/patreon/api.rb b/lib/patreon/api.rb index 5aa8d0f..c4a666d 100644 --- a/lib/patreon/api.rb +++ b/lib/patreon/api.rb @@ -1,29 +1,55 @@ +# This file is auto-generated from the same code that generates +# https://docs.patreon.com. Community pull requests against this +# file may not be accepted. + module Patreon class API + include Patreon::Utils::JSONAPI + def initialize(access_token) @access_token = access_token end - def fetch_user(opts = {}) - get_parse_json(Utils::JSONAPI::URLUtil.build_url('current_user', opts[:includes], opts[:fields])) + def get_campaigns(opts = {}) + base_url = "campaigns" + url = URLUtil.build_url(base_url, opts[:includes], opts[:fields], opts[:count], opts[:cursor]) + get_parse_json(url) + end + + def get_identity(opts = {}) + base_url = "identity" + url = URLUtil.build_url(base_url, opts[:includes], opts[:fields]) + get_parse_json(url) + end + + def get_webhooks(opts = {}) + base_url = "webhooks" + url = URLUtil.build_url(base_url, opts[:includes], opts[:fields], opts[:count], opts[:cursor]) + get_parse_json(url) + end + + def get_campaigns_by_id_members(resource_id, opts = {}) + base_url = "campaigns/#{resource_id}/members" + url = URLUtil.build_url(base_url, opts[:includes], opts[:fields], opts[:count], opts[:cursor]) + get_parse_json(url) end - def fetch_campaign(opts = {}) - get_parse_json(Utils::JSONAPI::URLUtil.build_url('current_user/campaigns', opts[:includes], opts[:fields])) + def get_campaigns_by_id(resource_id, opts = {}) + base_url = "campaigns/#{resource_id}" + url = URLUtil.build_url(base_url, opts[:includes], opts[:fields]) + get_parse_json(url) end - def fetch_campaign_and_patrons(opts = {}) - opts[:includes] = opts[:includes] ? Array(opts[:includes]) : [] - opts[:includes].concat(Schemas::Campaign.default_relationships + [Schemas::Campaign::Relationships::PLEDGES]) - fetch_campaign(opts) + def get_webhooks_by_id(resource_id, opts = {}) + base_url = "webhooks/#{resource_id}" + url = URLUtil.build_url(base_url, opts[:includes], opts[:fields]) + get_parse_json(url) end - def fetch_page_of_pledges(campaign_id, opts = {}) - params = {} - params["page[count]"] = opts[:count] || 10 - params["page[cursor]"] = opts[:cursor] if opts[:cursor] - url = "campaigns/#{campaign_id}/pledges?#{Rack::Utils.build_query(params)}" - get_parse_json(Patreon::Utils::JSONAPI::URLUtil.build_url(url, opts[:includes], opts[:fields])) + def get_members_by_id(resource_id, opts = {}) + base_url = "members/#{resource_id}" + url = URLUtil.build_url(base_url, opts[:includes], opts[:fields]) + get_parse_json(url) end private @@ -43,7 +69,7 @@ def get_json(suffix) #SECURITY HOLE http.set_debug_output($stdout) if ENV['DEBUG'] - req = Net::HTTP::Get.new("/api/oauth2/api/#{suffix}") + req = Net::HTTP::Get.new("/api/oauth2/v2/#{suffix}") req['Authorization'] = "Bearer #{@access_token}" req['User-Agent'] = Utils::Client.user_agent_string http.request(req).body @@ -53,4 +79,4 @@ def parse_json(json) JSON::Api::Vanilla.parse(json) end end -end +end \ No newline at end of file diff --git a/lib/patreon/schemas/address.rb b/lib/patreon/schemas/address.rb new file mode 100644 index 0000000..7bdf865 --- /dev/null +++ b/lib/patreon/schemas/address.rb @@ -0,0 +1,32 @@ +# This file is auto-generated from the same code that generates +# https://docs.patreon.com. Community pull requests against this +# file may not be accepted. + +module Patreon + module Schemas + module Address + Name = 'address' + + class Attributes + include Utils::Enum + + define :ADDRESSEE, 'addressee' + define :LINE_1, 'line_1' + define :LINE_2, 'line_2' + define :POSTAL_CODE, 'postal_code' + define :CITY, 'city' + define :STATE, 'state' + define :COUNTRY, 'country' + define :PHONE_NUMBER, 'phone_number' + define :CREATED_AT, 'created_at' + end + + class Relationships + include Utils::Enum + + define :USER, 'user' + define :CAMPAIGNS, 'campaigns' + end + end + end +end \ No newline at end of file diff --git a/lib/patreon/schemas/benefit.rb b/lib/patreon/schemas/benefit.rb new file mode 100644 index 0000000..e31cb99 --- /dev/null +++ b/lib/patreon/schemas/benefit.rb @@ -0,0 +1,40 @@ +# This file is auto-generated from the same code that generates +# https://docs.patreon.com. Community pull requests against this +# file may not be accepted. + +module Patreon + module Schemas + module Benefit + Name = 'benefit' + + class Attributes + include Utils::Enum + + define :TITLE, 'title' + define :DESCRIPTION, 'description' + define :BENEFIT_TYPE, 'benefit_type' + define :RULE_TYPE, 'rule_type' + define :CREATED_AT, 'created_at' + define :DELIVERED_DELIVERABLES_COUNT, 'delivered_deliverables_count' + define :NOT_DELIVERED_DELIVERABLES_COUNT, 'not_delivered_deliverables_count' + define :DELIVERABLES_DUE_TODAY_COUNT, 'deliverables_due_today_count' + define :NEXT_DELIVERABLE_DUE_DATE, 'next_deliverable_due_date' + define :TIERS_COUNT, 'tiers_count' + define :IS_DELETED, 'is_deleted' + define :IS_PUBLISHED, 'is_published' + define :IS_ENDED, 'is_ended' + define :APP_EXTERNAL_ID, 'app_external_id' + define :APP_META, 'app_meta' + end + + class Relationships + include Utils::Enum + + define :TIERS, 'tiers' + define :DELIVERABLES, 'deliverables' + define :CAMPAIGN, 'campaign' + define :CAMPAIGN_INSTALLATION, 'campaign_installation' + end + end + end +end \ No newline at end of file diff --git a/lib/patreon/schemas/campaign.rb b/lib/patreon/schemas/campaign.rb index a5adeba..e2b6255 100644 --- a/lib/patreon/schemas/campaign.rb +++ b/lib/patreon/schemas/campaign.rb @@ -1,6 +1,12 @@ +# This file is auto-generated from the same code that generates +# https://docs.patreon.com. Community pull requests against this +# file may not be accepted. + module Patreon module Schemas module Campaign + Name = 'campaign' + class Attributes include Utils::Enum @@ -10,74 +16,38 @@ class Attributes define :ONE_LINER, 'one_liner' define :MAIN_VIDEO_EMBED, 'main_video_embed' define :MAIN_VIDEO_URL, 'main_video_url' - define :IMAGE_SMALL_URL, 'image_small_url' define :IMAGE_URL, 'image_url' + define :IMAGE_SMALL_URL, 'image_small_url' define :THANKS_VIDEO_URL, 'thanks_video_url' define :THANKS_EMBED, 'thanks_embed' define :THANKS_MSG, 'thanks_msg' define :IS_MONTHLY, 'is_monthly' + define :HAS_RSS, 'has_rss' + define :HAS_SENT_RSS_NOTIFY, 'has_sent_rss_notify' + define :RSS_FEED_TITLE, 'rss_feed_title' + define :RSS_ARTWORK_URL, 'rss_artwork_url' define :IS_NSFW, 'is_nsfw' define :IS_CHARGED_IMMEDIATELY, 'is_charged_immediately' - define :IS_CHARGE_UPFRONT_ELIGIBLE, 'is_charge_upfront_eligible' - define :IS_PLURAL, 'is_plural' define :CREATED_AT, 'created_at' define :PUBLISHED_AT, 'published_at' define :PLEDGE_URL, 'pledge_url' - define :PLEDGE_SUM, 'pledge_sum' define :PATRON_COUNT, 'patron_count' - define :CREATION_COUNT, 'creation_count' - define :OUTSTANDING_PAYMENT_AMOUNT_CENTS, 'outstanding_payment_amount_cents' + define :DISCORD_SERVER_ID, 'discord_server_id' + define :GOOGLE_ANALYTICS_ID, 'google_analytics_id' + define :SHOW_EARNINGS, 'show_earnings' + define :VANITY, 'vanity' + define :URL, 'url' end class Relationships include Utils::Enum - define :REWARDS, 'rewards' + define :TIERS, 'tiers' define :CREATOR, 'creator' + define :BENEFITS, 'benefits' define :GOALS, 'goals' - define :PLEDGES, 'pledges' - define :CURRENT_USER_PLEDGE, 'current_user_pledge' - define :POST_AGGREGATION, 'post_aggregation' - define :CATEGORIES, 'categories' - define :PREVIEW_TOKEN, 'preview_token' - end - - class << self - def default_attributes - [ - Attributes::SUMMARY, - Attributes::CREATION_NAME, - Attributes::PAY_PER_NAME, - Attributes::ONE_LINER, - Attributes::MAIN_VIDEO_EMBED, - Attributes::MAIN_VIDEO_URL, - Attributes::IMAGE_SMALL_URL, - Attributes::IMAGE_URL, - Attributes::THANKS_VIDEO_URL, - Attributes::THANKS_EMBED, - Attributes::THANKS_MSG, - Attributes::IS_MONTHLY, - Attributes::IS_NSFW, - Attributes::IS_CHARGED_IMMEDIATELY, - Attributes::IS_PLURAL, - Attributes::CREATED_AT, - Attributes::PUBLISHED_AT, - Attributes::PLEDGE_URL, - Attributes::PLEDGE_SUM, - Attributes::PATRON_COUNT, - Attributes::CREATION_COUNT, - Attributes::OUTSTANDING_PAYMENT_AMOUNT_CENTS, - ] - end - - def default_relationships - [ - Relationships::REWARDS, - Relationships::CREATOR, - Relationships::GOALS, - ] - end + define :CAMPAIGN_INSTALLATIONS, 'campaign_installations' end end end -end +end \ No newline at end of file diff --git a/lib/patreon/schemas/deliverable.rb b/lib/patreon/schemas/deliverable.rb new file mode 100644 index 0000000..6b1aefa --- /dev/null +++ b/lib/patreon/schemas/deliverable.rb @@ -0,0 +1,28 @@ +# This file is auto-generated from the same code that generates +# https://docs.patreon.com. Community pull requests against this +# file may not be accepted. + +module Patreon + module Schemas + module Deliverable + Name = 'deliverable' + + class Attributes + include Utils::Enum + + define :COMPLETED_AT, 'completed_at' + define :DELIVERY_STATUS, 'delivery_status' + define :DUE_AT, 'due_at' + end + + class Relationships + include Utils::Enum + + define :CAMPAIGN, 'campaign' + define :BENEFIT, 'benefit' + define :MEMBER, 'member' + define :USER, 'user' + end + end + end +end \ No newline at end of file diff --git a/lib/patreon/schemas/goal.rb b/lib/patreon/schemas/goal.rb index 5d012f7..45ac7ba 100644 --- a/lib/patreon/schemas/goal.rb +++ b/lib/patreon/schemas/goal.rb @@ -1,6 +1,12 @@ +# This file is auto-generated from the same code that generates +# https://docs.patreon.com. Community pull requests against this +# file may not be accepted. + module Patreon module Schemas module Goal + Name = 'goal' + class Attributes include Utils::Enum @@ -9,27 +15,14 @@ class Attributes define :DESCRIPTION, 'description' define :CREATED_AT, 'created_at' define :REACHED_AT, 'reached_at' + define :COMPLETED_PERCENTAGE, 'completed_percentage' end class Relationships - end - - class << self - def default_attributes - [ - Attributes::AMOUNT_CENTS, - Attributes::TITLE, - Attributes::DESCRIPTION, - Attributes::CREATED_AT, - Attributes::REACHED_AT, - ] - end + include Utils::Enum - def default_relationships - [ - ] - end + define :CAMPAIGN, 'campaign' end end end -end +end \ No newline at end of file diff --git a/lib/patreon/schemas/media.rb b/lib/patreon/schemas/media.rb new file mode 100644 index 0000000..83ac0ca --- /dev/null +++ b/lib/patreon/schemas/media.rb @@ -0,0 +1,31 @@ +# This file is auto-generated from the same code that generates +# https://docs.patreon.com. Community pull requests against this +# file may not be accepted. + +module Patreon + module Schemas + module Media + Name = 'media' + + class Attributes + include Utils::Enum + + define :FILE_NAME, 'file_name' + define :SIZE_BYTES, 'size_bytes' + define :MIMETYPE, 'mimetype' + define :STATE, 'state' + define :OWNER_TYPE, 'owner_type' + define :OWNER_ID, 'owner_id' + define :OWNER_RELATIONSHIP, 'owner_relationship' + define :UPLOAD_EXPIRES_AT, 'upload_expires_at' + define :UPLOAD_URL, 'upload_url' + define :UPLOAD_PARAMETERS, 'upload_parameters' + define :DOWNLOAD_URL, 'download_url' + define :IMAGE_URLS, 'image_urls' + define :CREATED_AT, 'created_at' + define :METADATA, 'metadata' + end + + end + end +end \ No newline at end of file diff --git a/lib/patreon/schemas/member.rb b/lib/patreon/schemas/member.rb new file mode 100644 index 0000000..421b655 --- /dev/null +++ b/lib/patreon/schemas/member.rb @@ -0,0 +1,37 @@ +# This file is auto-generated from the same code that generates +# https://docs.patreon.com. Community pull requests against this +# file may not be accepted. + +module Patreon + module Schemas + module Member + Name = 'member' + + class Attributes + include Utils::Enum + + define :PATRON_STATUS, 'patron_status' + define :IS_FOLLOWER, 'is_follower' + define :FULL_NAME, 'full_name' + define :EMAIL, 'email' + define :PLEDGE_RELATIONSHIP_START, 'pledge_relationship_start' + define :LIFETIME_SUPPORT_CENTS, 'lifetime_support_cents' + define :CURRENTLY_ENTITLED_AMOUNT_CENTS, 'currently_entitled_amount_cents' + define :LAST_CHARGE_DATE, 'last_charge_date' + define :LAST_CHARGE_STATUS, 'last_charge_status' + define :NOTE, 'note' + define :WILL_PAY_AMOUNT_CENTS, 'will_pay_amount_cents' + end + + class Relationships + include Utils::Enum + + define :ADDRESS, 'address' + define :CAMPAIGN, 'campaign' + define :CURRENTLY_ENTITLED_TIERS, 'currently_entitled_tiers' + define :USER, 'user' + define :PLEDGE_HISTORY, 'pledge_history' + end + end + end +end \ No newline at end of file diff --git a/lib/patreon/schemas/oauthclient.rb b/lib/patreon/schemas/oauthclient.rb new file mode 100644 index 0000000..da472f8 --- /dev/null +++ b/lib/patreon/schemas/oauthclient.rb @@ -0,0 +1,37 @@ +# This file is auto-generated from the same code that generates +# https://docs.patreon.com. Community pull requests against this +# file may not be accepted. + +module Patreon + module Schemas + module OAuthClient + Name = 'oauthclient' + + class Attributes + include Utils::Enum + + define :CLIENT_SECRET, 'client_secret' + define :NAME, 'name' + define :DESCRIPTION, 'description' + define :AUTHOR_NAME, 'author_name' + define :DOMAIN, 'domain' + define :VERSION, 'version' + define :ICON_URL, 'icon_url' + define :PRIVACY_POLICY_URL, 'privacy_policy_url' + define :TOS_URL, 'tos_url' + define :REDIRECT_URIS, 'redirect_uris' + define :DEFAULT_SCOPES, 'default_scopes' + define :CATEGORY, 'category' + end + + class Relationships + include Utils::Enum + + define :USER, 'user' + define :CAMPAIGN, 'campaign' + define :CREATOR_TOKEN, 'creator_token' + define :APPS, 'apps' + end + end + end +end \ No newline at end of file diff --git a/lib/patreon/schemas/pledge.rb b/lib/patreon/schemas/pledge.rb deleted file mode 100644 index 25b1158..0000000 --- a/lib/patreon/schemas/pledge.rb +++ /dev/null @@ -1,50 +0,0 @@ -module Patreon - module Schemas - module Pledge - class Attributes - include Utils::Enum - - define :AMOUNT_CENTS, 'amount_cents' - define :TOTAL_HISTORICAL_AMOUNT_CENTS, 'total_historical_amount_cents' - define :DECLINED_SINCE, 'declined_since' - define :CREATED_AT, 'created_at' - define :PLEDGE_CAP_CENTS, 'pledge_cap_cents' - define :PATRON_PAYS_FEES, 'patron_pays_fees' - define :UNREAD_COUNT, 'unread_count' - end - - class Relationships - include Utils::Enum - - define :PATRON, 'patron' - define :REWARD, 'reward' - define :CREATOR, 'creator' - define :ADDRESS, 'address' - define :CARD, 'card' - define :PLEDGE_VAT_LOCATION, 'pledge_vat_location' - end - - class << self - def default_attributes - [ - Attributes::AMOUNT_CENTS, - Attributes::DECLINED_SINCE, - Attributes::CREATED_AT, - Attributes::PLEDGE_CAP_CENTS, - Attributes::PATRON_PAYS_FEES, - ] - end - - def default_relationships - [ - Relationships::PATRON, - Relationships::REWARD, - Relationships::CREATOR, - Relationships::ADDRESS, - Relationships::PLEDGE_VAT_LOCATION, - ] - end - end - end - end -end diff --git a/lib/patreon/schemas/pledgeevent.rb b/lib/patreon/schemas/pledgeevent.rb new file mode 100644 index 0000000..a1195cc --- /dev/null +++ b/lib/patreon/schemas/pledgeevent.rb @@ -0,0 +1,30 @@ +# This file is auto-generated from the same code that generates +# https://docs.patreon.com. Community pull requests against this +# file may not be accepted. + +module Patreon + module Schemas + module PledgeEvent + Name = 'pledgeevent' + + class Attributes + include Utils::Enum + + define :TYPE, 'type' + define :DATE, 'date' + define :PAYMENT_STATUS, 'payment_status' + define :TIER_TITLE, 'tier_title' + define :TIER_ID, 'tier_id' + define :AMOUNT_CENTS, 'amount_cents' + define :CURRENCY_CODE, 'currency_code' + end + + class Relationships + include Utils::Enum + + define :PATRON, 'patron' + define :CAMPAIGN, 'campaign' + end + end + end +end \ No newline at end of file diff --git a/lib/patreon/schemas/post.rb b/lib/patreon/schemas/post.rb new file mode 100644 index 0000000..250e983 --- /dev/null +++ b/lib/patreon/schemas/post.rb @@ -0,0 +1,33 @@ +# This file is auto-generated from the same code that generates +# https://docs.patreon.com. Community pull requests against this +# file may not be accepted. + +module Patreon + module Schemas + module Post + Name = 'post' + + class Attributes + include Utils::Enum + + define :TITLE, 'title' + define :CONTENT, 'content' + define :IS_PAID, 'is_paid' + define :IS_PUBLIC, 'is_public' + define :PUBLISHED_AT, 'published_at' + define :URL, 'url' + define :EMBED_DATA, 'embed_data' + define :EMBED_URL, 'embed_url' + define :APP_ID, 'app_id' + define :APP_STATUS, 'app_status' + end + + class Relationships + include Utils::Enum + + define :USER, 'user' + define :CAMPAIGN, 'campaign' + end + end + end +end \ No newline at end of file diff --git a/lib/patreon/schemas/reward.rb b/lib/patreon/schemas/reward.rb deleted file mode 100644 index 5c0145f..0000000 --- a/lib/patreon/schemas/reward.rb +++ /dev/null @@ -1,45 +0,0 @@ -module Patreon - module Schemas - module Goal - class Attributes - include Utils::Enum - - define :AMOUNT_CENTS, 'amount_cents' - define :USER_LIMIT, 'user_limit' - define :REMAINING, 'remaining' - define :DESCRIPTION, 'description' - define :REQUIRES_SHIPPING, 'requires_shipping' - define :CREATED_AT, 'created_at' - define :URL, 'url' - define :PATRON_COUNT, 'patron_count' - end - - class Relationships - include Utils::Enum - - define :CREATOR, 'creator' - end - - class << self - def default_attributes - [ - Attributes::AMOUNT_CENTS, - Attributes::USER_LIMIT, - Attributes::REMAINING, - Attributes::DESCRIPTION, - Attributes::REQUIRES_SHIPPING, - Attributes::CREATED_AT, - Attributes::URL, - Attributes::PATRON_COUNT, - ] - end - - def default_relationships - [ - Relationships::CREATOR - ] - end - end - end - end -end diff --git a/lib/patreon/schemas/tier.rb b/lib/patreon/schemas/tier.rb new file mode 100644 index 0000000..b2b64b9 --- /dev/null +++ b/lib/patreon/schemas/tier.rb @@ -0,0 +1,40 @@ +# This file is auto-generated from the same code that generates +# https://docs.patreon.com. Community pull requests against this +# file may not be accepted. + +module Patreon + module Schemas + module Tier + Name = 'tier' + + class Attributes + include Utils::Enum + + define :AMOUNT_CENTS, 'amount_cents' + define :USER_LIMIT, 'user_limit' + define :REMAINING, 'remaining' + define :DESCRIPTION, 'description' + define :REQUIRES_SHIPPING, 'requires_shipping' + define :CREATED_AT, 'created_at' + define :URL, 'url' + define :PATRON_COUNT, 'patron_count' + define :POST_COUNT, 'post_count' + define :DISCORD_ROLE_IDS, 'discord_role_ids' + define :TITLE, 'title' + define :IMAGE_URL, 'image_url' + define :EDITED_AT, 'edited_at' + define :PUBLISHED, 'published' + define :PUBLISHED_AT, 'published_at' + define :UNPUBLISHED_AT, 'unpublished_at' + end + + class Relationships + include Utils::Enum + + define :CAMPAIGN, 'campaign' + define :TIER_IMAGE, 'tier_image' + define :BENEFITS, 'benefits' + end + end + end +end \ No newline at end of file diff --git a/lib/patreon/schemas/user.rb b/lib/patreon/schemas/user.rb index 2dd3484..09d6c0c 100644 --- a/lib/patreon/schemas/user.rb +++ b/lib/patreon/schemas/user.rb @@ -1,6 +1,12 @@ +# This file is auto-generated from the same code that generates +# https://docs.patreon.com. Community pull requests against this +# file may not be accepted. + module Patreon module Schemas module User + Name = 'user' + class Attributes include Utils::Enum @@ -8,78 +14,25 @@ class Attributes define :FIRST_NAME, 'first_name' define :LAST_NAME, 'last_name' define :FULL_NAME, 'full_name' - define :GENDER, 'gender' - define :STATUS, 'status' + define :IS_EMAIL_VERIFIED, 'is_email_verified' define :VANITY, 'vanity' define :ABOUT, 'about' - define :FACEBOOK_ID, 'facebook_id' define :IMAGE_URL, 'image_url' define :THUMB_URL, 'thumb_url' - define :THUMBNAILS, 'thumbnails' - define :YOUTUBE, 'youtube' - define :TWITTER, 'twitter' - define :FACEBOOK, 'facebook' - define :TWITCH, 'twitch' - define :IS_SUSPENDED, 'is_suspended' - define :IS_DELETED, 'is_deleted' - define :IS_NUKED, 'is_nuked' + define :CAN_SEE_NSFW, 'can_see_nsfw' define :CREATED, 'created' define :URL, 'url' define :LIKE_COUNT, 'like_count' - define :COMMENT_COUNT, 'comment_count' - define :IS_CREATOR, 'is_creator' define :HIDE_PLEDGES, 'hide_pledges' - define :TWO_FACTOR_ENABLED, 'two_factor_enabled' + define :SOCIAL_CONNECTIONS, 'social_connections' end class Relationships include Utils::Enum - define :PLEDGES, 'pledges' - define :CARDS, 'cards' - define :FOLLOWS, 'follows' + define :MEMBERSHIPS, 'memberships' define :CAMPAIGN, 'campaign' - define :PRESENCE, 'presence' - define :SESSION, 'session' - define :LOCATIONS, 'locations' - define :CURRENT_USER_FOLLOW, 'current_user_follow' - define :PLEDGE_TO_CURRENT_USER, 'pledge_to_current_user' - end - - class << self - def default_attributes - [ - Attributes::EMAIL, - Attributes::FIRST_NAME, - Attributes::LAST_NAME, - Attributes::FULL_NAME, - Attributes::GENDER, - Attributes::STATUS, - Attributes::VANITY, - Attributes::ABOUT, - Attributes::FACEBOOK_ID, - Attributes::IMAGE_URL, - Attributes::THUMB_URL, - Attributes::THUMBNAILS, - Attributes::YOUTUBE, - Attributes::TWITTER, - Attributes::FACEBOOK, - Attributes::TWITCH, - Attributes::IS_SUSPENDED, - Attributes::IS_DELETED, - Attributes::IS_NUKED, - Attributes::CREATED, - Attributes::URL, - ] - end - - def default_relationships - [ - Relationships::CAMPAIGN, - Relationships::PLEDGES, - ] - end end end end -end +end \ No newline at end of file diff --git a/lib/patreon/schemas/webhook.rb b/lib/patreon/schemas/webhook.rb new file mode 100644 index 0000000..e517a2a --- /dev/null +++ b/lib/patreon/schemas/webhook.rb @@ -0,0 +1,29 @@ +# This file is auto-generated from the same code that generates +# https://docs.patreon.com. Community pull requests against this +# file may not be accepted. + +module Patreon + module Schemas + module Webhook + Name = 'webhook' + + class Attributes + include Utils::Enum + + define :TRIGGERS, 'triggers' + define :URI, 'uri' + define :PAUSED, 'paused' + define :LAST_ATTEMPTED_AT, 'last_attempted_at' + define :NUM_CONSECUTIVE_TIMES_FAILED, 'num_consecutive_times_failed' + define :SECRET, 'secret' + end + + class Relationships + include Utils::Enum + + define :CLIENT, 'client' + define :CAMPAIGN, 'campaign' + end + end + end +end \ No newline at end of file diff --git a/lib/patreon/utils/jsonapi/url_util.rb b/lib/patreon/utils/jsonapi/url_util.rb index 142617d..7821571 100644 --- a/lib/patreon/utils/jsonapi/url_util.rb +++ b/lib/patreon/utils/jsonapi/url_util.rb @@ -5,13 +5,15 @@ module Patreon module Utils module JSONAPI class URLUtil - def self.build_url(url, includes=nil, fields=nil) + def self.build_url(url, includes=nil, fields=nil, count=nil, cursor=nil) parsed_url = URI.parse(url) params = parsed_url.query ? Rack::Utils.parse_query(parsed_url.query) : {} params['include'] = joined_or_null(includes) if includes fields.each do |name, val| - params["fields[#{name}]"] = val + params["fields[#{name}]"] = val.respond_to?(:join) ? val.join(',') : val end if fields + params["page[count]"] = count if count + params["page[cursor]"] = cursor if cursor query = params.empty? ? "" : "?#{Rack::Utils.build_query(params)}" "#{parsed_url.path}#{query}" diff --git a/lib/patreon/version.rb b/lib/patreon/version.rb index 7f2044b..b0926c7 100644 --- a/lib/patreon/version.rb +++ b/lib/patreon/version.rb @@ -1,3 +1,3 @@ module Patreon - VERSION = "0.5.1" + VERSION = "1.0.0" end diff --git a/spec/api_spec.rb b/spec/api_spec.rb index 795b48e..cb1028b 100644 --- a/spec/api_spec.rb +++ b/spec/api_spec.rb @@ -1,3 +1,7 @@ +# This file is auto-generated from the same code that generates +# https://docs.patreon.com. Community pull requests against this +# file may not be accepted. + require 'json' describe Patreon::API do @@ -5,97 +9,132 @@ @api = Patreon::API.new("some token") end - describe "Patreon::API#fetch_user" do + describe "Patreon::API" do before(:all) do @response = File.read(File.expand_path("fixtures/current_user.json", __dir__)) end - it "should get current_user" do - @api.expects(:get_json).with("current_user").returns(@response) - response = @api.fetch_user + it "should parse data" do + @api.expects(:get_json).with("identity").returns(@response) + response = @api.get_identity assert_equal response.data.pledges.count, 5 assert_equal response.data.vanity, "corgi" assert_equal response.data.first_name, "Corgi" end - it "should get current_user and the user should be mutable" do - @api.expects(:get_json).with("current_user").returns(@response) - response = @api.fetch_user - assert_equal response.data.pledges.count, 5 - assert_equal response.data.vanity, "corgi" + it "should allow mutating data" do + @api.expects(:get_json).with("identity").returns(@response) + response = @api.get_identity assert_equal response.data.first_name, "Corgi" response.data.first_name = "Jack" assert_equal response.data.first_name, "Jack" end - it "should get current_user correctly if field is nil" do + it "should support nill value" do munged_response = JSON.parse(@response) munged_response['data']['attributes']['first_name'] = nil - @api.expects(:get_json).with("current_user").returns(munged_response.to_json) - response = @api.fetch_user - assert_equal response.data.pledges.count, 5 - assert_equal response.data.vanity, "corgi" + @api.expects(:get_json).with("identity").returns(munged_response.to_json) + response = @api.get_identity assert_nil response.data.first_name end + end - it "should get current_user with includes" do - @api.expects(:get_json).with("current_user?include=hello").returns(@response) - @api.fetch_user(includes: "hello") + describe "Patreon::API#get_campaigns" do + before(:all) do + @response = File.read(File.expand_path("fixtures/current_user.json", __dir__)) end - it "should get current_user with fields" do - @api.expects(:get_json).with("current_user?fields%5Bhello%5D=there").returns(@response) - @api.fetch_user(fields: {hello: "there"}) + it "should return data" do + resource_id = "32187" + expected_url = "campaigns" + @api.expects(:get_json).with(expected_url).returns(@response) + response = @api.get_campaigns() + assert_equal response.data.id, resource_id end end - describe "Patreon::API#fetch_campaign" do + describe "Patreon::API#get_identity" do before(:all) do - @response = File.read(File.expand_path("fixtures/fetch_campaign.json", __dir__)) + @response = File.read(File.expand_path("fixtures/current_user.json", __dir__)) end - it "should get fetch_campaign" do - @api.expects(:get_json).with("current_user/campaigns").returns(@response) - response = @api.fetch_campaign - assert_equal response.data.count, 1 - assert_equal response.data[0].creation_name, "an unforgettable high school experience" + it "should return data" do + resource_id = "32187" + expected_url = "identity" + @api.expects(:get_json).with(expected_url).returns(@response) + response = @api.get_identity() + assert_equal response.data.id, resource_id end + end - it "should get fetch_campaign with includes" do - @api.expects(:get_json).with("current_user/campaigns?include=hello").returns(@response) - @api.fetch_campaign(includes: "hello") + describe "Patreon::API#get_webhooks" do + before(:all) do + @response = File.read(File.expand_path("fixtures/current_user.json", __dir__)) end - it "should get fetch_campaign with fields" do - @api.expects(:get_json).with("current_user/campaigns?fields%5Bhello%5D=there").returns(@response) - @api.fetch_campaign(fields: {hello: "there"}) + it "should return data" do + resource_id = "32187" + expected_url = "webhooks" + @api.expects(:get_json).with(expected_url).returns(@response) + response = @api.get_webhooks() + assert_equal response.data.id, resource_id end end - describe "Patreon::API#fetch_campaign_and_patrons" do + describe "Patreon::API#get_campaigns_by_id_members" do before(:all) do - @response = File.read(File.expand_path("fixtures/fetch_campaign.json", __dir__)) + @response = File.read(File.expand_path("fixtures/current_user.json", __dir__)) end - it "should get fetch_campaign_and_patrons" do - @api.expects(:get_json).with("current_user/campaigns?include=rewards%2Ccreator%2Cgoals%2Cpledges").returns(@response) - @api.fetch_campaign_and_patrons + it "should return data" do + resource_id = "32187" + expected_url = "campaigns/#{resource_id}/members" + @api.expects(:get_json).with(expected_url).returns(@response) + response = @api.get_campaigns_by_id_members(resource_id) + assert_equal response.data.id, resource_id end + end - it "should get fetch_campaign_and_patrons with more includes" do - @api.expects(:get_json).with("current_user/campaigns?include=doohickey%2Crewards%2Ccreator%2Cgoals%2Cpledges").returns(@response) - @api.fetch_campaign_and_patrons(includes: "doohickey") + describe "Patreon::API#get_campaigns_by_id" do + before(:all) do + @response = File.read(File.expand_path("fixtures/current_user.json", __dir__)) + end + + it "should return data" do + resource_id = "32187" + expected_url = "campaigns/#{resource_id}" + @api.expects(:get_json).with(expected_url).returns(@response) + response = @api.get_campaigns_by_id(resource_id) + assert_equal response.data.id, resource_id end end - describe "Patreon::API#fetch_page_of_pledges" do + describe "Patreon::API#get_webhooks_by_id" do before(:all) do - @response = File.read(File.expand_path("fixtures/fetch_campaign.json", __dir__)) + @response = File.read(File.expand_path("fixtures/current_user.json", __dir__)) end - it "should get fetch_page_of_pledges" do - @api.expects(:get_json).with("campaigns/123/pledges?page%5Bcount%5D=10").returns(@response) - @api.fetch_page_of_pledges(123) + it "should return data" do + resource_id = "32187" + expected_url = "webhooks/#{resource_id}" + @api.expects(:get_json).with(expected_url).returns(@response) + response = @api.get_webhooks_by_id(resource_id) + assert_equal response.data.id, resource_id end end -end + + describe "Patreon::API#get_members_by_id" do + before(:all) do + @response = File.read(File.expand_path("fixtures/current_user.json", __dir__)) + end + + it "should return data" do + resource_id = "32187" + expected_url = "members/#{resource_id}" + @api.expects(:get_json).with(expected_url).returns(@response) + response = @api.get_members_by_id(resource_id) + assert_equal response.data.id, resource_id + end + end + +end \ No newline at end of file diff --git a/spec/util_spec.rb b/spec/util_spec.rb index 5b8afa9..7d24795 100644 --- a/spec/util_spec.rb +++ b/spec/util_spec.rb @@ -14,17 +14,32 @@ url = Patreon::Utils::JSONAPI::URLUtil.build_url("/", ["some", "include"]) assert_equal url, "/?include=some%2Cinclude" end - + it "should build a url with a fields" do url = Patreon::Utils::JSONAPI::URLUtil.build_url("/", nil, {hey: 123}) assert_equal url, "/?fields%5Bhey%5D=123" end + + it "should build a url with multiple fields" do + url = Patreon::Utils::JSONAPI::URLUtil.build_url("/", nil, {hey: ["one", "two"]}) + assert_equal url, "/?fields%5Bhey%5D=one%2Ctwo" + end it "should build a url with a fields and includes" do url = Patreon::Utils::JSONAPI::URLUtil.build_url("/", ["some", "include"], {hey: 123}) assert_equal url, "/?include=some%2Cinclude&fields%5Bhey%5D=123" end + it "should build a url with a count" do + url = Patreon::Utils::JSONAPI::URLUtil.build_url("/", nil, nil, 20) + assert_equal url, "/?page%5Bcount%5D=20" + end + + it "should build a url with a cursor" do + url = Patreon::Utils::JSONAPI::URLUtil.build_url("/", nil, nil, nil, "1234") + assert_equal url, "/?page%5Bcursor%5D=1234" + end + it "should merge with a pre-existing querystring" do url = Patreon::Utils::JSONAPI::URLUtil.build_url("/?1=2", ["some", "include"], {hey: 123}) assert_equal url, "/?1=2&include=some%2Cinclude&fields%5Bhey%5D=123"