So I'm making this weird kinda discord bot. It displays a set of obstacles, and adds a corresponding key that you need to press to a string. It adds a 'w' for every '...', and an 's' for every '***'. In Discord, the player has to type the correct string in to pass the level. So it all works and displays properly. The call function is '!go', and that displays the level. But it fails me before I can type in the string. I want to know, why is it automatically activating? My message.content function is outside that loop. I think it is because I type '!go' and it doesn't reset my message. Here is the code:
#client.event
async def on_message(message):
global correct_answerS
correct_answerS = ""
obstacleList = []
for i in range (0, 24):
randNum = random.randint(1,2)
if randNum == 1:
obstacleList.append('...')
correct_answerS += 'w'
if randNum == 2:
obstacleList.append('***')
correct_answerS += 's'
if message.content == ('!practice'):
sky = str("```css\n A ... ... *** ...```")
skyembed = discord.Embed(title="!============================!")
skyembed.add_field(name='When you see three dots, it is a w. When you see 3 asteriks, it is an s.', value = sky)
await message.channel.send(embed=skyembed)
if message.content == ('wwsw'):
await message.channel.send("Success.")
if message.content == ('!go'):
randlev = (str("```css\n A "))
for i in range(0, 24):
randlev += (str(obstacleList[i]) + " ")
randlev += "```"
randlevembed = discord.Embed(title="!===============================================!")
randlevembed.add_field(name='Good luck!', value = randlev)
await message.channel.send(embed=randlevembed)
print(correct_answerS)
if message.content == (correct_answerS):
await message.channel.send("Success!")
else:
await message.channel.send("Fail.")
#client.event
async def on_ready():
print("Ready")
print(client.user.id)
print('--------------------------')
await client.change_presence(activity=discord.Game(name='up and away'))
client.run(Token)
There is no error message, just as soon as I type '!go', it displays the level and then continually says 'Fail.' until I stop it.
I don't know what to do, any help is just that, helpful. Thanks.
The bot is stuck in a loop where it's sending a message, and then processing that message, which causes it to send another message, etc. You can add a check to the beginning of on_message to force it to ignore bot-generated messages:
#client.event
async def on_message(message):
if message.author.bot:
return
...
Related
Wow... Hello, I'm back here after two days. (Thank you to the person who helped me last time..)
First of all, this code works in the direction I want.
However, there is a problem.
This bot's command is "!공지". However, this bot sends me a message because the code works no matter what chat I write... I want to make it work only when I write "!공지"
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith("!공지"):
await message.channel.purge(limit=1)
i = (message.author.guild_permissions.send_messages)
if i is True:
notice = message.content[4:]
channel = client.get_channel(927233433489526904)
embed = discord.Embed(title="*브리핑*", description="\n――――――――――――――――――――――――――――\n\n{}\n\n――――――――――――――――――――――――――――".format(notice), color=0x00ff00)
embed.set_footer(text="-C0de")
embed.set_thumbnail(url="https://i.imgur.com/UDJYlV3.png")
await channel.send (embed=embed)
if i is False:
await message.channel.send("{}, 당신은 관리자가 아닙니다".format(message.author.mention))
If you want the code to exit if the user's message doesn't start with "!공지" then add
if message.content.startswith("!공지"):
await message.channel.purge(limit=1)
else:
return
This will exit the function if the message does not start with those characters.
The problem lies in this:
i = (message.author.guild_permissions.send_messages)
if i is True:
Since anyone who writes something has that permission, i will always be true.
I guess what you want to do is to indent those two lines, so it is inside the if-block that checks the command.
Try moving your i = (message.author.guild_permissions.send_messages) line to the same indentation as the if conditional, while also initializing your i before the if-else statement:
i = False
if message.content.startswith("!공지"):
await message.channel.purge(limit=1)
i = (message.author.guild_permissions.send_messages) # set only in condition.
else:
i = False
When inserted in code:
#client.event
async def on_message(message):
if message.author == client.user:
return
i = False # initialize i
if message.content.startswith("!공지"):
await message.channel.purge(limit=1)
i = (message.author.guild_permissions.send_messages) # set only in condition.
else:
i = False
if i is True:
notice = message.content[4:]
channel = client.get_channel(927233433489526904)
embed = discord.Embed(title="*브리핑*", description="\n――――――――――――――――――――――――――――\n\n{}\n\n――――――――――――――――――――――――――――".format(notice), color=0x00ff00)
embed.set_footer(text="-C0de")
embed.set_thumbnail(url="https://i.imgur.com/UDJYlV3.png")
await channel.send (embed=embed)
if i is False:
await message.channel.send("{}, 당신은 관리자가 아닙니다".format(message.author.mention))
This should let your code properly branch based on the command
I am a beginner in python and i am to trying to code a discord game bot in which you have to choose your paths.
I want that the user first run !adv command and then can press 'c' to continue but my code is not able to do so.
I am not getting any error but after running the !adv command ,i am not able to run the 'c' command to further do something.
client = discord.Client()
#client.event
async def on_ready():
general_channel = client.get_channel(864471185907908608)
await general_channel.send('Hey!')
#client.event
async def on_message(message):
count = 0
msg = message.content.lower()
general_channel = client.get_channel(864471185907908608)
if count == 0:
if msg == '!adv':
await general_channel.send('Hello '+ message.author.name +'. \nWelcome to the Lands of The Supreme Lord , The Godfather.\nYou woke up in the marketplace with crowd bustling everywhere.\nYou have many questions.\nWhat led you to this place and whats your destiny?\nYou are set to write your own path here.\nPress c to continue.')
count += 1
async def on_message(message):
msg = message.content.lower()
if count == 1:
if msg == 'c':
await general_channel.send('\nYou see a vase shop and an weaponsmith ahead.\nDecide who you want to talk.\nType v or w')
Please include the code for the solution as well because it is easy to understand with code.
Thanks in advance
You cannot really have more than one on_message (though you're not registering the second one as an event). To wait for a user response you should use client.wait_for:
#client.event
async def on_message(message):
def check(m): # simple check to wait for the correct user
return m.author == message.author and m.channel == message.channel
count = 0
msg = message.content.lower()
general_channel = client.get_channel(864471185907908608)
if count == 0:
if msg == '!adv':
await general_channel.send('Hello '+ message.author.name +'. \nWelcome to the Lands of The Supreme Lord , The Godfather.\nYou woke up in the marketplace with crowd bustling everywhere.\nYou have many questions.\nWhat led you to this place and whats your destiny?\nYou are set to write your own path here.\nPress c to continue.')
# Waiting for the response
resp = await client.wait_for("message", check=check)
if resp.content.lower() == "c":
# continue the story
await general_channel.send('\nYou see a vase shop and an weaponsmith ahead.\nDecide who you want to talk.\nType v or w')
resp2 = await client.wait_for("message", check=check)
if resp2.content.lower() in ["v", "w"]:
# continue the story
...
count += 1
You might wanna use some return statements to not have such deep indentation.
I have been making a Discord bot for one of my servers, and one of it's functions is to prevent curse words. I want it to toggle the censor mode when you type in a command. However, instead of switching the variable to 1 and back again, it just stays on 0, even though I get the "Bad words will now not work" output.
#client.event
async def on_message(message):
swareCensor: int = 0
if message.content == 'f! censor':
if swareCensor == 0:
await message.channel.send('Bad words will now not work')
swareCensor += 1
else:
await message.channel.send('The bad word filter is now off')
swareCensor *= 0
if swareCensor == 1:
if 'fuck' in message.content:
await message.delete()
await message.channel.send('Sware has been detected')
It wouldn't be ideal for swears to be censored all the time, especially if I want it on multiple servers
I would first of all strongly recommend using the actual command method instead of saying if message == "!command" in an onMessage event.
swearFilter = False
#client.command()
async def sensor(ctx):
swearFilter = not swearFilter
await ctx.send(f"Swear filter is now set to {swearFilter}")
#client.event()
async def on_message(message):
if swearFilter:
if "fuck" in message.content:
await message.delete()
await message.channel.send("Swear detected!")
i am creating a python discord bot, and i have a function that if a message is sent in a certain channel,
it randomly sends out a response,everything works fine but i want to restrict the bot to react only when the sent message contains a png, jpg or jpeg file
heres the code(look for the bottom if str(message.channel) statement):
#client.event
async def on_message(message):
await client.process_commands(message)
if str(message.channel) not in restr:
if message.content == ".sabaton":
random.seed(time.time())
randnum = random.randint(0, len(songs) - 1)
await message.channel.send(file=discord.File(songs[randnum]))
elif message.content == ".time":
await message.channel.send(f"Current time is {time.localtime()}")
elif message.content == ".pmsh":
await message.channel.send(help)
if client.user.mention in message.content.split():
await message.channel.send('Дарова гандон(иха),мой префикс "."')
if str(message.channel) == "🥳творчество🥳":
random.seed(time.time())
rn3 = random.randint(1,2)
if rn3 == 1 and message.author.bot == False:
await message.channel.send("Заебись творчество")
elif rn3 == 2 and message.author.bot == False:
await message.channel.send("Фигня творчество")
Attachments in discord.py have information about their file type in their content_type attribute. This should hopefully make for cleaner code too!
Apart from the access, #Sofi's logic still applies:
for attachment in message.attachments:
if attachment.content_type in ('image/jpeg', 'image/jpg', 'image/png'):
# Your Logic Here
If you just need to check if something is an image, your code can be simpler:
for attachment in message.attachments:
if 'image' in attachment.content_type:
# Your Logic Here!
You can use the following conditions to restrict it:
if message.attachments[0].url.endswith('PNG') or message.attachments[0].url.endswith('JPG') or message.attachments[0].url.endswith('JPEG'):
pass
else:
pass
Change the pass according to your content.
New python-enthusiast here.
I am currently making a discord bot that responds with 16 pictures in a 4x4-grid when a specific user types in the chat:
XXXX
XXXX
XXXX
XXXX
This is my current code:
import discord
from secrets import TOKEN
from emotes import *
# user IDs
bonvang_ID = "417010736988946444"
djursing_ID = "124806046568022016"
jonathan_ID = "151788707760832512"
alex_ID = "151745760935936001"
snuffles_ID = "221360712222507009"
# bot = commands.Bot(command_prefix='!')
client = discord.Client()
# prints message in terminal when bot is ready
#client.event
async def on_ready():
print(f"Logged in as {client.user}")
# #client.event
# async def on_member_join(member):
# await message.channel.send(f"""Welcome to the server {member}!\n
# I'm just a simple bot made by Mr.Nofox.\n
# If you want to know more about the commands, ask him or try your luck with the others! :)""")
def member_amount():
# create a variable that contains all the servers
active_servers = client.servers
# create a variable to store amount of members per server
sum = 0
# loop through the servers, get all members and add them up, this includes bots
for s in active_servers:
sum += len(s.members)
return sum
def picture_grid():
return (f"{pic01} {pic02} {pic03} {pic04}\n{pic05} {pic06} {pic07} {pic08}\n{pic09} {pic10} {pic11} {pic12}\n{pic13} {pic14} {pic15} {pic16}\n)
#client.event
async def on_message(message):
# print(f"{message.channel}: {message.author}: \"{message.content}\"")
guild = client.get_all_members()
if "!count()" == message.content:
await client.send_message(message.channel, f"```py\nTotal members: {member_amount()}```")
elif "!report()" == message.content:
online = 0
idle = 0
offline = 0
for member in guild:
if str(member.status) == "online":
online += 1
if str(member.status) == "offline":
offline += 1
if str(member.status) == "idle" or str(member.status) == "dnd":
idle += 1
await client.send_message(message.channel, f"```Online: {online}\nIdle/busy.dnd: {idle}\nOffline: {offline}```")
#TODO: Make a neat function for the pictures in message that responds with 4x4 image in chat when a given user types
if (message.author.id == alex_ID or message.author.id == snuffles_ID):
await client.send_message(message.channel, "DET ER MIN SØN!")
await client.send_message(message.channel, picture_grid())
# add bot-token found on website
client.run(TOKEN)
All the emotes are in a file called "emotes.py" which I import.
Each emote is a string-code, example:
pic01 = '<:1_:543049824644235265>'
The line I am using to get this to work atm. is:
await client.send_message(message.channel, f"{pic01} {pic02} {pic03} {pic04}\n{pic05} {pic06} {pic07} {pic08}\n{pic09} {pic10} {pic11} {pic12}\n{pic13} {pic14} {pic15} {pic16}\n")
This is awful coding practice and therefore I want to make a function that returns:
f"{pic01} {pic02} {pic03} {pic04}\n{pic05} {pic06} {pic07} {pic08}\n{pic09} {pic10} {pic11} {pic12}\n{pic13} {pic14} {pic15} {pic16}\n"
My initial thought was something like:
def picture_grid():
return (f"{pic01} {pic02} {pic03} {pic04}\n{pic05} {pic06} {pic07} {pic08}\n{pic09} {pic10} {pic11} {pic12}\n{pic13} {pic14} {pic15} {pic16}\n")
This does the trick and converts the first code to:
await client.send_message(message.channel, picture_grid())
But merely moves the bad code to another place.. I am currently stuck by what should be a simple task.
Any ideas?