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"]
Related
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content == 'Hey Sloime':
if message.author.id == xxx:
await message.channel.send('Yes master?')
elif message.author.id == xxx:
await message.channel.send('Tell me brother')
else:
await message.channel.send('TF u want?')
else:
return
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content == 'Can I have my Dis ID?':
await message.channel.send(message.author.id)
else:
await message.channel.send('Do I look like I can answer that?')
return
client.run(os.environ['TOKEN'])
It's my first time ever coding in Python, I have experience coding in c, c++, java and sql. My problem is that after I enter the second event on this bot I want to wait for a message corresponding to the first event, but it keeps looping on the second event, I apologize in advance if this is very simple.
Something like this?
#client.event
async def on_message(message):
if message.content == 'i want cheese':
await message.channel.send('how much?')
msg = await client.wait_for('message')
await message.channel.send(f'ok, you want {msg.content} cheese')
# you can do a check like this also
msg = await client.wait_for('message', check=lambda msg: msg.author.id == xxx)
wait_for('message') waits for a message to happen
I'm creating a mod-mail feature which members can message the bot and it will respond with instructions. However the event works fine with the exception of bot commands. Here is my code. Strangely no errors were detected.
sent_users = []
modmail_channel = client.get_channel(910023874727542794)
#client.event
async def on_message(message):
if message.guild:
return
if message.author == client.user:
return
if message.author.id in sent_users:
return
embed = discord.Embed(color = color)
embed.set_author(name=f"Misaland Modmail System", icon_url=f'{message.author.avatar_url}')
embed.add_field(name='Report a Member: ', value=f"React with <:Wojak1:917122152078147615> if you would like to report a member.")
embed.add_field(name='Report a Staff Member:', value=f"React with <:grim1:925758467099222066> if you would like to report a staff.")
embed.add_field(name='Warn Appeal:', value=f"React with <:Lovecat:919055184125100102> if you would like to appeal a warning.")
embed.add_field(name='Question:', value=f"React with <:gasm:917112456776679575> if you have a question about the server")
embed.add_field(name='Leave a Review', value=f"React with <:surebuddy1:917122193287163924> to leave a review about the server")
embed.add_field(name='Server Invite', value=f'React with <:smirk:910565317363773511> to get the server invite.')
embed.set_footer(text='Any questions asked that isnt related to the list, you will be severely abused')
msg = await message.author.send(embed=embed)
await msg.add_reaction("<:Wojak1:917122152078147615>")
await msg.add_reaction("<:grim1:925758467099222066>")
await msg.add_reaction("<:Lovecat:919055184125100102>")
await msg.add_reaction("<:gasm:917112456776679575>")
await msg.add_reaction("<:surebuddy1:917122193287163924>")
await msg.add_reaction("<:smirk:910565317363773511>")
sent_users.append(message.author.id)
try:
def check(reaction, user):
return user == message.author and str(reaction.emoji) in ['<:Wojak1:917122152078147615>', '<:grim1:925758467099222066>','<:Lovecat:919055184125100102>','<:gasm:917112456776679575>','<:surebuddy1:917122193287163924>','<:smirk:910565317363773511>']
reaction, user = await client.wait_for("reaction_add", timeout=60, check=check)
if str(reaction.emoji) == "<:Wojak1:917122152078147615>":
embed = discord.Embed(color=color)
embed.set_author(name=f"Misaland Member Report", icon_url=f'{message.author.avatar_url}')
embed.add_field(name="How to Report:", value="Send the ID of the person you are reporting and attach a screenshot breaking the rules")
embed.set_footer(text="Misaland | Member Report")
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=color)
await modmail_channel.send(embed=embed)
except asyncio.TimeoutError:
await message.delete()
Try putting
await bot.process_commands(message)
at the end of your code in
async def on_message(message):
If you're using commands outside of on_message, it's overridden
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
#client.command()
async def spam(ctx):
while True:
time.sleep(2)
await ctx.send("spam")
#client.event
async def on_message(message):
if message.content == "!stop":
# stop spamming
I want the code to stop spamming but I'm not sure how.
Try this example using wait_for:
#client.command()
async def spam(ctx):
def check(m):
return m.author == ctx.author and m.channel == ctx.channel
stopped = False
await ctx.send("spam")
while not stopped:
try:
message = await client.wait_for("message", check=check, timeout=2)
stopped = True if message.content.lower() == "!stop" else False
except asyncio.TimeoutError: # make sure you've imported asyncio
await ctx.send("spam")
await ctx.send("spam finished!")
References:
Client.wait_for()
Message.author
Message.channel