patreon

package module
v0.0.0-...-646111f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 17, 2019 License: MIT Imports: 10 Imported by: 0

README

Build Status GoDoc Go Report Card codecov MIT license Patreon

patreon-go

patreon-go is a Go client library for accessing the Patreon API.

How to import

The patreon-go package may be installed by running:

go get gopkg.in/mxpv/patreon-go.v1

or

import "gopkg.in/mxpv/patreon-go.v1"

Basic example

import "gopkg.in/mxpv/patreon-go.v1"

func main() {
	client := patreon.NewClient(nil)
  
	user, err := client.FetchUser()
	if err != nil {
		// ...
	}

	print(user.Data.Id)
}

Authentication

The patreon-go library does not directly handle authentication. Instead, when creating a new client, pass an http.Client that can handle authentication for you, most likely you will need oauth2 package.

Here is an example with static token:

import (
	"gopkg.in/mxpv/patreon-go.v1"
	"golang.org/x/oauth2"
)

func NewPatreonClient(ctx context.Context, token string) *patreon.Client {
	ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token})
	tc := oauth2.NewClient(ctx, ts)
	
	client := patreon.NewClient(tc)
	return client
}

Automatically refresh token:

func NewPatreonClient() (*patreon.Client, error) {
	config := oauth2.Config{
		ClientID:     "<client_id>",
		ClientSecret: "<client_secret>",
		Endpoint: oauth2.Endpoint{
			AuthURL:  AuthorizationURL,
			TokenURL: AccessTokenURL,
		},
		Scopes: []string{"users", "pledges-to-me", "my-campaign"},
	}

	token := oauth2.Token{
		AccessToken:  "<current_access_token>",
		RefreshToken: "<current_refresh_token>",
		// Must be non-nil, otherwise token will not be expired
		Expiry: time.Now().Add(-24 * time.Hour),
	}

	tc := config.Client(context.Background(), &token)

	client := NewClient(tc)
	_, err := client.FetchUser()
	if err != nil {
		panic(err)
	}

	print("OK")
}

Look & Feel

func Example_fetchPatronsAndPledges() {
	ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: testAccessToken})
	tc := oauth2.NewClient(oauth2.NoContext, ts)

	// Create client with static access token
	client := NewClient(tc)

	// Get your campaign data
	campaignResponse, err := client.FetchCampaign()
	if err != nil {
		panic(err)
	}

	campaignId := campaignResponse.Data[0].Id

	cursor := ""
	page := 1

	for {
		pledgesResponse, err := client.FetchPledges(campaignId,
			WithPageSize(25),
			WithCursor(cursor))

		if err != nil {
			panic(err)
		}

		// Get all the users in an easy-to-lookup way
		users := make(map[string]*User)
		for _, item := range pledgesResponse.Included.Items {
			u, ok := item.(*User)
			if !ok {
				continue
			}

			users[u.Id] = u
		}

		fmt.Printf("Page %d\r\n", page)

		// Loop over the pledges to get e.g. their amount and user name
		for _, pledge := range pledgesResponse.Data {
			amount := pledge.Attributes.AmountCents
			patronId := pledge.Relationships.Patron.Data.Id
			patronFullName := users[patronId].Attributes.FullName

			fmt.Printf("%s is pledging %d cents\r\n", patronFullName, amount)
		}

		// Get the link to the next page of pledges
		nextLink := pledgesResponse.Links.Next
		if nextLink == "" {
			break
		}

		cursor = nextLink
		page++
	}

	fmt.Print("Done!")
}

Documentation

Overview

Package patreon is a Go client library for accessing the Patreon API.

Example (FetchPatronsAndPledges)

Fetches the list of pledges with corresponding users. This example is a port of PHP version https://github.com/Patreon/patreon-php/blob/master/examples/patron-list.php

ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: testAccessToken})
tc := oauth2.NewClient(oauth2.NoContext, ts)

// Create client with static access token
client := NewClient(tc)

// Get your campaign data
campaignResponse, err := client.FetchCampaign()
if err != nil {
	panic(err)
}

campaignId := campaignResponse.Data[0].ID

cursor := ""
page := 1

for {
	pledgesResponse, err := client.FetchPledges(campaignId,
		WithPageSize(25),
		WithCursor(cursor))

	if err != nil {
		panic(err)
	}

	// Get all the users in an easy-to-lookup way
	users := make(map[string]*User)
	for _, item := range pledgesResponse.Included.Items {
		u, ok := item.(*User)
		if !ok {
			continue
		}

		users[u.ID] = u
	}

	fmt.Printf("Page %d\r\n", page)

	// Loop over the pledges to get e.g. their amount and user name
	for _, pledge := range pledgesResponse.Data {
		amount := pledge.Attributes.AmountCents
		patronId := pledge.Relationships.Patron.Data.ID
		patronFullName := users[patronId].Attributes.FullName

		fmt.Printf("%s is pledging %d cents\r\n", patronFullName, amount)
	}

	// Get the link to the next page of pledges
	nextLink := pledgesResponse.Links.Next
	if nextLink == "" {
		break
	}

	cursor = nextLink
	page++
}

fmt.Print("Done!")
Output:

Example (RefreshToken)

Automatically refresh token

config := oauth2.Config{
	ClientID:     "<client_id>",
	ClientSecret: "<client_secret>",
	Endpoint: oauth2.Endpoint{
		AuthURL:  AuthorizationURL,
		TokenURL: AccessTokenURL,
	},
	Scopes: []string{"users", "pledges-to-me", "my-campaign"},
}

token := oauth2.Token{
	AccessToken:  "<current_access_token>",
	RefreshToken: "<current_refresh_token>",
	// Must be non-nil, otherwise token will not be expired
	Expiry: time.Now().Add(-24 * time.Hour),
}

tc := config.Client(oauth2.NoContext, &token)

client := NewClient(tc)
_, err := client.FetchUser()
if err != nil {
	panic(err)
}

print("OK")
Output:

Index

Examples

Constants

View Source
const (
	// AuthorizationURL specifies Patreon's OAuth2 authorization endpoint (see https://tools.ietf.org/html/rfc6749#section-3.1).
	// See Example_refreshToken for examples.
	AuthorizationURL = "https://www.patreon.com/oauth2/authorize"

	// AccessTokenURL specifies Patreon's OAuth2 token endpoint (see https://tools.ietf.org/html/rfc6749#section-3.2).
	// See Example_refreshToken for examples.
	AccessTokenURL = "https://api.patreon.com/oauth2/token"
)
View Source
const (
	// EventCreatePledge specifies a create pledge event
	EventCreatePledge = "pledges:create"

	// EventUpdatePledge specifies an update pledge event
	EventUpdatePledge = "pledges:update"

	// EventDeletePledge specifies a delete pledge event
	EventDeletePledge = "pledges:delete"
)
View Source
const (
	// HeaderEventType specifies an event type HTTP header name
	HeaderEventType = "X-Patreon-Event"

	// HeaderEventSignature specifies message signature HTTP header name to verify message body
	HeaderSignature = "X-Patreon-Signature"
)
View Source
const CampaignDefaultRelations = "rewards,creator,goals"

CampaignDefaultRelations specifies default includes for Campaign.

View Source
const PledgeDefaultRelations = "patron,reward,creator,address,pledge_vat_location"

PledgeDefaultRelations specifies default includes for Pledge.

View Source
const UserDefaultRelations = "campaign,pledges"

UserDefaultRelations specifies default includes for User.

Variables

This section is empty.

Functions

func VerifySignature

func VerifySignature(message []byte, secret string, signature string) (bool, error)

VerifySignature verifies the sender of the message

func WithCursor

func WithCursor(cursor string) requestOption

WithCursor controls cursor-based pagination. Cursor will also be extracted from navigation links for convenience.

func WithFields

func WithFields(resource string, fields ...string) requestOption

WithFields specifies the resource attributes you want to be returned by API.

func WithIncludes

func WithIncludes(include ...string) requestOption

WithIncludes specifies the related resources you want to be returned by API.

func WithPageSize

func WithPageSize(size int) requestOption

WithPageSize specifies the number of items to return.

Types

type Address

type Address struct {
	Type       string `json:"type"`
	ID         string `json:"id"`
	Attributes struct {
		Addressee   string `json:"addressee"`
		City        string `json:"city"`
		Country     string `json:"country"`
		Line1       string `json:"line_1"`
		Line2       string `json:"line_2"`
		PhoneNumber string `json:"phone_number"`
		PostalCode  string `json:"postal_code"`
		State       string `json:"state"`
	} `json:"attributes"`
}

Address represents a Patreon's address.

type AddressRelationship

type AddressRelationship struct {
	Data  Data `json:"data"`
	Links struct {
		Related string `json:"related"`
	} `json:"links"`
}

AddressRelationship represents 'address' include.

type Campaign

type Campaign struct {
	Type       string `json:"type"`
	ID         string `json:"id"`
	Attributes struct {
		Summary                       string   `json:"summary"`
		CreationName                  string   `json:"creation_name"`
		DisplayPatronGoals            bool     `json:"display_patron_goals"`
		PayPerName                    string   `json:"pay_per_name"`
		OneLiner                      string   `json:"one_liner"`
		MainVideoEmbed                string   `json:"main_video_embed"`
		MainVideoURL                  string   `json:"main_video_url"`
		ImageSmallURL                 string   `json:"image_small_url"`
		ImageURL                      string   `json:"image_url"`
		ThanksVideoURL                string   `json:"thanks_video_url"`
		ThanksEmbed                   string   `json:"thanks_embed"`
		ThanksMsg                     string   `json:"thanks_msg"`
		IsChargedImmediately          bool     `json:"is_charged_immediately"`
		IsMonthly                     bool     `json:"is_monthly"`
		IsNsfw                        bool     `json:"is_nsfw"`
		IsPlural                      bool     `json:"is_plural"`
		CreatedAt                     NullTime `json:"created_at"`
		PublishedAt                   NullTime `json:"published_at"`
		PledgeURL                     string   `json:"pledge_url"`
		PledgeSum                     int      `json:"pledge_sum"`
		PatronCount                   int      `json:"patron_count"`
		CreationCount                 int      `json:"creation_count"`
		OutstandingPaymentAmountCents int      `json:"outstanding_payment_amount_cents"`
	} `json:"attributes"`
	Relationships struct {
		Categories      *CategoriesRelationship      `json:"categories,omitempty"`
		Creator         *CreatorRelationship         `json:"creator,omitempty"`
		Rewards         *RewardsRelationship         `json:"rewards,omitempty"`
		Goals           *GoalsRelationship           `json:"goals,omitempty"`
		Pledges         *PledgesRelationship         `json:"pledges,omitempty"`
		PostAggregation *PostAggregationRelationship `json:"post_aggregation,omitempty"`
	} `json:"relationships"`
}

Campaign represents Patreon's campaign. Valid relationships: rewards, creator, goals, pledges, current_user_pledge, post_aggregation, categories, preview_token.

type CampaignRelationship

type CampaignRelationship struct {
	Data  Data `json:"data"`
	Links struct {
		Related string `json:"related"`
	} `json:"links"`
}

CampaignRelationship represents 'campaign' include.

type CampaignResponse

type CampaignResponse struct {
	Data     []Campaign `json:"data"`
	Included Includes   `json:"included"`
}

CampaignResponse wraps Patreon's campaign API response

type Card

type Card struct {
	Type       string `json:"type"`
	ID         string `json:"id"`
	Attributes struct {
		// PayPal
		CardType         string   `json:"card_type"`
		CreatedAt        NullTime `json:"created_at"`
		ExpirationDate   NullTime `json:"expiration_date"`
		HasFailedPayment bool     `json:"has_a_failed_payment"`
		IsVerified       bool     `json:"is_verified"`
		Number           string   `json:"number"`
		PaymentToken     string   `json:"payment_token"`
		PaymentTokenID   int      `json:"payment_token_id"`
	} `json:"attributes"`
	Relationships struct {
		User *UserRelationship `json:"user"`
	} `json:"relationships"`
}

Card represents Patreon's credit card or paypal account.

type CategoriesRelationship

type CategoriesRelationship struct {
	Data []Data `json:"data"`
}

CategoriesRelationship represents 'categories' include.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client manages communication with Patreon API.

func NewClient

func NewClient(httpClient *http.Client) *Client

NewClient returns a new Patreon API client. If a nil httpClient is provided, http.DefaultClient will be used. To use API methods which require authentication, provide an http.Client that will perform the authentication for you (such as that provided by the golang.org/x/oauth2 library).

func (*Client) Client

func (c *Client) Client() *http.Client

Client returns the HTTP client configured for this client.

func (*Client) FetchCampaign

func (c *Client) FetchCampaign(opts ...requestOption) (*CampaignResponse, error)

FetchCampaign fetches your own profile and campaign info. This API returns a representation of the user's campaign, including its rewards and goals, and the pledges to it. If there are more than twenty pledges to the campaign, the first twenty will be returned, along with a link to the next page of pledges.

func (*Client) FetchPledges

func (c *Client) FetchPledges(campaignId string, opts ...requestOption) (*PledgeResponse, error)

FetchPledges fetches a list of pledges to you. This API returns a list of pledges to the provided campaignId. They are sorted by the date the pledge was made, and provide relationship references to the users who made each respective pledge. The API response will also contain a links section which may be used to fetch the next page of pledges, or go back to the first page.

func (*Client) FetchUser

func (c *Client) FetchUser(opts ...requestOption) (*UserResponse, error)

FetchUser fetches a patron's profile info. This API returns a representation of the user who granted your OAuth client the provided access_token. It is most typically used in the OAuth "Log in with Patreon" flow to create or update the user's account on your site.

type CreatorRelationship

type CreatorRelationship struct {
	Data  Data `json:"data"`
	Links struct {
		Related string `json:"related"`
	} `json:"links"`
}

CreatorRelationship represents 'creator' include.

type Data

type Data struct {
	ID   string `json:"id"`
	Type string `json:"type"`
}

Data represents a link to entity.

type Error

type Error struct {
	Code     int    `json:"code"`
	CodeName string `json:"code_name"`
	Detail   string `json:"detail"`
	ID       string `json:"id"`
	Status   string `json:"status"`
	Title    string `json:"title"`
}

Error describes error details.

type ErrorResponse

type ErrorResponse struct {
	Errors []Error `json:"errors"`
}

ErrorResponse is a Patreon error response.

func (ErrorResponse) Error

func (e ErrorResponse) Error() string

type Goal

type Goal struct {
	Type       string `json:"type"`
	ID         string `json:"id"`
	Attributes struct {
		Amount              int      `json:"amount"`
		AmountCents         int      `json:"amount_cents"`
		CompletedPercentage int      `json:"completed_percentage"`
		CreatedAt           NullTime `json:"created_at"`
		ReachedAt           NullTime `json:"reached_at"`
		Title               string   `json:"title"`
		Description         string   `json:"description"`
	} `json:"attributes"`
}

Goal represents a Patreon's goal.

type GoalsRelationship

type GoalsRelationship struct {
	Data []Data `json:"data"`
}

GoalsRelationship represents 'goals' include.

type Includes

type Includes struct {
	Items []interface{}
}

Includes wraps 'includes' JSON field to handle objects of different type within an array.

func (*Includes) UnmarshalJSON

func (i *Includes) UnmarshalJSON(b []byte) error

UnmarshalJSON deserializes 'includes' field into the appropriate structs depending on the 'type' field. See http://gregtrowbridge.com/golang-json-serialization-with-interfaces/ for implementation details.

type Meta

type Meta struct {
	Count int `json:"count"`
}

Meta represents extra information about relationship.

type NullTime

type NullTime struct {
	time.Time
	Valid bool
}

NullTime represents a time.Time that may be JSON "null". golang prior 1.8 doesn't support this scenario (fails with error: parsing time "null" as ""2006-01-02T15:04:05Z07:00"": cannot parse "null" as """)

func (*NullTime) UnmarshalJSON

func (t *NullTime) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler with JSON "null" support

type PatronRelationship

type PatronRelationship struct {
	Data  Data `json:"data"`
	Links struct {
		Related string `json:"related"`
	} `json:"links"`
}

PatronRelationship represents 'patron' include.

type Pledge

type Pledge struct {
	Type       string `json:"type"`
	ID         string `json:"id"`
	Attributes struct {
		AmountCents    int      `json:"amount_cents"`
		CreatedAt      NullTime `json:"created_at"`
		DeclinedSince  NullTime `json:"declined_since"`
		PledgeCapCents int      `json:"pledge_cap_cents"`
		PatronPaysFees bool     `json:"patron_pays_fees"`
		// Optional properties
		TotalHistoricalAmountCents    *int  `json:"total_historical_amount_cents"`
		IsPaused                      *bool `json:"is_paused"`
		HasShippingAddress            *bool `json:"has_shipping_address"`
		OutstandingPaymentAmountCents *int  `json:"outstanding_payment_amount_cents"`
	} `json:"attributes"`
	Relationships struct {
		Patron  *PatronRelationship  `json:"patron"`
		Reward  *RewardRelationship  `json:"reward"`
		Creator *CreatorRelationship `json:"creator"`
		Address *AddressRelationship `json:"address"`
	} `json:"relationships"`
}

Pledge represents Patreon's pledge. Valid relationships: patron, reward, creator, address (?), card (?), pledge_vat_location (?).

type PledgeResponse

type PledgeResponse struct {
	Data     []Pledge `json:"data"`
	Included Includes `json:"included"`
	Links    struct {
		First string `json:"first"`
		Next  string `json:"next"`
	} `json:"links"`
	Meta struct {
		Count int `json:"count"`
	} `json:"meta"`
}

PledgeResponse wraps Patreon's pledges API response

type PledgesRelationship

type PledgesRelationship struct {
	Data  []Data `json:"data"`
	Links struct {
		First string `json:"first"`
		Next  string `json:"next"`
	} `json:"links"`
	Meta Meta `json:"meta"`
}

PledgesRelationship represents 'pledges' include.

type PostAggregationRelationship

type PostAggregationRelationship struct {
	Data  Data `json:"data"`
	Links struct {
		Related string `json:"related"`
	} `json:"links"`
}

PostAggregationRelationship represents 'post_aggregation' include.

type Reward

type Reward struct {
	Type       string `json:"type"`
	ID         string `json:"id"`
	Attributes struct {
		Amount           int      `json:"amount"`
		AmountCents      int      `json:"amount_cents"`
		CreatedAt        NullTime `json:"created_at"`
		DeletedAt        NullTime `json:"deleted_at"`
		EditedAt         NullTime `json:"edited_at"`
		Description      string   `json:"description"`
		ImageURL         string   `json:"image_url"`
		PatronCount      int      `json:"patron_count"`
		PostCount        int      `json:"post_count"`
		Published        bool     `json:"published"`
		PublishedAt      NullTime `json:"published_at"`
		RequiresShipping bool     `json:"requires_shipping"`
		Title            string   `json:"title"`
		UnpublishedAt    NullTime `json:"unpublished_at"`
		URL              string   `json:"url"`
	} `json:"attributes"`
}

Reward represents a Patreon's reward.

type RewardRelationship

type RewardRelationship struct {
	Data  Data `json:"data"`
	Links struct {
		Related string `json:"related"`
	} `json:"links"`
}

RewardRelationship represents 'reward' include.

type RewardsRelationship

type RewardsRelationship struct {
	Data []Data `json:"data"`
}

RewardsRelationship represents 'rewards' include.

type User

type User struct {
	Type       string `json:"type"`
	ID         string `json:"id"`
	Attributes struct {
		FirstName       string   `json:"first_name"`
		LastName        string   `json:"last_name"`
		FullName        string   `json:"full_name"`
		Vanity          string   `json:"vanity"`
		Email           string   `json:"email"`
		About           string   `json:"about"`
		FacebookId      string   `json:"facebook_id"`
		Gender          int      `json:"gender"`
		HasPassword     bool     `json:"has_password"`
		ImageURL        string   `json:"image_url"`
		ThumbURL        string   `json:"thumb_url"`
		YouTube         string   `json:"youtube"`
		Twitter         string   `json:"twitter"`
		Facebook        string   `json:"facebook"`
		IsEmailVerified bool     `json:"is_email_verified"`
		IsSuspended     bool     `json:"is_suspended"`
		IsDeleted       bool     `json:"is_deleted"`
		IsNuked         bool     `json:"is_nuked"`
		Created         NullTime `json:"created"`
		URL             string   `json:"url"`
		DiscordId       string   `json:"discord_id"`
	} `json:"attributes"`
	Relationships struct {
		Pledges *PledgesRelationship `json:"pledges,omitempty"`
	} `json:"relationships"`
}

User represents a Patreon's user. Valid relationships: pledges, cards, follows, campaign, presence, session, locations, current_user_follow, pledge_to_current_user.

type UserRelationship

type UserRelationship struct {
	Data  Data `json:"data"`
	Links struct {
		Related string `json:"related"`
	} `json:"links"`
}

UserRelationship represents 'user' include

type UserResponse

type UserResponse struct {
	Data     User     `json:"data"`
	Included Includes `json:"included"`
	Links    struct {
		Self string `json:"self"`
	} `json:"links"`
}

UserResponse wraps Patreon's fetch user API response

type WebhookPledge

type WebhookPledge struct {
	Data Pledge `json:"data"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL