so i was making a discord bot and made a modmail system and got this error. can someone plz help and tell me where i am going wrong i searched many similar errors but didnt find the answer.
bot:
import random
import os
import sys
import asyncio
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True
client = commands.Bot(command_prefix='-', intents=intents)
client.remove_command("help")
#client.event
async def on_ready():
await client.change_presence(status=discord.Status.idle, activity=discord.Game('Do -help'))
print('functioning...')
#client.event
async def on_member_join(member):
print(f'{member} has joined the server.')
await member.create_dm()
await member.dm_channel.send(f'Hi {member.mention}, welcome to my Discord server!')
#client.event
async def on_member_remove(member):
print(f'{member} has left the server.')
for filename in os.listdir("./cogs"):
if filename.endswith(".py"):
client.load_extension(f'cogs.{filename[:-3]}')
#client.command(brief="Load", help="Loading cogs")
async def load(ctx, extension):
client.load_extension(f'cogs.{extension}')
#client.command(brief="Unload", help="Unloading cogs")
async def unload(ctx, extension):
client.unload_extension(f'cogs.{extension}')
#client.command(brief="Ping", help="The time it takes for a small data set to be transmitted from your device to a server on the Internet and back to your device again.")
async def ping(ctx):
await ctx.send(f'Pong! {round(client.latency*1000)}ms')
#client.command(aliases=['test','8ball', 'future'], brief="8ball", help="A little fun game.")
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.",
"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."]
await ctx.send(f'Question: {question}\nAnswer: {random.choice(responses)}')
#client.command(aliases=['purge','clean'], brief="Purge", help="Clears a fixed number of messahes.")
#commands.has_permissions(manage_messages=True)
async def clear(ctx, amount=5):
await ctx.channel.purge(limit=amount)
#client.command(brief="Kick", help="Kicks a person out of the guild.")
#commands.has_permissions(manage_messages=True)
async def kick(ctx, member:discord.Member, *, reason=None):
message = f"You have been kicked from {ctx.guild.name}, reason: {reason}"
await member.send(message)
await member.kick(reason=reason)
await ctx.send(f'Kicked {member.mention}')
#client.command(brief="Ban", help="Bans a person in the guild.")
#commands.has_permissions(manage_messages=True)
async def ban(ctx, member:discord.Member, *, reason=None):
message = f"You have been banned from {ctx.guild.name}, reason: {reason}"
await member.send(message)
await member.ban(reason=reason)
await ctx.send(f'Banned {member.mention}')
#client.command(brief="Unban", help="Unbans a banned person in the guild.")
#commands.has_permissions(manage_messages=True)
async def unban(ctx, *, user=None):
try:
user = await commands.converter.UserConverter().convert(ctx, user)
except:
await ctx.send("Error: user could not be found!")
return
try:
bans = tuple(ban_entry.user for ban_entry in await ctx.guild.bans())
if user in bans:
await ctx.guild.unban(user, reason="Responsible moderator: "+ str(ctx.author))
else:
await ctx.send("User not banned!")
return
except discord.Forbidden:
await ctx.send("I do not have permission to unban!")
return
except:
await ctx.send("Unbanning failed!")
return
await ctx.send(f"Successfully unbanned {user.mention}!")
class DurationConverter(commands.Converter):
async def convert(self, ctx, argument):
amount=argument[:-1]
unit=argument[-1]
if amount.isdigit() and unit in ['s','m','h','d']:
return(int(amount),unit)
raise commands.BadArgument(message="Not a valid duration")
#client.command(brief="Tempban", help="Temporarily bans a person in the guild.")
#commands.has_permissions(manage_messages=True)
async def tempban(ctx, member: commands.MemberConverter, duration: DurationConverter):
multiplier={'s':1, 'm':60, 'h':3600, 'd':86400}
amount, unit= duration
message = f"You have been banned from {ctx.guild.name}, for {amount}{unit}"
await member.send(message)
await ctx.guild.ban(member)
await ctx.send(f'{member.mention} has been banned for {amount}{unit}')
await asyncio.sleep(amount*multiplier[unit])
await ctx.guild.unban(member)
#client.command(brief="Tempmute", help="Temporarily mutes a person in the guild.")
#commands.has_permissions(manage_messages=True)
async def tempmute(ctx, member: discord.Member, duration: DurationConverter, reason=None):
multiplier = {'s': 1, 'm': 60, 'h': 3600, 'd': 86400}
amount, unit = duration
guild = ctx.guild
muteRole = discord.utils.get(guild.roles, name="Muted")
await member.add_roles(muteRole, reason=reason)
await ctx.send(f"{member.mention} has been muted in {ctx.guild} for {amount}{unit}")
await member.send(f"You have been muted in {ctx.guild} for {amount}{unit}")
await asyncio.sleep(amount*multiplier[unit])
await member.remove_roles(muteRole, reason=reason)
await ctx.send(f"{member.mention} has been unmuted in {ctx.guild} ")
await member.send(f"You have been unmuted in {ctx.guild} ")
def restart_bot():
os.execv(sys.executable, ['python'] + sys.argv)
#client.command(name= 'restart', brief="Restart", help="Restarts the bot.")
async def restart(ctx):
await ctx.send("Restarting bot...")
restart_bot()
#client.command( brief="Connects", help="Connects the bot.")
async def connect(self):
print(" bot connected")
#client.command(brief="Disconnects", help="Disconnects the bot.")
async def disconnect(self):
print("bot disconnected")
#client.command(brief="Mute", help="Mutes a person in the guild.")
#commands.has_permissions(manage_messages=True)
async def mute(ctx, member: discord.Member, *, reason=None):
guild = ctx.guild
muteRole = discord.utils.get(guild.roles, name="Muted")
if not muteRole:
await ctx.send("No Mute Role found! Creating one now...")
muteRole = await guild.create_role(name="Muted")
for channel in guild.channels:
await channel.set_permissions(muteRole, speak=False, send_messages=False, read_messages=True,
read_message_history=True)
await member.add_roles(muteRole, reason=reason)
await ctx.send(f"{member.mention} has been muted in {ctx.guild} | Reason: {reason}")
await member.send(f"You have been muted in {ctx.guild} | Reason: {reason}")
#client.command(brief="Unmute", help="Unmutes a muted person in the guild.")
#commands.has_permissions(manage_messages=True)
async def unmute(ctx, member: discord.Member, *, reason=None):
guild = ctx.guild
muteRole = discord.utils.get(guild.roles, name="Muted")
await member.remove_roles(muteRole, reason=reason)
await ctx.send(f"{member.mention} has been unmuted in {ctx.guild}")
await member.send(f"You have been unmuted in {ctx.guild}")
#client.command(brief="Slowmode", help="Enables a rate limit per message.")
#commands.has_permissions(manage_messages=True)
async def slowmode(ctx, time:int):
if (not ctx.author.guild_permissions.manage_messages):
await ctx.send('Cannot run command! Requires: ``Manage Messages``')
return
if time == 0:
await ctx.send('Slowmode is currently set to `0`')
await ctx.channel.edit(slowmode_delay = 0)
elif time > 21600:
await ctx.send('You cannot keep the slowmode higher than 6 hours!')
return
else:
await ctx.channel.edit(slowmode_delay = time)
await ctx.send(f"Slowmode has been set to `{time}` seconds!")
#client.command(brief="Prefix", help="Changes the prefix.")
async def setprefix(ctx, prefix):
client.command_prefix = prefix
await ctx.send(f"Prefix changed to ``{prefix}``")
#client.command(brief="Avatar", help="Displays a guild members pfp.")
async def avatar(ctx, member: discord.Member = None):
if member == None:
member = ctx.author
icon_url = member.avatar_url
avatarEmbed = discord.Embed(title=f"{member.name}\'s Avatar", color=0x802BAE)
avatarEmbed.set_image(url=f"{icon_url}")
avatarEmbed.timestamp = ctx.message.created_at
await ctx.send(embed=avatarEmbed)
client.run(token)
modmail:
import discord
import asyncio
from discord.ext.commands import Cog
client = discord.Client()
sent_users = []
class modmail(Cog):
def __init__(self, bot):
self.bot = bot
#Cog.listener()
async def on_message(self,message):
if message.guild: # ensure the channel is a DM
return
if message.author.bot:
return
if message.author == client.user:
return
if message.author.id in sent_users: # Ensure the intial message hasn't been sent before
return
modmail_channel = discord.utils.get(client.get_all_channels(), name="modmail")
embed = discord.Embed(color=0x00FFFF)
embed.set_author(name=f"Modmail System",
icon_url="https://cdn.discordapp.com/icons/690937143522099220/34fbd058360c3d4696848592ff1c5191.webp?size=1024")
embed.add_field(name='Report a member:', value=f"React with 1️⃣ if you want to report a member.")
embed.add_field(name='Report a Staff Member:', value=f"React with 2️⃣ if you want to report a Staff Member.")
embed.add_field(name='Warn Appeal:', value=f"React with 3️⃣ if you would like to appeal a warning.")
embed.add_field(name='Question:',
value=f"React with 4️⃣ if you have a question about our moderation system or the server rules.")
embed.set_footer(text="Modmail")
msg = await message.channel.send(embed=embed)
await msg.add_reaction("1️⃣")
await msg.add_reaction("2️⃣")
await msg.add_reaction("3️⃣")
await msg.add_reaction("4️⃣")
sent_users.append(message.author.id) # add this user to the list of sent users
try:
def check(reaction, user):
return user == message.author and str(reaction.emoji) in ["1️⃣", "2️⃣", "3️⃣", "4️⃣"]
reaction, user = await client.wait_for("reaction_add", timeout=60, check=check)
if str(reaction.emoji) == "1️⃣":
embed = discord.Embed(color=0x00FFFF)
embed.set_author(name=f"Modmail System",
icon_url="https://cdn.discordapp.com/icons/690937143522099220/34fbd058360c3d4696848592ff1c5191.webp?size=1024")
embed.add_field(name='How to Report:',
value="Send the ID of the person you are reporting and attach add a screen shot of them breaking a rule (can be ToS or a server rule).")
embed.set_footer(text="Report a member ")
await message.author.send(embed=embed)
message = await client.wait_for("message", timeout=60, check=lambda
m: m.channel == message.channel and m.author == message.author)
embed = discord.Embed(title=f"{message.content}", color=0x00FFFF)
await modmail_channel.send(embed=embed)
except asyncio.TimeoutError:
await message.channel.send("Reaction timeout!!!")
#Cog.listener()
async def on_ready(self):
print("modmail ready")
def setup(bot):
bot.add_cog(modmail(bot))
logcog:
import discord
import datetime
from datetime import datetime
from discord.ext.commands import Cog
class Example(Cog):
def __init__(self, client):
self.client = client
#Cog.listener()
async def on_ready(self):
print("log ready")
#Cog.listener()
async def on_message(self, message):
if not message.guild:
pass
else:
if not message.content and message.channel:
pass
else:
channel = discord.utils.get(message.guild.channels, name='log')
embed = discord.Embed(title="Message sent", description=message.author, color=message.author.color,
timestamp=datetime.utcnow())
embed.add_field(name="Message Sent", value=message.content, inline=True)
embed.add_field(name="Channel Sent", value=message.channel, inline=True)
await channel.send(embed=embed)
#Cog.listener()
async def on_message_edit(self, before, after):
if len(before.content)==0 and len(after.content)==0 and len(before.channel)==0:
pass
elif not before.guild:
pass
else:
channel = discord.utils.get(before.guild.channels, name='log')
embed = discord.Embed(title="Message edited", description=before.author, color=before.author.color,
timestamp=datetime.utcnow())
embed.add_field(name="Before edit", value=before.content, inline=True)
embed.add_field(name="After edit", value=after.content, inline=True)
embed.add_field(name="Channel Sent", value=before.channel, inline=True)
await channel.send(embed=embed)
#Cog.listener()
async def on_message_delete(self, message):
if not message.content and message.channel:
pass
elif not message.guild:
pass
else:
channel = discord.utils.get(message.guild.channels, name='log')
embed = discord.Embed(title="Message deleted", description=message.author, color=message.author.color,
timestamp=datetime.utcnow())
embed.add_field(name="Deleted Message", value=message.content, inline=True)
embed.add_field(name="The channel is", value=message.channel, inline=True)
await channel.send(embed=embed)
def setup(client):
client.add_cog(Example(client))
so when i run this code i get the reaction message and embed in the dm but when i click on the reaction i get no further out put and after 60s a message comes reaction timeout. I dont get any error message either.
So I finally solved the problem, which stemmed from the intents setup. In my main file I used this code:
intents = discord.Intents.default()
intents.members = True
bot = commands.Bot(command_prefix='!', intents=intents)
bot.load_extension("cogs.maincog")
bot.run(token)
You may want to do this slightly differently (like by using client), but the important part is the intents. This is apparently because the privileged intent "members" is required when testing for reactions is direct messages. I replaced the client with the Bot class, so the testing function became:
reaction, user = await self.bot.wait_for("reaction_add", timeout=60, check=check)
As far as I have tested, this should work perfectly well but let me know if you have any problems or want me to link the full code.
Edit: Look at how to enable privileged intents here.
Hey so when I type $opgg or $ftgopgg it will not come up with anything on the following
#bot.event
async def on_message(message):
if message.content('$opgg'):
response = 'Spend me the names'
await message.channel.send(response)
def check(m):
return m.author.id == message.author.id
opgg = await bot.wait_for('message')
await message.channel.send(f'https://oce.op.gg/multi/query={opgg.content.replace(" ", "%20")}')
print("done")
#bot.event
async def on_message(message):
if message.content == '$ftgopgg':
teamopgg = "https://oce.op.gg/multi/query=Disco Inferno, spranze, killogee, blank76, reeks"
await message.send(teamopgg.replace(" ", "%20"))
print("Tdone")
it was working like an hour ago but I could not use both commands, I don't know if I've gotten code work or if there is a mistake
You have 2 on_message events but discord.py supports only one.
If you are trying to create commands for your bot I recommend use #client.command() decorator instead of listening on_message event.
Something like:
import discord
from discord.ext import commands
bot = commands.Bot(command_prefix="$", intents=discord.Intents.all())
#bot.command()
async def opgg(ctx):
response = "Spend me the names"
await message.channel.send(response)
def check(m):
return m.author.id == message.author.id
#bot.command()
async def ftgopgg(ctx):
teamopgg = "https://oce.op.gg/multi/query=Disco Inferno, spranze, killogee, blank76, reeks"
await message.send(teamopgg.replace(" ", "%20"))
print("Tdone")
bot.run("TOKEN")
If you want to use bot.command() and on_message event at the same time, you can use :
#bot.listen()
async def on_message(message):
instead of:
#bot.event
async def on_message(message):
Simple fix all i had to do was remove the lower #bot.event and async def on_message(message)
new code:
#bot.event
async def on_message(message):
if message.content('$opgg'):
response = 'Spend me the names'
await message.channel.send(response)
def check(m):
return m.author.id == message.author.id
opgg = await bot.wait_for('message')
await message.channel.send(f'https://oce.op.gg/multi/query={opgg.content.replace(" ", "%20")}')
print("done")
if message.content == '$ftgopgg':
teamopgg = "https://oce.op.gg/multi/query=Disco Inferno, spranze, killogee, blank76, reeks"
await message.send(teamopgg.replace(" ", "%20"))
print("Tdone")
I was just adding some extra code to my discord bot to play youtube music, but then i go to run the bot and it starts as normal and works, but then when i go to test the new commands nothing works, no errors or anything, then i try the basic commands like /hello that was working fine before and that also is not doing anything. The bot as Administration role.
Ive double checked Iam not spelling commands wrong, but even if I was the on_command_error function should call. Also i did a print debug statement at the start of the /play command and not even that gets called, and I havent changed anything major. Anyone have any ideas?
from discord.ext import commands
from dotenv import load_dotenv
from lxml import html
import youtube_dl
import requests
import random
import discord
import requests
import shutil,os
# Load .env file
load_dotenv()
PREFIX = "/"
bot = commands.Bot(command_prefix=PREFIX)
# EVENTS #
#bot.event
async def on_ready():
await bot.get_channel(888736019590053898).send(f"We back online! All thanks to *sploosh* :D")
#bot.event
async def on_command_error(ctx, error):
if isinstance(error, commands.CommandNotFound):
replies = ["Err is that even a command?", "Can you type bro?", "Yeah... thats not a command buddy.", "Sorry forgot you can't spell"]
await ctx.send(random.choice(replies))
#bot.event
async def on_message(message):
if str(message.channel) == "images-videos" and message.content != "":
await message.channel.purge(limit=1)
# COMMANDS #
#bot.command()
async def hello(ctx):
# Get a random fact
url = 'http://randomfactgenerator.net/'
page = requests.get(url)
tree = html.fromstring(page.content)
hr = str(tree.xpath('/html/body/div/div[4]/div[2]/text()'))
await ctx.reply("**Hello Bozo!**\n" + "*Random Fact : *" + hr[:-9]+"]")
#bot.command()
async def randomNum(ctx, start:int = None, end:int = None):
if(start == None or end == None):
await ctx.reply("*Check your arguments!*\n```/randomNum START_NUMBER END_NUMBER```")
else:
randNum = random.randint(start, end)
await ctx.reply(f"*{randNum}*")
#bot.command()
#commands.is_owner()
async def kick(ctx, member:discord.Member = None, *, reason="You smell bozo."):
if(member == None):
await ctx.reply("*Check your arguments!*\n```/kick #MEMBER REASON(optional)```")
elif ctx.author.id in (member.id, bot.user.id):
await ctx.reply("*You cant kick yourself/me you silly.*")
else:
await member.kick(reason=reason)
#bot.command()
#commands.is_owner()
async def ban(ctx, member:discord.Member = None, *, reason="Bye Bye! :D."):
if(member == None):
await ctx.reply("*Check your arguments!*\n```/kick #MEMBER REASON(optional)```")
elif ctx.author.id in (member.id, bot.user.id):
await ctx.reply("*You cant ban yourself/me you silly.*")
else:
await member.ban(reason=reason)
#bot.command()
#commands.is_owner()
async def close_bot(ctx):
replies = ["Well bye!", "Guess I go now?", "Please let me stay..."]
await ctx.send(random.choice(replies))
await bot.close()
# YOUTUBE AUDIO PLAYER
#bot.command()
async def play(ctx, url : str):
print("WORKING")
if(url == None):
await ctx.reply("*Check your arguments!*\n```/play VIDEO_URL```")
else:
song = os.path.isfile("songs/song.mp3")
try: # Check if song exists if so remove it
if(song):
os.remove("songs/song.mp3")
except PermissionError:
await ctx.reply("*Wait for current song to end, or use 'stop' command*")
return
voiceChannel = discord.utils.get(ctx.guild.voice_channels, name="Lounge")
await voiceChannel.connect()
voice = discord.utils.get(bot.voice_clients, guild = ctx.guild)
ytdl_opts = { # Some options you need to pass in
'format': 'bestaudio/best',
'postprocessors':[{
'key':'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192'
}],
}
with youtube_dl.YoutubeDL(ytdl_opts) as ydl:
ydl.download(url) # Download the vid
for file in os.listdir("./"): # Change the name and move to songs folder
if file.endswith(".mp3"):
os.rename(file, "song.mp3")
shutil.move("song.mp3", "songs")
voice.play(discord.FFmpegPCMAudio(source="songs/song.mp3")) # Play the song
#bot.command()
async def leave(ctx):
voice = discord.utils.get(bot.voice_clients, guild = ctx.guild)
if(voice.is_connected()):
voice.disconnect()
else:
await ctx.reply("*How can I leave a voice channel if I'am not connected?*")
#bot.command()
async def pause(ctx):
voice = discord.utils.get(bot.voice_clients, guild = ctx.guild)
if(voice.is_playing()):
voice.pause()
else:
await ctx.reply("*Can't pause buddy, nothings playing...*")
#bot.command()
async def resume(ctx):
voice = discord.utils.get(bot.voice_clients, guild = ctx.guild)
if(voice.is_paused()):
voice.resume()
else:
await ctx.reply("*Can't resume buddy, audio is already playing*")
#bot.command()
async def stop(ctx):
voice = discord.utils.get(bot.voice_clients, guild = ctx.guild)
voice.stop()
if __name__ == "__main__":
bot.run(os.getenv("BOT_TOKEN"))
You need to have bot.process_commands(message) inside your custom on_message events,
#bot.event
async def on_message(message):
if str(message.channel) == "images-videos" and message.content != "":
await message.delete()
await bot.process_commands(message)
I've also changed message.channel.purge(limit=1) to message.delete() because it's the proper way of deleting a message
For more info as to why this is required, see the faq
Good afternoon, I want the bot to delete its embed message in a minute, how do I implement it, here is the code
#client.command(pass_context = True)
#commands.has_any_role(819292703589269514,817408828500213860,817408830240456754,817643991331766283)
async def clear (ctx, amount : int):
await ctx.channel.purge(limit = amount + 1)
emb = discord.Embed (title = 'Удалено {} сообщений!'.format(amount), colour = discord.Color.gold())
await ctx.send(embed = emb)
await asyncio.sleep(15)
await emb.delete()
If anyone else has the problem here is an answer:
Please take care of the correct indentation, there are too many spaces in some places.
You can also use an delete_after "event" instead of your emb.delete().
It would look like this:
#client.command(pass_context=True)
#commands.has_any_role(819292703589269514, 817408828500213860, 817408830240456754, 817643991331766283)
async def clear(ctx, amount: int):
await ctx.channel.purge(limit=amount + 1)
emb = discord.Embed(title='Удалено {} сообщений!'.format(amount), color=discord.Color.gold())
await ctx.send(embed=emb, delete_after=60) # delet_after added
If you want to use your method you have to define the embed you are sending:
#client.command(pass_context=True)
#commands.has_any_role(819292703589269514, 817408828500213860, 817408830240456754, 817643991331766283)
async def clear(ctx, amount: int):
await ctx.channel.purge(limit=amount + 1)
emb = discord.Embed(title='Удалено {} сообщений!'.format(amount), colour=discord.Color.gold())
test1 = await ctx.send(embed=emb) # We define the embed as test1
await asyncio.sleep(15)
await test1.delete() # test1 (Embed) gets deleted
It is pretty simple to do so. You just need to define a variable which sends the embed. Here's the code -
#client.command(pass_context = True)
#commands.has_any_role(819292703589269514,817408828500213860,817408830240456754,817643991331766283)
async def clear (ctx, amount : int):
await ctx.channel.purge(limit = amount + 1)
emb = discord.Embed (title = 'Удалено {} сообщений!'.format(amount), colour = discord.Color.gold())
sendemb = await ctx.send(embed = emb)
await asyncio.sleep(15)
await sendemb.delete()
So here all I did was name the embed sending (sendemb) and after sleeping for 15 seconds, it deletes it!
Hope I helped you.
So I'm making bot in python and I don't know how to make that other user can write -join and then bot will trigger the commend. My code currently is in cogs so I'm using #commands.command instead #bot.command. Here is my code:
class GamesCog(commands.Cog, name="Games"):
def __init__(self, bot):
self.bot = bot
#commands.command()
async def game(self, ctx):
await ctx.send("Find a second person to play dice or play against the bot. (-join/-bot)")
await ctx.send(file=discord.File('game.jpg'))
def check(msg):
return msg.author == ctx.author and msg.channel == ctx.channel and msg.content.lower() in ["-join", "-bot"]
msg = await self.bot.wait_for("message", check=check)
def setup(bot):
bot.add_cog(GamesCog(bot))
print('File games.py is ready')
I know that in the return msg.author author shouldn't be there, I just don't know what to replace it with.
You're actually doing nothing with the message, you're waiting for it, and then nothing
msg = await self.bot.wait_for("message", check=check)
if msg.content.lower() == "-join":
# Do something
elif msg.content.lower() == "-bot":
# Do something
def check(msg):
return msg.channel == ctx.channel and msg.content.lower() in ["-join", "-bot"]