Skip to content

Commit 65d15d5

Browse files
committed
Add custom help command
This is not the greatest help command out there, but a solid one to start with and better than the default of discord.py
1 parent 29354e0 commit 65d15d5

File tree

2 files changed

+127
-2
lines changed

2 files changed

+127
-2
lines changed

src/cogs/help.py

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import discord
2+
from discord.ext import commands
3+
4+
import utils as utl
5+
from environment import OWNER_NAME, OWNER_ID, VERSION, PREFIX
6+
7+
"""
8+
This custom help command is a replacement for the default one on any Discord Bot written in discord.py!
9+
However, you must put "bot.remove_command('help')" in your bot, and the command must be in a cog for it to work.
10+
11+
Original concept by Jared Newsom (AKA Jared M.F.)
12+
[link no longer available] https://gist.github.com/StudioMFTechnologies/ad41bfd32b2379ccffe90b0e34128b8b
13+
Rewritten and optimized by https://github.com/nonchris
14+
https://gist.github.com/nonchris/1c7060a14a9d94e7929aa2ef14c41bc2
15+
16+
This version relies more on the structure around this module than the gist does, which is more 'stand alone'
17+
"""
18+
19+
20+
class Help(commands.Cog):
21+
"""
22+
Sends this help message
23+
"""
24+
25+
def __init__(self, bot):
26+
self.bot = bot
27+
28+
@commands.command(aliases=['h', 'hilfe'])
29+
# @commands.bot_has_permissions(add_reactions=True,embed_links=True)
30+
async def help(self, ctx, *params):
31+
"""Shows all modules of that bot"""
32+
33+
# checks if cog parameter was given
34+
# if not: sending all modules and commands not associated with a cog
35+
if not params:
36+
# checks if owner is on this server - used to 'tag' owner
37+
try:
38+
owner = ctx.guild.get_member(OWNER_ID).mention
39+
40+
except AttributeError:
41+
owner = OWNER_NAME
42+
43+
# starting to build embed
44+
emb = discord.Embed(title='Commands and modules', color=utl.blue_light,
45+
description=f'Use `{PREFIX}h <module>` to gain more information about that module '
46+
f':smiley:\n')
47+
48+
# iterating trough cogs, gathering descriptions
49+
cogs_desc = ''
50+
for cog in self.bot.cogs:
51+
# ignoring boring cogs
52+
if cog == "MessageListener" or cog == "Help":
53+
continue
54+
cogs_desc += f'`{cog}` {self.bot.cogs[cog].__doc__}\n'
55+
56+
# adding 'list' of cogs to embed
57+
emb.add_field(name='Modules', value=cogs_desc, inline=False)
58+
59+
# integrating trough uncategorized commands
60+
commands_desc = ''
61+
for command in self.bot.walk_commands():
62+
# if cog not in a cog
63+
# listing command if cog name is None and command isn't hidden
64+
if not command.cog_name and not command.hidden:
65+
commands_desc += f'{command.name} - {command.help}\n'
66+
67+
# adding those commands to embed
68+
if commands_desc:
69+
emb.add_field(name='Not belonging to a module', value=commands_desc, inline=False)
70+
71+
# setting information about author
72+
emb.add_field(name="About", value=f"The base of this Bots is developed by nonchris, using on discord.py.\n\
73+
This version of it is maintained by {owner}\n\
74+
Please visit https://github.com/nonchris/discord-bot to submit ideas or bugs.")
75+
emb.set_footer(text=f"Bot is running Version: {VERSION}")
76+
77+
# block called when one cog-name is given
78+
# trying to find matching cog and it's commands
79+
elif len(params) == 1:
80+
81+
# iterating trough cogs
82+
for cog in self.bot.cogs:
83+
# check if cog is the matching one
84+
if cog.lower() == params[0].lower():
85+
86+
# making title - getting description from doc-string below class
87+
emb = discord.Embed(title=f'{cog} - Commands', description=self.bot.cogs[cog].__doc__,
88+
color=utl.green)
89+
90+
# getting commands from cog
91+
for command in self.bot.get_cog(cog).get_commands():
92+
# if cog is not hidden
93+
if not command.hidden:
94+
emb.add_field(name=f"{PREFIX}{command.name}", value=command.help, inline=False)
95+
# found cog - breaking loop
96+
break
97+
98+
# if input not found
99+
# yes, for-loops have an else statement, it's called when no 'break' was issued
100+
else:
101+
emb = discord.Embed(title="What's that?!",
102+
description=f"I've never heard from a module called `{params[0]}` before :scream:",
103+
color=utl.orange)
104+
105+
# too many cogs requested - only one at a time allowed
106+
elif len(params) > 1:
107+
emb = discord.Embed(title="That's too much.",
108+
description="Please request only one module at once :sweat_smile:",
109+
color=utl.orange)
110+
111+
else:
112+
emb = discord.Embed(title="It's a magical place.",
113+
description="I don't know how you got here. But I didn't see this coming at all.\n"
114+
"Would you please be so kind to report that issue to me on github?\n"
115+
"https://github.com/nonchris/discord-bot/issues\n"
116+
"Thank you! ~Chris",
117+
color=utl.orange)
118+
119+
# sending reply embed using our own function defined above
120+
await utl.send_embed(ctx, emb)
121+
122+
123+
def setup(bot):
124+
bot.add_cog(Help(bot))

src/main.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,13 @@ async def on_ready():
4949
member_count += g.member_count
5050
print()
5151
await bot.change_presence(
52-
activity=discord.Activity(type=discord.ActivityType.watching, name=f"{prefix}help"))
52+
activity=discord.Activity(type=discord.ActivityType.watching, name=f"{PREFIX}help"))
5353

5454
# LOADING Extensions
55-
# bot.remove_command('help')
55+
bot.remove_command('help') # unload default help message
5656
initial_extensions = [
5757
'cogs.misc',
58+
'cogs.help'
5859
]
5960

6061
if __name__ == '__main__':

0 commit comments

Comments
 (0)