#tree.command(name = 'redeem', description = 'Redeems A Members Key')
async def redeem(interaction: discord.Interaction, key: str, member:discord.Member):
with open("bkeys.txt") as f:
if key in f.read():
em = discord.Embed(color=0xff0000)
em.add_field(name="Invalid Key", value="Sorry, this key has been blacklisted")
await interaction.response.send_message(embed=em)
return 0
with open("keys.txt") as f:
if key in f.read():
role = interaction.guild.get_role(1071561081685811210)
await member.add_roles(member, role)
em = discord.Embed(color=0x008525)
em.add_field(name="Key Redeemed", value="Key has now been redeemed")
await interaction.response.send_message(embed=em)
f = open("ukeys.txt", "w")
f.write(key)
f.write('\n')
else:
em = discord.Embed(color=0xff0000)
em.add_field(name="Invalid Key", value="Inputed key has already been used!")
await interaction.response.send_message(embed=em)
Error
**This has been a command I have been trying to work on its just the add roles will not work, btw im new to python so I don't know much sorry, so if anyone could just drop the code please.
**
I tried changing the (1071561081685811210) to my role name ("Buyer") and asking for help but I didn't understand.
like bruh has said you should change
member.add_roles(member,role)
to
member.add_roles(role)
New to programming. I'm creating a bot for moderators to view and add to a filter trigger word list, which is saved as an external text file. When the command to add a word is evoked, it gets added to the text file. But when I make the command to view the list in the server, the printed list doesn't get updated and the last entry just made is not there.
with open('triggers.txt', 'r') as x:
global triggerlist
trig = x.read()
triggerlist = trig.split()
#client.command(aliases = ["viewlist", "viewtriggers"]) #view
#has_permissions(ban_members = True)
async def viewblocklist(ctx):
channel = client.get_channel(LOG_CHANNEL_ID)
await ctx.message.add_reaction(emoji_thumbsup)
printformat = '\n'.join(triggerlist)
await channel.send(printformat)
#client.command(aliases = ["addlist", "addtrigger"]) #add/append
#has_permissions(ban_members = True)
async def addblocklist(ctx, *, arg):
with open('triggers.txt', 'a+') as x:
x.write(arg.strip().lower()+'\n')
x.flush()
x.close()
await ctx.message.add_reaction(emoji_thumbsup)
return
I have a json load/save/dump function to count how many time a single word is said in a specific channel. It works great, but I lose the data after reboot of the bot. Below is my code.
def load_counters():
with open('cup.json', 'r') as f:
counters = json.load(f)
return counters
def save_counters(counters):
with open('cup.json', 'w') as f:
json.dump(counters, f)
if message.channel.id == 709551578612498453:
if message.content == ('cup'):
counters = load_counters()
counters["cup"] += 1
save_counters(counters)
return
else:
cup_meta = client.get_channel(709984510678269982)
cup_channel = client.get_channel(709551578612498453)
await cup_meta.send(message.author.mention + ' has violated the sacred rules of Cup')
await message.delete()
await cup_channel.send('cup')
return
with open('cup.json', 'r') as f:
counters1 = json.load(f) # Open and load the file
totalcup = counters1['cup']
if message.content == ('!totalcup'):
await message.channel.send(f"Cup has been said {totalcup} times since Bender reset me.")
Here is the json file - right now if I were to run !totalcup, the bot spits out '13' but the file says 0. Not sure if I am missing something as I am new to code.
{
"cup": 0
}
I just figured it out. The code does work as intended, it is a problem with how my host (Heroku) operates. There isn't anything I can do until I find a new hosting situation.
What I'm trying to do: I have an on_message event for a 'global chat' command that I have created. This would send messages to any server that was in the json, currently supporting images, multiple lines of text, and custom emojis (as long as the bot shared a server with said emoji).
My problem: As you can see in the image above, one person, 'S o u p', has their profile picture replaced with a duck emoji. For context's sake, their avatar is not that of a duck emoji. However, if you were to look at the most recent message, the profile picture is shown. I believe that the problem lies in the size of the message.author's avatar. The PIL library may be a good solution, but I do not want to save the image.
Code I have tried:
avatar_bytes = await message.author.avatar_url.read()
guildem = client.get_guild(738285544911405107)
try:
em = await guildem.create_custom_emoji(name=f'{message.author.name}', image=avatar_bytes)
except:
em = '🦆'
The code above is the one I had used in the image example I had provided.
avatar = message.author.avatar_url_as(size=128) # resize avatar
avatar_bytes = await avatar.read() # then read as bytes?
Above code gives exact same results. Avatars are turned into duck emojis.
Others I have looked at:
How to crop an image to a shape for eg. circle using Pillow in Discord.py?: Messages did not send when using the code here. I assumed that using the PIL library would help reduce the file size significantly one way or the other without saving the image.
How to reduce the image file size using PIL: All the answers required saving the image, which I do not want to do. I tried tweaking the code a little bit, but caused all avatars to be turned into duck emojis.
If necessary, I will include the entire on_message event. However, this does not feel relevant nor necessary to include since the emojis are only a small portion of said event.
Edit: Here is the code to the entire on_message event.
#client.event
async def on_message(message):
if message.author == client.user: # stop bot from replying to self
return
else:
if not message.guild: # prevent errors when messaging in bot dm's
return
f = open("global text.json") # existing json
"""
{
"747061937673732097": 765059798131539988,
"724783642546536458": 818707151122989119,
"761524419003809832": 813963773295591485,
"755309786232258630": 760381389685784587,
"738285544911405107": 738285544911405110
}
"""
data = json.load(f)
for i in data:
if str(i) == str(message.guild.id):
if data[str(message.guild.id)] == message.channel.id:
avatar_bytes = await message.author.avatar_url.read()
guildem = client.get_guild(738285544911405107) # guild to upload emojis to
try:
em = await guildem.create_custom_emoji(name=f'{message.author.name}', image=avatar_bytes) # create emoji using avatar_bytes in guildem server
except:
em = '🦆'
### functions ###
def censor(text): # censor words for safety
banned = ["test"] # bad words were here, removed for stackoverflow reasons
text = text.split()
nearly = []
for word in text:
if any(item in word.lower() for item in banned):
word = word.lower()
replaced = word.replace(word, ('#'*(len(word))))
nearly.append(replaced)
else:
nearly.append(word)
message = ' '.join(nearly)
return message
def parag(string): # check for \n
length = [string]
if string in ["", " ", " ", " "]:
return "<:transparent:774136812813811713>"
final_list = []
if '\n' in string:
length = string.split('\n')
for item in length:
thing = censor(item)
final_list.append(thing)
return paragger(final_list)
def paragger(list: list): # returns original message with \n
message = ""
for item in list:
message += f"> {item}\n"
return message
msg = parag(message.content)
### attachment handling ###
embed_list = []
if message.attachments:
if len(message.attachments) == 1:
embed = discord.Embed(title=f"{message.author}'s file", color=0xc39ce6)
for file in message.attachments:
embed.set_image(url=file.url)
embed_list.append(embed)
else:
count = 1
for file in message.attachments:
embed = discord.Embed(title=f"{message.author}'s file {count}")
embed.set_image(url=file.url)
embed_list.append(embed)
for i in data:
if str(i) != str(message.guild.id):
channel = client.get_channel(data[str(i)])
try:
await channel.send(f"{em} {message.author} \n{msg}", allowed_mentions=allowed_mentions)
if len(embed_list) > 0:
for embed in embed_list:
await channel.send(embed=embed)
except:
await channel.send(f"{em} {message.author} \n> {em}", allowed_mentions=allowed_mentions) # only happens if message is larger than 2000 char
if em != '🦆':
await em.delete() # delete the custom emoji to make space for more emojis later on
break
await client.process_commands(message) # process, prevent commands breaking
Your issue is here:
em = await guildem.create_custom_emoji(name=f'{message.author.name}', image=avatar_bytes)
You see, discord.py is looking for an emoji name with alphanumeric characters or underscores. S o a p does not fit this requirement, hence the error you have gotten. The following fixes the issue by replacing said characters with an underscore.
avatar_bytes = await message.author.avatar_url_as(size=128).read() # size=128 makes the size smaller for emojis
name = message.author.name.replace('-', '_').replace(' ', '_') # Replace the erroring characters
try:
em = await guildem.create_custom_emoji(name=f'{name}', image=avatar_bytes)
except:
em = '🦆'
EDIT: After taking another look, the problem wasn't what I thought after all, the issue with the user named S o a p was that it had non alphanumeric characters, I've updated my answer to fix this.
You don't need to save image. This is how you send images to discord without saving it:
import io
import PIL
image = PIL.Image.new("RGB", (200, 200), (255, 255, 255))
bytes_io = io.BytesIO()
image.save(bytes_io, format="png")
bytes_io.seek(0)
file = discord.File(bytes_io, "white.png")
#now you can send this file to discord
await ctx.send(file=file)
I am working on a command list command in JSON and I am having troubles with making a number alignment in the code.
#client.command()
async def command_list(ctx):
with open("commands.json", "r") as f:
y = json.load(f)
embed = discord.Embed(description="\n".join(y[str(ctx.guild.id)]),
colour=discord.Colour())
embed.set_author(name=ctx.author, icon_url=ctx.author.avatar_url)
await ctx.send(embed=embed)
I want it to be sent like this:
1. <1stcommandname>
2. <2ndcommandname>
3. <3rdcommandname>
...