Skip to content

Commit

Permalink
Template v4.0
Browse files Browse the repository at this point in the history
* Now using [`disnake`](https://docs.disnake.dev)
* Added a command that uses buttons *(coinflip)*
* Added a command that uses selection dropdown *(rps)*
* **Every** command is now in slash command **and** normal command (old way with prefix)
    * Make sure to **enable the message intents** for normal commands as it's now a privileged intent.
    * The **slash command** is **above**, the **normal command** is **below**
  • Loading branch information
Krypton committed Nov 27, 2021
1 parent f5039a3 commit bcdc942
Show file tree
Hide file tree
Showing 13 changed files with 980 additions and 284 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ Here is an explanation of what everything is:

| Variable | What it is |
| ------------------------- | ----------------------------------------------------------------------|
| YOUR_BOT_PREFIX_HERE | The prefix you want to use for normal commands |
| YOUR_BOT_TOKEN_HERE | The token of your bot |
| YOUR_BOT_PERMISSIONS_HERE | The permissions integer your bot needs when it gets invited |
| YOUR_APPLICATION_ID_HERE | The application ID of your bot |
| OWNERS | The user ID of all the bot owners |

Expand Down Expand Up @@ -137,7 +139,7 @@ the [tags on this repository](https://github.com/kkrypt0nn/Python-Discord-Bot-Te

## Built With

* [Python 3.9](https://www.python.org/)
* [Python 3.9.9](https://www.python.org/)

## License

Expand Down
13 changes: 11 additions & 2 deletions UPDATES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

Here is the list of all the updates that I made on this template.

### Version 4.0

* Now using [`disnake`](https://docs.disnake.dev)
* Added a command that uses buttons *(coinflip)*
* Added a command that uses selection dropdown *(rps)*
* **Every** command is now in slash command **and** normal command (old way with prefix)
* Make sure to **enable the message intents** for normal commands as it's now a privileged intent.
* The **slash command** is **above**, the **normal command** is **below**

### Version 3.1.1

* Fixed `TypeError: 'NoneType' object is not iterable` for prefix -> Python 3.10
Expand Down Expand Up @@ -65,7 +74,7 @@ Here is the list of all the updates that I made on this template.
### Version 2.4

* Added some fun commands
* Colors are saved in the [config file](config.py) for easier usage
* Colors are saved in the [config file](config.json) for easier usage
* Cogs are now being loaded automatically
* Fixed some typos

Expand All @@ -89,7 +98,7 @@ Here is the list of all the updates that I made on this template.

* Added cogs
* Added f-strings and removed `.format()`
* Created [config file](config.py) for easier setup
* Created [config file](config.json) for easier setup

### Version 1.2

Expand Down
110 changes: 81 additions & 29 deletions bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Description:
This is a template to create your own discord bot in python.
Version: 3.1.1
Version: 4.0
"""

import json
Expand All @@ -12,10 +12,10 @@
import random
import sys

import discord
from discord.ext import tasks
from discord.ext.commands import Bot
from discord_slash import SlashCommand, SlashContext
import disnake
from disnake import ApplicationCommandInteraction
from disnake.ext import tasks, commands
from disnake.ext.commands import Bot

import exceptions

Expand All @@ -28,44 +28,43 @@
"""
Setup bot intents (events restrictions)
For more information about intents, please go to the following websites:
https://discordpy.readthedocs.io/en/latest/intents.html
https://discordpy.readthedocs.io/en/latest/intents.html#privileged-intents
https://docs.disnake.dev/en/latest/intents.html
https://docs.disnake.dev/en/latest/intents.html#privileged-intents
Default Intents:
intents.messages = True
intents.reactions = True
intents.guilds = True
intents.emojis = True
intents.bans = True
intents.guild_typing = False
intents.typing = False
intents.dm_messages = False
intents.dm_reactions = False
intents.dm_typing = False
intents.emojis = True
intents.guild_messages = True
intents.guild_reactions = True
intents.guild_typing = False
intents.guilds = True
intents.integrations = True
intents.invites = True
intents.reactions = True
intents.typing = False
intents.voice_states = False
intents.webhooks = False
Privileged Intents (Needs to be enabled on dev page), please use them only if you need them:
intents.presences = True
intents.members = True
intents.messages = True
intents.presences = True
"""

intents = discord.Intents.default()
intents = disnake.Intents.default()

bot = Bot(command_prefix="", intents=intents) # The command prefix is a required argument, but will never be used
slash = SlashCommand(bot, sync_commands=True)
bot = Bot(command_prefix=config["prefix"], intents=intents)


# The code in this even is executed when the bot is ready
@bot.event
async def on_ready():
print(f"Logged in as {bot.user.name}")
print(f"Discord.py API version: {discord.__version__}")
print(f"disnake API version: {disnake.__version__}")
print(f"Python version: {platform.python_version()}")
print(f"Running on: {platform.system()} {platform.release()} ({os.name})")
print("-------------------")
Expand All @@ -76,7 +75,7 @@ async def on_ready():
@tasks.loop(minutes=1.0)
async def status_task():
statuses = ["with you!", "with Krypton!", "with humans!"]
await bot.change_presence(activity=discord.Game(random.choice(statuses)))
await bot.change_presence(activity=disnake.Game(random.choice(statuses)))


# Removes the default help command of discord.py to be able to create our custom help command.
Expand All @@ -96,35 +95,88 @@ async def status_task():

# The code in this event is executed every time someone sends a message, with or without the prefix
@bot.event
async def on_message(message: discord.Message):
async def on_message(message: disnake.Message):
# Ignores if a command is being executed by a bot or by the bot itself
if message.author == bot.user or message.author.bot:
return
await bot.process_commands(message)


# The code in this event is executed every time a command has been *successfully* executed
# The code in this event is executed every time a slash command has been *successfully* executed
@bot.event
async def on_slash_command(ctx: SlashContext):
full_command_name = ctx.name
split = full_command_name.split(" ")
executed_command = str(split[0])
async def on_slash_command(interaction: ApplicationCommandInteraction):
print(
f"Executed {executed_command} command in {ctx.guild.name} (ID: {ctx.guild.id}) by {ctx.author} (ID: {ctx.author.id})")
f"Executed {interaction.data.name} command in {interaction.guild.name} (ID: {interaction.guild.id}) by {interaction.author} (ID: {interaction.author.id})")


# The code in this event is executed every time a valid commands catches an error
# The code in this event is executed every time a valid slash command catches an error
@bot.event
async def on_slash_command_error(context: SlashContext, error: Exception):
async def on_slash_command_error(interaction: ApplicationCommandInteraction, error: Exception):
if isinstance(error, exceptions.UserBlacklisted):
"""
The code here will only execute if the error is an instance of 'UserBlacklisted', which can occur when using
the @checks.is_owner() check in your command, or you can raise the error by yourself.
'hidden=True' will make so that only the user who execute the command can see the message
"""
embed = disnake.Embed(
title="Error!",
description="You are blacklisted from using the bot.",
color=0xE02B2B
)
print("A blacklisted user tried to execute a command.")
return await interaction.send(embed=embed, ephemeral=True)
elif isinstance(error, commands.errors.MissingPermissions):
embed = disnake.Embed(
title="Error!",
description="You are missing the permission(s) `" + ", ".join(
error.missing_permissions) + "` to execute this command!",
color=0xE02B2B
)
print("A blacklisted user tried to execute a command.")
return await context.send("You are blacklisted from using the bot.", hidden=True)
return await interaction.send(embed=embed, ephemeral=True)
raise error


# The code in this event is executed every time a normal command has been *successfully* executed
@bot.event
async def on_command_completion(ctx):
fullCommandName = ctx.command.qualified_name
split = fullCommandName.split(" ")
executedCommand = str(split[0])
print(
f"Executed {executedCommand} command in {ctx.guild.name} (ID: {ctx.message.guild.id}) by {ctx.message.author} (ID: {ctx.message.author.id})")


# The code in this event is executed every time a normal valid command catches an error
@bot.event
async def on_command_error(context, error):
if isinstance(error, commands.CommandOnCooldown):
minutes, seconds = divmod(error.retry_after, 60)
hours, minutes = divmod(minutes, 60)
hours = hours % 24
embed = disnake.Embed(
title="Hey, please slow down!",
description=f"You can use this command again in {f'{round(hours)} hours' if round(hours) > 0 else ''} {f'{round(minutes)} minutes' if round(minutes) > 0 else ''} {f'{round(seconds)} seconds' if round(seconds) > 0 else ''}.",
color=0xE02B2B
)
await context.send(embed=embed)
elif isinstance(error, commands.MissingPermissions):
embed = disnake.Embed(
title="Error!",
description="You are missing the permission(s) `" + ", ".join(
error.missing_permissions) + "` to execute this command!",
color=0xE02B2B
)
await context.send(embed=embed)
elif isinstance(error, commands.MissingRequiredArgument):
embed = disnake.Embed(
title="Error!",
description=str(error).capitalize(),
# We need to capitalize because the command arguments have no capital letter in the code.
color=0xE02B2B
)
await context.send(embed=embed)
raise error


Expand Down
Loading

0 comments on commit bcdc942

Please sign in to comment.