Skip to content

Commit 429cfd1

Browse files
committed
Template v3.0
**Now using slash commands**
1 parent f1ca373 commit 429cfd1

File tree

10 files changed

+430
-239
lines changed

10 files changed

+430
-239
lines changed

README.md

+11
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ All the updates of the template are available [here](UPDATES.md).
3939

4040
## Disclaimer
4141

42+
Slash commands can take **some hours** to get registered on guilds, so if you want to test a command you should use
43+
the `guild_ids` parameter in the command decorator so that it gets registered instantly. Example:
44+
45+
```py
46+
@cog_ext.cog_slash(
47+
name="command",
48+
description="Command description",
49+
guild_ids=[GUILD_ID1, GUILD_ID2] # These should be testing guild(s) ID, as always: an integer.
50+
)
51+
```
52+
4253
When using the template you confirm that you have read the [license](LICENSE.md) and comprehend that I can take down
4354
your repository if you do not meet these requirements.
4455

UPDATES.md

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

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

5+
### Version 3.0
6+
7+
**Now using slash commands**
8+
59
### Version 2.8
610

711
* Blacklisted users are now **saved** in the file

bot.py

+7-36
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Description:
44
This is a template to create your own discord bot in python.
55
6-
Version: 2.8
6+
Version: 3.0
77
"""
88

99
import json
@@ -13,8 +13,9 @@
1313
import sys
1414

1515
import discord
16-
from discord.ext import commands, tasks
16+
from discord.ext import tasks
1717
from discord.ext.commands import Bot
18+
from discord_slash import SlashCommand, SlashContext
1819

1920
if not os.path.isfile("config.json"):
2021
sys.exit("'config.json' not found! Please add it and try again.")
@@ -55,6 +56,7 @@
5556
intents = discord.Intents.default()
5657

5758
bot = Bot(command_prefix=config["bot_prefix"], intents=intents)
59+
slash = SlashCommand(bot, sync_commands=True)
5860

5961

6062
# The code in this even is executed when the bot is ready
@@ -96,53 +98,22 @@ async def on_message(message):
9698
# Ignores if a command is being executed by a bot or by the bot itself
9799
if message.author == bot.user or message.author.bot:
98100
return
99-
# Ignores if a command is being executed by a blacklisted user
100-
with open("blacklist.json") as file:
101-
blacklist = json.load(file)
102-
if message.author.id in blacklist["ids"]:
103-
return
104101
await bot.process_commands(message)
105102

106103

107104
# The code in this event is executed every time a command has been *successfully* executed
108105
@bot.event
109-
async def on_command_completion(ctx):
110-
fullCommandName = ctx.command.qualified_name
106+
async def on_slash_command(ctx: SlashContext):
107+
fullCommandName = ctx.name
111108
split = fullCommandName.split(" ")
112109
executedCommand = str(split[0])
113110
print(
114-
f"Executed {executedCommand} command in {ctx.guild.name} (ID: {ctx.message.guild.id}) by {ctx.message.author} (ID: {ctx.message.author.id})")
111+
f"Executed {executedCommand} command in {ctx.guild.name} (ID: {ctx.guild.id}) by {ctx.author} (ID: {ctx.author.id})")
115112

116113

117114
# The code in this event is executed every time a valid commands catches an error
118115
@bot.event
119116
async def on_command_error(context, error):
120-
if isinstance(error, commands.CommandOnCooldown):
121-
minutes, seconds = divmod(error.retry_after, 60)
122-
hours, minutes = divmod(minutes, 60)
123-
hours = hours % 24
124-
embed = discord.Embed(
125-
title="Hey, please slow down!",
126-
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 ''}.",
127-
color=0xE02B2B
128-
)
129-
await context.send(embed=embed)
130-
elif isinstance(error, commands.MissingPermissions):
131-
embed = discord.Embed(
132-
title="Error!",
133-
description="You are missing the permission `" + ", ".join(
134-
error.missing_perms) + "` to execute this command!",
135-
color=0xE02B2B
136-
)
137-
await context.send(embed=embed)
138-
elif isinstance(error, commands.MissingRequiredArgument):
139-
embed = discord.Embed(
140-
title="Error!",
141-
description=str(error).capitalize(),
142-
# We need to capitalize because the command arguments have no capital letter in the code.
143-
color=0xE02B2B
144-
)
145-
await context.send(embed=embed)
146117
raise error
147118

148119

cogs/fun.py

+15-79
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,17 @@
33
Description:
44
This is a template to create your own discord bot in python.
55
6-
Version: 2.7
6+
Version: 3.0
77
"""
88

9-
import asyncio
109
import json
1110
import os
12-
import random
1311
import sys
1412

1513
import aiohttp
1614
import discord
1715
from discord.ext import commands
18-
from discord.ext.commands import BucketType
16+
from discord_slash import cog_ext, SlashContext
1917

2018
if not os.path.isfile("config.json"):
2119
sys.exit("'config.json' not found! Please add it and try again.")
@@ -28,24 +26,21 @@ class Fun(commands.Cog, name="fun"):
2826
def __init__(self, bot):
2927
self.bot = bot
3028

31-
"""
32-
Why 1 and 86400?
33-
-> Because the user should be able to use the command *once* every *86400* seconds
34-
35-
Why BucketType.user?
36-
-> Because the cool down only affects the current user, if you want other types of cool downs, here are they:
37-
- BucketType.default for a global basis.
38-
- BucketType.user for a per-user basis.
39-
- BucketType.server for a per-server basis.
40-
- BucketType.channel for a per-channel basis.
41-
"""
42-
43-
@commands.command(name="dailyfact")
44-
@commands.cooldown(1, 86400, BucketType.user)
45-
async def dailyfact(self, context):
29+
@cog_ext.cog_slash(
30+
name="randomfact",
31+
description="Get a random fact."
32+
)
33+
async def randomfact(self, context: SlashContext):
4634
"""
47-
Get a daily fact, command can only be ran once every day per user.
35+
Get a random fact.
4836
"""
37+
38+
# This is, for now, only temporary
39+
with open("blacklist.json") as file:
40+
blacklist = json.load(file)
41+
if context.author.id in blacklist["ids"]:
42+
return
43+
4944
# This will prevent your bot from stopping everything when doing a web request - see: https://discordpy.readthedocs.io/en/stable/faq.html#how-do-i-make-a-web-request
5045
async with aiohttp.ClientSession() as session:
5146
async with session.get("https://uselessfacts.jsph.pl/random.json?language=en") as request:
@@ -60,65 +55,6 @@ async def dailyfact(self, context):
6055
color=0xE02B2B
6156
)
6257
await context.send(embed=embed)
63-
# We need to reset the cool down since the user didn't got his daily fact.
64-
self.dailyfact.reset_cooldown(context)
65-
66-
@commands.command(name="rps")
67-
async def rock_paper_scissors(self, context):
68-
choices = {
69-
0: "rock",
70-
1: "paper",
71-
2: "scissors"
72-
}
73-
reactions = {
74-
"🪨": 0,
75-
"🧻": 1,
76-
"✂": 2
77-
}
78-
embed = discord.Embed(title="Please choose", color=0xF59E42)
79-
embed.set_author(name=context.author.display_name, icon_url=context.author.avatar_url)
80-
choose_message = await context.send(embed=embed)
81-
for emoji in reactions:
82-
await choose_message.add_reaction(emoji)
83-
84-
def check(reaction, user):
85-
return user == context.message.author and str(reaction) in reactions
86-
87-
try:
88-
reaction, user = await self.bot.wait_for("reaction_add", timeout=10, check=check)
89-
90-
user_choice_emote = reaction.emoji
91-
user_choice_index = reactions[user_choice_emote]
92-
93-
bot_choice_emote = random.choice(list(reactions.keys()))
94-
bot_choice_index = reactions[bot_choice_emote]
95-
96-
result_embed = discord.Embed(color=0x42F56C)
97-
result_embed.set_author(name=context.author.display_name, icon_url=context.author.avatar_url)
98-
await choose_message.clear_reactions()
99-
100-
if user_choice_index == bot_choice_index:
101-
result_embed.description = f"**That's a draw!**\nYou've chosen {user_choice_emote} and I've chosen {bot_choice_emote}."
102-
result_embed.colour = 0xF59E42
103-
elif user_choice_index == 0 and bot_choice_index == 2:
104-
result_embed.description = f"**You won!**\nYou've chosen {user_choice_emote} and I've chosen {bot_choice_emote}."
105-
result_embed.colour = 0x42F56C
106-
elif user_choice_index == 1 and bot_choice_index == 0:
107-
result_embed.description = f"**You won!**\nYou've chosen {user_choice_emote} and I've chosen {bot_choice_emote}."
108-
result_embed.colour = 0x42F56C
109-
elif user_choice_index == 2 and bot_choice_index == 1:
110-
result_embed.description = f"**You won!**\nYou've chosen {user_choice_emote} and I've chosen {bot_choice_emote}."
111-
result_embed.colour = 0x42F56C
112-
else:
113-
result_embed.description = f"**I won!**\nYou've chosen {user_choice_emote} and I've chosen {bot_choice_emote}."
114-
result_embed.colour = 0xE02B2B
115-
await choose_message.add_reaction("🇱")
116-
await choose_message.edit(embed=result_embed)
117-
except asyncio.exceptions.TimeoutError:
118-
await choose_message.clear_reactions()
119-
timeout_embed = discord.Embed(title="Too late", color=0xE02B2B)
120-
timeout_embed.set_author(name=context.author.display_name, icon_url=context.author.avatar_url)
121-
await choose_message.edit(embed=timeout_embed)
12258

12359

12460
def setup(bot):

0 commit comments

Comments
 (0)