Is there a way to give roles without a command? - python

I have a database with discord id, seconds and more
A plugin from a game server is measuring player activity and feed it inside the database
I was wondering if there is a way to make my bot give a role to that specific discord id as long as his activity is bigger than some value
ive tried this way but it doesn't work
#tasks.loop(seconds=10)
async def checkDB():
delete_oldDate()
list = get_db_list('players_activity', '*')
for i in list:
if str(i[3]) != 'None' and int(i[2]) >= min_activity:
user = i[3]
role = discord.utils.get(user.guild.roles, giveawayRole_ID)
await client.add_role(user, role)
else:
print("")
any ideas?

Adding roles inside and outside of a command works the same way. client.add_role doesn't exist, which is why it doesn't work. The correct function is Member.add_roles(list_of_roles).
Going off of context, I'm gonna assume your user is already a discord.Member instance, as you're calling it's guild attribute. You can also use Guild.get_role(role_id) to get the discord.Role instance of the role.
user = i[3]
role = user.guild.get_role(giveawayRole_ID)
await user.add_roles([role])
EDIT:
Apparently your user was not a discord.Member instance yet, so you'll have to get that first. You should've gotten an error from that though, which you didn't mention. In case user is a string, user.guild shouldn't work at all either.
First of all, instead of storing their Discord ID as Mihái#8090, you should store their actual ID, which is a number. You can get this by using Member.id whenever they use a command (to put them in the database), or right-clicking them and using Copy ID in Discord.
Seeing as you always want to use the same Guild, you should already have the Guild's ID stored somewhere as well.
guild_id = 000000000000 # Whatever the ID of your Guild is
guild = client.get_guild(guild_id)
member = guild.get_member(int(i[3]))
role = guild.get_role(giveawayRole_ID)
await member.add_roles([role])
So first get the Guild instance, then the user's Member instance in that guild, then the Role instance, and then give the member the role.

Related

Pythion Discord Bot #'ing people

I need when I run a command like /insult #name the bot #'s the person in the argument of the command and sends an image. I can do most of the rest but I can't seem to figure out of to have it #mention the person.
To mention a user in a command, you can use member: discord.Member. This helps you get a member object in the command itself. You can view more on how you can use a discord.Member object here. An example on how to use this in a command can also be found in the docs, view this: Discord Converters.
You can view how these can be incorporated below, including a None variable as a default to avoid errors in your console if the ctx.author does not mention a member.
#client.command() # or bot.command(), or whatever you're using
async def insult(ctx, member:discord.Member=None):
if member == None: # Happens if ctx.author does not mention a member..
member = ctx.author # ..so by default the member will be ctx.author
# You can use member.mention to mention/ ping/ # the person assigned as member
await ctx.send(f"Be insulted {member.mention}!")
# A not as good way to do it would be:
await ctx.send(f"Be insulted <#{member.id}>!")
# both methods work the same way, but member.mention is recommended

making a bot using discord.py to assign roles to members based on status message

i want to make a discord bot which assigns a role called "supporter" to a user whose status message contains a string called "Testing" using discord.py. I am unable to find a way to get the status message contents.
In order to achieve what you want, simply iterate over all members via
for member in guild.members:
where guild is the object of the guild you want to check.
And then get the activities of each member. You will need to check, if the activity is not none.
for member in guild.members:
memberActivity = member.activity
if not (memberActivity is None):
nameOfActivity = memberActivity.name
Afterwards you can check if "Testing" is the name of the activity. And if thats the case, assign the role:
for member in guild.members:
memberActivity = member.activity
if not (memberActivity is None):
nameOfActivity = memberActivity.name
if "Testing" in nameOfActivity:
await member.add_roles(testingRole)
where testingRole is the object of your testing role.
You will need to have the presence intent for this to work!

I would like to be able to have a bot automatically update a members username to a specific nickname if the user doesn't already have a nickname

#Cog.listener()
async def on_member_update(self, before, after):
n = before.nick
if n:
if n.lower().count("★") <= 0:
await after.edit(nick="NICKNAME")
The code above changes the users nickname to "NICKNAME" if the user has attempted to change their nickname without the Star symbol. But I would like to have the bot automatically update their usernames instead and change it to the Star symbol nickname without the users having to manually do it themselves, if they don't already have it in there username to begin with.
You could use the on_member_join event and change the nickname when someone joins a guild
async def on_member_join(member):
await member.edit(nick="NICKNAME")
Note: This will work when someone joins a guild, but it will not change the nick of the users that already are in the guild, you could make a simple command for that
async def whatever(ctx):
for member in ctx.guild.members:
if not "★" in member.nick: # Or whatever character
await member.edit(nick="NICKNAME")
Reference:
on_member_join
Member.edit
Check out the event on_member_join to assign once they join the server. For existing members, you could periodically iterate over guild.members and adapt all the members where necessary.

How To make my bot send message when a specific user is typing?

I want to have my bot respond to when a specific user starts typing (i.e. me)
#client.event
async def on_typing(channel, user, when):
member = client.get_user(id='user_id')
me = 'my_id'
if me == member.typing:
await channel.send('*cough* loser...')
If I use == to compare I get no response, if I use != the bot responds to everyone as expected.
If I run the if statement as:
if me.typing:
await channel.send('*cough* loser...')
The bot just responds to everyone again, what gives?
Your code as some errors:
client.get_user() only takes one argument, which is a single id and has to be an integer. You'd have to use it this way → user = client.get_user(id).
Reading the doc, member.typing() that allows you to have this xxxx is typing and returns a context manager, not an integer, that's why your first if statement isn't triggered.
As explained above, me != member.typing is always triggered because they will never be the same type and same value.
You don't really need to get a user object, you can just use user.id and compare it to the ID you want.
IDs must be integers, not strings or else, the if statement will never trigger.
#client.event
async def on_typing(channel, user, when):
if user.id == your_id: #Replace your_id with the id you want (must be an int)
await channel.send('*cough* loser...')
Reference: discord.py documentation → discord.on_typing

How to how to convert username to discord ID?

I have a simple questions about discord. I am trying to create an economy system, and it works well, but I want to customize it a bit. I am using this person's module: https://github.com/Rapptz/discord.py
How do I convert a username to a discord ID. For example if I have a discord "command" to allow people to gift each other money, like: james#0243 types !give 100 bob#9413.
How can I convert bob#9413 to a discord id like 58492482649273613 because in my database, I have people's users stored as their ID rather than their actual username as people can change their username.
Use a converter to get the Member object of the target, which will include their id.
from discord import Member
from dicord.ext.commands import Bot
bot = Bot(command_prefix='!')
#bot.command()
async def getids(ctx, member: Member):
await ctx.send(f"Your id is {ctx.author.id}")
await ctx.send(f"{member.mention}'s id is {member.id}")
bot.run("token")
Converters are pretty flexible, so you can give names, nicknames, ids, or mentions.
on_message callback function is passed the message.
message is a discord.Message instance.
It has author and
mentions attributes which could be instances of discord.Member or discord.User depending on whether the message is sent in a private channel.
The discord.Member class subclasses the discord.User and the user id can be accessed there.
You could use get_member_named to do something like
#client.command(pass_context = True)
async def name_to_id(ctx, *, name):
server = ctx.message.server
user_id = server.get_member_named(name).id
The name can have an optional discriminator argument, e.g. “Jake#0001” or “Jake” will both do the lookup. However the former will give a more precise result.
prefix_choice = "!"
bot = commands.Bot(max_messages=10000, command_prefix=commands.when_mentioned_or(prefix_choice))
#bot.command()
async def membersLog(ctx):
for i, member in enumerate(ctx.message.server.members):
list_mem_num = (f'{i}')
list_mem_id = (f'{member.id}')
list_mem = (f'{member}')
list_mem_name = (f'{member.name}')
list_all = (f'Number: {list_mem_num} ID: {list_mem_id} Name: {list_mem} ({list_mem_name})\n')
print(list_all)
You can use this to collect all memberinfo of the server where the call comes from. This is the code I use for this.

Categories

Resources