im making a bot for my discord server but i have problem and my problem is this:
There is a command for the warning which is $warn and a command to remove the warnings is $clrw and another command to show the warnings is $warns but there is a problem.
When the user uses the $clrw command, it means that the variable that is accumulated during the warning becomes 0, but for all users, it means when the user use $clrw #moonboyInstead of only the desired person's warren being deleted, all people's warrens are deleted and this is a big problem!
my code:
#app.command()
# #commands.has_permissions(Warning = True)
async def warn(ctx,member: discord.Member,*,reason = None):
global num
if reason == None:
await ctx.send(f"hey {ctx.author.mention} pls enter a reason!")
else:
num += 1
# await member.send(f"hey {ctx.author.mention} you have been warned bequase {reason} from {ctx.guild.name} pls dont do it again!")
await ctx.send(f"{member} has been warned bequase {reason} ! ")
return num
#app.command()
async def clrw(ctx,member:discord.Member):
global num
num = 0
await ctx.send(f"{member} warns has been deleted!")
#app.command()
async def warns(ctx,member: discord.Member):
if num <= 0:
await ctx.send(f"{member} has no warns!")
else:
await ctx.send(f"{member} has {num} warns!")
the global variable num is not related to any particular user. If you wanted to do it per user, you could use a dictionary of their user ids.
warns = dict()
# add a warning
userid = member.id # not sure if this is exactly how to get id, check docs
if userid not in warns:
warns[userid] = 1
else:
warns[userid] += 1
# clear warnings
warns[userid] = 0
# display warnings
if warns[userid] == 0:
await ctx.send(f"{member} has no warnings")
else:
await ctx.send(f"{member} has {warns[userid]} warnings")
(This is all pseudocode to show how dicts work. This will obviously not work when pasted directly into your code)
You're lacking understanding of the variable num.
The Problem:
Atm what you are doing is, just adding and removing to the same variable or number in this case.
The code cannot know if u meant a diff user this way.
The Fix:
You should convert ur variable num to a dictionary. If the bot is gonna be for just one server then a simple dictionary should be enough.
Example:
When doing the current num +=1 replace it with num[member.id] +=1
For reset instead of num = 0 do num[member.id] = 0
For the getting of warnings, instead of num do num[member.id]
In this case u will mention who exactly u want to reset the warns for, get it from or add to.
Also don't forget to convert the current num value where u set it the first time to num = []
Hope this helps!
PS. The amount of warns will reset on bot restart, as this is a variable in the code its not saved anywhere outside. I would recommend saving it in a file or redis server.
Example code for the error in the comment:
Use this for the command where u add the warning.
The reason u got that error is that u cannot add a +1 warning to an user who is not added in the array itself.
if member.id not in num:
num[member.id] = 1
else:
num[member.id] +=1
So u don't get a similar error with the getting of the warn.
Example:
if member.id not in the num or num[member.id] == 0:
await ctx.send(f"{member} has no warns!")
else:
await ctx.send(f"{member} has {num[member.id]} warns!")
Related
I made a bot, and now I want to add a "guess" command where the user tries to guess a number between 1 - 100. The bot will generate a random number and then I want it to record messages after the command has been sent, and only the messages of that user.
Here is the code that I've made so far:
##GUESS COMMAND
#client.command(name="guess")
async def guess(ctx):
await ctx.reply("I thought of a number between **1 and 100, You got 5 guesses good luck!**")
guesses = 0
num = random.randint(1, 100)
print(num)
So like Me: .guess Bot: I thought of a number between 1 and 100, You got 5 guesses good luck! Me:33 Bot: Incorrect, the number that I guessed is lower/higher (depending on the num var and what the user sent after the command)
I added the guesses variable which adds 1 everytime the user guessed a number to keep track of how many guesses were sent so if it reaches 5 the bot will stop the command and say something like "The number i guessed was ..." and I added print(num) for debigging purposes
I tried adding on_message after the command, but it didn't work out
#client.command(name="guess")
async def guess(ctx):
await ctx.reply("I thought of a number between **1 and 100, You got 5 guesses good luck!**")
guesses = 0
num = random.randint(1, 100)
while True:
if guesses>5: # Just in case so it always makes sure there are 5 attempts
await ctx.reply("No more attempts left") # Tell about no more attempts
break # Break the loop so it doesn't wait for new messages
msg = await client.wait_for('message',check=lambda m:m.author == ctx.author and m.channel == ctx.channel and m.content.isdigit()) # Wait for a message in the same channel, by the same user, and make sure the message content is numeral
guesses+=1 # Another attempt to guess
num_ = int(msg.content) # The number which the user tried to guess
if num!=num_:
await ctx.reply(f"Incorrect! The number that I chose is {'higher' if num_<num else 'lower'}") # tell about it, one lined if else
else: # if its correct
await ctx.reply(f"Correct! The number that I chose was {num}") # The message about it
break # no need to wait for messages again
if guesses == 5: # no more attempts left
await ctx.reply(f"No more attempts left my number was {num}!") # Tell about it
break #no more checking
print(num)
Hey there, thats the answer, I made a lot of discord bots, so if you got questions, be sure to hit me up ;)
Edit:
Since I was asked to explain it, I did it, again if you have questions, be sure to let me know :)
In my bot, the user has to enter the date of birth, then I have to transfer this date into a set function, the result of which is later inserted as an index into a list, from where the corresponding image will be sent to the user.
Now I will show you a part of the code, it's an example of both the handler and the function, through which I want to run the user's message. As long as you use a randomly generated number and not the result from the function, everything works perfectly. The thing is that I need exactly the result you get through the calculations and for that I need to insert the message sent by the user into a variable, so that you could continue working with it - and that's exactly what I fail to accomplish.
The Question: how do you assign the user’s message to a variable in aiogram in order to further interact with it?
#dp.message_handler(commands=['start'])
async def begin(message: types.Message):
await bot.send_message(message.from_user.id, f"{text1}")
#dp.message_handler()
async def datarozh(message: types.Message):
if message.text[2] == '/' and message.text[5] == '/' and len(message.text) == 10:
await bot.send_message(message.from_user.id, f"blablabla", reply_markup=mainmenu)
elif message.text == 'Begin':
chatid = message.from_user.id
arkankart = InputFile(path_or_bytesio=f"{img_list[result_def]}") # this is where you need to substitute the value from the function after processing the user's message
await dp.bot.send_photo(chat_id=chatid, photo=arkankart, caption='blablabla')
data = "11/11/2011" # the plan is to use the user's message instead of data
s = data.split('/')
lisst = []
for i in s:
lisst.append(int(i))
def day(a): # I have several different variations of the functions through which I would run the user's message, here's one of them
result = 0
while a[0] != 0:
b = a[0] % 10
result += b
a[0] = a[0] // 10
return result
You can use function message.text to check the user's message.
#dp.message_handler()
async def send_answer(message: types.Message):
if message.text == "Test1":
print("Cool!")
So if you would to assign user's message to a variable:
#dp.message_handler()
async def send_answer(message: types.Message):
your_variable = message.text
if your_variable == "Test1":
print("Cool!")
This question already has answers here:
Why does on_message() stop commands from working?
(2 answers)
Closed last year.
So I've been writing a bot using discord.py, and I've found an error I can't seem to be able to fix.
First, I have something like this:
#client.command()
async def ping(ctx):
await ctx.send("Pong!")
Then I added an entire section here:
#client.event
async def on_message(message):
# print(message)
if message.content.startswith('$random'):
if len(message.content) == 7:
await message.channel.send("**You need to provide a valid number range. Examples: *$random 7 69 | $random 69 (automatically sets the first number as 1)***")
else:
if message.content.split(" ",1)[1] == "help":
await message.channel.send("**You need to provide a valid number range. Examples: *$random 7 69 | $random 69 (automatically sets the first number as 1)***")
try:
if message.content.split(" ",2)[2] != "":
number1 = int(message.content.split(" ",2)[1])
number2 = int(message.content.split(" ",2)[2])
number2send = str(random.randint(number1,number2))
await message.channel.send("Your random number is: **" + number2send + "**")
return
except:
try:
if message.content.split(" ",1)[1] != "":
number = int(message.content.split(" ",1)[1])
number2send = str(random.randint(1,number))
await message.channel.send("Your random number is: **" + number2send + "**")
return
except:
await message.channel.send("**You need to provide a valid number range. Examples: *$random 7 69 | $random 69 (automatically sets the first number as 1)***")
return
if message.content.startswith('$timein'):
if len(message.content) == 7:
await message.channel.send("**You need to provide a valid country***")
else:
try:
lad = message.split(" ",1)[1]
print("Location address:", lad)
location = geolocator.geocode(lad)
print("Latitude and Longitude of the said address:")
print((location.latitude, location.longitude))
# pass the Latitude and Longitude
# into a timezone_at
# and it return timezone
obj = TimezoneFinder()
# returns 'Europe/Berlin'
result = obj.timezone_at(lng=location.longitude, lat=location.latitude)
print("Time Zone : ", result)
except:
return
And any command made like the first section and $timein command does not work anymore, while both worked on their own, and I have no idea why.
I feel like the errors are caused by the differences in
#client.command
and
#client.event
So this is probably what's causing the issue.
Anyways, to any kind people helping me with these, thanks in advance!
Your commands doesn't work because of on_message. What happens is you are overriding the default on_message and defaut on_message is the one that handles the commands. You can fix it by adding a bot.process_commands(message) line at the end of your on_message.
Discord.py has this issue covered on it's F.A.Q, read more here.
Also, a side note. Please don't handle commands by yourself, Discord.py's commands extension has a lot of features you probably didn't discover. Please learn more about commands, it will save tons of work from your shoulders and will be easier to develop your dream bot.
Im Trying To Make A Rapid Fire Type Question, Basically "j" is the variable for points and i want it to change/decrease (and to check for messages) every 0.5 seconds ... The Problem Is That No Matter How Late I Try I get 1000 points. Also Im New. (btw sorry for bad english)
The Code:
def check(m):
return m.author == message.author and m.channel
mn = randint(5, 15)
mn1 = randint(5, 10)
mz = mn * mn1
membed = discord.Embed(
title="Here's The Question",
description=str(mn) + " * " + str(mn1) + ''' Type Your Answer Below.. ''',
url=None,
color=discord.Color.blue())
mzz = await message.send(embed=membed)
j = 1100
for i in range(0, 5):
sleep(0.5)
j = j - 100
gt = await bot.wait_for('message', check=check)
if int(gt.content) == int(mz):
await message.send(f'Its Right.. You Got **{j}** Points')
else:
await message.send(f'Its Wrong.. The Answer Is **{j}**')
Please Help...
The issue is because you're misunderstanding how await works.
await foo() causes your program to sleep until foo() returns a value.
When you type await bot.wait_for(), you are saying:
Sleep until bot.wait_for() returns a value
bot.wait_for() only returns a value when it receives a message.
The full flow of your program is thus:
You enter the first loop i = 0. j gets set to 1000.
You sleep until you receive a message. Because you can receive a message any time in the future (say, ten seconds or ten minutes or fifteen hours, etc.), you never enter the second loop i = 1. Basically, your program is frozen at this point until somebody sends you a message.
The solution here is to ask your bot to time out waiting for a message, so it can continue to the next value of i. A timeout tells your bot to sleep only for a specified amount of time before continuing your program. Conveniently, the wait_for command provides a timeout parameter:
j = 1100
for i in range(0, 5):
j = j - 100
try: # A try/except block is needed because this throws an error if bot times out
gt = await bot.wait_for('message', check=check, timeout=0.5)
if int(gt.content) == int(mz):
await message.send(f'Its Right.. You Got **{j}** Points')
break
else:
await message.send(f'Its Wrong.. The Answer Is **{j}**')
except:
continue
else:
await message.send("Whoops, you're out of time! You got zero points.")
How do you make a bot respond to a message and ask a question, like
Me:!guess 10
bot: pick a number between 1 and 10
me: 4
bot: incorrect, it was 5!
I can't figure out how to do this,
because once you respond to a command, I don't know how to have something like a global variable to save the answer.
This is some code I used, hopefully this will help, this give you 5 guesses to get it right and it gives you hints with bigger and expands on what you wanted, so you could adapt it if you don't want the bigger and smaller!
#commands.command()
async def game(self, ctx):
number = random.randint(0, 100)
for i in range(0, 5):
await ctx.send('guess')
response = await self.bot.wait_for('message')
guess = int(response.content)
if guess > number:
await ctx.send('bigger')
elif guess < number:
await ctx.send('smaller')
else:
await ctx.send('yes!')