Configuring Patreon integration with Discourse


(Rafael dos Santos Silva) #1

Discourse Patreon Installation

First of all you need a working Discourse install with our official Patreon plugin.

:warning: During all the guide, swap with your forum domain.

Getting your Patreon Credentials

You can visit the Patreon Client & API Keys page and fill all the required fields. Use as the Redirect URIs.

Click on Create Client.
When the app appears on the page, click the arrow to expand the content:

If everything is successful you will receive a Client ID, a Client Secret and 2 tokens:

Save this token because you will need those later.

Configuring Discourse

Visit and enable and fill all the settings.

  • Note that you must fill Patreon creator discourse username only if you are using Patreon creator account to login in Discourse through “Login with Patreon” feature. In that case it is the value of local Discourse account username. Else you can skip it.
    It is needed because Patreon creator access token will be changed whenever you login.
  • Continuing this guide you will also find the Patreon webhook secret

Running the first sync

Now that everything is set up, go to and you will get a screen like this:

Let’s click on the Update Patreon Data button so we get the first batch of data from Patreon. You will never need to do this again, because the plugin runs 4 times a day in the background for you.

Clicking on the button starts a process that takes a little while (usually 30 seconds) and if everything works out you will get a message like this:

After clicking OK you will refresh the page, but now all your Patreon data will be avaliable.

You can select the automatically created patrons group on the left and $0 - All Patrons on the right and after that click on the save button. Now click on the Sync Groups button again.


Now, every Patreon has a group membership on the patrons group of you forum. This includes a group flair and a badge too!

Additional Stuff

Edit the badge and the group description with links to your Patreon page so it’s easier for new members to discover how to achieve then.


If you want to react faster to new Patrons, changes in tier and stuff like that, you can trigger a new sync between Discourse and Patreon on every change

To do that first visit Patreon WebHooks Page and create a new webhook pointing to

The result will be similar to this:

If necessary, switch to Off the triggers that do not interest you, then click on Send test to see this window

Click again on Send test

If the test fails you will see Status code: 403 (you will have to double check the configuration)
If the test is passed you will see Status code: 200.

Copy the webhook secret and paste it in patreon_webhook_secret setting.

That’s it.

Discourse Patreon Integration
Integrating Discourse With Patreon
Integrating Discourse With Patreon
Discourse on Azure Container Service?
Discourse Hosting - Digital Ocean vs Linode
(ampburner) #2

Awesome guys!
It took me a while but I have things running at


Where does the group become visible to users?
I added a link “support us” to the main menu via a custom javascript hack. does the trick for me. Am I missing something though?

Thanks again guys. I’m sorry for the radio silence on my end :frowning: better late than never :slight_smile:

edit - code sample because I figure people might want to use this

        activate: function() {

function insertNavigationConditionally()
    if(jQuery("#support-hf-li").length <= 0){
        jQuery('ul.nav li:last').after('<li id="support-hf-li" class="ember-view" title="support Hitman forum"><a href="/groups/patrons/">Support Hitmanforum</a></li>'); 


(Rafael dos Santos Silva) #3

Hi @ampburner,

There is the Groups entry on the hamburger menu, and the Patreon badge that will be on patrons user cards. So every time they post users get reminded about it.

Anyway, the link you have on the top should probably stay.

(Thorbjørn Lindeijer) #4

Great feature, thanks!

Since Patreon has actually changed their logo in the meantime and the transparent parts of the P tend to make it look somewhat ugly, I made the following image based on the new Patreon logo which I think works very well:


For forums using other colors, one of the following may fit better:

(Jeff Atwood) #5

Hey those look great – thanks! I am warming up to the new branding.

(Daniela) #6

Sorry guys, after the last upgrade to Beta 13 a new setting has been added:

From what I understand Patreon’s webhook page has been modified and old webhooks are no longer working but you have to create a new one. Then you need to copy/paste the new secret in the patreon webhook secret. Is it correct?

(Jeff Atwood) #7

Sue @techapj can follow up with you on that.

(Arpit Jalan) #8

This issue was reported to us by a customer and we added a new site setting patreon webhook secret to fill in the webhook secret. From what I understood, all the Patreon webhooks now have individual secret, so your old webhook must have a secret generated and simply filling that in patreon webhook secret should work?

Updated the first post to reflect the changes.

(Daniela) #9

I think so, but because the patreon client id was the same as the patreon webhook secret I was unsure about how to proceed. In doubt, I deleted the old webhook, I created a new one (with a new secret), tested it and added it to discourse.

In my case the old webhooks were 3, with 3 secret equal to the client id (before the change you had to associate a webhook with each group).
Now it seems that there is no longer a group association, and I can just create one webhook for all groups.


Great. I’ve deleted the old webhook and created a new one.

BTW… i’ve never been able to get the Patreon login to work… I’ve followed the instructions multiple times.

Always gets here:

But never beyond:

Error Logs:

Can be found here…

Message (3 copies reported)
(patreon) Authentication failure! invalid_credentials: OAuth2::Error, access_denied: 
{"error": "access_denied"}

/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/logster-1.2.7/lib/logster/logger.rb:93:in `add_with_opts'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/logster-1.2.7/lib/logster/logger.rb:50:in `add'
/usr/local/lib/ruby/2.4.0/logger.rb:543:in `error'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:161:in `log'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:473:in `fail!'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-oauth2-1.4.0/lib/omniauth/strategies/oauth2.rb:78:in `rescue in callback_phase'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-oauth2-1.4.0/lib/omniauth/strategies/oauth2.rb:67:in `callback_phase'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:230:in `callback_call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:187:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:167:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:189:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:167:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:189:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:167:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:189:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:167:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:189:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:167:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:189:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:167:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:189:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/strategy.rb:167:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/omniauth-1.6.1/lib/omniauth/builder.rb:63:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/conditional_get.rb:25:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/head.rb:12:in `call'
/var/www/discourse/lib/middleware/anonymous_cache.rb:147:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/session/abstract/id.rb:232:in `context'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/session/abstract/id.rb:226:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/cookies.rb:613:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/callbacks.rb:26:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/callbacks.rb:97:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/callbacks.rb:24:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/debug_exceptions.rb:59:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/logster-1.2.7/lib/logster/middleware/reporter.rb:31:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/rack/logger.rb:36:in `call_app'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/rack/logger.rb:26:in `call'
/var/www/discourse/config/initializers/100-quiet_logger.rb:16:in `call'
/var/www/discourse/config/initializers/100-silence_logger.rb:29:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/request_id.rb:25:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/method_override.rb:22:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/runtime.rb:22:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/executor.rb:12:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/actionpack-5.1.4/lib/action_dispatch/middleware/static.rb:125:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/sendfile.rb:111:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-mini-profiler-0.10.5/lib/mini_profiler/profiler.rb:171:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/message_bus-2.0.8/lib/message_bus/rack/middleware.rb:63:in `call'
/var/www/discourse/lib/middleware/request_tracker.rb:110:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/engine.rb:522:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/railtie.rb:185:in `public_send'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/railtie.rb:185:in `method_missing'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/urlmap.rb:68:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/urlmap.rb:53:in `each'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/rack-2.0.3/lib/rack/urlmap.rb:53:in `call'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_server.rb:606:in `process_client'
/var/www/discourse/lib/scheduler/defer.rb:85:in `process_client'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_server.rb:702:in `worker_loop'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_server.rb:549:in `spawn_missing_workers'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/unicorn-5.3.0/lib/unicorn/http_server.rb:142:in `start'
/var/www/discourse/vendor/bundle/ruby/2.4.0/gems/unicorn-5.3.0/bin/unicorn:126:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.4.0/bin/unicorn:23:in `load'
/var/www/discourse/vendor/bundle/ruby/2.4.0/bin/unicorn:23:in `<main>'

hostname	highCPU-webonly
process_id	[4954, 4706, 5331]
application_version	aa134294cc1ffd4967a47ae8823e11aeefd97c89
REQUEST_URI	[/auth/patreon/callback?code=mncA41GgmeeRGNNv0WVIAQ90M3Ejl1&state=3ee0b92978575c2d0f8ce3eccf137601032349c519fb678a, /auth/patreon/callback?code=hTrFVSrgmS8UKQUf7fnDxGWDEd0GG6&state=cb205aeb9b081f6cd81450603bfbc2ab948e194d1cb4726c, /auth/patreon/callback?code=UE6H4TqQBpWykc0ACZt4a2YJqpWix4&state=df67afda1da79a06f6685a18996dc4f3f8f39288a452651d]
HTTP_USER_AGENT	Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
HTTP_ACCEPT	text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
code	[mncA41GgmeeRGNNv0WVIAQ90M3Ejl1, hTrFVSrgmS8UKQUf7fnDxGWDEd0GG6, UE6H4TqQBpWykc0ACZt4a2YJqpWix4]
state	[3ee0b92978575c2d0f8ce3eccf137601032349c519fb678a, cb205aeb9b081f6cd81450603bfbc2ab948e194d1cb4726c, df67afda1da79a06f6685a18996dc4f3f8f39288a452651d]

(Daniela) #11

My patreon login still works, but I have enabled it before all the recent changes introduced on patreon.

In any case, you should check the discourse logs and see what errors come out.

(Evan Bourcier) #12

Hey guys - I believe I’ve followed all the steps properly so far, but when I go to sync data on the plugin page nothing happens. I’ve double checked my tokens, unsure what else I could be missing. I’m currently on a trial, but I have a 2000 member community I’m attempting to move to a private discourse using Patreon, so any help is much appreciated!

(Evan Bourcier) #13

“Update Patreon Data etc” does nothing currently, any ideas?

(Rafael dos Santos Silva) #14

We pushed a fix in the last hours, please try updating.

If the error persist, check /logs and paste the error here.

(Daniela) #15

I have just update all because I saw that new patrons were not added to their respective groups.
Eventually I checked the settings on Patreon and I found out that tokens (Access + Refresh) had changed, but Discourse did not notice it.
Then on sidekiq I started the triggers Jobs::PatreonSyncPatronsToGroups and Jobs::PatreonUpdateTokens and everything started to work again.

Question: does this job (Jobs::PatreonUpdateTokens) runs only when the tokens are manually changed to Discourse?

Patreon Plugin Not Updating
(Vinoth Kannan) #16

Hi @Trash,

Currently I am working on this workflow only. I will post the updates soon after I finish the checking.

(Vinoth Kannan) #17

@Trash It looks like you are not running the latest version of the plugin. The fix for your issue is already updated in official repo 10 hours ago. Else please post your log details as @falco requested.


Tokens are valid for up to one month after they are issued

As per the documentation from Patreon we keep refreshing it once in 7 days only.

(Daniela) #18

The plugin, as well as the site, was updated.

After the update I triggered the job PatreonSyncPatronsToGroups manually without result.
After that, I checked the setting on Patreon and I see the new tokens.
At that point I changed the tokens manually (about 30 mins after the rebuild, because I was fixing some problems on the dark theme).
I checked again sidekiq and I have seen this Jobs::PatreonUpdateTokens. As I had seen it would start after 6 days, I run it manually and then I run again Jobs::PatreonSyncPatronsToGroups.
Then I checked one of the patrons who were not in the group and saw that he was immediately added

These are the steps I did.

(Vinoth Kannan) #19

I guess your plugins get updated above and you triggered the jobs manually and everything working now. Is it?

(Daniela) #20

Generally I update all via GUI, but today we updated via SSH because there was also a docker_manager update.
But yes, after the manual trigger all is working now.