How to rig a bot's command to only a certain user - discord.py

I've been making this pp size machine, which is somewhat like dank memer's one
#client.command()
async def pp(ctx,member : discord.Member):
size=random.randint(1,10)
message = "8"
for x in range (size):
message= message + "="
if x == size-1:
message = message + "D"
if member == "PROTATO#6826":
message = "8D"
ppsize = discord.Embed(color=discord.Colour.orange(), title=f"PP size",description=f"""{member}'s penis
{message} """)
await ctx.send(embed = ppsize)
But i want to rig the command for a certain user to only show "8D" instead of the random lengths.
But no matter what it is the
if member == "PROTATO#6826":
message = "8D"
code doesnt run or gets over looked?
Can someone help me out with this?

You can check if the member mentioned has the same id as a specific user. You can either enable developer mode on discord, or you can print the member.id at the very beginning. Do view a code example below.
#client.command()
async def pp(ctx, member: discord.Member):
print(member.id) # this would print a user's unique id
message = "Hey!"
if member.id == 394506589350002688: # replace this id with what was printed at the start
message = "Hello!"
await ctx.send(message)
Similar Questions:
How to check if message was sent by certain user? - SO
How do I detect if the message is sent by a specific user id? - SO

Related

How to make bot respond without prefix in certain situation while still responding to other commands in discord.py

I'm making a game using discord.py and the bot has a few commands already, but once the game itself starts I want users to be able to input answers without requiring a prefix but I'm not sure how to do this. I tried using on_message for this situation to immediately, and while I'm pretty sure the on_message subroutine works how I want, adding it causes the other subroutines to stop being executed. Is there another way to do this? Here's a bit of the code:
bot = commands.Bot(command_prefix="-") #sets the bot prefix
#bot.event
async def on_message(ctx): #accepts all answers without needing a command
if len(playerQuestions[0]) == True and (str(ctx.channel.name) == channels[0] or str(ctx.channel.name) == channels[1]):
await guess(ctx, ctx.content)
#bot.command()
async def join(ctx): #subroutine for the join command - allows users to join the lobby before the game begins
if gameInProgress == True: #blocks the command from being used if a game is in progress
await ctx.send("There is currently a game in progress, so this action cannot currently be performed.")
else:
response = ""
flag = False
for i in range(0, len(players)): #compares sender of message to each player in the lobby to check if user is already in the lobby
if ctx.author == players[i]:
await ctx.channel.send("You are already in the lobby")
flag = True
if flag == False: #adds the user to the lobby if not already in and announces it
players.append(ctx.author)
response = (ctx.author.mention) + " has joined the lobby. \n"
response = response + (str(len(players)) + " in lobby. \n")
await ctx.send(response)
so if someone types "-join" and the requirements therefore aren't met in the on_message subroutine, how could I make the program execute the code in the join subroutine?

How to change channel permissions without having a message sent first?

I have a program that changes what channel members can see at certain times of the day. To do this, I can either change the roles that every member has, or change the permissions of each channel. However, I have looked all over the web and all of the ways for either method require a message to be sent so that the data from that message can be read and put into the function, such as:
#client.command()
async def perm(ctx):
await ctx.channel.set_permissions(ctx.guild.default_role, send_messages=False
Change the permissions of a discord text channel with discord.py
or
async def addrole(ctx):
member = ctx.message.author
role = get(member.server.roles, name="Test")
await bot.add_roles(member, role)
Discord.py | add role to someone
My current program looks like this:
import discord
client = discord.Client()
import datetime
async def live_day(schedule):
current_place = "the void"
while True:
current_time = str((datetime.datetime.now() -datetime.timedelta(hours=7)).time())
int_time = int(current_time[:2] + current_time[3:5])
for x in range(len(schedule)):
try:
start_time = schedule[x][1]
end_time = schedule[x + 1][1]
except IndexError:
end_time = 2400
if current_place != schedule[x][0] and int_time >= start_time and int_time < end_time:
current_place = schedule[x][0]
#Change the channel permissions of the current place to allow viewing
#Change the channel permissions of the last channel to disallow viewing
#client.event
async def on_ready():
print("{0.user} has arrived for duty".format(client))
client.loop.create_task(live_day([
("Home", 0),
("Work", 900),
("Home", 1700),
("Nightclub", 2000),
("Home", 2200),
]))
client.run(my_secret)
Never mind the badly written code, how would I do this or where should I go to figure this out? Any help is appreciated. Thanks!
Edit: I could get the channels individually by using this,
channel1=client.get_channel(channelid)
discord.py, send message by channel id without on_message() event?
but then I can't use this for more than one server. How can I get channels by name?
Note on on_ready():
This function is not guaranteed to be the first event called. Likewise, this function is not guaranteed to only be called once. This library implements reconnection logic and thus will end up calling this event whenever a RESUME request fails.
Using this function may crash the bot.
Instead create background tasks and use wait_until_ready().
You can find examples in https://github.com/Rapptz/discord.py/blob/v1.7.3/examples/background_task.py
If you want to change only one channel's permissions (per guild) this might fit your needs:
#changing "Home" channel visibility, every day at 5 pm.
#client.event
async def on_ready():
while True:
await asyncio.sleep(1)
current_time = datetime.datetime.now()
five_pm = current_time.replace(hour=17, minute=0, second=0)
if current_time == five_pm:
for guild in client.guilds: #looping through all the guilds your bot is in
channel = discord.utils.get(client.get_all_channels(), name="Home") #getting channel by name by using "discord.utils"
await channel.set_permissions(guild.default_role, view_channel=True) #changing permissions
By using the on_ready() event you can loop through the time check without sending any message.
Remember to import discord.utils.

How to use reaction as button in discord.py

If we have a message with ⬇️ and ⬆️ Reaction.
How can we get all users reacted in particular emojis and how to use as button.
Like,
If a user reacts his name will be added in message along with the emoji which he reached.
Here is a simple example this is not the best method since this will be active on all bot messages when someone reacts with ⬆️. The best is save the message id that you want then do a check here to make sure it is the wanted message.
If message.id is not an option then make a dedicated channel for this and hard code the id of that channel, this is not the best practice but it will work.
#bot.event
async def on_raw_reaction_add(payload):
channel = bot.get_channel(payload.channel_id)
message = channel.get_message(payload.message_id)
# guild = bot.get_guild(payload.guild_id)
emoji = payload.emoji.name
# skip DM messages
if isinstance(channel, discord.DMChannel):
return
# only work if in bot is the author
# skip messages not by bot
# skip reactions by the bot
if message.author.id != bot.user.id or payload.member.id == bot.user.id:
return
if emoji == '⬆️':
up_users = f"{message.content} \n {user.name}"
await message.edit(up_users)
# remove user reaction
reaction = discord.utils.get(message.reactions, emoji=emoji)
await reaction.remove(payload.member)

'RawReactionActionEvent' object has no attribute 'author Issue with adding a cooldown on event

I'm trying to add a cooldown to a on_raw_reaction_add event in discord.py. I'm trying to do this by using cooldown mapping. The result should be to limit how many times this message
embed.description = f"It looks like you're joining us on a newly registered account. Verification requires accounts to be atleast a day old so please stick around and try again at {test_time.time().strftime(format)}."
is sent to a user if they don't meet the account age upon adding a reaction, which should be one reaction before the cooldown kicks in.
The error I get is 'RawReactionActionEvent' object has no attribute 'author not sure why this is happening.
Here is the full code I'm working with:
#commands.Cog.listener()
async def on_raw_reaction_add(self, payload): # Will be dispatched every time a user adds a reaction to a message the bot can se
general = self.bot.get_channel(701547632354525249)
introductions = self.bot.get_channel(705068046267580566)
botroom = self.bot.get_channel(706610280032894996)
if not payload.guild_id:
# In this case, the reaction was added in a DM channel with the bot
return
guild = self.bot.get_guild(payload.guild_id)
author = guild.get_member(payload.user_id)
bucket = self._cd.get_bucket(payload)
retry_after = bucket.update_rate_limit()
seconds = bucket.update_rate_limit()
seconds = round(seconds, 2)
hours, remainder = divmod(int(seconds), 3600)
minutes, seconds = divmod(remainder, 60)
if retry_after:
verification_error = f"You can do that again in **{minutes}m {seconds}s**."
embed = discord.Embed(title="You have already verified.", description=verification_error, colour=discord.Colour(0xff8100))
await message.channel.send(embed=embed)
pass
if payload.message_id != 743841858727444550:
return
else:
guild = self.bot.get_guild(payload.guild_id) # You need the guild to get the member who reacted
member = guild.get_member(payload.user_id) # Now you have the key part, the member who should receive the role
if payload.emoji.id != 743077610115956816:
reaction = payload.emoji.id
role = discord.utils.get(guild.roles, name="Members")
newbies = discord.utils.get(guild.roles, name="Newbies")
restricted_role = discord.utils.get(guild.roles, name="Restricted")
role = discord.Object(743840972068356116) # Pass the role's ID here
else:
return
if restricted_role in member.roles:
return
if member.created_at + dt.timedelta(days=30) <= dt.datetime.today():
await member.add_roles(role, reason='New member verified') # Finally add the role to the member
await member.add_roles(newbies, reason='New member verified') # Finally add the role to the member
welcome = f'Welcome {member.mention}! feel free to get started with adding some <#706648361196978177>'
intros = f'Hey {member.mention}! now that you\'re a member of our group, maybe you\'d like to tell us a bit about yourself. Tell us an interesting fact about yourself and so on... As always keep it sensible and fun.'
await general.send(welcome)
sent = await introductions.send(intros)
await asyncio.sleep(900)
await sent.delete()
else:
format = '%I:%M%p'
member1 = member.created_at.strftime("%I:%M%p")
dt3 = dt.datetime.strptime(member1, format)
test_time = dt3 + dt.timedelta(minutes = 1500)
embed = discord.Embed(colour=discord.Color(0x7289DA))
embed.title = f"Hey there {member.display_name}!"
embed.description = f"It looks like you're joining us on a newly registered account. Verification requires accounts to be atleast a day old so please stick around and try again at {test_time.time().strftime(format)}."
await member.send(embed=embed)
Help would be appreciated.
Under your #client.command statement just add
#commands.cooldown(1, 30, commands.BucketType.user)
This example will give a single user a cool down of 30 seconds for 1 use. You can configure BuckType to channel and server as well.

Problem with (AttributeError) client.logs_from

i was creating bot for discord channel. But I don't understand where i have wronged or errored in my code
I was do from tutorial but in video this wrong not present. Then I search this problem in another tutorial, but i don't have result pls help
#client.command(pass_context=True, name='clear', aliases=['purgemessages'], no_pm=True)
async def clear(ctx, number):
number = int(number)
if number > 99 or number < 1:
await ctx.send("Sorry comrade>-< \n But i can deleted message within a range of 1 - 99")
else:
author = ctx.message.author
authorID = author.id
mgs = []
number = int(number)
channel = ctx.message.channel
async for x in client.logs_from((channel), limit = int(number)):
mgs.append
await ctx.message.channel.delete_messages(ctx, member, mgs)
await ctx.send("This was deleted ^^")
I want a bot to delete messages
You should use client.purge() to do it.
It seems that you're looking for a way to delete the command caller's messages (a.k.a author).
Here's a quick example using purge() method :
author = ctx.message.author
# check function
def is_caller(message):
if(message.author.id == author.id):
return(True)
else:
return(False)
# delete the author's messages
# the purge method returns a list of deleted messages
deleted_message = await client.purge(
limit = number,
check = is_caller
)
await ctx.send(f"{len(deleted_message)} messages deleted.")
The limit is represented by the number parameter of your command.
Hope it helped !

Resources