Note: Due to the recent Reddit API changes, the public bot is no longer invitable.
Automatically detects new posts made on Reddit that match the specified queries and are in the specified subreddits, and sends them to Discord.
This bot primarily uses the Discord API (through JDA) and the Reddit API (through JRAW), in conjuction with a MongoDB for the backend (through the MongoDB Java Driver). The database set up by this project uses hashed and compound indexes when appropriate, ensuring O(log(n))
performance for queries.
This is a rewrite of an old version of this project. Porting over from JavaScript to Java was necessary in order to gain access to multithreading capabilities, which allow for individual servers to run the primary script concurrently with one another. It also allows for each individual server to control /start
and /stop
of their respective scripts.
Here is a pseudocode outline of how the bot works:
- On login, initialize commands to Discord API.
- When a Discord server requests to start script (
/start
):- Begin a new
GuildWorker
thread attributed to the given Discord server. The thread will useUpdateDB
methods for any database updates. The thread also runs the following script:- Every 30 seconds until script told to stop (
/stop
, or server removes Bot while script is in action), do the following:- For all queries attributed to the given server, search each one on Reddit and get results
- For each result from the Reddit search, check database if results has been searched for, and from the current server.
- If yes, do nothing (if the database has the entry, it means it has been searched for from the current server already)
- If no, send the query to Discord, and send the query to the database with an expiration date of two hours
- For each result from the Reddit search, check database if results has been searched for, and from the current server.
- For all queries attributed to the given server, search each one on Reddit and get results
- Every 30 seconds until script told to stop (
- Begin a new
- Constantly listen for other commands/events
- If user runs comamand (
/ping
or/addchannel
or/removechannel
or/addquery [query] [subreddit]
or/removequery [query] [subreddit]
), respond appropriately throughUpdateDB
(if needed) - If Bot is added to new server, add the corresponding server info to the database through
UpdateDB
- If Bot is removed from a server, remove the corresponding server info from the database through
UpdateDB
- If user runs comamand (
- For read/write requests to database, keep operations in sync with
updateRedditLock
andotherLock
.updateRedditLock
is a lock for theupdateReddit(...)
method, whileotherLock
is a lock for all the other read/write methods.- No need for special locks for each method; MongoDB automatically handles it for multiple concurrent operations to a single document, as described here.
/ping
: Replies with pong!/start
: Starts the primary script for detecting new Reddit posts, and posting them on Discord./stop
: Stops running the primary script./addchannel
: Allows the bot to post in the channel in which the command was sent./removechannel
: Revokes the bot's access to post in the channel in which the command was sent./addquery [query] [subreddit]
: Adds a new query (search term, subreddit) to the search list attributed to the respective Discord server, if such an entry does not already exist. (Subreddit is last space separated keyword provided; defaults to "all" if only one space separated keyword provided.)/removequery [query] [subreddit]
: Removes a query (search term, subreddit) from the search list attributed to the respective Discord server, if such an entry does already exist. (Subreddit is last space separated keyword provided; defaults to "all" if only one space separated keyword provided.)
No longer available.
See here for instructions on how to self-host this bot.
- Add POJOs (basically the way to implement schemas for Java MongoDB)
- Use an actual
.config
file or.env
variables (the fakeConfig.java
class doesn't really count)- For whatever reason, the Java boilerplate,
.jar
stuff, and the ubuntu terminal for hosting makes it really hard to set either of the two approaches up
- For whatever reason, the Java boilerplate,