Learn to Code via Tutorials on Repl.it

← Back to all posts
Migrating from discord.py async to rewrite
minx28 (201)

Hey everyone!

Recently, discord.py went through a major update, with quite a lot of changes to how certain things are done. Pretty much any discord bot that hasn't been updated will stop working, so I made this tutorial so you can easily update your code.

This is only a brief description of the changes. For a full guide to migrating, visit this page.


IDs are now integers rather than strings. If before you did myChannel=client.get_channel("437048931827056644"), now you have to do myChannel=client.get_channel(437048931827056644).

This also applies if you are storing IDs for channels, servers or users in .env - you will have to do myServer=int(os.getenv("SERVER")).

Sending messages

In rewrite, many methods have been moved out of client. The most important example is now instead of await client.send_message(myChannel,"Hello World!"), you now need await myChannel.send("Hello World!"). To send private messages, you do the same but replace the channel with the user - myUser.send("Hello World!"). The other arguments you can pass (embed= etc) remain the same.

Some other examples of this are:

  • await client.delete_message(myMSG) --> await myMSG.delete()
  • await client.kick(myMember) --> await myMember.kick()

Servers are now Guilds

Pretty much every single instance of the word server in the library is now a guild instead. The class is now discord.Guild, the server a message came from is message.guild, and the list of the bot's servers is now client.guilds. If in doubt about whether something should be server or guild, choose guild.

Checking if a channel is a DM

discord.Channel has been split up into a few different classes. The important ones we need to know about are discord.abc.GuildChannel and discord.abc.PrivateChannel. To check if a channel is a DM, you now have to use isinstance(myChannel,discord.abc.PrivateChannel).

Other changes

  • To edit a message, you now do await myMessage.edit(content="New content!") instead of await client.edit_message(myMessage,new_content="New content!"). Note the change from new_content to content.
  • send_file has been removed. To send a file, you use the same method, send, as for text and embeds:
with open("myPicture.png","rb") as myPicture:
    await myChannel.send(file=discord.File(myPicture))
  • myMessage.timestamp is now myMessage.created_at


  • If your command takes a long time to process and output a result, it is now easier to send "typing" whilst your code runs:
async with myChannel.typing():
  • To get all the users the bot can see, you can now use client.users
  • To get a channel's history, you can use async for message in myChannel.history(): which will iterate through each discord.Message, or you can use channelHistory=await channel.history().flatten(), which returns a list of discord.Message


This is one of the biggest changes, and the main reason why I personally migrated to rewrite before the library updated.
In async, you had to do client=discord.Client(shard_count=3,shard_id=1) (if this was the second shard of a 3-shard bot) and run the same code separately for each shard - I achieved this using threading and running the entire bot as a function, where the shard_id was passed as an argument and each instance of the function was run in a separate thread. I then had to use a database that every shard could access and post their own individual server and user counts, in order to get the totals. This often made me want to cry myself to sleep.
In rewrite, you can simply do client=discord.AutoShardedClient(). That's it. client.servers and client.users will now give the entire lists, including the parts that belong to other shards, and you only need to run one instance of the bot. Your bot is sharded with approximately 1000 servers to a shard, although you can control this by doing client=discord.AutoShardedClient(shard_count=3) if you want a specific number of shards (bear in mind that the maximum number of servers a single shard can connect to is 2500).

That's all I'm going to cover. This tutorial is not by any means a definitive guide to migrating, you can find one of those here, and also make sure to check out the docs here.

Post your newly-migrated bots in the comments section!

I hope you found this post helpful. If you did (or even if you didn't) please leave an upvote!

Also, be sure to check out @TheDrone7's tutorials on how to make a discord bot and how to keep a discord bot running on Repl.it.
(No, I was not paid to plug those.)

@timmy_i_chen consider featuring this in newsletter? 😉