Purpose of this plugin
This plugin does several things:
Allows you to power a Discord bot using your Discourse server to do stuff to link the two systems. Fork this repo and expand it with simple Ruby to create all kinds of bot functionality.
Existing functionality to serve as examples and useful utility:
- Provides some two-way auto posting of content that meet some criteria.
- Command to copy messages ad hoc to Discourse
- Command to sync group membership to role membership of your Discord server with your Discourse instance.
The plugin provides an extensible skeleton upon which you could build some additional features. PRs for generally useful additions welcome.
these aren’t the two sync commands, just an illustration of bot interaction that is possible. the second command in the screenshot was deprecated during development
It is necessarily complex to set up, but great for fans of both systems who are keen to put the time in to understand how each system works, at least on a functional and conceptual level. You need to understand some of the fundamentals of how Discourse and Discord user management works to get the best out of this plugin.
There are four commands:
To check if the bot is responding, just type “Ping!” and the bot should respond with “ : Pong!” - marvellous, eh? (this is a bit of a meme btw!)
!disckick <min_trust_level: default 2>
Typing this will kick any user that exists on your Discourse but at a Trust Level below your supplied value. The default if you don’t supply a value is 2.
!discsync <clean up: default false, min_visibility: default 0, include automated groups: default false>
This command will attempt to copy over all groups into Roles on Discord which match provided criteria (or defaults if not provided). It will then attempt to populate the roles as per the Group membership on Discourse. It’s a one way sync only. No Discourse data is ever changed.
!disccopy <number_of_messages> <optional_target_category_name> <optional_target_topic_name>
Allows you to copy Discord message history to your Discourse instance from within Discord chat. This can cope with 1,000’s of messages in one go (but for that volume will take time).
Two way communication
Here are the settings
- You can designate an Announcements Channel on Discord in the plugin settings.
- You can now type into the assigned Discord Announcements Channel and this will post your message to your assigned Discourse Topic in the plugin settings
- You can set up a list of Categories in Discourse to post to the Announcements channel on your Discord if someone Posts there or adds a new Topic (either or both).
- Automated per message chat copy, by channel to any identically named Category on Discourse: if the channel name matches the Category name, it will copy the message into Discourse
In addition I’ve added a new file to manage Discord events supported by the
discordrb API, with Announcements logic being the first example (feel free to develop new ones and PR if of general use to the community).
NB For any message copied into Discourse from Discord, the User will show correctly if that user has logged into Discourse using the Discord login (So Discord Bot is able to match the users).
State of this plugin
This is a complex plugin to set-up. That was pretty unavoidable.
However, it’s child’s-play to use once it’s all up and running.
Consider the code as currently in Beta. It’s been tested, even in Production, but likely to contain bugs. I recommend testing this first on a fresh Discord server before applying it to your “Production” main Discord server, unless you are just starting out.
Any bugs are much more likely to upset your Discord instance than your Discourse instance, because there are no changes made to Discourse. However, I’ve written it in a way that means most things are recoverable and you can merely repeat something to fix an issue usually. Discourse is used as a master for membership and group information and this data is used to update membership and Roles on your Discord server.
- a Discord server on which you are Admin
- a Discord App (see below)
- a Discord Bot (see below)
- ssh root access to your Discourse server
- updates to app.yml to install the plugin
- All users of your Discourse will need to login using Discord OAuth login that will appear on your login page once the plugin is installed.
Go here and create an app:
Hit “New Application”
You will need to create a Bot and it will look something like this (leave it not ‘public’):
You will need to authorise the bot in the browser, see Discord Developer Portal
Once the bot is set up, copy the Token. You will need to enter that into Discourse later.
You need just one plugin for this now that Discord Social Login is now native to Discourse core (wooo )
Then at the prompt
./launcher rebuild app as usual.
This should work, np.
You may get some console and log errors indicating a failure of the bot on first build as you’ve not yet entered the bot’s credentials in the front end of Discourse’s settings yet. (more gracefully handling this is a todo, I’ll delete this bit when that gets done). It will do no harm though and Discourse itself will work normally.
Once in your Discourse admin area, go to Plugin Settings and fill these:
You will get the IDs from Discord interface. You will need to activate Developer Mode to allow you to copy these IDs. In Discord, go to your Settings - > Appearance - > ADVANCED and enable Developer Mode:
You can then get ID’s on from the interface, e.g.:
You will also need to fill in the Discord OAuth Settings. The Client ID and Secret are from your very same Discord App.
Once you’ve set these, go back to your root prompt in linux and type:
./launcher restart app
If you’ve set up your Discord and Discourse servers correctly, you should see the bot join the server.
If ever the bot falls over (it will go offline) you will need to do the same thing again to bring it back. Improved independence of the bot from the Discourse core server is a to do. That said, I’ve run a bot in Production for a long while and it’s yet to fall over.
If you have an idea for another command that leverages the link between Discourse and Discord that you believe would be useful to the wider community let me know in the replies and we can look at the potential to implement that. NB this bot is not intended to perform tasks outside the scope of Discourse.
The main goal of this plugin was to allow the user to create a bot on their Discord that would be powered by their Discourse server and be able to carry out some basic membership management functions. It also provides a foundation for any additional bot-like interactions between the two systems for the future. Part of the motivation for using bots is that they are just plain fun.
Bot commands are ad hoc by their very nature.
The bot will start up an instance of itself if you go into a rails console session on the server. This will cause the bot to appear to respond twice (but in fact there are two bots now). In the rails console simply stop the additional bot by typing:
The Robot is a bit chatty during ‘online’ Discourse upgrades as keeps getting reactivated during the upgrade process. This comes back to working out a good way to running the bot in a separate, managed process instead of a thread branched off the webserver. I believe this is all harmless though, and if the bots output is only to your admin channel on Discord, do you really care?
Currently, the bot will spawn a copy of itself if you enter the rails console. Be aware this means it will process any events twice, so my suggestion is keep your time in the console to a minimum. PR welcome for solutions to solve this.
There are several backers to thank for this plugin which took me a big while to get to this stage inc. @Wedgebert, @FoohonPie. Thanks to Jeff for his generous contribution. Thanks to @angus for all the encouragement and dealing with the financial support.
The plugin was inspired by the work @Watercolor_Games did at an earlier stage and relies on the discord OAuth plugin built by @featheredtoast
The plugin relies on the semi-official Discord-backed
discordrb Ruby library and the fantastic work Discord team has done to make their system accessible. Thanks to @Falco for helping me with a dependency in an extremely responsive manner.
Additionally, of course, this would not be possible without the amazing plugin ecosystem of Discourse (woo!)
State of these instructions
They will be improved in time and I welcome feedback. There are areas that are bound to be unclear.