This document contains snippets that I've used and tested. It's not meant to be an official guide, but rather a document for looking up small snippets of code. For an extensive reference on the API, please visit the official documentation.
- Installation
- Initialization
- Setting up configurations
- Events
- Rich Presence
- Commands
- Combining commands and
on_message
- Aliases for commands
- Sending messages
- Users and Mentions
- Interactivity
- Dad bot example
You can install discord.py using pip: pip install discord.py
.
Note: pip
might have to be pip3
on some Linux/MacOS systems.
from discord.ext import commands
bot = commands.Bot()
The Bot
class can take the following arguments (and more):
- case_insensitive: bool: Bot command is case insensitive
- description: str: Description for the bot
- help_command: discord.ext.commands.HelpCommand: ...
- self_bot: bool: Bot will only listen to commands invoked by itself if
True
(default:False
)
The full docs can be found here.
You might not want to pollute your main file with settings. This is how you can include your setting in another file.
config.py
TOKEN="" # Your bots token
CMD_PREFIX="" # The command prefix
DESCRIPTION="" # The description (optional)
main.py
from discord.ext import commands
from config import *
bot = commands.Bot(command_prefix=CMD_PREFIX, description=DESCRIPTION)
bot.run(TOKEN)
A bot can listen for certain events. Two common ones are on_ready
and on_message
:
@bot.event
async def on_ready():
print("Bot is ready!")
@bot.event
async def on_message(msg):
print("A message was sent!")
Ever see those user playing game
things in Discord? They're called rich presence
. You can easily add them to your bot. This will need to happen in the on_ready
listener.
import discord
@bot.event
async def on_ready():
await bot.change_presence(status=discord.Status.online, activity=discord.Game("a game of blackjack."), afk=False)
You can also pass the presence when initiating the bot.
import discord
from discord.ext import commands
activity = discord.Game("a game of blackjack.")
bot = commands.bot(activity=activity)
Note that bot.change_presence
will overwrite this.
discord.Status
is an enum
which contains the following statuses: online
, offline
, idle
, dnd
, invisible
For more information, visit the docs.
discordpy
makes it very easy to add commands to your bot.
@bot.commands()
async def foo(ctx):
...
This will add a command named foo
to your bot. In Discord, this command would be called like this: {CMD_PREFIX}foo
.
You may have noticed on_message
and commands don't work well together: it will always only execute on_message
, and not the commands. In order to still process the commands, use bot.process_commands
.
@bot.event
async def on_message(msg):
# Do your on_message duties
await bot.process_commands(msg)
To see if a user said a particular phrase, you can use the in
keyword:
if "hello" in msg.content: await msg.channel.send("Hello back!")
Sometimes it's handy to have multiple ways to call the same command. Instead of writing the same function over and over again, you can add aliases
.
@bot.command(aliases=["bar", "baz"])
async def foo(ctx):
print("foo, bar or baz was called!")
You can run this command in Discord using {CMD_PREFIX}[foo|bar|baz]
.
In the newest version, you're able to send messages to the context
immediately, without having to grab the channel first.
@bot.command()
async def foo(ctx):
await ctx.send("foo called!")
discord.Message
(which is passed to on_message
) however, doesn't have this luxury.
@bot.event
async def on_message(msg):
await msg.channel.send("A message was sent!")
Getting the author of a message:
@bot.event
async def on_message(msg):
print(f"Author: {msg.author}")
@bot.command()
async def foo(ctx):
print(f"Author: {ctx.author}")
# OR
print(f"Author: {ctx.message.author}")
Sometimes, you want to mention the author of the command. This can be done as such.
@bot.command()
async def foo(ctx):
await ctx.send(f"foo was called by: {ctx.author.mention}")
You can also check the message to see what people were mentioned.
@bot.event
async def on_message(msg):
people_mentioned = ctx.message.mentions
channels_mentioned = ctx.message.channel_mentions
roles_mentioned = ctx.message.role_mentions
This is a list
of User
s, Channel
s and Role
s mentioned.
Sometimes you want to "communicate" with a user invoking your bot. You can do this by awaiting messages in your code manually.
import asyncio
@bot.command()
async def doAction(ctx):
await ctx.send("Are you sure you want to do this? [y(es)/n(o)]")
def check(m):
return m.author == ctx.author
try:
msg = await bot.wait_for('message', check=check, timeout=10)
# OR `check=lambda m: m.author == ctx.author`
if msg.content.lower() in ['y', 'yes']:
await ctx.send("Doing it!")
elif msg.content.lower() in ['n', 'no']:
await ctx.send("Not doing it!")
else:
await ctx.send("I did not understand that, aborting!")
except asyncio.TimeoutError as e:
await ctx.send("Looks like you waited to long.")
wait_for
takes in a string which tells discordpy what to wait for. The docs are not explicit on which events can be awaited.
The check
parameter checks incoming messages for a certain condition. If that condition is met, it will return the Message
.
The timeout
parameter is the timeout in seconds.
Both check
and timeout
are optional.
from discord.ext import commands
bot = commads.Bot(command_prefix='d!')
@bot.event
async def on_message(msg):
content = msg.content.lower():
if "shut up" in content:
await msg.channel.send(f"Listen here {msg.author.name}, I will not tolerate you saying the words that consist of the letters 's h u t u p' being said in this server, so take your own advice and close thine mouth in the name of the christian minecraft server owner.")
if "i'm" in content:
await msg.channel.send(f"Hello {content.split("i'm")[1]}, I'm dad!")
await bot.process_commands(msg)
@bot.command()
async def dadjoke(ctx):
await ctx.send("I bought shoes from a drug dealer once, I don't know what he laced them with, but I was tripping all day.")
bot.run("Super Secret Token")
The old branch has been deleted now that rewrite has been released. Hence, this command wil fail as the branch no longer exists. The current version now can be installed with just
pip install discord.py[voice]
or justpip install discord.py
as these examples do not need voice.Perhaps consider updating this in the gist.