I am trying to learn discord.py V2.0. If I create a slash command without entering a guild to use then I takes some time before discord updated the bot slash command list. The qustion is how should I provide the guilds in my cog python file?
Here is my main.py:
import os
import asyncio
#---
import discord
from discord import app_commands
from discord.ext import commands
#---
MY_GUILD = discord.Object(id=1041079018713260173)
TOKEN = "token goes here"
intents = discord.Intents.default()
bot = commands.Bot(command_prefix="!", intents=intents)
class abot(discord.Client):
def __init__(self, *, intents: discord.Intents):
super().__init__(intents=intents)
self.bot = bot
self.synced = False
self.tree = app_commands.CommandTree(self.bot)
async def on_ready(self):
await self.tree.sync(guild=MY_GUILD)
self.synced = True
async def load():
print("---Cogs---")
for filename in os.listdir("./cogs"):
if filename.endswith(".py"):
await bot.load_extension(f"cogs.{filename[:-3]}")
print(f'[i]: Loaded "{filename}" into cogs')
async def main():
await load()
await bot.start(TOKEN)
asyncio.run(main())
Here is the event.py file inside of "cogs" folder:
import asyncio
import os
#---
import discord
from discord import app_commands
from discord.ext import commands
status = "testar bara..."
MY_GUILD = discord.Object(id=1041079018713260173)
class events(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.Cog.listener()
async def on_ready(self):
print("---Info---")
print(f'Logged in as | "{self.bot.user}" | and is now online!')
await self.bot.change_presence(status=discord.Status.online, activity=discord.Game(status))
print(f'Updated status to -> "{status}"')
print("Running and listening for commands....")
print(f"----")
#app_commands.command(name = "latency", description="brrarar testar")
async def latencyf(self, interaction: discord.Interaction):
await interaction.response.send_message(f"test... test...")
async def setup(bot):
await bot.add_cog(events(bot))
You do not need to provide the guilds yourself. You can use bot.guilds, which provides a list of all the guilds where the bot is connected to.
Related
I've provided code of two files. bot.py - runs bot, ping.py - cog file.
The problem is that Cog doesn't work, bot doesn't respond to commands, in my ping.py file i have ping command
bot.py
import discord as ds
import asyncio
import os
from dotenv import load_dotenv
from discord.ext import commands
load_dotenv()
intents = ds.Intents.all()
intents.message_content = True
bot = commands.Bot(command_prefix='!', intents=intents)
#bot.event
async def on_message(message):
if message.author == bot.user:
return
username = str(message.author)
user_message = str(message.content)
channel = str(message.channel)
print(f"{username} said: '{user_message}' ({channel})")
async def load_cogs():
for filename in os.listdir('./cogs'):
if filename.endswith('.py'):
await bot.load_extension(f'cogs.{filename[:-3]}')
#bot.event
async def on_ready():
print(f'{bot.user} is now running.')
async def main():
await load_cogs()
async with bot:
TOKEN = os.getenv('TOKEN')
await bot.start(TOKEN)
asyncio.run(main())
ping.py
import discord
from discord.ext import commands
import asyncio
class ping(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.command(name="ping", description="Returns Pong!")
async def ping(self, ctx):
await ctx.send("Pong!")
async def setup(bot: commands.Bot):
await bot.add_cog(ping(bot))
After running bot display 0 errors. I tried to changing intents from default() to all() but it didn't help.
You override the on_message event, and you don't have a process_commands in it, so the bot won't be processing any commands.
You can fix this by adding bot.process_commands inside the event.
#bot.event
async def on_message(message):
...
await bot.process_commands(message)
Or register it as a listener so it doesn't override the default event.
#bot.listen()
async def on_message(message):
...
I'm trying to get custom commands to work in my Discord server. But it doesn't work when I'm not using a decorator, and I do not know how to make it work within a class.
Please help.
(XXX.. just replaces an ID here)
Please have a look at add_my_commands() function. This one should be able to take the prefix and respond with the info. This doesn't work currently.
I have a main.py file which runs separately, as follows:
# Import discord.py
import discord
from discord.ext import commands
# Import Bot Token
from apikeys import *
# Import classes
from steward_bot import MyClient
intents = discord.Intents.default() # or .all() if you ticked all, that is easier
intents.message_content = True
intents.members = True # If you ticked the SERVER MEMBERS INTENT
# Initialize client
bot = MyClient(command_prefix="!", intents=intents)
bot.run(DISCORD_TOKEN)
The MyClient class:
class MyClient(commands.Bot):
def __init__(self, *args, command_prefix, **kwargs):
super().__init__(
*args, command_prefix=command_prefix, case_insensitive=True, **kwargs
)
self.target_message_id = XXXX
self.add_my_commands()
async def on_ready(self):
print("We have logged in as {0.user}".format(self))
print("---------------------------------------------")
async def on_member_remove(self, member):
channel = self.get_channel(XXXX)
await channel.send("Goodbye")
async def on_raw_reaction_add(self, payload):
"""
Give a role based on a reaction emoji
"""
if payload.message_id != self.target_message_id:
return
guild = self.client.get_guild(payload.guild_id)
print(payload.emoji.name)
print("Hello")
# Responding to messages
async def on_message(self, message):
if message.author == self.user:
return
if message.content == "Test":
await message.channel.send("Hey hey chill")
if message.content == "cool":
await message.add_reaction("\U0001F60E")
if message.content == "give me our prefix":
await message.channel.send(str(self.command_prefix))
await self.process_commands(message)
# Throws out reactions to messages
async def on_reaction_add(self, reaction, user):
await reaction.message.channel.send(f"{user} reacted with {reaction.emoji}")
def add_my_commands(self):
#self.command(name="info", pass_context=True)
async def info(ctx):
"""
ctx - context (information about how the command was executed)
info
"""
print(ctx)
await ctx.send("Hello X")
await ctx.send(ctx.guild)
await ctx.send(ctx.author)
await ctx.send(ctx.message.id)
Within the server, I want to run the command "!info" and get the information out. Would appreciate any help!
No need to define your entire bot within a class. Create a main.py file with your bot defined and import cogs from there. I'd also set up my commands through a cog with commands.command().
Example of how I'd go about adding an !info command:
main.py
import discord
from discord.ext import commands
from info import InfoCog
intents = discord.Intents.default()
intents.members = True
intents.guilds = True
intents.messages = True
intents.reactions = True
intents.presences = True
# Initialize client
bot = commands.Bot(command_prefix='!', intents=intents)
bot.add_cog(InfoCog(bot))
#bot.event
async def on_ready(self):
print("We have logged in as {0.user}".format(self))
print("---------------------------------------------")
bot.run(TOKEN)
info.py
import discord
from discord.ext import commands
class InfoCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.command()
async def info(self, ctx):
await ctx.send('Info')
Or, you could jumble everything into one file. This is how I used to do it with all my commands & events. It was easier to get the hang of at first.
main.py
# Import discord.py
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True
intents.guilds = True
intents.messages = True
intents.reactions = True
intents.presences = True
bot = commands.Bot(command_prefix='!', intents=intents)
#bot.event
async def on_ready(bot):
print("We have logged in as {0.user}".format(bot))
print("---------------------------------------------")
# [...]
#bot.command()
async def info(ctx):
await ctx.send('info')
# [...]
#bot.event
async def on_message(message):
if message.author == bot.user:
return
if message.content == "give me our prefix":
await message.channel.send(str(bot.command_prefix))
if message.content == "Test":
await message.channel.send("Hey hey chill")
# [...]
#bot.event()
async def on_member_remove(member):
channel = bot.get_channel(CHANNELID)
await channel.send(f"Goodbye, {member}")
# [...]
bot.run(TOKEN)
I want to use a slash command in DMs. Take this simple test.py file in the folder cogs/.
import discord
from discord.ext import commands
from discord import app_commands
class Test(commands.Cog):
def __init__(self, bot: commands.Bot) -> None:
self.bot = bot
#commands.Cog.listener()
async def on_ready(self):
print("Loaded test command cog.")
#app_commands.command(name="test", description="Test command")
async def test(self, interaction: discord.Interaction):
await interaction.response.send_message(f'Hello')
async def setup(bot: commands.Bot) -> None:
await bot.add_cog(Test(bot))
Outside the cogs folder is my launch_bot.py file which start the bot:
import discord
from discord.ext import commands
import json
with open("cogs/jsons/settings.json") as json_file:
data_dict = json.load(json_file)
guild_id = data_dict["guild_id"]
class MyBot(commands.Bot):
def __init__(self) -> None:
super().__init__(
command_prefix = "kt$",
intents = discord.Intents.all(),
tree_cls=CustomCommandTree)
async def setup_hook(self) -> None:
for filename in os.listdir("./cogs"):
if filename.endswith(".py"):
await self.load_extension(f"cogs.{filename[:-3]}")
await bot.tree.sync(guild=discord.Object(id=guild_id))
async def on_ready(self):
application_info = await self.application_info()
bot_owner = application_info.owner
await bot_owner.create_dm()
self.bot_owner_dm_channel = bot_owner.dm_channel
await self.change_presence(activity=discord.Game(presence_message))
print(f"Logged in as\n\tName: {self.user.name}\n\tID: {self.user.id}")
print(f"Running pycord version: {discord.__version__}")
print(f"Synced commands to guild with id {guild_id}.")
bot = MyBot()
bot.run(bot_token)
I tried following the instructions which were described in link but I have no guild specified, so this doesn't work.
The docs says it should work but it doesn't for me any ideas?
If you are using pycord, at least for me commands were usable in dm's by default. I'll show you how to disable that if you ever need to.
#bot.command()
#commands.guild_only()
async def example(ctx):
#do things
I want to add a username or id to the code so that when I (or somebody else) does .d #username, the selfbot does the whole ".accept" and "u 4" response.
Code:
import discord
import os
from discord.ext.commands import Bot
from discord.ext import commands
import asyncio
client = discord.Client()
b = Bot(command_prefix = ".d")
#b.event
async def on_ready():
print("rdy")
#b.event
async def on_message(message)
if message.content == ".d":
await message.channel.send(".accept")
await message.channel.send("u 4")
b.run(os.getenv("TOKEN"), bot = False)
You should use commands it makes things alot easier.
#b.command(aliases=['.d'])
async def d(ctx, member: discord.Member):
await ctx.send(".accept")
await ctx.send("u 4")
I added the .d in aliases cause you cannot have a function starting with . . Here is the link for more information. https://discordpy.readthedocs.io/en/latest/ext/commands/api.html?highlight=group#commands
How to load commands from multiple files Python Bot below is my main.py and other python files with commands. Is this correct method or do i need to change anything? do i need to add token, prefix, bot = commands.Bot, bot.run(token) etc in all files.
main.py
token = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
prefix = "?"
import discord
from discord.ext import commands
startup_extensions = ["second", "third"]
bot = commands.Bot(command_prefix=prefix)
bot.remove_command("help")
#bot.event
async def on_ready():
print('Logged in as')
print(bot.user.name)
print(bot.user.id)
print('------')
#bot.command(pass_context=True)
async def hello1(ctx):
msg = 'Hello {0.author.mention}'.format(ctx.message)
await bot.say(msg)
bot.run(token)
second.py
import discord
from discord.ext import commands
class Second():
def __init__(self, bot):
self.bot = bot
#commands.command(pass_context=True)
async def hello2(ctx):
msg = 'Hello{0.author.mention}'.format(ctx.message)
await bot.say(msg)
def setup(bot):
bot.add_cog(Second(bot))
third.py
import discord
from discord.ext import commands
class Third():
def __init__(self, bot):
self.bot = bot
#commands.command(pass_context=True)
async def hello3(ctx):
msg = 'Hello{0.author.mention}'.format(ctx.message)
await bot.say(msg)
def setup(bot):
bot.add_cog(Third(bot))
Would you could do is setup your file with cogs for example your main file:
import discord
from discord.ext import commands
client = commands.Bot(command_prefix="!") # <- Choose your prefix
# Put all of your cog files in here like 'moderation_commands'
# If you have a folder called 'commands' for example you could do #'commands.moderation_commands'
cog_files = ['commands.moderation_commands']
for cog_file in cog_files: # Cycle through the files in array
client.load_extension(cog_file) # Load the file
print("%s has loaded." % cog_file) # Print a success message.
client.run(token) # Run the bot.
Say in your moderation_commands file it would look like:
import discord
from discord.ext import commands
class ModerationCommands(commands.Cog):
def __init__(self, client):
self.client = client
#commands.command(name="kick") # Your command decorator.
async def my_kick_command(self, ctx) # ctx is a representation of the
# command. Like await ctx.send("") Sends a message in the channel
# Or like ctx.author.id <- The authors ID
pass # <- Your command code here
def setup(client) # Must have a setup function
client.add_cog(ModerationCommands(client)) # Add the class to the cog.
You can find more information on cogs here: https://discordpy.readthedocs.io/en/stable/ext/commands/cogs.html