I am new to developing discord bots and have encountered an issue. the "except" function is not working and draws a syntax error.
The error that it draws is here:
File "bot.py", line 36
except MissingRequiredArgument:
^
SyntaxError: invalid syntax
And the code is here:
import random
from discord.ext import commands
client = commands.Bot(command_prefix = '.')
#client.event
async def on_ready():
print("Bot is ready!")
await client.change_presence(activity = discord.Game("with fire"))
#client.command()
async def eightball(ctx, *, question):
repsonses = [ 'It is certain.',
'It is decidedly so.',
'Without a doubt.',
'Yes – definitely.',
'You may rely on it.',
'As I see it, yes.',
'Most likely.',
'Outlook good.',
'Yes.',
'Signs point to yes.',
'Reply hazy, try again.',
'Ask again later.',
'Better not tell you now.',
'Cannot predict now.',
'Concentrate and ask again.',
"Don't count on it.",
'My reply is no.',
'My sources say no.',
'Outlook not so good.',
'Very doubtful.']
embed = discord.Embed(title="Fireplace", description=(f'{repsonses[random.randint(0, 20)]}'), colour = discord.Colour.orange())
embed.set_footer(text = " By logiccc", icon_url="https://pbs.twimg.com/media/C6F-YfVUwAE91mv.jpg")
await ctx.send(embed=embed)
except:
embed = discord.Embed(title="Fireplace", description=("Sorry! Something went wrong... The command syntax is .eightball <question>"), colour = discord.Colour.orange())
embed.set_footer(text = " By logiccc", icon_url="https://pbs.twimg.com/media/C6F-YfVUwAE91mv.jpg")
#client.command()
async def ping(ctx):
embed = discord.Embed(title="Fireplace", description="Pong!", colour = discord.Colour.orange())
embed.set_footer(text = " By logiccc", icon_url="https://pbs.twimg.com/media/C6F-YfVUwAE91mv.jpg")
await ctx.send(embed=embed)```
I have no idea why this happens. Anyone else know?
Edit: I have tried the code in the comment but it doesn't work. I just keep getting the error message in the console and no reply from the bot. Any tips?
You are using try-except the wrong way, take a look at the comments I left in the code below. You can learn about it here.
#client.command()
async def eightball(ctx, *, question):
repsonses = ['It is certain.',
'It is decidedly so.',
'Without a doubt.',
'Yes – definitely.',
'You may rely on it.',
'As I see it, yes.',
'Most likely.',
'Outlook good.',
'Yes.',
'Signs point to yes.',
'Reply hazy, try again.',
'Ask again later.',
'Better not tell you now.',
'Cannot predict now.',
'Concentrate and ask again.',
"Don't count on it.",
'My reply is no.',
'My sources say no.',
'Outlook not so good.',
'Very doubtful.']
try: # Try to do this
embed = discord.Embed(title="Fireplace", description=(f'{repsonses[random.randint(0, 20)]}'),
colour=discord.Colour.orange())
embed.set_footer(text=" By logiccc", icon_url="https://pbs.twimg.com/media/C6F-YfVUwAE91mv.jpg")
await ctx.send(embed=embed)
except: # If can't then do this
embed = discord.Embed(title="Fireplace", description=(
"Sorry! Something went wrong... The command syntax is .eightball <question>"),
colour=discord.Colour.orange())
embed.set_footer(text=" By logiccc", icon_url="https://pbs.twimg.com/media/C6F-YfVUwAE91mv.jpg")
Related
I know next to nothing about coding in Python but I created this bot from tutorials I found online and it does little things in my private server.
One thing we'd love to do is to react to certain messages so they will be collected in a specific channel. I've seen a few servers do this, like a highlights kind of thing.
I found something promising here in Stackoverflow but it's in javascript :<
Edit: 2023-01-19 08:53 GMT+8
#client.event
async def on_reaction_add(reaction, member):
if str(reaction.emoji) == "⭐":
channel = await bot.get_channel(channel_id)
await channel.send(reaction.message.content)
Final code
edited: 2023-01-20 17:14 GMT+8
#bot.event
async def on_reaction_add(reaction, user):
if reaction.emoji == "⭐":
astrometrics = bot.get_channel(channel id here)
embed = discord.Embed(color = 0xFEE75C)
embed.set_author(name = reaction.message.author.name, icon_url = reaction.message.author.display_avatar)
embed.add_field(name = "Message Content", value = reaction.message.content)
if len(reaction.message.attachments) > 0:
embed.set_image(url = reaction.message.attachments[0].url)
embed.add_field(name = "Go to message", value = reaction.message.jump_url, inline = False)
await astrometrics.send(embed = embed)
You can check certain messages in on_message event. And for getting a specific channel in your server, you need to have the channel id. link
Something like this:
#bot.event
async def on_message(message):
if message.content == 'the certain message':
specific_channel = await bot.get_channel(channel_id)
await specific_channel.send(message.content)
But this might have some rate-limited consequence if the 'certain message' was too much and sent at a high rate. (If yes, then there's nothing you can do since rate-limited is a discord limitation).
I want to send an error message when my bot's role is insufficient, but I can't. I tried all the "MissingRole" commands but none of them work...
#Bot.event
async def on_command_error(ctx, error):
if isinstance(error, commands.BotMissingPermissions):
.
.
.
await ctx.channel.send(embed=embed)
if isinstance(error, commands.BotMissingPermissions):
await ctx.message.add_reaction("❌")
aEmbed = discord.Embed(
title=f"**__Error__**",
description="Whatever you want the bot to say to the user",
colour=discord.Colour.red()
)
await ctx.send(embed=aEmbed)
return
This is how I made the "BotMissingPermissions". The code is pretty basic, it just puts a "X" reaction to the message that made the error and then sends an embed saying what went wrong then returns so that it can continue functioning without any problems
Also the response you told the bot to do (await ctx.channel.send("Something something")) could be changed to await ctx.send("Something").
I am trying to re-do my bot's 8ball command, I try to use the following code
#client.command(aliases=['8ball'])
async def _8ball(ctx, *, question):
responses = ['It is certain.',
'It is decidedly so.',
'Without a doubt.',
'Yes - definitely.',
'You may rely on it.',
'As I see it, yes.',
'Most likely.',
'Outlook good.',
'Yes.',
'Signs point to yes.',
'Reply hazy, try again.',
'Ask again later.',
'No.',
'Better not tell you now.',
'Cannot predict now.',
'Concentrate and ask again.',
"Don't count on it.",
'My reply is no.',
'My sources say no.',
'Outlook not so good.',
'Very doubtful.']
responses = random.choice(responses)
embed=discord.Embed(title="8ball", description="Ask the 8ball!", color=discord.Color.dark_purple())
embed.add_field(name="Q: {question}", value="A: {responses}", inline=False)
await ctx.send(embed=embed)
But the python file refuses to launch, and returns
File "C:\Users\r00t_technologies\Documents\bot\enigmatic-peak-21114\bot_development.py", line 135
await ctx.send(embed=embed)
^
SyntaxError: 'await' outside function
Is anyone able to help me with this issue?
EDIT: Nevermind I'm just an idiot and was looking at the wrong line, sorry for the inconvienience (I am somewhat inexperienced at this)
I Dont know Why the error say await outside a function but its already in function, i Edited Your Code And i Tested it in my Bot And it works perfectly.
So Try this:
#client.command()
async def _8ball(ctx, *, question):
responses = ['It is certain.',
'It is decidedly so.',
'Without a doubt.',
'Yes - definitely.',
'You may rely on it.',
'As I see it, yes.',
'Most likely.',
'Outlook good.',
'Yes.',
'Signs point to yes.',
'Reply hazy, try again.',
'Ask again later.',
'No.',
'Better not tell you now.',
'Cannot predict now.',
'Concentrate and ask again.',
"Don't count on it.",
'My reply is no.',
'My sources say no.',
'Outlook not so good.',
'Very doubtful.']
responses = random.choice(responses)
embed=discord.Embed(title="8ball", description="Ask the 8ball!", color=discord.Color.dark_purple())
embed.add_field(name="Q: " + question, value="A:" + responses, inline=False)
await ctx.send(embed=embed)
You need to have more than one aliases in the aliases =. Try [‘8ball’, ‘8b’]
how are you doing today i sure hope your doing great im sorry for the spam on other account i apologize. ok so my problem is that i switched from client to bot basically bot = commands.Bot i tried renaming all the commmands to bot.event or bot.command can someone pls help me pls i would appreciate it thank you here is the code :)
#bot.command()
async def ping(ctx):
await ctx.send(f'Pong!\n`{round(client.latency*1000)}ms`')
#bot.command(aliases=['8ball'])
async def _8ball(ctx, *, question):
responses = [ "It is certain.",
"As I see it, yes",
"Ask again later.",
"Better not tell you now.",
"Cannot predict now.",
"Concentrate and ask again.",
"Don't count it",
"It is certain.",
"It is decidedly so.",
"Most likely.",
"My reply is no."
"My sources say no.",
"Outlook not so good.",
"Outlook good.",
"Reply hazy, try again.",
"Signs point to yes.",
"Very doubtful.",
"Without a doubt.",
"Yes.",
"Yes – definitely.",
"You may rely on it." ]
await ctx.send(f'Question: {question}\nAnswer: {random.choice(responses)}')
#commands.has_permissions(ban_members=True)
#bot.command()
async def kick(ctx, user: discord.Member, *, reason="No reason provided"):
await user.ban(reason=reason)
kick = discord.Embed(title=f":boom: Kicked {user.name}!", description=f"Reason: {reason}\nBy: {ctx.author.mention}")
await ctx.message.delete()
await ctx.channel.send(embed=kick)
await user.send(embed=kick)
#commands.has_permissions(ban_members=True)
#bot.command()
async def ban(ctx, user: discord.Member, *, reason="No reason provided"):
await user.ban(reason=reason)
ban = discord.Embed(title=f":boom: Banned {user.name}!", description=f"Reason: {reason}\nBy: {ctx.author.mention}")
await ctx.message.delete()
await ctx.channel.send(embed=ban)
await user.send(embed=ban)
#bot.command()
async def unban(ctx, *, member):
banned_users = await ctx.guild.bans()
member_name, member_discriminator = member.split('#')
for ban_entry in banned_users:
user = ban_entry.user
if (user.name, user.discriminator) == (member_name, member_discriminator):
await ctx.guild.unban(user)
await ctx.channel.send(f"Unbanned: {user.mention}")
#bot.command(pass_context = True)
async def mute(ctx, user_id, userName: discord.User):
if ctx.message.author.server_permissions.administrator:
user = ctx.message.author
role = discord.utils.get(user.server.roles, name="Muted")
#bot.command()
async def serverinfo(ctx):
name = str(ctx.guild.name)
description = str(ctx.guild.description)
owner = str(ctx.guild.owner)
id = str(ctx.guild.id)
region = str(ctx.guild.region)
memberCount = str(ctx.guild.member_count)
icon = str(ctx.guild.icon_url)
embed = discord.Embed(
title=name + " Server Information",
description=description,
color=discord.Color.blue()
)
embed.set_thumbnail(url=icon)
embed.add_field(name="Owner", value=owner, inline=True)
embed.add_field(name="Server ID", value=id, inline=True)
embed.add_field(name="Region", value=region, inline=True)
embed.add_field(name="Member Count", value=memberCount, inline=True)
await ctx.send(embed=embed)
await client.add_roles(user, role)
#bot.command()
async def setdelay(ctx, seconds: int):
await ctx.channel.edit(slowmode_delay=seconds)
await ctx.send(f"Set the slowmode delay in this channel to {seconds} seconds!")
#bot.command()
async def afk(ctx, mins):
current_nick = ctx.author.nick
await ctx.send(f"{ctx.author.mention} has gone afk for {mins} minutes.")
await ctx.author.edit(nick=f"{ctx.author.name} [AFK]")
counter = 0
while counter <= int(mins):
counter += 1
await asyncio.sleep(60)
if counter == int(mins):
await ctx.author.edit(nick=current_nick)
await ctx.send(f"{ctx.author.mention} is no longer AFK")
break
def setup(bot):
bot.add_cog(Afk(bot))
def user_is_me(ctx):
return ctx.message.author.id == "Your ID"
def convert(time):
pos = ["s","m","h","d"]
time_dict = {"s" : 1, "m" : 60, "h" : 3600, "d": 3600*24}
unit = time[-1]
if unit not in pos:
return -1
try:
val = int(time[:-1])
except:
return -2
return val * time_dict[unit]
#bot.command()
#commands.has_permissions(kick_members=True)
async def giveaway(ctx):
await ctx.send("Let's start with this giveaway! Answer these questions within 15 seconds!")
questions = ["Which channel should it be hosted in?", "What should be the duration of the giveaway? (s|m|h|d)", "What is the prize of the giveaway?"]
answers = []
def check(m):
return m.author == ctx.author and m.channel == ctx.channel
for i in questions:
await ctx.send(i)
try:
msg = await bot.wait_for('messsage', timeout=15.0, check=check)
except asyncio.TimeoutError:
await ctx.send('You didn\'t answer in time, please be quicker next time!')
return
else:
answers.append(msg.content)
try:
c_id = int(answers[0][2:-1])
except:
await ctx.send(f"You didn't mention a channel properly. Do it like this {ctx.channel.mention} next time.")
return
channel = bot.get_channel(c_id)
time = convert(answers[1])
if time == -1:
await ctx.send(f"You didn't answer with a proper unit. Use (s|m|h|d) next time!")
return
elif time == -2:
await ctx.send(f"The time just be an integer. Please enter an integer next time.")
return
prize = answers[2]
await ctx.send(f"The giveaway will be in {channel.mention} and will last {answers[1]} seconds!")
embed = discord.embed(title = "Giveaway!", description = f"{prize}", color = ctx.author.color)
embed.add_field(name = "Hosted by:", value = ctx.author.mention)
embed.set_footer(text = f"Ends {answers[1]} from now!")
my_msg = await channel.send(embed = embed)
await my_msg.add_reaction("🎉")
await asyncio.sleep(time)
new_msg = await channel.fetch_message(my_msg.id)
users = await new_msg.reactions[0].users().flatten()
users.pop(users.index(bot.user))
winner = random.choice(users)
await channel.send(f"Congratulations! {winner.mention} won the prize: {prize}!")
#bot.command()
#commands.has_permissions(kick_members=True)
async def reroll(ctx, channel : discord.TextChannel, id_ : int):
try:
new_msg = await channel.fetch_message(id_)
except:
await ctx.send("The ID that was entered was incorrect, make sure you have entered the correct giveaway message ID.")
users = await new_msg.reactions[0].users().flatten()
users.pop(users.index(bot.user))
winner = random.choice(users)
await channel.send(f"Congratulations the new winner is: {winner.mention} for the giveaway rerolled!")
if you want me to answer anything to help you solve it feel free to comment thank you so much have a great day!
It seems like you copied most of the code from the internet and bashed it together to create a bot or a cog (based on your question I would guess a bot).
Assuming this is a snippet of your main bot file and not a cog there are a couple of things that could be different:
Put your utility functions in one place (peferably after your import statatements). It's good practise overall and makes more readeable code.
Unless you have a cog class in the same file as your bot instance (which is bad practise) you shouldn't need this:
def setup(bot):
bot.add_cog(Afk(bot))
If there is a cog class named Afk you should move it into a separate file (putting the cog class into the main bot file defeats the purpose of the cog)
In your mute command you have pass_context = True. This is from the old version of discord.py and is no longer needed.
I can't tell you much more since there's no point in trying to debug your code since you didn't give us any errors or stacktrace to work with.
It is very exhausting, so you can just leave client in every command, just write this client = commands.Bot(command_prefix = 'your prefix') it is the same bot, but it just has a different name.
If you meant that, because i didn't really understand what you need
I have a bot that I want to reply to a specific word, and it does. However, if you type any message including that word, it will also reply. How do I stop that?
For example. If I was to say "Who", the bot would reply with "go away lucas"
However, if I was to say "Who is this person?" the bot would still reply with "go away lucas"
Is there any fix to this? Thanks!
async def on_message(message):
if message.content.startswith('who'):
msg = 'who'.format(message)
await message.channel.send('go away lucas')
await bot.process_commands(message)
I see you are using startswith().
the command startswith() returns True if the message starts with the desired string for example:
a = "who"
b = "who is lucas"
print(a.startswith("who"))
print(b.startswith("who"))
The output will be:
True
True
If you want the command to work only when the content of the message is "who", try this:
async def on_message(message):
if message.content == "who":
msg = 'who'.format(message)
await message.channel.send('go away lucas')
await bot.process_commands(message)