Discord.py bot sending messages multiple times - python-3.x

I'm new to coding in python, and I'm having trouble with this code.
#client.event
async def on_message(message):
if message.author == client.user:
return
if 'choose my pick' in message.content:
channel = message.channel
await channel.send('Que role tu ta?')
def check(m):
return m.content == 'top' or 'jg' or 'mid' or 'adc' or 'sup' and m.channel == channel
role = await client.wait_for('message', check=check)
sentence_start = random.choice(inu_exp)
iten = random.choice(itens)
if 'top' in role.content:
champion = random.choice(top_champs)
await channel.send(f'{sentence_start} {champion} de {iten}')
await client.process_commands(message)
It works as I want to, when someone type 'choose my pick' it asks 'Que role tu ta', but it asks many times, and it also sends the answer await channel.send(f'{sentence_start} {champion} de {iten}') many times.
Here's the output: https://prnt.sc/y1cucv
I'm using python 3.8.6

I have tested your code onto another bot and it only sent the message once! Make sure that there aren't multiple clients running at the same time! Another thing to make sure of is your internet ping as this could cause lag and result in having multiple messages! (Past Experience)
In addition, if your still having problems please send the entire code (without the token of course) because many variables are missing and I can't do anything without those variables. For example the inu_exp!

Related

how to make a command that only works for a certain role in a certain channel, otherwise it sends them a message to ask for a role

I'm currently coding a discord bot on the side and I'm stuck on a command that I'm trying to only make certain role to use it, when the wrong role type the command he got a reply to get the right role and I'm wondering how I can mix those 2 commands in 1
thanks for your help, im a noob since i just start coding
#commands.has_any_role('Sluts', 'Customer')
#commands.cooldown(1, 17992, commands.BucketType.user)
async def generate(ctx):
if ctx.message.channel.name == 'Channel_id':
emoji2 = bot.get_emoji(932456512180338759)
await ctx.reply('Initialized')
await ctx.message.add_reaction(emoji1)
await ctx.message.add_reaction(emoji2)
#await main.script()
await ctx.author.send('DM: Done! Enjoy!')
else
await ctx.send('You can not use this command here: checkout #channel_id')
and this line
#bot.command()
#commands.has_any_role('Leaker', 'Customer')
#commands.cooldown(1, 300, commands.BucketType.user)
async def generate(ctx):
emoji2 = bot.get_emoji(877247467459084298)
await ctx.message.add_reaction(emoji2)
await ctx.send('You can not use this command here,open a ticket to get the right role')
await ctx.author.send('DM: ')
I suggest not using commands.has_any, because you need to use on_command_error which is not the nicest thing.
You should check if. a certain role is in the author
if special_user_id in [role.id for role in ctx.author.roles]

How to allow only one person at a time to use discord bot

So I have this line of code:
async def on_message(message):
if message.content == "!test":
await asyncio.sleep(15)
await message.channel.send("Hello world"!)
If I want this line of code to run ONLY to one person at a time (that is, if someone else is using the bot other people will not be able to use the bot), how should I code this?
I'm using discord.Client() instead of discord.Bot(), and I intend to keep it that way.
If you want to make that only 1 person can use it at a time so you can add an if statement as I have added below:
occupied = False
#client.event
async def on_message(message):
global occupied
if not occupied:
occupied = True
elif occupied:
await ctx.send("Someone is using command pls wait")
return
if message.content == "!test":
await asyncio.sleep(15)
await message.channel.send("Hello world"!)
I have added the if statement so if someone runs command var occupied will be true and then if someone else tries to run the command it will show someone is using it.

Discord bot function stops working when in a guild with other specific bots

Ok, So..I have made an on guild join captcha for my bot. Works how you'd think it would work. User joins, gets a DM with a captcha, user completes the captcha, they get access/a role. They fail the captcha, it regens a new one and says try again.
The following code works flawlessly and without error except for when it can't DM a user (not my issue that I need help with).
HOWEVER, and idk if this has anything to do with my code or discord intents or other discord bots in the same server my bot is in..but when the bot is in a server alone with no other bots, works flawlessly with all functionality. The moment I have the bot in the server with Welcomer bot for example. It generates the captcha, sends it to the user, then nothing.. no response, no error on my end. Just nothing. The user can send the captcha answer all they want but they get no response, no role, no error or new captcha. The rest of the bots commands and code still work and the bot remains online.
I know the code works and functions fully because I just tested it multiple times with many different people including myself.
It's just when it is in the same server with other bots that it just stops working. Some bots don't interfere but others do and I have no way of telling until I start kicking them until I find the one stopping my bots DM captcha stuff from working. Like welcomer bot. I know it sounds weird but it's true. I've spent literal weeks testing this out and this is all just what I've found out. I am honestly out of ideas..
Like I said, idk if it has anything to do with the discord bots intents or my code. I was hoping someone here could have answers or an explanation.
This is what I have for my bots intents.
intents = discord.Intents.default()
intents.members = True
BOT_Prefix=("t.", "T.")
eye = commands.Bot(command_prefix=BOT_Prefix, intents=intents) #eye replaces Client. So instead of #Client.command/event it's #eye.command/event.
And this is the captcha code/function.
#eye.event
async def on_member_join(user: discord.Member):
while True:
verified = discord.utils.get(user.guild.roles, id=649739504940351489)
res = r.get("https://captcha.manx7.net/insecure/new", headers={"captcha-length":"5"}).json();
if res['error']:
print(res['error'] + " - Manx7 Error")
user.send("Something went wrong while trying to set-up a captcha session, please contact `" + bot_author + "` for help.")
return
captcha_answer = res['response']['code']
embed = discord.Embed(title="Server Captcha", description=f"```fix\nHello {user.name},\nYou will not be able to gain access to the server until you complete this captcha.\nPlease Type The Follwoing Below To Verify!!\n\nNotes:\n1)The letters are case sensitive and are the big colorful ones.\n\n2)DM " + bot_author + " if the bot breaks or if you encounter any bugs!!\n\n-----------------------------\nCaptchca API - https://captcha.manx7.net/```")
embed.set_footer(text=f"{botver} by Ori", icon_url='https://cdn.discordapp.com/attachments/850592305420697620/850595192641683476/orio.png')
embed.set_image(url=res['response']['image'])
await user.send(embed=embed)
#Everything above this line/message works fine every time.
msg = await eye.wait_for("message")
if msg.author.id == eye.user.id:
return #Ignores itself (Used to send captcha, error then send it again when a user joined. This stops that.)
if msg.author.bot:
return #Ignores bots
if msg.content == captcha_answer:
embed2 = discord.Embed(title="Verified!", description=f":white_check_mark: Thank you for verifying!. You have now been given access to the server!", color=discord.Color.green())
embed2.set_footer(text=f"{botver} by Ori", icon_url='https://cdn.discordapp.com/attachments/850592305420697620/850595192641683476/orio.png')
await user.send(embed=embed2)
await user.add_roles(verified, reason="None")
break
else:
embed3 = discord.Embed(title="Error!", description="\n\n__Captcha Failed, Please Try Again__\n\n", color=discord.Color.red())
await user.send(embed=embed3)
pass
Your guess is as good as mine. This has been an issue of mine for weeks now going on a month..
Any help is appreciated.
Since no check kwarg was provided in your wait_for, it will take input from all users, including bots + in any channel visible to the bot.
So, when a user joins and welcomer post its welcome message in a channel
if msg.author.bot:
return #Ignores bots
is triggered
Do notice, you are returning and not passing so it returns and after that your wait_for becomes useless
define a check function and use the following check kwarg inside your wait_for constructor
def check(m):
return m.author == user and m.channel == x.channel
so your code now becomes:
#eye.event
async def on_member_join(user): # you need not typecast in an event, it by default knows that user is a discord.Member object
while True:
verified = discord.utils.get(user.guild.roles, id=649739504940351489)
res = r.get("https://captcha.manx7.net/insecure/new", headers={"captcha-length":"5"}).json();
if res['error']:
print(res['error'] + " - Manx7 Error")
user.send("Something went wrong while trying to set-up a captcha session, please contact `" + bot_author + "` for help.")
return
captcha_answer = res['response']['code']
embed = discord.Embed(title="Server Captcha", description=f"```fix\nHello {user.name},\nYou will not be able to gain access to the server until you complete this captcha.\nPlease Type The Follwoing Below To Verify!!\n\nNotes:\n1)The letters are case sensitive and are the big colorful ones.\n\n2)DM " + bot_author + " if the bot breaks or if you encounter any bugs!!\n\n-----------------------------\nCaptchca API - https://captcha.manx7.net/```")
embed.set_footer(text=f"{botver} by Ori", icon_url='https://cdn.discordapp.com/attachments/850592305420697620/850595192641683476/orio.png')
embed.set_image(url=res['response']['image'])
x = await user.send(embed=embed)
#Everything above this line/message works fine every time.
def check(m): # m is a Message object
return m.author == user and m.channel == x.channel # return only if the user responded in bot's dms and user is the person who triggered the event
msg = await eye.wait_for("message", check=check)
if msg.author.id == eye.user.id:
return #Ignores itself (Used to send captcha, error then send it again when a user joined. This stops that.)
if msg.content == captcha_answer:
embed2 = discord.Embed(title="Verified!", description=f":white_check_mark: Thank you for verifying!. You have now been given access to the server!", color=discord.Color.green())
embed2.set_footer(text=f"{botver} by Ori", icon_url='https://cdn.discordapp.com/attachments/850592305420697620/850595192641683476/orio.png')
await user.send(embed=embed2)
await user.add_roles(verified, reason="None")
break
else:
embed3 = discord.Embed(title="Error!", description="\n\n__Captcha Failed, Please Try Again__\n\n", color=discord.Color.red())
await user.send(embed=embed3)
pass

Need help getting discord.py bot to edit message when multiple users react

I am trying to make an command for hosting events within discord. How I am trying to get it to work is when any users react to the message's pre-sent reaction the field "entered" is edited to add the username of any user that reacts. I have got the bot to await for a reaction and it effectively edits an embedded message to add a field. Problem is i need it to accept more then one users reaction (multiple users) and update the field every time so it shows everyone who has reacted in the embed field. The code I have right now works for the first user but stops working for anyone after that.
Here is my code so far:
# Event creation command
#bot.command()
async def eventcreate(ctx, arg1, arg2):
eventembed = discord.Embed(
title= ":partying_face: GIVEAWAY!!! :partying_face:",
color=7419530
)
eventembed.add_field(
name= "Event",
value=arg1,
inline=False
)
eventembed.add_field(
name= "Prize",
value=arg2,
inline=False
)
message = await ctx.send(embed=eventembed)
await message.add_reaction('🥳')
def check (reaction, user):
return str(reaction.emoji) == '🥳' and user != bot.user
while True:
try:
reaction, user = await bot.wait_for('reaction_add', timeout=604800, check=check)
if str(reaction.emoji) == '🥳':
reacted = user.name
eventembed.add_field(
name= "Entered:",
value= f"```{reacted}```",
inline=False
)
await message.edit(embed=eventembed)
await message.remove_reaction(reaction, user)
except asyncio.TimeoutError:
await message.remove_reaction('🥳')
Any help with this would be greatly appreciated. Thanks in advance!!
This is because the await bot.wait_for only waits for 1 event. You'll need to put that inside a loop.

How would I make my bot made in discord.py create a text message with custom permissions?

So I have a discord bot made with python3.6, and I want him to create a text channel, but only for admins.
I know how to create a text channel using await client.create_channel(), but I do not know how would I set custom permissions and how would I send a message to it.
Thank you!
My code (in case you need it):
#client.event
async def discord.on_server_join(server):
await client.send_message(channel, "Thank you for using Phantom. From all the developers, we want to thank you, as we know there are thousands of other bots out there.")
await client.send_message(channel, "You should see that a new channel was created and is called \"Phantom\". That is the phantom moderation channel and is used for administrating your phantom instance.")
server = ctx.message.server
await client.create_channel(server, "Phantom", type=discord.ChannelType.text)
#client.event
async def on_message(message):
# The code continues here, but I think you only need the on_server_join function.
The documentation for create_channel provides a similar example. Below, it is updated to make the channel visible to any role with administrator permissions.
def overwrites(server):
invisible = discord.PermissionOverwrite(read_messages=False)
visible = discord.PermissionOverwrite(read_messages=True)
perms = [(server.default_role, invisible)]
for role in server.roles:
if role.permissions.administrator:
perms.append((role, visible))
return perms
#client.event
async def discord.on_server_join(server):
await client.send_message(channel, "Thank you for using Phantom. From all the developers, we want to thank you, as we know there are thousands of other bots out there.")
await client.send_message(channel, "You should see that a new channel was created and is called \"Phantom\". That is the phantom moderation channel and is used for administrating your phantom instance.")
server = ctx.message.server
channel = await client.create_channel(server, "Phantom", *overwrites(server), type=discord.ChannelType.text)
await client.send_message(channel, "Hello!")
The simplest way of doing this is trying to check the if a player has a specific role,
for instance, checking if the player has the admin role. Here's a example.
if message.content.lower().startswith('/admin'):
role = discord.utils.get(message.server.roles,id='420576440111726592') #Replace the numbers with your role's id
if "340682622932090890" in [role.id for role in message.author.roles]: #Do the same here
await client.send_message(message.channel, "Aye you have admin!")
else:
await client.send_message(message.channel, "You do not have permissions to do this command")
I'm not a expert and also haven't tested this out, So tell me if it doesn't work.

Resources