I'm trying to make my bot give role after a command is being called but I'm not sure what is the right command. I searched online but every single one I tried gave an error. Anyone know the correct form of the command?
The code:
#iports the discord folder and commands for our bot
import discord
from discord.ext import commands
from discord import Member
from discord.ext.commands import has_permissions
from discord.ext import tasks
#sets the command prefix
Client = commands.Bot(command_prefix = ";")
#print Nuggie is ready in the console when the bot is activeted
#Client.event
async def on_ready():
await Client.change_presence(status=discord.Status.online, activity = discord.Game("With Your Mom"))
print("Nuggie is ready")
#Client.command()
async def setup_verification(ctx, arg):
channel_id = 768983636296204318
await clear(ctx)
Text = "send ;verify to this message to get verified and get access to the server!"
embedVar = discord.Embed(title = "Verify your identity", description = Text, color = 0xC311EF)
embedVar.add_field(name = "\u200B", value = "\u200B")
embedVar.add_field(name = "This proccess in crucial for the server.", value = "Without this, the server is exposed to raids." , inline=False)
await ctx.channel.send(embed=embedVar)
#await ctx.send(Text)
#Client.command()
async def verify(ctx):
channel = 768983636296204318
if discord.TextChannel.id == channel:
clear()
await ctx.send("This message is not available in this channel! Pls only use command where it's supposed to be!")
else:
author = ctx.message.author.name
#Role = discord.utils.get(author.server.roles, name="Member")
await Message.add_roles(author, "Member")
#roleRemove = get(user.server.roles, name='member')
await Client.remove_role(author, "Unverified")
await ctx.send(f"{author} you are verified!")
await asyncio.sleepdelay(s = 60)
clear(ctx, 2)
Client.run('My_Token')
and the error I get when I run verify is:
Ignoring exception in command verify:
Traceback (most recent call last):
File "C:\Users\roy\AppData\Roaming\Python\Python38\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\roy\Desktop\Folders\Atom\Discord Bot\Nuggie.py", line 40, in verify
await Message.add_roles(author, "Member")
NameError: name 'Message' is not defined
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\roy\AppData\Roaming\Python\Python38\site-packages\discord\ext\commands\bot.py", line 903, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\roy\AppData\Roaming\Python\Python38\site-packages\discord\ext\commands\core.py", line 859, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Users\roy\AppData\Roaming\Python\Python38\site-packages\discord\ext\commands\core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: NameError: name 'Message' is not defined
You need the Member object and you can call add_roles() on it. ctx.author is your Member object, now you need to get your Role object. There is different ways to get the Role object. You can get it by ID using Guild.get_role(role_id) or you can get it by name using discord.utils.get
memberRole = discord.utils.get(ctx.guild.roles, name='Member')
Now since you have your Member object and your Role object you can simply call Member.add_roles() on your Member object.
await ctx.author.add_roles(memberRole)
Same thing to remove the Unverified role, except you call Member.remove_roles()
Related
I've been trying to create some commands using discord.py. I've created a command which creates a channel based on the text a user inputs using the following code:
import discord
import os
client = discord.Client()
#client.event
async def on_message(message):
if message.author == client.user:
return
msg = message.content
if msg.startswith('$new'):
guild = discord.Guild
await guild.create_text_channel(msg.split(' ',1)[1])
When a command is entered into discord this is the output:
Ignoring exception in on_message
Traceback (most recent call last):
File "/home/runner/Switch-Bot/venv/lib/python3.8/site-packages/discord/client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "main.py", line 30, in on_message
if msg.startswith('$new'):
TypeError: create_text_channel() missing 1 required positional argument: 'name'
You did
guild = discord.Guild
await guild.create_text_channel(msg.split(' ',1)[1])
This calls an instance method from the class, so you'll have to specify the instance (self) that you want it to work with, which will cause the name argument to not be passed the way you want it to be.
See here
What you want is to execute it from the instance:
await message.guild.create_text_channel(msg.split(' ',1)[1])
# or
await discord.Guild.create_text_channel(message.guild, msg.split(' ',1)[1])
you should also change
guild = discord.Guild
to
guild = message.guild
trying to make a global banning system with cogs but it gives me cog errors and im not too good with cog. the code is from an old github repo by the way so i dont take credit for this.
bot.py:
import discord
import os
import json
from discord.ext import commands
client = commands.Bot(command_prefix = ".")
client.remove_command("help")
#client.event
async def on_ready():
print("Global Banning System is online!")
for filename in os.listdir("cogs"):
if filename.endswith(".py"):
client.load_extension(f"cogs.gbs")
client.run(token)
and i also have another file in a new folder ("cogs") that is called "gbs.py".
gbs.py:
import discord
from discord.ext import commands
class gbs(commands.Cog):
def __init__(self, client):
self.client = client
#commands.command()
#commands.has_role(roleid) # Staff's Role
async def gban(self, ctx, member: discord.User):
channel = self.client.get_channel(channelid) # Logs
auth = ctx.author
await ctx.send("Ban Issue successfuly opened. Now, please type the ban reason!")
reason = await self.client.wait_for('message', timeout = 600)
embed = discord.Embed(title = f"Global Banned {member.name}", colour = 0xFF0000)
embed.add_field(name = "Reason:", value = reason.content, inline = False)
embed.add_field(name = "User ID:", value = f"`{member.id}`",)
embed.add_field(name = "Staff Member:", value = f"{auth.name}")
embed.set_thumbnail(url = member.avatar_url)
await ctx.send(embed = embed)
await ctx.send(f"**{member.name}** has been globbaly banned!")
for guild in self.gbs.guilds:
await guild.ban(member)
def setup(client):
gbs.add_cog(gbs(client))
This is the errors that it gives me.
Traceback (most recent call last):
File "C:\Users\user-01\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\cog.py", line 723, in _load_from_module_spec
setup(self)
File "C:\Users\user-01\Desktop\Global Banning System - Discord Bot\cogs\gbs.py", line 28, in setup
gbs.add_cog(gbs(client))
AttributeError: type object 'gbs' has no attribute 'add_cog'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\user-01\Desktop\Global Banning System - Discord Bot\bot.py", line 15, in <module>
client.load_extension(f"cogs.gbs")
File "C:\Users\user-01\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\cog.py", line 783, in load_extension
self._load_from_module_spec(spec, name)
File "C:\Users\user-01\AppData\Local\Programs\Python\Python310\lib\site-packages\discord\cog.py", line 728, in _load_from_module_spec
raise errors.ExtensionFailed(key, e) from e
discord.errors.ExtensionFailed: Extension 'cogs.gbs' raised an error: AttributeError: type object 'gbs' has no attribute 'add_cog'
You add a cog class to your bot not to your gbs. So replace gbs with client to solve the problem.
def setup(client):
# instead of gbs.add_cog...
client.add_cog(gbs(client)
Documentation
when I am trying to send a message to a channel it won't work. Anyone knows why?
This here is the command I am using. This is just the code block of the not working section.
#bot.command(pass_context=True)
async def test2(ctx):
await ctx.message.delete()
print("The Test is being started")
Channel = config['bot']['id1']
await Channel.send("test2")
And in My Config file, I have this
[bot]
id1= 916845047CENSORED
And when I try to run it I get this error:
The test is being started
Ignoring exception in command test2:
Traceback (most recent call last):
File "C:\Python\Python38\lib\site-packages\discord\ext\commands\core.py", line 85, in wrapped
ret = await coro(*args, **kwargs)
File "c:/Users/jp/Desktop/DISCORD BOT/bot.py", line 224, in test2
await Channel.send("test2")
AttributeError: 'str' object has no attribute 'send'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Python\Python38\lib\site-packages\discord\ext\commands\bot.py", line 939, in invoke
await ctx.command.invoke(ctx)
File "C:\Python\Python38\lib\site-packages\discord\ext\commands\core.py", line 863, in invoke
await injected(*ctx.args, **ctx.kwargs)
File "C:\Python\Python38\lib\site-packages\discord\ext\commands\core.py", line 94, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'str' object has no attribute 'send'
If anyone knows how to fix this I would thank you very much
Edit:
The way to solve this is:
add the int to the channel ID if it is from a txt file/config
#bot.command(pass_context=True)
async def test2(ctx):
await ctx.message.delete()
Channel_Id = config['bot']['id1']
print("Test is being started")
Chanel = bot.get_channel(int(Channel_Id))
await Chanel.send("test2")
Look at line 85 to find the line throwing the error. It's saying that the Channel object taken from config['bot']['id1'] is of type str. You are then trying to invoke the method .send() on a str type, which it does not have.
...
Channel = config['bot']['id1']
await Channel.send("test2")
With discord.py, channel objects are not just integers. Instead, you have to fetch the channel, either from a guild after fetching the guild with its id, or fetching the channel straight away. Here are some ways to do this:
Channel_Id = config['bot']['id1']
# Based on your error, ensure to convert Channel_Id to an Integer
# Example: "123454" -> 123454
Channel_Id = int(Channel_Id)
# Method 1: Fetching channel straight away
Channel = bot.get_channel(Channel_id)
# Method 2: Fetching channel from guild
Guild_Id = config['bot']['GuildId'] # of course you may need to add a new config
# Remember to convert this to an Integer as well!
Guild_Id = int(Guild_Id)
Guild = bot.get_guild(Guild_Id)
Channel = Guild.get_channel(Channel_Id)
await Channel.send("Test")
Other helpful links:
bot.get_channel(id) - discord.py docs
guild.get_channel(id) - discord.py docs
Please note: When searching for this answer, it is recommended not to use bot.fetch_channel as this is an API call. The above methods are recommended for general use.
Edit: When using bot.get_channel or the likes, you are likely to require Intents.
Links to questions like this:
discord.py channel returns None
How do I get the discord.py intents to work?
client.get_channel(id) returning "None"
'NoneType' object has no attribute 'send'
The way to solve this is:
add the int to the channel ID if it is from a txt file/config
#bot.command(pass_context=True)
async def test2(ctx):
await ctx.message.delete()
Channel_Id = config['bot']['id1']
print("Test is being started")
Chanel = bot.get_channel(int(Channel_Id))
await Chanel.send("test2")```
So, everything is basically said in the title. I have this code:
#commands.Cog.listener()
async def on_raw_reaction_add(self, payload):
channel = await self.bot.fetch_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
user = message.guild.get_member(payload.user_id)
guild = self.bot.get_guild(payload.guild_id)
emoji = payload.emoji
if message.id == 849352038801211403:
role = discord.utils.get(guild.roles, name = "[Role]")
if emoji.id == 849345681277452328: await user.add_roles(user, Apex)
else:
await channel.send("Incorrect emoji")
await message.remove_reaction(emoji, user)
And it is saying this error:
Ignoring exception in on_raw_reaction_add
Traceback (most recent call last):
File "C:\Users\mbuxiq\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "c:\Users\mbuxiq\Desktop\Code\Bot\Cogs\serverRelated.py", line 66, in on_raw_reaction_add
if emoji.id == 849345681277452328: await user.add_roles(user, Apex)
File "C:\Users\mbuxiq\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\member.py", line 676, in add_roles
await req(guild_id, user_id, role.id, reason=reason)
File "C:\Users\mbuxiq\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\http.py", line 243, in request
raise NotFound(r, data)
discord.errors.NotFound: 404 Not Found (error code: 10011): Unknown Role
I am clueless on what should I do. Please, help me. Thank you!
Your error message states Unknown Role # await user.add_roles(user, Apex)!
First of all, Apex isn't declared in the code you provided. Make sure it is when you call it. But since it didn't throw a NameError I guess it is.
Second of all, user is of type discord.Member since you declare it as
user = message.guild.get_member(payload.user_id)
But await discord.Member.add_roles() only takes discord.Role as arguments not members! This is where your error comes from. You're trying to assign a member as a role, which doesn't make sense at all. Simply removing user from your add_roles function call should fix your isse
#commands.Cog.listener()
async def on_raw_reaction_add(self, payload):
channel = await self.bot.fetch_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
user = message.guild.get_member(payload.user_id)
guild = self.bot.get_guild(payload.guild_id)
emoji = payload.emoji
if message.id == 849352038801211403:
role = discord.utils.get(guild.roles, name = "[Role]")
if emoji.id == 849345681277452328:
await user.add_roles(Apex)
else:
await channel.send("Incorrect emoji")
await message.remove_reaction(emoji, user)
So I want to play local files in my discord voice channel, right now it joins the voice channel but it does not play anything. This is the code:
if message.content.startswith('$Hest'):
where = message.content.split(" ")[1]
channel = get(message.guild.channels, name=where)
voicechannel = await channel.connect()
voicechannel.play(discord.FFempegPCMAudio(executable='D:/ffmpeg/ffmpeg/bin/ffplay.exe', source='D:/ffmpeg/Horse.mp3'))
And this is my output when I try to do it
Traceback (most recent call last):
File "F:\Apanda\CustomMultiPyBot\venv\lib\site-packages\discord\client.py", line 343, in _run_event
await coro(*args, **kwargs)
File "F:/Apanda/CustomMultiPyBot/main.py", line 41, in on_message
voicechannel.play(discord.FFempegPCMAudio(executable='D:/ffmpeg/ffmpeg/bin/ffplay.exe', source='D:/ffmpeg/Horse.mp3'))
AttributeError: module 'discord' has no attribute 'FFempegPCMAudio'
This issue is just that you are trying to use discord.FFempegPCMAudio when the class is actually discord.FFmpegPCMAudio.
So to correct your code:
if message.content.startswith('$Hest'):
where = message.content.split(" ")[1]
channel = get(message.guild.channels, name=where)
voicechannel = await channel.connect()
voicechannel.play(
discord.FFmpegPCMAudio(
'D:/ffmpeg/Horse.mp3',
executable='D:/ffmpeg/ffmpeg/bin/ffplay.exe'
)
)
And if you wanted to restructure this to use the discord.ext.commands framework, your code would look something like this:
import discord
from discord.ext import commands
bot = commands.Bot(command_prefix="$")
#bot.command(name="Hest")
async def hest(ctx, where):
channel = discord.utils.get(ctx.guild.channels, name=where)
voicechannel = await channel.connect()
voicechannel.play(
discord.FFmpegPCMAudio(
'D:/ffmpeg/Horse.mp3',
executable='D:/ffmpeg/ffmpeg/bin/ffplay.exe'
)
)
bot.run("<token>")