'Changing server icon/pfp using nextcord/discord.py
Im trying to do a command that changes the server icon/pfp by getting a URL & sending a "Good." Text when the command ends. So in short, I want my bot to get the URL than changing the server pfp/icon to the specified url/image ex : ",setpfp URL"
My Code:
@bot.command()
async def setpfp(ctx,*,icon:typing.Union[bytes,str]):
await ctx.guild.edit(icon=icon)
await ctx.send("Good.")
`
Full TraceBack Error:
Ignoring exception in on_command_error
Traceback (most recent call last):
File "/home/runner/Kituzomoa/venv/lib/python3.8/site-packages/nextcord/ext/commands/core.py", line 168, in wrapped
ret = await coro(*args, **kwargs)
File "main.py", line 59, in setpfp
await ctx.guild.edit(icon=icon)
File "/home/runner/Kituzomoa/venv/lib/python3.8/site-packages/nextcord/guild.py", line 1542, in edit
fields['icon'] = utils._bytes_to_base64_data(icon)
File "/home/runner/Kituzomoa/venv/lib/python3.8/site-packages/nextcord/utils.py", line 480, in _bytes_to_base64_data
mime = _get_mime_type_for_image(data)
File "/home/runner/Kituzomoa/venv/lib/python3.8/site-packages/nextcord/utils.py", line 466, in _get_mime_type_for_image
if data.startswith(b'\x89\x50\x4E\x47\x0D\x0A\x1A\x0A'):
TypeError: startswith first arg must be str or a tuple of str, not bytes
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/runner/Kituzomoa/venv/lib/python3.8/site-packages/nextcord/client.py", line 415, in _run_event
await coro(*args, **kwargs)
File "main.py", line 1787, in on_command_error
raise error
File "/home/runner/Kituzomoa/venv/lib/python3.8/site-packages/nextcord/ext/commands/bot.py", line 1052, in invoke
await ctx.command.invoke(ctx)
File "/home/runner/Kituzomoa/venv/lib/python3.8/site-packages/nextcord/ext/commands/core.py", line 933, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "/home/runner/Kituzomoa/venv/lib/python3.8/site-packages/nextcord/ext/commands/core.py", line 177, in wrapped
raise CommandInvokeError(exc) from exc
nextcord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: startswith first arg must be str or a tuple of str, not bytes
Solution 1:[1]
You have to first download the image from the url and pass it after reading.
Here is how I do it for my bot's avatar. Same goes for guild icons.
for image_record in db_avatars.find():
url = image_record["url"]
# create directory
file_name = os.path.join(
os.path.join(os.getcwd(), "avatars"), url.split("/")[-1]
)
# download images
res = requests.get(url, stream=True)
if res.status_code == 200:
file_exists = os.path.exists(file_name)
if not file_exists:
with open(file_name, "wb") as f:
shutil.copyfileobj(res.raw, f)
print("Image successfully downloaded: ", file_name)
else:
print("This image already exists!")
else:
print("Image Couldn't be retrieved")
# read the file and change avatar
with open(self.select_random_image_path(), "rb") as file:
print(file)
new_avatar = file.read()
await self.bot.wait_until_ready()
await self.bot.user.edit(avatar=new_avatar)
print("Avatar changed successfully!")
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |