discord.py how add role to member - discord.py

I cannot solve the problem. How to add a role to the user who called the !role command.
Please, help.
import discord
from discord.ext import commands
from apex_legends import ApexLegends
intents = discord.Intents.default()
intents.members = True
client = commands.Bot(command_prefix='!', intents = intents)
#client.command()
async def rank(ctx, user_name,):
rank = get_apex_rank(user_name) #return str role name
await ctx.send(f"{rank}")# successfully receiving a response from the bot
member = ctx.author
role = discord.utils.get(member.guild.roles, name=rank)
await member.add_roles(role)
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'User' object has no attribute 'guild'
def get_apex_rank(name):
try:
player = apex.player(name)
a = player.__dict__
return a['_data']['metadata']["rankName"]
except:
return "Wrong name"

#client.command():
async def role(ctx):
role = discord.utils.get(ctx.guild.roles, name="enter role name") #enter role name here
user = ctx.message.author
await user.add_roles(role)

Related

I want to make introduction and make bot give role to the user after user introduce

I want to make introduction and make bot give role to the user after user introduce himself.
My code is
import discord
from Secret import Token
from discord.ext import commands
from discord.utils import get
bot = commands.Bot(command_prefix='*',intents=discord.Intents.all())
#Introduction
#bot.command(pass_context=True)
async def ind(ctx,user: discord.User = None):
#UserID
if not user:
userId = ctx.author.id
#Name
await ctx.channel.send(f'<#{userId}> Name?')
msg = await bot.wait_for('message')
name = (msg.content)
#Age
await ctx.channel.send(f'<#{userId}> Age?')
msg2 = await bot.wait_for('message')
old = (msg2.content)
#Give Role
role = user.guild.get_role()
user.add_role(1030982386235736064)
#Send Info
channel = bot.get_channel(1030963854450761598)
await channel.send(f'<#{userId}>\nName -> {name}\nAge -> {old}')
await channel.send('------------------------------------------>')
bot.run(Token)
and Its get error after use command
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'NoneType' object has no attribute 'guild'

Message content intent is not enabled. Prefix commands may not work as expected unless you enable this

I don't know why I'm getting this error. I have all the intents enabled as seen in the image below.
This is my first project** in discord.py, and I don't really understand some things.
Here is the code I have (hoping this is relavant):
import nextcord
from nextcord import Interaction
from nextcord.ext import commands
intents = nextcord.Intents.default()
intents.members = True
command_prefix = '!'
client = commands.Bot(command_prefix, intents = intents)
#client.event
async def on_ready():
print('logged in as {0.user}'.format(client))
print(command_prefix)
testserver = 988598060538015815
#nextcord.slash_command(name = "hello", description = "Bot Says Hello", guild_ids = [testserver])
async def hellocommand(interaction: Interaction):
await interaction.response.send_message("yoooo")
client.run("my token")
change intents = nextcord.Intents.default() to intents = nextcord.Intents.all()

how to trigger the event in case of bot restart or crash discord.py

I would like my bot when I restart it or crash it activates an event that deletes momentary data. I tried using on_disconnect as an event but it doesn't work. In the code below I used on_disconnect as a command but I wish there was an event. It's possible?
async def on_disconnect(ctx):
cursor = levelsystem_db.cursor()
for member in ctx.guild.members:
cursor.execute(f"SELECT * FROM anti_spam WHERE client_id = {str(member.id)}")
result = cursor.fetchall()
print(member, member.id, len(result))
if (len(result) != 0):
cursor.execute(f"DELETE FROM anti_spam WHERE client_id = {str(member.id)}")
levelsystem_db.commit()
print(f"ho rimosso i dati di {member}")
EDIT:
import discord
class Bot(discord.Client):
def __init__(self) -> None:
discord.Client.__init__(self)
return
async def on_ready(self) -> None:
await self.close() # This can simulate a crash for now
return
if __name__ == '__main__':
client = Bot()
client.run(token)
# Code after crash here
print('Bot has crashed')
cursor = levelsystem_db.cursor()
guild = client.get_guild(637626960599842824)
print(guild)
for member in guild.members:
cursor.execute(f"SELECT * FROM anti_spam WHERE client_id = {str(member.id)}")
result = cursor.fetchall()
print(member, member.id, len(result))
if (len(result) != 0):
cursor.execute(f"DELETE FROM anti_spam WHERE client_id = {str(member.id)}")
levelsystem_db.commit()
print(f"ho rimosso i dati di {member}")
If the bot crashes, you can have code after your client.run('TOKEN') that will be executed. For example:
import discord
class Bot(discord.Client):
def __init__(self) -> None:
discord.Client.__init__(self)
return
async def on_ready(self) -> None:
await self.close() # This can simulate a crash for now
return
if __name__ == '__main__':
client = Bot()
client.run('TOKEN')
# Code after crash here
print('Bot has crashed')
With this implementation, you could even call a subprocess that would bring the bot back online.
Edit (Event Loop Error Fix):
You will want to import these:
from asyncio import set_event_loop
from asyncio import SelectorEventLoop
from selectors import SelectSelector
Then have this line before creating the client:
set_event_loop(SelectorEventLoop(SelectSelector()))

How do I define a member inside a on_raw_reaction_remove()?

I tried to write a code that will remove a role from a member when a certain reaction is added. My code works fine until the end, where the role is removed from the member, where an "Attribute error" pops up; "AttributeError: 'NoneType' object has no attribute 'remove_roles'"
Here's my code:
#client.event
async def on_raw_reaction_remove(payload):
await client.wait_until_ready()
guild = await client.fetch_guild(payload.guild_id)
member = get(guild.members, id=payload.user_id)
if payload.message_id == id:
if payload.emoji.name == "a":
role = discord.utils.get(guild.roles, name = "a")
elif payload.emoji.name == "b":
role = discord.utils.get(guild.roles, name = "b")
await member.remove_roles(role)
My guess is that i'm defining member the wrong way, but I have no idea how to fix it
In this situation client.get_user() works better.
Here is the fixed code
#client.event
async def on_raw_reaction_remove(payload):
await client.wait_until_ready()
guild = await client.fetch_guild(payload.guild_id)
member = client.get_user(id=payload.user_id)
if payload.message_id == id:
if payload.emoji.name == "a":
role = discord.utils.get(guild.roles, name = "a")
elif payload.emoji.name == "b":
role = discord.utils.get(guild.roles, name = "b")
await member.remove_roles(role)
Hope this helped!
The main reason behind this is payload.member is None when using on_raw_reaction_remove.
This is actually because discord does not send this data, so discord.py has it as None.
Source-https://github.com/Rapptz/discord.py/issues/5871
To work around this, you get the guild object in question, then grab the member object from the guild.
The payload does not have the guild object either, so we have to get that as well.
What I did is I actually created the member object and tacked it onto the payload manually in the case of on_raw_reaction_remove.
This way both on_raw_reaction_add and on_raw_reaction_remove have the same payload for my final processing.
async def on_raw_reaction_remove(self, payload):
guild = self.get_guild(payload.guild_id) #Self here is Client/Bot
member = guild.get_member(payload.user_id)
payload.member = member
await reaction_role(payload, remove=True)
Furthermore, this requires the privileged members intent. To enable it, log back into the developer portal and look for the privileged intents > member intent, then tick the slider to on.
intent = discord.Intents.default()
intent.members = True
The intent needs to be passed to the client, or bot wrapper if using the bot extension.
commands.Bot.__init__(self, <...>, intents=intent)

auto mute a member if they say a specific word discord py rewrite

import discord
import re
from itertools import cycle
class Status(commands.Cog):
def __init__(self, client):
self.client = client
#commands.Cog.listener()
async def on_message(self, ctx):
if ctx.author.id == self.client.user.id:
return
if re.search("\.\.\.", ctx.content):
await ctx.send("you're... gonna get... muted... if you.. talk... like.. this...")
user = ctx.message.author
# print(str(user))
# print(str(message.content))
muted_role = discord.utils.get(ctx.author.guild.roles, name="Muted")
await self.client.add_roles(ctx.author, muted_role)
What I want is to temporarily mute a user if they use ellipses in a message they send. ctx.send doesn't work, the bot does not send a message to the channel. It says that self.client.add_roles doesn't exist.
Muted is a role that I have created that does not have any send message permissions.
Any idea why? Some help would be hugely appreciated. I'm using
AttributeError: 'Message' object has no attribute 'send' this is the error I get
[EDIT]
#commands.Cog.listener()
# #commands.command()
async def on_message(self, message):
if message.author.id == self.client.user.id:
return
if re.search("\.\.\.", message.content):
await message.channel.send("you're... gonna get... muted... if you.. talk... like.. this...")
user = message.author
muted_role = discord.utils.get(message.guild.roles, name="Muted")
await user.add_roles(muted_role, reason="you know what you did", atomic=True)
I took a look at the documentation and did this, it works, thank you for the support :)
There were many mistakes, please have a look at the documentation.
I have correct them for you -
#commands.Cog.listener()
async def on_message(self, message):
if message.author.id == self.client.user.id:
return
else:
await message.channel.send("you're... gonna get... muted... if you.. talk... like.. this...")
user = message.author
print(str(user))
print(str(message.content))
muted_role = discord.utils.get(message.guild.roles, name="Muted")
await self.user.add_roles(muted_role)
Let me know if you do still get any errors.
Last edit-
I tried this command for myself outside a cog, and it works perfectly fine :)
#client.event
async def on_message(message):
if message.author.id == client.user.id:
return
elif "test" in message.content:
await message.channel.send("you're... gonna get... muted... if you.. talk... like.. this...")
user = message.author
print(str(user))
print(str(message.content))
muted_role = discord.utils.get(message.guild.roles, name="Muted")
await user.add_roles(muted_role)
else:
return
await client.process_commands(message)

Resources