My Discord Bot doesnt respond to Commands, but it logs the User ID when someone writes something. Why is this the Case? What have i done wrong? Is there something missing in the on_message listener? The last thing i added to my Code was the Rank System which i am working on, but even when i comment it out, the Bot still doesnt respond to commands like +macarena. Here is the Code:
import os
import discord
from dotenv import load_dotenv
from discord.ext import commands
from user import User
############## Init Variables #############
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
GUILD = os.getenv('DISCORD_GUILD')
DATA = os.getcwd() + '\\data\\'
bot = commands.Bot(command_prefix='+')
bot.remove_command('help')
rank_list = []
############## Main Code #############
#bot.event
async def on_ready():
for guild in bot.guilds:
if guild.name == GUILD:
break
print(
f'{bot.user} is connected to the following guild:\n'
f'{guild.name}(id: {guild.id})'
)
if(os.path.isfile(DATA + 'database.txt')):
print('Database File for Rank System exists and is ready for processing!')
else:
print('Database File doesnt exist and will be created....')
create_file()
print('File is created and ready for use!')
#bot.event
async def on_message(message):
#rank_system(message)
pass
#bot.command(name='help')
async def help_command(ctx):
embed = discord.Embed(
title = "Bot Commands",
description = "Hier werden alle Commands von diesem Bot aufgelistet. Alle nachfolgenden Commands müssen mit dem Präfix '+' aufgerufen werden.",
color = discord.Color.blue()
)
embed.add_field(name="Algorithmen", value="Lexikon", inline=True)
embed.add_field(name="Datenstrukturen", value="Lexikon", inline=True)
embed.add_field(name="macarena", value="Fun Commands", inline=True)
await ctx.send(embed=embed)
#Rank System
def rank_system(message):
author = str(message.author)
userid = str(message.author.id)
time = str(message.created_at)
channel = str(message.channel)
user = search_user(userid)
if user == None:
rank_list.append(User(author,userid,time,channel))
else:
user.add_xp()
print(userid)
#bot.command(name='rank')
async def get_rank(message):
print("I am Here")
id = str(message.author.id)
user = search_user(id)
response = f"You are Rank {user.get_rank()} and you have {user.get_xp()}."
await message.channel.send(response)
#Lexikon Commands
#bot.command(name='Algorithmen')
async def algo_command(message):
response = "Es gibt viele verschiedene Algorithmen hier eine kurze Auflistung von den bekanntesten:\n\n- Bubble Sort\n- Quick Sort\n- Merge Sort"
await message.channel.send(response)
#bot.command(name='Datenstrukturen')
async def datenstrukturen_command(message):
response = "Es gibt viele verschiedene Datenstrukturen hier eine kurze Auflistung von den bekanntesten:\n\n- Stack\n- Queue\n- List"
await message.channel.send(response)
#Vote Commands
#Fun Commands
#bot.command(name='macarena')
async def makarena_command(message):
print("Funktioniert")
response = "Hast du ernsthaft so viel Langeweile, dass du diesen Command ausprobierst....Schäm dich ;)"
await message.channel.send(response)
#Sound Board
#Helper Class
def create_file():
open(os.path.join(DATA, "database.txt"), "x")
def read_file():
pass
def write_file(text):
pass
def search_user(id):
for x in rank_list:
print("Loop User %s",x.get_userID())
if x.get_userID() == id:
return x
return None
bot.run(TOKEN)
Thanks for the Help in advance :) I am really confused and cant figure out what i am doing wrong
You need to use process_commands() at the end of on_message events to make other commands work. Read more
#bot.event
async def on_message(message):
#some code if you want, if you want to pass then don't make on_message event
await bot.process_commands(message)
Try and change your command names like this
#bot.command()
async def macarena(message):
#code
It will run when using {prefix}macarena
Related
Im trying to make a Discord Bot that is able to Timeout users.
The general idea is that my friends and I can timeout eachother with tickets for about a minute.
But I cant get the discord.Member.timeout() to work.
I looked into the Discord.py doc but I cant find my mistake.
Down below I have put the important code as bold.
The error occures at
print("1")
await member1.timeout(timeout)
print("2")
The program prints "1" and thats it.
The only error message I get is from Discord (This interaction wasnt succesfull)
Please help me.
import discord
from discord.ext import commands
import json
import random
from discord import app_commands
import datetime
member1 = discord.Member
class SelectMenu3(discord.ui.View):
options1 = [
discord.SelectOption(label="Timeouten", value="1", description="Timeout someone"),
discord.SelectOption(label="Enttimeouten", value="2", description="Opposite")
]
#discord.ui.select(placeholder="Options", options=options1)
async def menu_callback3(self, interaction: discord.Interaction, select):
with open("cogs/eco.json", "r") as f:
user_eco = json.load(f)
global member1
member = interaction.user
select.disabled = True
eco_embed = discord.Embed(title="Timeouts", description="", colour=discord.Color.blue())
eco_embed.add_field(name="Amount Timeout:", value=f"{user_eco[str(member.id)]['Timeout']}")
**if select.values[0] == "1":
if user_eco[str(member.id)]['Timeout'] >= 1:
timeout = datetime.timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=1, hours=0, weeks=0)
print("1")
await member1.timeout(timeout)
print("2")
else:
await interaction.response.send_message(content="Du hast nicht genug Timeout-Tickets für diese Aktion",
ephemeral=True)
**
elif select.values[0] == "2":
if user_eco[str(member.id)]['Timeout'] >= 1:
pass
else:
await interaction.response.send_message(content="Du hast nicht genug Timeout-Tickets für diese Aktion",ephemeral=True)
**#app_commands.command(name="timeout", description="")
async def timeout(self, interaction: discord.Interaction, member: discord.Member):
global member1
member1 = member
view = SelectMenu3()
await interaction.response.send_message(content="Choose", view=view,
ephemeral=True)
**
I just found the problem, in Discord Roles exist and a User whos Role is lower in the hierarchy cant timeout any users that are higher up.
Therefore I just had to move up my Bots Role to be at the top (still below my own role as a safety measure) and everything is working just fine now.
I am building a discord bot but it just won't run. I tried everything. Help me! I am building an economy discord bot. I think there is some issue with the lists in the json file. When I run, it says command "" not found. I have tried literally everything. Help me as soon as possible #Python!
import discord
from discord.ext import commands
import random
import json
import os
client = commands.Bot(command_prefix="!")
os.chdir("FOLDER PATH PROVIDED")
#client.event
async def on_ready():
await client.change_presence(activity=discord.Game("In Development"))
print("Ready")
#client.command
async def balance(ctx):
await users(ctx.author)
users = await data()
user = ctx.author
wallet_amount = users[str(user.id)]["Wallet"]
bank_amount = users[str(user.id)]["Bank"]
em = discord.Embed(title="Account")
em.add_field(name="Wallet", value=wallet_amount)
em.add_field(name="Bank", value=bank_amount)
await ctx.send(embed=em)
#client.command
async def beg(ctx):
await account(ctx.author)
users = await data()
user = ctx.author
earning = random.randrange(101)
await ctx.send(f"Someone gave you {earning}")
users[str(user.id)]["Wallet"] = + earning
with open("bank.json") as file:
json.dump(users, file)
async def account(user):
data()
if str(user.id) in users:
return False
else:
users[str(user.id)]["Wallet"] = {}
users[str(user.id)]["Wallet"] = 0
users[str(user.id)]["Bank"] = 0
with open("bank.json") as file:
json.dump(users, file)
return True
async def data():
with open("bank.json") as file:
accounts = json.load(file)
return accounts
client.run("TOKEN PROVIDED")
The json file:
{
}
you are miss interpreting event and command,
#client.command() is correct..
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
Hello I tried to make a bot with Discord.py and I tried implementing this to my code but I get the error in the title. I don't know a lot of Python yet and I'm very new so I don't know what may cause this error. Any help would be great, thanks!
import discord
import os
import requests
import json
import random
from keep_alive import keep_alive
import asyncio
client = discord.Client()
basura = ["rezero"]
verdad = [
"es una mierda",
"no debería existir",
"VIVA K-ON",
]
def get_quote():
response = requests.get("https://zenquotes.io/api/random")
json_data = json.loads(response.text)
quote = json_data[0]['q'] + " - " + json_data[0]['a']
return (quote)
#client.event
async def on_ready():
print ('We logged in as {0.user}'.format(client))
#client.event
async def on_message(self,message):
if message.author.id == self.user.id:
return
if message.content.startswith('Hola'):
await message.channel.send('Sup nerd')
if message.content.startswith('Inspirame'):
quote = get_quote()
await message.channel.send(quote)
if any(word in message.content for word in basura):
await message.channel.send(random.choice(verdad))
if message.content.startswith('^Guess'):
await message.channel.send('Adivina un numero del 1 al 10')
def is_correct(m):
return message.content.author == message.author and m.content.isdigit()
answer = random.randint(1,10)
try:
guess = await self.wait_for('message',check=is_correct,timeout=5.0)
except asyncio.TimeoutError:
return await message.channel.send('Se acabó el tiempo, la respuesta era {}.'.format(answer))
if int(guess.content) == answer:
await message.channel.send('Acertaste')
else:
await message.channel.send('Fallaste, la respuesta era {}.'.format(answer))
keep_alive()
client.run(os.getenv('TOKEN'))
Giving the full error log and the exact code run is good practice here.
This error indicates that the 'on_message' function was not given its 'message' argument. In this case, I would presume that you forgot to delete the 'self' argument when extracting this method from an object to make a stand-alone function out of it.
I have this as my music class to make my bot play music
class Music(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.bot.music = lavalink.Client(self.bot.user.id)
self.bot.music.add_node("localhost", 7000, 'server-utils', 'eu', 'music-node')
self.bot.add_listener(self.bot.music.voice_update_handler, 'on_socket_response')
self.bot.music.add_event_hook(self.track_hook)
#commands.command(name="music")
async def music(self, ctx, opt, *, arg=None):
if opt == "join":
print(f"music join command worked")
member = discord.utils.find(lambda m: m.id == ctx.author.id, ctx.guild.members)
if member is not None and member.voice is not None:
vc = member.voice.channel
player = self.bot.music.player_manager.create(ctx.guild.id, endpoint=str(ctx.guild.region))
if not player.is_connected:
player.store('channel', ctx.guild.id)
await self.connect_to(ctx.guild.id, str(vc.id))
if opt == "play" and arg is not None:
try:
player = self.bot.music.player_manager.get(ctx.guild.id)
query = f'ytsearch:{arg}'
results = await player.node.get_tracks(query)
tracks = results['tracks'][0:10]
i = 0
query_result = ''
for track in tracks:
i = i + 1
query_result = query_result + f'{i}) {track["info"]["title"]}\n'
embed = discord.Embed()
embed.description = query_result
await ctx.channel.send(embed=embed)
def check(m):
return m.author.id == ctx.author.id
reponse = await self.bot.wait_for('message', check=check)
track = tracks[int(reponse.content)-1]
player.add(requester=ctx.author.id, track=track)
if not player.is_playing:
await player.play()
except Exception as error:
print(error)
if opt == "stop":
try:
player = self.bot.music.player_manager.get(ctx.guild.id)
if player.is_playing:
await player.stop()
except Exception as error:
print(error)
if opt == "leave":
player = self.bot.music.player_manager.get(ctx.guild.id)
if player.is_playing:
await player.stop()
await self.disconnect_from(ctx.guild.id)
async def track_hook(self, event):
if isinstance(event, lavalink.events.QueueEndEvent):
guild_id = int(event.player.guild_id)
await self.connect_to(guild_id, None)
async def connect_to(self, guild_id: int, channel_id: int):
ws = self.bot._connection._get_websocket(guild_id)
await ws.voice_state(str(guild_id), channel_id)
async def disconnect_from(self, guild_id: int):
ws = self.bot._connection.voice_clients
print(ws)
def setup(bot):
bot.add_cog(Music(bot))
Everythink works fine except the part to disconnect from the channel he is connected to... I've tried lots of things and can't figure out how to make it disconnect..
Ps: Here the command doesn't do anything but to print a list where I hoped there would be the bot connect, but it had nothing there
I believe it's because you're passing the guild id as opposed to the voice channels id, for example.
You're in the guild; Hello World with an ID of 12345
You're in the guilds voice channel of; Hello World voice channel which has an id of 6789.
so you're trying to use the guild.id as opposed to the voice channel id. Does this make sense?
Can't you do await ctx.voice_client.disconnect()
if opt == "leave":
player = self.bot.music.player_manager.get(ctx.guild.id)
if player.is_playing:
await player.stop()
await ctx.voice_client.disconnect()
I did a disconnect command on my Discord bot using VoiceClient.disconnect(). I got some trouble with it in my first approach because the connect command generated the VoiceClient object, but disconnect command could not use it since it was a local variable on the other command, so i just made it global and it works
#commands.command()
async def enter(self, ctx):
try:
canal = ctx.author.voice.channel
global voice_client
voice_client = await canal.connect()
except AttributeError:
await ctx.send("Você precisa estar conectado a um canal de voz")
except discord.errors.ClientException:
await ctx.send("Eu já estou conectado ao seu canal de voz")
#commands.command()
async def leave(self, ctx):
try:
await voice_client.disconnect()
except NameError:
await ctx.send("Eu não estou conectado a nenhum canal de voz :worried:")
The full music cog that I coded:
https://github.com/Voz-bonita/Discord-Bot/blob/master/Music%20extension.py