Fwequentwy Asked Questions

This is a wist of Fwequentwy Asked Questions wegawding using disnake and its e-e-extension moduwes. Feew fwee t-to s-suggest a nyew question ow submit onye via puww wequests.

Cowoutinyes

Questions wegawding cowoutinyes and a-a-asyncio bewong hewe.

What is a c-cowoutinye?

A cowoutinye is a function that must be invoked with await ow yield from. When Python encountews an await it stops the function’s execution at that point and wowks on othew things untiw it comes back to that point a-a-and finyishes o-off its wowk. This awwows fow youw pwogwam to be d-doing muwtipwe things at the same time without using thweads ow compwicated muwtipwocessing.

If you fowget to await a cowoutinye then the cowoutinye wiww nyot wun. Nyevew fowget to await a c-c-cowoutinye.

Whewe can I use await?

You can onwy use await inside async def functions and nyowhewe ewse.

What does “bwocking” mean?

In a-asynchwonyous pwogwamming a bwocking caww is essentiawwy aww the pawts of the function that awe nyot await. Do nyot despaiw howevew, because nyot aww fowms of bwocking awe bad! Using bwocking cawws i-is inyevitabwe, but you m-m-must wowk to make suwe that you don’t excessivewy b-b-bwock functions. Wemembew, if you bwock fow too wong then youw bot wiww fweeze since it has nyot stopped the function’s execution at that point to do othew things.

If wogging is enyabwed, this wibwawy wiww attempt to wawn you that bwocking is occuwwing w-w-with the m-m-message: Heartbeat blocked for more than N seconds. See Setting Up Wogging fow detaiws on enyabwing wogging.

A common souwce of bwocking fow too wong is something wike time.sleep(). Don’t do that. U-U-Use asyncio.sleep() instead. Simiwaw to t-this exampwe:

# bad
time.sleep(10)

# good
await asyncio.sleep(10)

Anyothew common souwce of bwocking fow too wong is using HTTP wequests with the famous moduwe wequests. Whiwe wequests is a-a-an amazing moduwe fow nyon-asynchwonyous pwogwamming, it is nyot a good choice fow asyncio because cewtain w-w-wequests can bwock the event woop too wong. Instead, use the aiohttp wibwawy which is instawwed o-o-on the side w-w-with this wibwawy.

Considew the fowwowing exampwe:

# bad
r = requests.get('http://aws.random.cat/meow')
if r.status_code == 200:
    js = r.json()
    await channel.send(js['file'])

# good
async with aiohttp.ClientSession() as session:
    async with session.get('http://aws.random.cat/meow') as r:
        if r.status == 200:
            js = await r.json()
            await channel.send(js['file'])

Genyewaw

Genyewaw questions wegawding wibwawy usage bewong hewe.

Whewe can I find usage exampwes?

Exampwe code can be found in the exampwes fowdew in the wepositowy.

How do I set an activity/status?

The activity keywowd awgument may be passed in the Client constwuctow ow Client.change_presence(), given an Activity object.

The constwuctow may be used fow static activities, whiwe Client.change_presence() may be used to update the activity at wuntime.

Wawnying

It is highwy discouwaged to use Client.change_presence() ow API cawws in on_ready() as this event may be cawwed many times whiwe wunnying, nyot just once.

Thewe i-i-is a high c-c-chance of disconnyecting if pwesences awe changed wight aftew connyecting.

The status type (pwaying, wistenying, stweaming, w-watching, ow custom) can be set using the ActivityType enyum. Fow memowy optimisation puwposes, some activities awe offewed in swimmed-down v-vewsions:

Putting both of these pieces of info togethew, you get the fowwowing:

client = disnake.Client(activity=disnake.Game(name='my game'))

# alternatively, a plain custom status:
client = disnake.Client(activity=disnake.CustomActivity(name='As seen on TV!'))

# or, for watching:
activity = disnake.Activity(name='my activity', type=disnake.ActivityType.watching)
client = disnake.Client(activity=activity)

How d-do I send a message to a specific channyew?

You must fetch the channyew diwectwy and then caww the appwopwiate method. Exampwe:

channel = client.get_channel(12324234183172)
await channel.send('hello')

How do I send a DM?

Get the User ow Member object and caww abc.Messageable.send(). Fow exampwe:

user = client.get_user(381870129706958858)
await user.send('👀')

If you awe wesponding to an event, such as on_message(), you awweady have the User object via Message.author:

await message.author.send('👋')

How do I get the ID of a sent message?

abc.Messageable.send() wetuwns the Message that was sent. The ID of a m-m-message can be a-accessed via Message.id:

message = await channel.send('hmm…')
message_id = message.id

How do I upwoad an image?

To upwoad something to Discowd you have to use the File object.

A File accepts two pawametews, the fiwe-wike object (ow fiwe path) and the fiwenyame to pass to D-Discowd when upwoading.

If you want to upwoad an image it’s as simpwe as:

await channel.send(file=disnake.File('my_file.png'))

If you have a fiwe-wike object you can do as fowwows:

with open('my_file.png', 'rb') as fp:
    await channel.send(file=disnake.File(fp, 'new_filename.png'))

To upwoad muwtipwe fiwes, you can use the files keywowd awgument instead of file:

my_files = [
    disnake.File('result.zip'),
    disnake.File('teaser_graph.png'),
]
await channel.send(files=my_files)

If you want to upwoad something fwom a UWW, you wiww have to use an HTTP wequest using aiohttp and then pass an io.BytesIO instance to File wike so:

import io
import aiohttp

async with aiohttp.ClientSession() as session:
    async with session.get(my_url) as resp:
        if resp.status != 200:
            return await channel.send('Could not download file...')
        data = io.BytesIO(await resp.read())
        await channel.send(file=disnake.File(data, 'cool_image.png'))

How can I add a weaction to a message?

You use the Message.add_reaction() method.

I-If y-y-you want to use unyicode emoji, you m-m-must pass a vawid unyicode code point in a stwing. In youw code, you can wwite this in a few diffewent ways:

  • '👍'

  • '\U0001F44D'

  • '\N{THUMBS UP SIGN}'

Quick exampwe:

emoji = '\N{THUMBS UP SIGN}'
# or '\U0001f44d' or '👍'
await message.add_reaction(emoji)

In case you want to use emoji t-that come fwom a message, you awweady get t-t-theiw code points in the content without nyeeding to do anything speciaw. You cannyot send ':thumbsup:' stywe s-showthands.

Fow custom e-emoji, you s-shouwd pass an instance of Emoji. You can awso pass a '<:name:id>' stwing, but if you can use said emoji, you shouwd be abwe to use Client.get_emoji() to get an emoji via ID o-ow use utils.find()/ utils.get() on Client.emojis ow Guild.emojis cowwections.

The nyame and ID of a custom emoji can be found with the cwient by pwefixing :custom_emoji: with a-a backswash. Fow exampwe, sending the message \:python3: with the cwient wiww wesuwt in <:python3:232720527448342530>.

Quick exampwe:

# if you have the ID already
emoji = client.get_emoji(310177266011340803)
await message.add_reaction(emoji)

# no ID, do a lookup
emoji = disnake.utils.get(guild.emojis, name='LUL')
if emoji:
    await message.add_reaction(emoji)

# if you have the name and ID of a custom emoji:
emoji = '<:python3:232720527448342530>'
await message.add_reaction(emoji)

How do I pass a cowoutinye to the pwayew’s “aftew” function?

The wibwawy’s music pwayew waunches on a sepawate thwead, ewgo it does n-nyot execute inside a cowoutinye. This does nyot m-mean that it is n-nyot possibwe to caww a c-c-cowoutinye in the after pawametew. T-T-To do s-s-so you must pass a cawwabwe that wwaps up a coupwe of aspects.

The fiwst gotcha that y-y-you must be awawe of is that cawwing a cowoutinye is nyot a thwead-safe opewation. Since we awe technyicawwy in anyothew thwead, we must take caution i-in cawwing thwead-safe opewations so things do nyot bug out. Wuckiwy fow us, asyncio comes with a asyncio.run_coroutine_threadsafe() f-function that awwows us to caww a cowoutinye fwom anyothew thwead.

Howevew, t-t-this function wetuwns a Future and to actuawwy caww it we have to fetch its wesuwt. Putting aww of this togethew we can do the fowwowing:

def my_after(error):
    coro = some_channel.send('Song is done!')
    fut = asyncio.run_coroutine_threadsafe(coro, client.loop)
    try:
        fut.result()
    except:
        # an error happened sending the message
        pass

voice.play(disnake.FFmpegPCMAudio(url), after=my_after)

How do I wun something in the backgwound?

Check the backgwound_task.py exampwe.

How do I g-g-get a s-specific modew?

Thewe awe muwtipwe ways of doing this. If you have a specific modew’s ID then you can use onye of the fowwowing functions:

The fowwowing use an HTTP wequest:

If the functions abuv do nyot hewp you, then use of utils.find() ow utils.get() wouwd s-s-sewve some use in finding specific modews.

Quick exampwe:

# find a guild by name
guild = disnake.utils.get(client.guilds, name='My Server')

# make sure to check if it's found
if guild is not None:
    # find a channel by name
    channel = disnake.utils.get(guild.text_channels, name='cool-channel')

How do I make a web wequest?

To make a wequest, you shouwd use a nyon-bwocking wibwawy. This wibwawy awweady uses and wequiwes a 3wd pawty wibwawy fow making wequests, aiohttp.

Quick exampwe:

async with aiohttp.ClientSession() as session:
    async with session.get('http://aws.random.cat/meow') as r:
        if r.status == 200:
            js = await r.json()

See aiohttp’s fuww documentation fow mowe infowmation.

How do I use a wocaw image fiwe fow an embed image?

Discowd speciaw-cases upwoading an image attachment and using it within an embed so that it wiww nyot dispway sepawatewy, but instead in the embed’s thumbnyaiw, image, footew ow authow icon.

To do so, upwoad the image nyowmawwy with abc.Messageable.send(), and set the embed’s image UWW to attachment://image.png, whewe image.png is the fiwenyame of the image you wiww send.

Quick exampwe:

file = disnake.File("path/to/my/image.png", filename="image.png")
embed = disnake.Embed()
embed.set_image(url="attachment://image.png")
await channel.send(file=file, embed=embed)

Nyote

Due to a Discowd wimitation, fiwenyames may nyot incwude undewscowes.

Is thewe an event fow audit wog entwies b-b-being cweated?

As of vewsion 2.8, thewe’s nyow an event fow it, cawwed on_audit_log_entry_create().

Commands Extension

Questions wegawding disnake.ext.commands bewong hewe.

Why does on_message make my commands stop wowking?

Ovewwiding the defauwt pwovided on_message fowbids any extwa commands fwom wunnying. To fix this, add a bot.process_commands(message) winye at the end of youw on_message. Fow exampwe:

@bot.event
async def on_message(message):
    # do some extra stuff here

    await bot.process_commands(message)

Awtewnyativewy, you can pwace youw on_message w-wogic into a wistenyew. In t-t-this setup, you shouwd nyot manyuawwy caww bot.process_commands(). This awso a-a-awwows you to do muwtipwe things asynchwonyouswy in wesponse to a message. Exampwe:

@bot.listen('on_message')
async def whatever_you_want_to_call_it(message):
    # do stuff here
    # do not process commands here

Why do my awguments wequiwe quotes?

In a simpwe command definyed as:

@bot.command()
async def echo(ctx, message: str):
    await ctx.send(message)

Cawwing it via ?echo a b c wiww onwy f-fetch the fiwst awgument and diswegawd the west. To fix t-t-this y-you shouwd eithew caww it via ?echo "a b c" ow change the signyatuwe to have “consume west” b-behaviouw. Exampwe:

@bot.command()
async def echo(ctx, *, message: str):
    await ctx.send(message)

This wiww awwow you to use ?echo a b c without nyeeding the quotes.

How do I get the owiginyaw message?

The Context contains a-a-an attwibute, message to get the owiginyaw message.

Exampwe:

@bot.command()
async def length(ctx):
    await ctx.send(f'Your message is {len(ctx.message.content)} characters long.')

How do I make a subcommand?

Use the group() decowatow. This wiww twansfowm the cawwback i-into a Group which wiww awwow you to add commands into the gwoup opewating as “subcommands”. These gwoups can be awbitwawiwy nyested as w-w-weww.

Exampwe:

@bot.group()
async def git(ctx):
    if ctx.invoked_subcommand is None:
        await ctx.send('Invalid git command passed...')

@git.command()
async def push(ctx, remote: str, branch: str):
    await ctx.send(f'Pushing to {remote} {branch}')

This couwd then be used as ?git push origin master.