Cant get user name discord.py - discord.py

I am making a bot for my favorite twitch streamer and medium length story short, I need a profile function for the bot. It works when you don't # someone in the second argument, but I want people to be able to see another users profile.
async def profile(ctx, user=None):
if user:
user = discord.User.display_name
else:
user = ctx.message.author.name
with open('users.json', 'r') as f:
file = json.load(f)
await ctx.send(f'PP: ``{file[user]}``')
users.json looks like this:

Your code at its current stage is quite confusing. Let me explain:
You have no method of properly accessing your user, instead calling an empty object.
You're using two separate ways to get the name, via name and display_name, which are two separate names. Adding to this, this method does not take into account that two users may have the same name.
You can define discord.Member within the command itself. If there is no user mentioned, this will default to the command author, ctx.author (which is the same as ctx.message.author).
In the code below, you will notice two ways of I have defined the variable user_info. If you're going to access the numbers based on a discord user's name, I would highly recommend replacing the name with the user id so you can access other discord user information via get_member or similar. Otherwise, feel free to continue using user.name.
Do view the revised code below.
async def profile(ctx, user:discord.Member=None):
if not user:
user = ctx.author
# either continue to save with the name..
user_info = user.name # or user.display_name but don't use both!
# ..or save with their user id
user_info = str(user.id)
with open('users.json', 'r') as f:
file = json.load(f)
await ctx.send(f'PP: ``{file[user_info]}``')

Related

How would i create a private text channel using discord.py?

I want to make it so when a member says: !contact, it opens a private text channel that only the creator can see, as well as the admins. I am very new to discord.py so sorry if this seems like a basic question. Ik there are other questions like this, but none of them seem to work, they say "guild is not defined"
Edit: sorry for not providing code
When posting questions on StackOverflow, you should always try to give examples of what code you have been trying and what you're confused over. Our purpose by answering your questions is to give you a better understanding of a topic and to make sure that you understand what you did wrong, and how to improve.
To get an instance of the current guild that the command is being run in, you can utilize the command context's guild property. Once we have an instance of the guild, we can create a text channel and specify permissions that we want the channel to have. When specifying the channel overwrites, you use a dictionary to map either a role or member to permission overwrite.
import discord
#client.command()
async def contact(ctx):
guild = ctx.guild
admin_role = guild.get_role(0) # Replace with id of admin role
overwrites = {
guild.default_role: discord.PermissionOverwrite(view_channel=False),
ctx.author: discord.PermissionOverwrite(view_channel=True),
admin_role: discord.PermissionOverwrite(view_channel=True),
guild.me: discord.PermissionOverwrite(view_channel=True)
}
await guild.create_text_channel("private-channel", overwrites=overwrites) # Replace with name of text channel

Using a mention as an input to a command

I'm trying to create a command for my bot that will go through and remove a specified number of messages from the mentioned user, the command syntax is .cleanfrom <#user> <numberOfMessages>.
in order to see how I can identify a user from a mention, I tried printing the input for the name like so.
#client.command(aliases=['cf'])
async def CleanFrom(ctx, user, count=5):
print(user)
but it just returns None.
How can i use a mention as an input for a command?
I'm not sure why it returns None but in order to get discord.Member object from an argument, you can use converters.
#client.command(aliases=['cf'])
async def CleanFrom(ctx, user: discord.Member, count=5):
...
This will return you a discord.Member object.

how to store discord userid using python 3

I'm trying to create a discord bot that could have the option to ban people forever. That means that even if someone unbanned him he will be banned again.
I'm trying to do that with a file that will save the userid but the problem is that the userid is not a string and I can't save it in a file.. but still if I can save it as str and convert it to integer it's not the problem.
My code is:
#client.command()
#commands.has_permissions(administrator=True)
async def testban(bot):
member = client.get_user(int(460688177846550528))
await member.ban(reason='this is a test')
Can someone help me, please?
Discord's User.id is an int. To write it to a file you can simply convert it to a str:
str(userId)
When reading it, you can convert it back to an int:
int(userIdStr)
The User object can then be retrieved using Client.get_user()

How to implement Patreon-only commands for a discord bot?

So i have seen another post with almost the exact same question however, mine is different.
I am fully aware there is a Patreon bot, however to my knowledge this is only valid on servers.
So lets say someone invites my bot, and tries a command that requires them to be a patron. How could my bot written in python do a check to see if they have become a patron for my product? And then set a role for them accordingly. Which i can then do the check on to allow them access to the command or not.
So essentially, it should do what the Patreon bot does, however would work on its own. Examples are such as the Dank Memer bot: which can be invited to any server and if one becomes a patron can use specific commands, otherwise you can't
I've looked around this topic for a while now and haven't been able to find any info on how to check if the user has become a patron or not.
Many thanks in advance!
If you know the patreons. just give them a role [patreons] or any name!
after giving them the role. copy the role id and paste it in patreons_role_id
ok, what this command does is, just it check for the [patreons] role in the member roles! if the [patreons] role is present! it will execute the #your code else it sends a custom message!
#client.event()
async def on_message(message):
if message.content == '!test':
is_patreon = False
for user_roles in message.author.roles:
if user_roles.id == patreons_role_id:
is_patreon = True
break
if is_patreon == True:#your code
else: await message.channel.send('THIS COMMAND IS ONLY AVAILABLE FOR PATREON!')
Let's assume you have a role for your patreons.
#client.command()
#commands.has_roles("PatreonRole")
async def commandname(ctx, args):
#do stuff
There is a way out, but its probably not the right one, so, If you know who your patreons are and you know their discord IDs as well, you can declare an if statement in the command similar to this -
#client.command()
async def your_command_name():
if member.id == #Your 1st Patreon's Discord ID:
#Your Code
elif member.id == #Your 2nd Patreon's Discord ID:
#Your code
else:
await ctx.send("You cannot use that command as you are not a patreon!")
But again this is probably not right way if you have a lot of patreons or you dont know their Discord IDs, but anyways this way was the only way I could come up with.
I hope that helped. :)

I have problems with command that gets what user typed after command

I am doing a Discord Bot for one SandBox page.
I have already made a program that scraps the data from ANY user you want it to. (It's input and after that it scraps the data)
Now there is a new problem. I want to make a command "rr2.info.UserHere"
The rr2. is prefix, but I want to make a command that gets what you typed after rr2.info. and saves it into a variable.
I have tried with some code I found online, but it wasn't working. After that I couldn't find ANYTHING else.
#client.event
async def on_message():
if message.content.startswith('rr2.info.'):
#This is the part I need help with! :D
I need a way of getting ANYTHING typed after rr2.info. and that command done!
It's not a good practice to use the on_message() as commands.
Better use command() fom discord.ext.commands.
Apparently you're looking for a way to store the user input into a variable, here is how you can do :
Using a command
You have defined rr2 as your prefix. Let's assume you are using a cog system :
#commands.command()
async def info(self, ctx, *, input: str):
await ctx.send(input)
return
The await ctx.send(input) line will send a message into the channel where the command has been used that contains what the user had passed as input.
So we have :
>>> rr2 info This is my input.
Output :
'This is my input.'
Using on_message event
If you absolutely want to use an event to store the user input you can use :
#client.event
async def on_message(message):
if message.content.startswith('rr2.info.'):
input = message.content # this will send the message with the 'rr2.info.' prefix
channel = message.channel
await channel.send(input)
This will have the exact same behaviour as the command() solution.
#client.event
async def on_message(message):
if message.content.startswith('rr2.info.'):
# Split method returns a list of strings after breaking the given string by the specified separator
# Example input is 'rr2.info.uwu' then after calling input.split('rr2.info.')
# we will get a list of ['', 'uwu'] , that's why we need to call second index to get the string after
# 'rr2.info.' with [1]
suffix = message.content.split('rr2.info.')[1]
# Don't send it if it's empty, it will be empty if the user for example sent just 'rr2.info.'
if suffix:
await message.channel.send(suffix)
else:
# Overriding the default provided on_message forbids any extra commands from running.
# To fix this, we add client.process_commands(message) line at the end of our on_message
await client.process_commands(message)
I also suggest changing the name client to bot it's nicer.
If you would like to do this same thing with commands you would have to change the source code of commands ext functions, mainly because the space is used as separator between commands/arguments and you want to pass that as a single string.

Resources