I followed a tutorial to make add a basic music function to a discord bot, but it doesnt respond to any commands. I get the "henlo frens i is alieving" message as to indicate that the bot is ready, and there are no errors showing up. But then when i try to use the ping command i get no response, and nothing shows up in the terminal unlike the other bots i've written.
from plznodie import plznodie
from discord.ext import commands
import music
import time
#vars
cogs=[music]
intents = discord.Intents()
intents.all()
client = commands.Bot(command_prefix = "!" , intents=intents)
intents.members = True
activvv = discord.Game("you guys complain")
#config
for i in range(len(cogs)):
cogs[i].setup(client)
#client.event
async def on_ready ():
await client.change_presence(status = discord.Status.online, activity = activvv)
print("Henlo frens i is alieving")
#client.command()
async def ping(ctx):
before = time.monotonic()
message = await ctx.send("Pong!")
ping = (time.monotonic() - before) * 1000
await message.edit(content=f"Pong! `{int(ping)}ms`")
client.run("TOKEN")```
Don't change_presence (or make API calls) in on_ready within your Bot or Client.
Discord has a high chance to completely disconnect you during the READY or GUILD_CREATE events (1006 close code) and there is nothing you can do to prevent it.
Instead set the activity and status kwargs in the constructor of these Classes.
bot = commands.Bot(command_prefix="!", activity=..., status=...)
As noted in the docs, on_ready is also triggered multiple times, not just once.
I can further confirm this because running your code snippet (without on_ready defined) on my machine actually worked :
to process commands you need to add on_message function
#client.event
async def on_message(msg):
await client.process_commands(msg)
Related
Trying to make a sorta complicated bot, but before i get started on writing the other code I wanted to just make sure that the bot worked in Discord, and was up and running and responding to a basic command - Send the message "Hello" when someone used the command "!hello".
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True
bot = commands.Bot(command_prefix='!', intents=intents)
TOKEN = "TOKEN"
#bot.event
async def on_ready():
print(f'Bot connected as {bot.user}')
#bot.command(name='hello')
async def dosomething(ctx):
print(f'Hello command made')
await ctx.send("Hello!")
bot.run(TOKEN)
the on_ready function does work, it outputs the name of the bot whenever it connects, but trying to get it to respond to a simple !hello command does nothing, it doesnt message in the channel and it doesn't print to console. Here's my permissions for the bot as well from Discord Developer Portal - https://imgur.com/a/xrcH1tw
Try adding this at the line above commands.Bot
intents.message_content = True
I would like to create a bot which can delete number of recently chat and history chat
import discord
import random
class MyClient(discord.Client):
async def on_ready(self):
print('Logged on as {0}!'.format(self.user))
async def on_message(self, message):
channel = message.channel.name
restricted_channels = ["command-bot"]
prefix = "-" # Replace with your prefix
# If the message starts with the prefix
if message.content.startswith(prefix):
if channel in restricted_channels:
command = message.content[len(prefix):]
if command.startswith("clear"):
await message.delete()
I have try this
if command.startswith("clear"):
await message.delete()
But it only delete the chat which have command "clear"
First off, personally, I would change the structure/ layout of your code. This is so that it is easier to read, and easier to change and add commands/ different functions to. This is the way I have my bot setup and how I have seen many other bots setup as well:
import discord
client = commands.Bot(command_prefix='your prefix', intents=discord.Intents.all()) # creates client
#client.event # used commonly for different events such as on_ready, on_command_error, etc...
async def on_ready():
print('your bot is online') # basic on_ready event and print statement so you can see when your bot has gone online
Now that we've gone through that part, let's get onto the purge/ clear command you're trying to make. I have one in my bots which generally looks something like this:
#client.command() # from our client declaration earlier on at the start
#commands.has_permissions(moderate_members=True) # for if you want only certain server members to be able to clear messages. You can delete this if you'd like
async def purge(ctx, amount=2): # ctx is context. This is declared so that it will delete messages in the channel which it is used in. The default amount if none is specified in the command is set to 2 so that it will delete the command call message and the message before it
await ctx.channel.purge(limit=amount) # ctx.channel.purge is used to clear/ delete the amount of messages the user requests to be cleared/ deleted within a specific channel
Hope this helps! If you have any questions or issues just let me know and I'll help the best I can
I am trying to make my bot delete all messages at once when a user asks the bot to do so, but my code isn't working.
import os
import discord
client = discord.Client()
client = commands.Bot(command_prefix='+')
#client.command(name='effacer')
async def purge(ctx):
async for msg in client.logs_from(ctx.message.channel):
await client.delete_messages(msg)
await ctx.send("Who am I? What is this place? And where the hell did the messages go?")
client.run(TOKEN)
How can I fix my code so that my bot can delete all messages? I believe my biggest problem is await client.delete_messages(msg), since Python continuously says that the client has no attribute to delete_messages.
By deleting every message would rate limit the bot, creating performance issues which would also slow down the bot. Instead it would be more efficient if the bot just deleted the channel and made a clone of it in the exact same place.
Here's the purge included in your command
#client.command(name='effacer')
async def purge(ctx):
await ctx.channel.delete()
new_channel = await ctx.channel.clone(reason="Channel was purged")
await new_channel.edit(position=ctx.channel.position)
await new_channel.send("Channel was purged")
So the way you would do that is with purge, not delete messages. This will delete all the messages in the channel AND keep the channel id the same, meaning you'll only need the manage_messages permission to run this command. The way it works is it counts all the messages in the channel and then purges that number of messages
import os
import discord
client = discord.Client()
client = commands.Bot(command_prefix='+')
#client.command(name='effacer')
async def purge(ctx):
limit = 0
async for msg in ctx.channel.history(limit=None):
limit += 1
await ctx.channel.purge(limit=limit)
client.run(TOKEN)
I'm making a bot for a pokemon server, and I'm trying to make a command that will give the 'Gym Leader' role to another user. I try using the command, and using the test command, but there is no response in the server nor the shell.
import os
import discord
from dotenv import load_dotenv
from discord.ext import commands
from discord.utils import get
bot = commands.Bot(command_prefix='b!', case_insensitive=True)
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
client = discord.Client()
#client.event #works
async def on_ready():
print(f'{client.user.name} has connected to Discord!')
channel = client.get_channel(697500755766018098)
#client.event #works
async def on_member_join(member):
await member.create_dm()
await member.dm_channel.send(
f'Hi {member.name}, welcome to Pokémon Beast Ball!\n\nThis server utilizes Pokecord and Mewbot.\n\nSay \'pkhelp\' in the server to learn about Pokecord commands.\nSay \';help\' in the server to learn about Mewbot commands.'
)
#bot.command() #doesn't work
async def test(ctx):
print("test recieved")
await ctx.send(ctx)
#bot.command(pass_context=True) #this is the command that really needs help
async def newleader(ctx: discord.User=None):
print("command recieved")
if not user:
await ctx.send("Invalid")
print("1")
else:
role = discord.utils.get(ctx.guild.roles, name="Gym Leader")
role2 = discord.utils.get(ctx.guild.roles, name="Purple UniTurtle Man")
if role in ctx.author.roles or role2 in ctx.author.roles:
print("2")
await ctx.send(f'A new Gym Leader has been appointed')
await user.add_roles(role)
await bot.remove_roles(ctx.author, role)
else:
print("3")
await ctx.send("You do not have permission to use this command")
client.run(TOKEN)
You are mixing bot and client and your client = discord.Client() is stepping on your bot = commands.Bot(...) statement. Since you want to do commands and events you only use the commands.Bot(...) statement.
Remove the client = discord.Client() statement and change your #client.event decorators to #bot.event.
Also if you want to reference the command context in your test command update it with the ctx parameter async def test(ctx):.
That will get you started using your commands and entering b1test will now work.
Please note that the case_insensitive=True on the commands declaration refers to the command name and not the prefix.
Did you check :
bot connection → make a "on_connect" event (not exactly the same as "on_ready") to see if your bot successfully connect to your server (before receiving data from discord). If not, try to add your bot again to your server and check if all tokens are goods.
bot permissions (if your bot have the right to write in channel, read messages from channels, manage roles) → if your bot cannot read messages, he can't read commands !
role priority (you can't manage roles highers thant yours) → go to "server settings" > "roles" > put your bot role above the 'Gym Leader' role (or at the top of the list if you don't care).
The problem isn't actually what the selected answer suggests. There is probably no reason to use both commands.Bot and discord.Client but using both won't lead to that issue.
The issue is because you are only running the client, not the bot. You need to also run the bot instance if you want it to function.
If you are not trying to do something specific, then just using either bot or client will suffice anyway, so that part of the selected answer was helpful in avoiding the issue at least.
I am writing a discord bot with discord.py.
I wrote an initial version but I decided it all needed reorganizing so I moved code to different files.
The code is all the same as it was before but now when I boot up the bot, the bot detects no messages being sent in any server unless the message came from the bot itself.
The main code that handles the client is:
import discord
import time
from command_list import *
from resource_functions import grab_setting_from_category
print("Main initialized")
client = discord.Client()
token = "BOT TOKEN"
prefix = "!"
#client.event
async def on_ready():
print("*** BOT IS READY ***")
async def server_count_loop():
while True:
servers = client.servers
await client.change_presence(
game=discord.Game(name=" in {0} Servers".format(str(len(servers)))))
time.sleep(10)
for server in client.servers:
for channel in server.channels:
if channel.name == "general":
await client.send_message(channel, content="Bot Online")
await server_count_loop()
#client.event
async def on_message(message):
print("Message detected from {0} as '{1}'".format(message.author, message.content))
if not message.author.bot:
global prefix
prefix = grab_setting_from_category(message.server.id, "server", "prefix")
if message.content.startswith(prefix):
for i in range(0,len(commands)):
key = list(commands.keys())[i]
table = list(commands.values())[i]
if message.content.startswith(prefix+key):
table["function"](message, commands)
client.run(token)
In the code there's the print(...) at the start of the on_message function which I am using as a basic way to let me know if the bot is detecting messages. The print statement prints whenever the bot sends a message in on_ready but no messages from other users on Discord are triggering the function.
Don't use:
time.sleep(...)
Instead, use:
await asyncio.sleep(...)
time.sleep is a blocking call, it blocks the asyncio loop to continue to run. That is why you need to have an asynchronous .sleep(...) method.