Discord.py bot.wait_for - python

#commands.command()
async def verify(self, ctx, length=10):
verify_characters = []
for _ in range(length):
verify_characters.append(random.choice(string.ascii_letters + string.digits + "!§$%&/()=?`-.<>"))
verify_msg = "".join(verify_characters)
print(verify_msg)
await ctx.author.send(f"Verify with the number {verify_msg}")
answer = await bot.wait_for('message', check=lambda message: message.author == ctx.author)
print("done")
if verify_msg == answer:
await ctx.author.send("Verified")
else:
await ctx.author.send(f"Verify again!")
Im trying to do a verify system, but after the bot.wait_for task nothing happens, i guess something in the line is wrong, has anybody solutions?

If you want it to be a dm command we can use the restriction #commands.dm_only()
However we then also have to check where the answer was given, we do that via some kind of custom check. I have modified your command a bit, but you can make the changes again personally.
Take a look at the following code:
#commands.dm_only() # Make it a DM-only command
#commands.command()
async def verify(self, ctx, length=10):
def check(m):
return ctx.author == m.author and isinstance(m.channel, discord.DMChannel)
verify_characters = []
for _ in range(length):
verify_characters.append(random.choice(string.ascii_letters + string.digits + "!§$%&/()=?`-.<>"))
verify_msg = "".join(verify_characters)
print(verify_msg)
await ctx.author.send(f"Verify with the number: {verify_msg}")
try: # Try to get the answer
answer = await bot.wait_for("message", check=check)
print(answer.content)
if verify_msg == answer.content:
await ctx.author.send("Verified!")
else:
await ctx.author.send("Verify again!")
except: # Used if you for example want to set a timelimit
pass

Edited to show full answer.
Hey ho done it lol.
Basically the message object contains a lot of data, so you need to pull the content of the message using answer.conent.
https://discordpy.readthedocs.io/en/latest/api.html?highlight=message#discord.Message.content for reference
#bot.command()
async def verify(ctx):
length=10
verify_characters = []
for _ in range(length):
verify_characters.append(random.choice(string.ascii_letters + string.digits + "!§$%&/()=?`-.<>"))
verify_msg = "".join(verify_characters)
print(verify_msg)
await ctx.author.send(f"Verify with the number {verify_msg}")
answer = await bot.wait_for('message')
print(answer.content)
print("done")
if verify_msg == answer.content:
await ctx.author.send("Verified")
else:
await ctx.author.send(f"Verify again!")
Give that a test run and let me know what happens ;)

Related

discord.py adding mentioned users to list

I want to make disposable register system by using list which makes adding the discord user to list when you mentioned it but when i try to get user input from message it fails
#bot.command()
async def gameset(ctx,playernum:int):
if playernum <= 10:
await ctx.send('player 1 "<assign #player" mention yourself like this!')
else:
await ctx.send('maximum 10 player!')
num = 1
while num < playernum:
playerlist = []
#bot.command()
async def assign(user):
if user == discord.User.mentioned_in(message=user):
listadd = user
playerlist.append(listadd)
await user.send(f"player {num + 1} mention yourself!")
elif user != discord.User:
await user.send("not user")
else:
await user.send("go fix it dumb")
if playerlist[num - 1] == discord.User:
num = num + 1
else:
await gameset.send("problem with the listing")
also i think this is not the only problem i tried like this too but then my mention/user percaption logic failed i think
#bot.command()
async def ata(user : discord.User):
if not user:
await user.send("go fix it dumb")
else:
listadd = user
playerlist.append(listadd)
await user.send(f"player {num + 1} mention yourself!")
I've tried with #bot.event but i made more progress with #bot.command so if this is able to do with #bot.event i would be pleased if you guys help me understand how can i do with event but command is sufficient too.
Edit: I tried using wait_for() command like this:
num = 1
while num < playernum:
playerlist = []
def check(msg2 : discord.member):
return msg2 == discord.mentions
msg2 = await bot.wait_for("message", check=check)
# player = await bot.fetch_member(msg2.id)
if msg2 == discord.member:
player = str(msg2.id)
listadd = player
playerlist.append(listadd)
await ctx.send(f"player {num + 1} mention yourself!")
num = num + 1
else:
await msg2.send("go fix it dumb")
and i think it worked but now i have another problem which is
discord.ext.commands.errors.CommandNotFound: Command "#!id>" is not found
i get this when i try to mention someone

How can i prevent swearwords on the server on discord.py

I am trying to block messages which contain swearwords.Swearwords in a text file btw.So,I got stuck because whenever I write swearwords,bot doesn't response my message.This is my code:
#client.event
async def on_message(message):
global swearword_count
global badwords
if message.author == client.user:
await client.process_commands(message)
else:
msg = message.content
for x in msg:
try:
if x in badwords:
if exception_counter[str(message.author.id)] == 0:
await message.channel.send("Please do not use this word ever")
swearword_count[str(message.author.id)] += 1
if swearword_count[str(message.author.id)] > 5 and exception_counter == 1:
await message.author.send("You've been banned due to bad words that you used.")
elif swearword_count[str(message.author.id)] > 5 and exception_counter == 0:
await message.author.send("You've been banned due to bad words that you used.")
await message.channel.send("Don't use this word")
else:
pass
except KeyError:
exception_handling[str(message.author.id)] = 1
swearword_count[str(message.author.id)] = 0
await message.author.send("If you use this word,you will get banned.")
continue
await client.process_commands(message)
#client.event
async def on_member_join(member):
channel = discord.utils.get(member.guild.text_channels, name="welcome")
await channel.send(f"{member.name},welcome :)")
global swearword_count
swearword_count[str(member.id)] = 0
exception_handling[str(member.id)] = 0
dm_channell = await member.create_dm()
await dm_channell.send(f"{member},welcome mate :)")
I've used dictionaries to store the data of users.So how can i fix this problem?If you have any advice,I'd love to see it
PS:My commands work properly.
It's because for x in msg: splits your message into single letters. You have to slice it for example by spaces: for x in msg.split(" "):, but this way if someone writes "badword" without spaces (ex. "badwordIlikeapples) this won't work. So try this:
for x in badwords:
try:
if x in msg:
...
This will catch all the "badwords", but if you write a word that contains the swear word inside it this will also be caught.

How do I make a command that checks for a message (Discord.py)

I'm here with a question. I made this command that pings someone but I don't know how to make it stop. Originally it would listen for "~stop" and it would break the message sending loop. It wouldn't work though. Please help!
#client.command()
async def ping(ctx, member:discord.User=None):
pingEvent = 0
if (member == None):
await ctx.send("who do you want me to ping stupid")
if "~stop" in ctx.channel
pingEvent = 0
else:
pingEvent = 1
while pingEvent <= 1:
await ctx.send(
f"{member.mention}"
)
if pingEvent == 0:
break
First of all, your bot will get rate limited and eventually banned for doing this, but for educational purposes. Here is the solution.
Checking for stop inside loop
for _ in range(20): #restrict pings to avoid being banned
await ctx.send(member.mention)
try:
msg = await client.wait_for("message", check= lambda x: x.author == ctx.author and x.content.contains('~stop'), timeout=2)
except asyncio.TimeoutError:
continue
else:
break
This will send a message once per two seconds since we set the timeout to 2. which is well below the rate limit but still breaks the ToS
References:
asyncio.TimeoutError - you have to import it with import asyncio
wait_for
Read the Terms of Services
This should do the trick and might look more simple than the answer above/below
def check(m):
return ctx.channel == m.channel and m.author == ctx.author
try:
message = await self.bot.wait_for('message', check=check, timeout=300)
except asyncio.TimeoutError:
await ctx.send("You've used too long to answer!")
else:
return

discord.py checking permissions within code

I've tried this but it didn't work(i marked the error line), I hope you can help me
#bot.event
async def on_message(message):
if 'https://' in message.content.lower():
if(message.channel.name.startswith("ticket")):
print("")
else:
>>>>>>if(has_permissions(manage_messages = True))
print("")
else:
await message.delete()
embed = discord.Embed(title=f'Message Deleted',description=f'**User** : ``{str(message.author)}``\n**Reason** : ``Url/Link detected in the Message``', color=0xFF0000 )
await message.channel.send(embed=embed)
You have an indentation error (you must add one indent after your first else):
#bot.event
async def on_message(message):
if 'https://' in message.content.lower():
if(message.channel.name.startswith("ticket")):
print("")
else:
if(has_permissions(manage_messages = True))
print("")
else:
await message.delete()
embed = discord.Embed(title=f'Message Deleted',description=f'**User** : ``{str(message.author)}``\n**Reason** : ``Url/Link detected in the Message``', color=0xFF0000 )
await message.channel.send(embed=embed)
To check for permissions withing your code, you can use Member.guild_permissions:
if ctx.author.guild_permissions.manage_messages:
print('You have permission')

how do you convert a python code that requires user input to work in a discord bot?

So I have a piece of code and it requires user input multiple times (and what is inputed is not alway the same). Instead of passing the code to everyone in my discord I would like to make it directly into a discord bot so everyone can use it. How do I all the bot to take in a user msg after a code is given
here is an example of kinda what I want:
-.botcalc
--this is discord bot, enter first number:
-1
--enter second number:
-2
--1+2 = 3
There are two ways you could write this command: one is using the "conversation" style in your question
from discord.ext.commands import Bot
bot = Bot("!")
def check(ctx):
return lambda m: m.author == ctx.author and m.channel == ctx.channel
async def get_input_of_type(func, ctx):
while True:
try:
msg = await bot.wait_for('message', check=check(ctx))
return func(msg.content)
except ValueError:
continue
#bot.command()
async def calc(ctx):
await ctx.send("What is the first number?")
firstnum = await get_input_of_type(int, ctx)
await ctx.send("What is the second number?")
secondnum = await get_input_of_type(int, ctx)
await ctx.send(f"{firstnum} + {secondnum} = {firstnum+secondnum}")
The second is to use converters to accept arguments as part of the command invocation
#bot.command()
async def calc(ctx, firstnum: int, secondnum: int):
await ctx.send(f"{firstnum} + {secondnum} = {firstnum+secondnum}")
Using wait_for
async def botcalc(self, ctx):
author = ctx.author
numbers = []
def check(m):
return m.author == author
for _ in ('first', 'second'):
await ctx.send(f"enter {_} number")
num = ""
while not num.isdigit():
num = await client.wait_for('message', check=check)
numbers.append[int(num)]
await channel.send(f'{numbers[0]}+{numbers[1]}={sum{numbers)}')
edit
Added a check

Categories

Resources