Zupie is a multipurpose discord.py bot.
- What is Zupie
- Questions
- Self Hosting
- Prerequisites
- Installing the source
- Setup
- Setup:config.py
- Setup:.env
- Setup: Module Installation
- Running the bot
- Setting up a virtual environment - Planned Plugins
- Contributing
- Issues & Bugs
- Pull Requests
- Pull Requests: Header
- Pull Requests: Body
- Pull Requests: Footer
- Development Environment - Code of Conduct
- License
Have a question? Please avoid opening issues for general questions. Instead, it is much better to ask your question on our Discord server.
This self-hosting guide requires you to have some basic knowledge about command line, Python, and Discord bots. We do not provide any official support for self-hosting.
In order to run Zupie, you will need to install the following software.
You may also want to set up a virtual environment so that Zupies requiremnts don't mess with your base enviroment.
Please fork this repository so that you can make pull requests. Then, clone your fork.
git clone https://github.com/<github-username>/zupie.git
Sometimes you may want to merge changes from the upstream repository to your fork.
git checkout master
git pull https://github.com/SnowyJaguar/zupie.git master
Configuration is done through a config.py
and .env
file.
You should make a copy of example.env
and rename it to .env
. All fields marked withFILL
must be filled in with the type specfied below:
TOKEN
: Your bots token as found on the Discord Developer PortalCLIENT_ID
: Your bot client ID as found on the Discord Developer PortalCLIENT_SECRET
: Your bot client secret as found on the Discord Developer PortalDEFAULT_GUILD
: The ID of your bots default guild / the ID of the only guild it's inDEFAULT_PREFIX
: The prefix that will be used for commandsSTATUS_WEBHOOK
: The URL of the webhook your bot will use to send status updates (shard connections/disconnections/restarts)DESCRIPTION
: The description of your botJOIN_CHANNEL
: The URL of the webhook your bot will use to send it's guild join/leave messagesADMIN_CHANNEL
: The URL of the webhook your bot will use to send it's admin logs (the messages that are sent when a owner/admin usees a admin/owner command)POSTGRES_DATABASE
: The name of the postgres database your bot will usePOSTGRES_USERNAME
: The name of the user your bot will use to connect to the postgres databasePOSTGRES_PASSWORD
: The password of the user your bot will use to connect to the postgres databasePOSTGRES_HOST
: The host addresses of your databse, if it's running on your local machine this will belocalhost
The network port of your postgres database, postgres defualts to5432
.-REDIS_HOST
: The host of the redis database your bot will useREDIS_PORT
: The port of the redis database your bot will useREDIS_PASSWORD
: The password of the redis database your bot will useMONGO_USERNAME
: The name of the user your bot will use to connect to the mongo databaseMONGO_PASSWORD
: The password of the user your bot will use to connect to the mongo databaseMONGO_CLUSTER
: The name of the cluster your bot will use to connect to the mongo databaseMONGO_DATABASE
: The name of the mongo database your bot will use
You should make a copy of config-example.py
and rename it to config.py
. All fields marked withFILL
must be filled in with the type specfied below:
activity
: The activity your bot will show on it's profilebackend : Owners
: The ID(s) of the bots owners, these members have access to owner specfic commandsbackend : Admins
: The ID(s) of the bots admins, these members have access to admin specfic commands
Zupie utilises discord.py and several other modules to function properly. The list of modules can be found in requirements.txt
and you can install them with the following command.
pip install -r requirements.txt
Congratulations! You have set up everything and you can finally have the bot up and running. Use the following command to run.
<Your source directory>python main.py
This is useful if you want to run a variety of python projects on a machine but not have version conflicts. I highly recommend doing this even if you only have one project, I didn't understand the appeal when I started using python but after a while I started seeeing the benefits. Go to your project’s working directory:
$ cd your-bot-source-directory
$ python3 -m venv env
Activate the virtual environment:
On Linux
$ source env/bin/activate
On Windows
$ env\Scripts\activate.bat
Use pip like usual:
$ (env) <Your source directory>pip install -r requirements.txt
Redis is not officially supported on Windows. However, you can install Redis on Windows by using WSL (Windows Subsystem for Linux). Read this to learn more about setting up a Linux enviroment using WSL.
Once you have a Linux enviroment, you can install Redis and Redis-Py with the commands found here or with the following commands.
sudo apt-add-repository ppa:redislabs/redis
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install redis-server
sudo service redis-server start
You can check that your redis server is running by using the Redis CLI
redis-cli
127.0.0.1:6379> ping
PONG
The dashboard will allow users to control almost everyhting about the bot from outside of discord. The dashboard will be written in Python using the FastAPI library.
This will let users create embeds json which will be stored in the db for later use in other plugins. This will mostly take the form of modal/form responses for the discord side of things but will also accept raw json input if someone has built a embed on a different platform and wants to import it. The Dashbaord will also include a page which connects to the embed builder so users can create their embeds outside of discord if they prefer.
This feature is going to be similar to most starboards in other bots. It's a feature idea that I really quite like so will aim to include in Zupie. I attempted a starboard on my private bot howver it had a few probblems that I just never had time to fix, this is the code if anyones intrestedin taking a look
@commands.Cog.listener()
async def on_raw_reaction_add(self, payload):
data = await self.bot.get_data(payload.guild_id) # Accessing data from main table
starboard = self.bot.get_channel(data[27]) # Pulling the starboard ID from main table and making it a channel object
stars = await self.bot.get_star(payload.message_id) # Accessing from the starboard table
#star_reactions = ["⭐", ":questionable_star:", ":star_struck:", ":star2:", ":StarPiece:", ":purple_star:"] # Listing the approved reactions to watch for
reactions_count = stars[3] # Inilizing a reaction count
with starboard.typing():
for star in self.bot.config.star_reactions: # Checking each option in the approved reactions
if payload.emoji.name == star: # Checking if the reaction used is in the approved list
stared_message = await self.bot.get_channel(payload.channel_id).fetch_message(payload.message_id) # Getting the the original msg as a message object
if not stared_message.author.bot and payload.member.id != stared_message.author.id: # Checking the person adding the reaction isn't a bot and/or that they aren't the person who sent the orginal message.
reactions_count = stars[1] + 1
# Declaring the Embed to post in the starboard channel
embed = discord.Embed(title = f"Starred message", description = f"{stared_message.content}" or "See attachment", colour = stared_message.author.colour, url = stared_message.jump_url, timestamp = datetime.datetime.utcnow())
if len(stared_message.attachments): # Checking if the orignal message contained a image
embed.set_image(url = stared_message.attachments[0].url) # Add the orginal msgs image to the embed
embed.set_author(name = stared_message.author, icon_url = stared_message.author.avatar_url)
if stared_message.id not in stars[0]: # Checking if the orignal message ID is NOT stored in the db
post = await starboard.send(embed = embed, content = f"Stars: {str(reactions_count)}") # Sending the embed to the starboard
async with self.bot.pool.acquire() as conn:
await conn.execute("UPDATE starboard SET Stared=$1 WHERE Post=$2, Count=$3", stared_message.id, post.id, reactions_count)
else:
temp = discord.Object(stars[2])
post = await self.bot.get_channel(starboard.id).fetch_message(temp) # Getting the the post msg as a message object
async with self.bot.pool.acquire() as conn:
await conn.execute("UPDATE starboard SET Count=$1", reactions_count)
await post.edit(embed = embed, content = f"Stars: {str(reactions_count)}")
else:
await stared_message.remove_reaction(payload.emoji, payload.member)
I have this feature on my private bot, it works well so I will probably port it over but I'm still on the fence as this will require Zupie having the privledge message intent which I'm sure compllelty sure I want.
I aim to add a logging plugin to Zupie which will log message deletions/edits, member join/leaves/updates, bot join/leaves etc
Note: All logs will be sent via webhooks for better performance, I don't want to be having to do a API call to fetch a log channel via ID each time I send a log and this also gives the user more control on where they want the logs sent as they can just change the webhook destination channel in their server settings.
I'm still on the fence on a full pledged moderation plugin howver the bot will most likley include ban
, kick
, warn
and timeout
commands.
This is a sub feature of the moderation plugin which I have working on my private bot so I'll most likley port this over, maybe with a few tweaks.
There won't be a music or leveling plugin in Zupie, at least not for while and probarbly not written by me. I think there's more than enough music/leveling bots out there even after Rythm and Grrovy shut down and I really don't think the community needs another one. I've also seen bots have instability issues with music plugins (looking at Mee6 & Carl-bot). If a music plugin was to be added then i think I would want it to be a premium or patron feature to reduce the amount of potential users.
A reminders plugin is definatly somehting I am intreted in adding to Zupie, I just need to figure out a way to process them that won't purge them if the bot gets restarted however safeguarding the reminders won't be added to the plugin immediately.
I'm intrested in adding in a feature that lets server owners/admins/mods create custom commands (tags) for their servers but I'm not sure how I'm going to implement such a feature. I had a look at how Carl-bot is doing it using JonSnowbd's or PhenoM4n4n's TagScriptEngine and think one of those or somehting like them might be the way to go. There's also RoboDanny's tags cog which I think is a good place to start and would provide a good basic custom command (tag) system.
I am definatly intrested in adding some paid for features. I'm not looking to lock entire plugins behind a paywall (other than a music one) but rather premium will give servers addional parts of existing plugins like one or two extra starboards and counting channels and it will give patrons extra features on any server they share with the bot (not sure what those might be yet).
I want to make legacy equivilants of all of the commands so that if someone doesn't want to use slash commands then they don't have to. The bots prefix is it's ping and I probarbly won't be adding a specfic prefix like !
or ?
.
Don't think this really needs a description as the names pretty obvius on what this is for. I also need to add in support for the logging
module.
I actually need to add tables to the databse for all this data, I'm just not sure how I'm going to lay it out so if anyones got any schema suggestions let me know.
Working on your first Pull Request? You can learn how from this free series How to Contribute to an Open Source Project on GitHub
Hi, thanks for your interest in contributing to Zupie! We'd love your help to make Zupie even better than it is today. there are many ways you can contribute to this project:
- Submitting bugs and feature requests
- Reviewing changes
- Contribute directly to the code base
- Sponsoring the project (Please let SbowyJaguar#1034 know on Discord)
For more information on contributing, please see the contributing guidelines.
The issue tracker here is only for bug reports and feature requests. Please do not use it to ask a question. Instead, ask it on our Discord server.
We track bugs and features using the GitHub issue tracker. If you come across any bugs or have feature suggestions, please let us know by submitting an issue, or even better, making a pull request.
Please follow these guidelines related to submitting a pull request.
Please follow our commit conventions below. For subsequent commits to a pull request, it is okay not to follow them, because they will be eventually squashed.
We follow the Conventional Commits to allow for more readable messages in the commit history.
The commit message must follow this format:
<type>(<scope>): <description>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
Additionally, the maximum length of each line must not exceed 72 characters.
The header is mandatory.
The type must be one of the following, the scope is optional and can be decided at your discretion.
build
: Changes to the build system or dependencies.ci
: Changes to our CI configuration files and scripts.chore
: Miscellaneous change.docs
: Changes only the documentation.feat
: Implements a new feature.fix
: Fixes an existing bug.perf
: Improves the performance of the code.refactor
: Changes to code neither fixes a bug nor adds a feature.style
: Changes to code that do not affect its functionality.test
: Adding missing tests or correcting existing tests.
The body is optional and can contain additional information, such as motivation for the commit.
The footer is optional and should contain any information about breaking changes. It is also the place to reference GitHub issues that the commit closes.
Breaking changes should start with BREAKING CHANGE:
with a space or two newlines. The rest of the
commit message is then used for explaining the change.
To set up your development environment, follow the self-hosting guide here. When you successfully self-host the bot, your development environment should more or less be ready.
This project is licensed under the BSD 3-Clause License