Skip to content

Instantly share code, notes, and snippets.

@wilfreddv
Last active November 2, 2021 20:32
Show Gist options
  • Save wilfreddv/15f20c068e9306955c6c3f6a8450aaca to your computer and use it in GitHub Desktop.
Save wilfreddv/15f20c068e9306955c6c3f6a8450aaca to your computer and use it in GitHub Desktop.
A cookbook for getting started with discord.py rewrite

This is not being maintained and might be outdated. Use at your own risk.

Cookbook for discord.py rewrite

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.

Contents

Installing discord.py

You can install discord.py using pip: pip install discord.py.

Note: pip might have to be pip3 on some Linux/MacOS systems.

Initiating a bot:

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.

Setting up configurations

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)

Bot events

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!")

Rich Presence

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.

Adding commands

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.

Combining commands and on_message

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!")

Adding aliases to your commands

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].

Sending back messages

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!")

About users and mentions

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 Users, Channels and Roles mentioned.

Interactivity

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.

Basic "dad bot" implementation

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")
@gamescom15
Copy link

git+https://github.com/Rapptz/discord.py@rewrite#egg=discord.py[voice]

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 just pip install discord.py as these examples do not need voice.

Perhaps consider updating this in the gist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment