Getting Names Of Your Patreon Patrons From The Patreon API

A common Patreon reward is to list patron names in the credits for your creations – on my patreon I have this on any tier more than €3. In order to implement this I used the patreon api python package so I could have it look up names automatically when people view my bot credits. Compared to other API packages I found it quite awkward to use, so figured it would be worthwhile to write up a guide on how to use it.

Creating a Patreon API Token

So, first you need to generate an API key for your account. To do this, visit this page and select the “Create Client” button. This will pop up a huge form. This has a lot of fields which may be irrelevant for you – the system is intended to building full OAuth apps for your patrons to interact with, but our use case is simply pulling information from our own campaigns. Just fill in the Required fields, and for Redirect URIs enter any valid URL. Once this is done you’ll get back to your clients list, expand your new client and pull out the Creator’s Access Token.

Image showing where on the screen the patreon client ID is

Treat this token with the same care you’d treat a password – do not share this code with anyone.

Connecting to Your Patreon Campaign

Now that you have your access token you can start working on the python code. First you need to create an api_client with api_client = patreon.API(CREATOR_ID) where “CREATOR_ID” is the Creator’s Access Token you got from the previous section. Now comes the awkward part, in order to actually get your pledge info you first need to get your campaign ID. You can do that with campaign_id = api_client.get_campaigns().data()[0].id(). Now that you have the campaign id you can actually get your pledge info using the api_client.fetch_page_of_pledges method, which take campaign id and a page size as arguments. Wow, that’s a lot of code! Here is how it looks so far.

api_client = patreon.API(CREATOR_ID)
campaign_id = api_client.get_campaigns().data()[0].id()
pledges_response = api_client.fetch_page_of_pledges(
    campaign_id,
    25,
)

The code above will get you an api response for your campaign that has up to 25 pledges. Do you have more pledges? Lucky for you! I’ll talk about pagination in a bit. First, I’ll talk about getting patron info from this code.

Extracting your Patron Info

So, how do we get the info? The first step is to extract the page of pledges from this object, we do that with all_pledges = pledges_response.data(). The “all_pledges” list is a list of pledge objects that contains partial info from our pledges – for our patrons all we have here is their ID. To get the info we need to iterate over this list, extract each patron id with patron_id = pledge.relationship('patron').id() and then use the api_client.find_resource_by_type_and_id method to get a patron object. From this object we can extract the names. Oof, much more code, here is what this section looks like in python.

names = []
all_pledges = pledges_response.data()
for pledge in all_pledges:
    patron_id = pledge.relationship('patron').id()
    patron = find_resource_by_type_and_id('user', patron_id)
    names.append(patron.attribute('full_name'))

I like sticking all this into a function, which will help later.

def get_names(all_pledges, names):
    for pledge in all_pledges:
        patron_id = pledge.relationship('patron').id()
        patron = find_resource_by_type_and_id('user', patron_id)
        names.append(patron.attribute('full_name'))

Getting Additional pages

Now, this is fine if we have a small campaign, but if we are lucky enough to have many followers we’re gonna need to get additional pages of names. This logic is actually contained within our pledges_response object. We can use the code cursor = api_client.extract_cursor(pledges_response) to extract a cursor from the response. If there are additional pages this will contain data used to get the next page. if there is not a next page then cursor will be None. We can add a cursor argument to the fetch_page_of_pledges method to instruct it to get the next page, or get the first page if cursor is None. Then, we can stuck all this into a while loop to handle the pagination. These blocks of text are hard to follow, aren’t they? Here is how the full code would look.

def get_names(all_pledges, names):
    """Function to add names from all_pledges to names list"""
    for pledge in all_pledges:
        patron_id = pledge.relationship('patron').id()
        patron = find_resource_by_type_and_id('user', patron_id)
        names.append(patron..attribute('full_name'))

api_client = patreon.API(CREATOR_ID)
campaign_id = api_client.get_campaigns().data()[0].id()
cursor = None
names = []
while True:
    pledges_response = api_client.fetch_page_of_pledges(
        campaign_id,
        25,
        cursor=cursor,
    )
    get_names(pledges_response.data(), names)
    cursor = api_client.extract_cursor(pledges_response)
    if not cursor:
        break

for name in names:
    print(name)

Enhancements For My Implementation

In my version of this code you will notice a few differences to the code shown here.

  1. I have a hardcoded campaign id instead of using api_client.get_campaigns().data()[0].id(). My campaign id isn’t going to change so doing this set of operations every time would be wasteful.
  2. I also filter my names by reward ID. My lowest reward doesn’t offer a place in credits so I had to add an extra check of the reward id for each patron.

My €10 custom flavour award is not going to use the patreon API. My plan here is to actually check via discord roles – the Patreon bot automatically gives patrons specific roles in my server, so I can do these checks all in Discord. Since this is a discord level reward I feel like I can get away with doing everything on discord rather than do more messing about with the Patreon API.

Conclusion

I hope this code can help you interact with the Patreon API for your own campaigns. If you want to support this kind of content, feel free to check out my patreon.

This entry was posted in Python, tutorial and tagged , , , , . Bookmark the permalink.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.