Commands don't function in nextcord 2.0.0 - python

I've programmed several Discord bots and am back after a long break. I am currently struggling with stuff that I used to be able to accomplish in no time. I set up my bot and added a single cog, a single test command, and a listener to feel if there is anything new but now I can't get anything to work properly. My prefix commands aren't working, messages don't seem to carry .content anymore and I can't trigger functions in my cogs.
Main file:
import nextcord as discord
from nextcord.ext import commands
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
bot = commands.Bot(command_prefix = "!", intents = intents)
#bot.event
async def on_ready():
bot.load_extension("Button Roles")
print("Ready")
#bot.event
async def on_message(message):
if message.author.bot == False:
#await message.channel.send(message.content)
print(message)
#bot.command()
async def ping2(ctx):
print("Pong2!")
await ctx.send("Pong!")
bot.run("Token placeholder")
Cog:
import nextcord as discord
from nextcord.ext import commands
from nextcord import Interaction
class RoleButton(discord.ui.View):
def __init__(self):
super().__init__(timeout = None)
self.value = None
#discord.ui.button(label = "Role1", style = discord.ButtonStyle.green)#Green, Gray, Blurple, Danger
async def Role1(self, button: discord.ui.Button, i: Interaction):
await i.response.send_message("Role 1", ephemeral = True)
self.value = 1
self.stop()
#discord.ui.button(label = "Role2", style = discord.ButtonStyle.danger)#Green, Gray, Blurple, Danger
async def Role2(self, button: discord.ui.Button, i: Interaction):
await i.response.send_message("Role 2", ephemeral = True)
self.value = 2
self.stop()
class Roles(commands.Cog):
def __init__(self, bot):
self.bot = bot
print("Cog ready")
testServerId = 946874409753403422
#commands.command()
async def ping(self, ctx):
await ctx.send("Pong!")
#commands.command()
async def roleMessage(self, ctx):
view = RoleButton()
await ctx.send("You have two options:", view = view)
await view.wait()
if view.i.value == None:
return
elif view.i.value == 1:
print("Role 1!")
elif view.i.value == 2:
print("Role 2!!")
def setup(bot):
bot.add_cog(Roles(bot))
Outputs:
Cog ready
Ready
<Message id=993515538649202748 channel=<TextChannel id=946874410286084129 name='general' position=1 nsfw=False news=False category_id=946874410286084127> type=<MessageType.default: 0> author=<Member id=355727891180290070 name='ℭruenie' discriminator='8426' bot=False nick=None guild=<Guild id=946874409753403422 name="Project" shard_id=0 chunked=True member_count=4>> flags=<MessageFlags value=0>>
Expected Output (Using message.content instead of message):
Cog ready
Ready
'Hi'
#When I use !ping or !ping2 I don't get any outputs/messages
I have enabled the Intents from the Developer Portal.

Related

Why the Cog is not loading?

I created a discord bot with cog and extensions, but the commands aren't being imported
Main file:
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
bot = commands.Bot(command_prefix=commands.when_mentioned_or('!'), intents=intents)
bot.remove_command('help')
#bot.event
async def on_ready():
print(f'Bot ready as {bot.user}')
bot.load_extension('.ext.moderation')
bot.run(***)
"Moderation.py" extension:
import discord
import datetime
from discord.ext import commands
from ..functions import Time
class Moderation(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.command()
#commands.has_permissions(ban_members = True)
async def ban(self, ctx, member : discord.Member = None, *, reason = None):
if member == None:
await ctx.send('Você deve especificar um membro para ser banido!', delete_after = 10)
else:
await member.ban(reason = reason)
#commands.command()
#commands.has_permissions(kick_members = True)
async def kick(self, ctx, member : discord.Member = None, *, reason = None):
if member == None:
await ctx.send('Você deve especificar um membro para ser expulso!', delete_after = 10)
else:
await member.kick(reason = reason)
#commands.command()
#commands.has_permissions(administrator = True)
async def unban(self, ctx, *, member = None):
if member == None:
await ctx.send('Você deve especificar um membro para ser desbanido!', delete_after = 10)
else:
banned_users = await ctx.guild.bans()
member_name, member_discriminator = member.split("#")
for ban_entry in banned_users:
user = ban_entry.user
if (user.name, user.discriminator) == (member_name, member_discriminator):
await ctx.guild.unban(user)
await ctx.send(f'Unbanned {user.mention}')
return
else:
await ctx.send('O membro não está banido!')
#commands.command(aliases=['purge','clean','limpar'])
#commands.has_permissions(manage_messages=True)
async def clear(self, ctx, amount: int = 10):
try:
int(amount)
except:
await ctx.send('Insira um número válido.', delete_after=5)
else:
await ctx.channel.purge(limit=amount)
await ctx.send(f'Apagou {amount} mensagens.', delete_after=5)
#commands.command(aliases=['mute'])
#commands.has_role('Mod' or 'Admin')
async def timeout(self, ctx, member : discord.Member, duration = '30m', *, reason = None):
lenght = Time.input_convert(duration)
if lenght == -1:
await ctx.send('Duração inválida! Digite a duração no formato (s/m/d/h).')
else:
lenght = datetime.timedelta(seconds = lenght)
await member.timeout(until = lenght, reason = reason)
def setup(bot):
bot.add_cog(Moderation(bot))
But whenever I try to use a command, this appears in the console instead: discord.ext.commands.errors.CommandNotFound: Command "ban" is not found
Where is the error?
I tried to change some parts of the code, using just Cogs or just extensions, but it isn't working anyway.
If you're using the latest version of discord.py, loading Cogs is Asynchronous now!
Do this for your main file:
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
class BotClient(commands.Bot):
def __init__(self):
super().__init__(command_prefix=commands.when_mentioned_or('!'), intents=intents, help_command=None)
async def setup_hook(self):
await self.load_extension('ext.moderation')
# Load cogs here
async def on_ready(self):
print(f'Bot ready as {self.user}')
bot = BotClient()
bot.run(***)
Then change the setup function on the cog with this:
async def setup(bot):
await bot.add_cog(Moderation(bot))'
More on this change:
https://discordpy.readthedocs.io/en/latest/migrating.html#extension-and-cog-loading-unloading-is-now-asynchronous
Migrating to v2.0: https://discordpy.readthedocs.io/en/latest/migrating.html#

unban based on reason discord.py

so my discord server got hacked and everyone got banned with "gotcha" reason
is there a way to make this code read this reason and unban everyone that has it?
if it's not a big problem can it send this unbanned nicks or id's in the channel?
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True
bot = commands.Bot(command_prefix = '!', intents=intents)
#bot.event
async def on_ready():
print('TO PRONTO FDP')
#bot.command()
async def pronto(ctx):
await ctx.send("Esperando...")
#bot.command()
async def massunban(ctx):
banlist = await ctx.guild.bans()
for users in banlist:
try:
await ctx.guild.unban(user=users.user)
await ctx.channel.send(f"UNBANNED: **{users.user}**")
except:
pass
await ctx.channel.send(f"Finalizado")
For discord.py 1.7.3 (stable)
#bot.command()
async def massunban(ctx: commands.Context):
bans = await ctx.guild.bans() # list of discord.BanEntry
for ban_entry in bans:
await ctx.guild.unban(user=ban_entry.user)
await ctx.send("Done!")
References:
discord.Guild.bans
discord.BanEntry
discord.Guild.unban
For discord.py 2.0 (latest)
#bot.command()
async def massunban(ctx: commands.Context):
# Because of a change in Discord's API,
# discord.Guild.bans() returns now a paginated iterator
# Flattening into a list
bans = [ban_entry async for ban_entry in ctx.guild.bans()] # list of discord.BanEntry
for ban_entry in bans:
await ctx.guild.unban(user=ban_entry.user)
await ctx.send("Done!")
References:
discord.Guild.bans
discord.BanEntry
discord.Guild.unban
i solved it
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.members = True
bot = commands.Bot(command_prefix = '!', intents=intents)
#bot.event
async def on_ready():
print('ready to go')
#bot.command()
async def help(ctx):
await ctx.send("!start")
#bot.command()
async def start(ctx):
reason = "Zardex V3"
reason2 = "Zardex v3"
reason3 = "zardex v3"
reason4 = None
await ctx.channel.send(f"*Loading...*")
print('Loading...')
banlist = await ctx.guild.bans()
for users in banlist:
if (reason==users.reason):
try:
await ctx.guild.unban(user=users.user)
await ctx.channel.send(f"Unbanned: **{users.user}** Reason: **{users.reason}**")
except:
pass
if (reason2==users.reason):
try:
await ctx.guild.unban(user=users.user)
await ctx.channel.send(f"Unbanned: **{users.user}** Reason: **{users.reason}**")
except:
pass
if (reason3==users.reason):
try:
await ctx.guild.unban(user=users.user)
await ctx.channel.send(f"Unbanned: **{users.user}** Reason: **{users.reason}**")
except:
pass
if (reason4==users.reason):
try:
await ctx.guild.unban(user=users.user)
await ctx.channel.send(f"Unbanned: **{users.user}** Reason: **{users.reason}**")
except:
pass
await ctx.channel.send(f"*Finished.*")
print('Finished.')

Taking away all of persons roles and giving them back after some time

I am trying to make a bot that once given a command will take away a persons roles and give them back after a certain amount of time. right now im getting the eror unexpected indent.
here is the code:
import discord
from discord.ext import commands
import ctx
import re
import time
from time import sleep
from discord.ext import rolelist, roles, role
class MyClient(discord.Client):
async def on_ready(self):
print('Logged on as', self.user)
async def on_message(self, message):
if message.author == self.user:
return
messageContent = message.content
if len(messageContent) > 0:
if re.search("^send.*court$", messageContent):
user_id = message.mentions[0].id
user = message.mentions[0]
await message.channel.send(
f"sending <#{user_id}> to court!"
)
async def listroles(ctx):
user_roles = [role.mention for role in ctx.message.author.roles if role.mentionable]
await message.channel.send(user_roles)
async def roles(ctx):
print(", ".join([str(r.id) for r in ctx.guild.roles]))
role = discord.utils.get(message.guild.roles, name="Jail")
await user.add_roles(role)
async def roles(user.roles):
rolelist = [r.mention for r in user.roles if r != ctx.guild.default_role]
roles = ", ".join(rolelist)
print(rolelist)
client = MyClient()
client.run('TOKEN_GOES_HERE')
Python don't use {} like C# or Java, it works with indentation. So your code should be this:
await user.add_roles(role)
async def get_roles(user):
rolelist = [r.mention for r in user.roles if r != ctx.guild.default_role]
roles = ", ".join(rolelist)
print(rolelist)

How do I run the discord bot after doing client.run()?

class MyClient(discord.Client):
def __init__(self, *args, loop=None, **options):
intents = discord.Intents.default()
intents.members = True
self.data = {}
super().__init__(intents=intents, *args, loop=None, **options)
async def on_ready(self):
print('Logged on as {0}!'.format(self.user))
for guild in self.guilds:
members = []
async for member in guild.fetch_members():
members.append(member)
if member.name == "Name":
await member.send("Hello :wave:")
self.data[guild] = members
print(self.data[guild])
async def on_message(self, message):
if message.author == self.user:
return
if message.content.startswith('$hello'):
await message.author.send(":wave:")
async def sendMessage(self, name, message):
for guild in self.data:
for member in self.data[guild]:
if name == member.name:
print(member.name)
await member.send(message)
and in another file ie main.py or something,
client = MyClient()
client.run(TOKEN)
while True:
sleep(5)
client.sendMessage("Me", "Hello")
Ideal, I would use this to notify me once my other code is finished running or something similar to that nature. I've tried Threading as in this example https://stackoverflow.com/a/62894021/9092466, but I can't figure out how to make the code wait for the client to finish getting ready
using sleep is not recommended for async libraries like discord.py, you can use discord.py's tasks to run a loop
from discord.ext import tasks
class MyClient(discord.Client):
def __init__(self, *args, loop=None, **options):
intents = discord.Intents.default()
intents.members = True
self.data = {}
super().__init__(intents=intents, *args, loop=None, **options)
self.send_message.start()
#tasks.loop(seconds= 5)
async def send_message(self, name, message):
for guild in self.data:
for member in self.data[guild]:
if name == member.name:
print(member.name)
await member.send(message)
#send_message.before_loop
async def before_sending(self): #waiting until the bot is ready
print('waiting...')
await self.bot.wait_until_ready()
References:
tasks
time.sleep is bad

How to unban a discord user given their ID

The code I'm currently using was perfectly fine, but I really want to unban with ID because it is much easier for me.
Current command is in a Cog file:
import discord
from discord.ext import commands
class unban(commands.Cog):
def __init__(self, client):
self.client = client
#commands.command()
#commands.has_permissions(administrator=True)
async def unban(self, ctx, *, member : discord.Member):
banned_users = await ctx.guild.bans()
member_name, member_discriminator = member.split("#")
for ban_entry in banned_users:
user = ban_entry.user
if (user.name, user.discriminator) == (member_name, member_discriminator):
await ctx.guild.unban(user)
unban = discord.Embed(title='UnBan Hammer Has Spoken! :boom:', description=f'**Moderator:** {ctx.author}\n **User UnBanned:** {member}\n', color=0x10940b)
unban.set_author(name="Moderating Action", icon_url=ctx.author.avatar_url)
await ctx.send(embed=unban)
return
def setup(client):
client.add_cog(unban(client))
How can I update this code to unban using the user ID instead?
async def unban(self, ctx, id: int) :
user = await client.fetch_user(id)
await ctx.guild.unban(user)
await ctx.send(f'{user} has been unbanned')
this should work for you, you can personalize even more, but that's just the main code you need.
Try
async def unban(self, ctx, *, member : discord.User):
await ctx.guild.unban(discord.Object(id = member.id))
unban = discord.Embed(title='UnBan Hammer Has Spoken! :boom:', description=f'**Moderator:** {ctx.author}\n **User UnBanned:** {member}\n', color=0x10940b)
unban.set_author(name="Moderating Action", icon_url=ctx.author.avatar_url)
await ctx.send(embed=unban)

Categories

Resources