Problem with (AttributeError) client.logs_from - discord.py

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 !

Related

How to rig a bot's command to only a certain user

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

Discord sniping edited messages not working

I've scrolled through other people's posts about this, ive tried reworking their code to mine, but it doesnt seem to work
snipe_message_author = {}
#client.event
async def on_message_edit(message_before, message_after):
snipe_message_author = message_before.author
guild = message_before.guild.name
#client.command()
async def snipeedit(ctx):
channel = ctx.channel
try:
snipeEmbed = discord.Embed(colour = discord.Colour.orange(),title=f"{snipe_message_author[channel.id]}", description = f"""Original message : {message_before.content}
Updated message : {message_after.content}""")
await ctx.send(embed = snipeEmbed)
except:
await ctx.send(f"There are no edited messages in #{channel.name}")
Every time i try the code, it returns "There are no edited messages in #*channel*"
I think its because of the snipe_message_author
thanks to anyone who helps.
As Łukasz Kwieciński's comment says:
You never add anything to snipe_message_author = {}, it can't work at all. Based on other posts, you can easily come up with a solution.
Take a look at the following code:
edited_messages = {}
#client.event
async def on_message_edit(message_before, message_after):
edited_messages[message_before.guild.id] = (message_before.content, message_after.content, message_before.author)
#client.command()
async def snipeedit(ctx):
try:
content_before, content_after, message_author = edited_messages[ctx.guild.id]
snipeEmbed = discord.Embed(color=discord.Colour.orange(), title=f"{message_author}",
description=f"Original message : {content_before}
Updated message : {content_after}")
await ctx.send(embed=snipeEmbed)
except:
await ctx.send(f"There are no edited messages in #{ctx.channel.name}")
In our on_message_edit event, we first define what should be "saved" for our guild or what exactly applies.
After we define these things, they are saved in the order specified. So now we have 3 "data" stored. We query or redefine these in our try statement and then read them from edited_messages for the corresponding ctx.guild.

'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.

I've got a problem where I want to create a voice channel every time 2 people use the same dedicated command, which I managed to do but

the problem is I can't connect the 2 users to it because I don't have the ID of the channel that has been created
Look at this code
async def join(ctx,i=[0],c=[0]):
author = ctx.author
guild = ctx.guild
if i[0] == 0:
channel = await guild.create_voice_channel(f"""Voice chat # {c[0]}""")
i[0] = 0
c[0]+=1
i[0] += 1
if i[0] == 2:
i[0] = 0
print(i[0])
return i[0]
Could anyone potentially help me with this?
For some elaboration - What happens here is, if the user types !join It will create a voice channel, in which i want the user to be sent into immediately, then a different user also uses !join and gets sent into the same channel (which I also covered by counting the number of people joining), so essentially if 2 people use the command, I want them to be sent into a dedicated voice channel, if other 2 users do the same, they also get sent into their own dedicated voice chat on the server. Thanks <3
If a user isn't connected to a voice channel, you can't make him join one.
The only thing you can do is moving someone to another channel with the move_to function.
To track which user is connected to a channel, you could have a dict which takes a channel id as a key and the two users as a value:
channels = {}
async def join(ctx, i=[0], c=[0]):
author = ctx.author
guild = ctx.guild
if i[0] == 0:
channel = await guild.create_voice_channel(f"""Voice chat # {c[0]}""")
channels[channel.id] = [#Your two users]
i[0] = 0
c[0]+=1
i[0] += 1
if i[0] == 2:
i[0] = 0
print(i[0])
return i[0]
A example of how to use move_to:
#commands.command()
async def move(ctx):
channel = bot.get_channel(ID) #ID must be an INT
await ctx.author.move_to(channel)
If you want to change the channel's user limit:
channel = await guild.create_voice_channel(f"""Voice chat # {c[0]}""")
await channel.edit(user_limit=2)
If you want to check how many members are connected:
async def check_channels(ctx):
for channel_id in self.channels.keys():
channel = bot.get_channel(int(channel_id))
if len(channel.members) == 0:
await channel.delete()

Python Youtube ffmpeg Session Has Been Invalidated

I get the following error while I'm playing YouTube audio with my bot
[tls # 0000024ef8c4d480] Error in the pull function.
[matroska,webm # 0000024ef8c4a400] Read error
[tls # 0000024ef8c4d480] The specified session has been invalidated for some reason.
Last message repeated 1 times
It seems like YouTube links expire? I don't really know but I need to fix this issue. This is my code:
class YTDLSource(discord.PCMVolumeTransformer):
def __init__(self, source, *, data, requester):
super().__init__(source)
self.requester = requester
self.title = data['title']
self.description = data['description']
self.uploader = data['uploader']
self.duration = data['duration']
self.web_url = data['webpage_url']
self.thumbnail = data['thumbnail']
def __getitem__(self, item: str):
return self.__getattribute__(item)
#classmethod
async def create_source(cls, ctx, player, search: str, *, loop, download=True):
async with ctx.typing():
loop = loop or asyncio.get_event_loop()
to_run = partial(ytdl.extract_info, url=search, download=download)
raw_data = await loop.run_in_executor(None, to_run)
if 'entries' in raw_data:
# take first item from a playlist
if len(raw_data['entries']) == 1:
data = raw_data['entries'][0]
else:
data = raw_data['entries']
#loops entries to grab each video_url
total_duration = 0
try:
for i in data:
webpage = i['webpage_url']
title = i['title']
description = i['description']
uploader = i['uploader']
duration = i['duration']
thumbnail = i['thumbnail']
total_duration += duration
if download:
source = ytdl.prepare_filename(i)
source = cls(discord.FFmpegPCMAudio(source), data=i, requester=ctx.author)
else:
source = {'webpage_url': webpage, 'requester': ctx.author, 'title': title, 'uploader': uploader, 'description': description, 'duration': duration, 'thumbnail': thumbnail}
player.queue.append(source)
except Exception as e:
print(e)
return
embed=discord.Embed(title="Playlist", description="Queued", color=0x30a4fb, timestamp=datetime.now(timezone.utc))
embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url)
embed.set_thumbnail(url=data[0]['thumbnail'])
embed.add_field(name=raw_data['title'], value=f"{len(data)} videos queued.", inline=True)
embed.set_footer(text=raw_data["uploader"] + ' - ' + '{0[0]}m {0[1]}s'.format(divmod(total_duration, 60)))
await ctx.send(embed=embed)
return
embed=discord.Embed(title="Playlist", description="Queued", color=0x30a4fb, timestamp=datetime.now(timezone.utc))
embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url)
embed.set_thumbnail(url=data['thumbnail'])
embed.add_field(name=data['title'], value=(data["description"][:72] + (data["description"][72:] and '...')), inline=True)
embed.set_footer(text=data["uploader"] + ' - ' + '{0[0]}m {0[1]}s'.format(divmod(data["duration"], 60)))
await ctx.send(embed=embed)
if download:
source = ytdl.prepare_filename(data)
else:
source = {'webpage_url': data['webpage_url'], 'requester': ctx.author, 'title': data['title'], 'uploader': data['uploader'], 'description': data['description'], 'duration': data['duration'], 'thumbnail': data['thumbnail']}
player.queue.append(source)
return
source = cls(discord.FFmpegPCMAudio(source), data=data, requester=ctx.author)
player.queue.append(source)
#classmethod
async def regather_stream(cls, data, *, loop):
loop = loop or asyncio.get_event_loop()
requester = data['requester']
to_run = partial(ytdl.extract_info, url=data['webpage_url'], download=True)
data = await loop.run_in_executor(None, to_run)
return(cls(discord.FFmpegPCMAudio(data['url']), data=data, requester=requester))
I'm using the rewrite branch of discord.py for the bot.
I'm not sure if I need to provide more details? Please let me know, I really need to get this fixed...
In fact it isn't really a problem with your code (and many people complain of this error).
This is just a possible issue when streaming a video. If you absolutely want to stream it, you have to accept this as a potential issue. Note how (almost) every music bots set limitations for the video/music you want to listen to.
If you need to ensure you do not get this issue, you have to fully download the music. (Which will also make the bot loading longer before playing).
Would you be able to post all your code? i may have a solution for you if i was able to see the whole code.
the solution i would recomend is to download the soong and then delete it after.
You could set your download to true and then add this in your player_loop
try:
# We are no longer playing this song...so, lets delete it!
with YoutubeDL(ytdlopts) as ydl:
info = ydl.extract_info(source.web_url, download=False)
filename = ydl.prepare_filename(info)
try:
if os.path.exists(filename):
os.remove(filename)
else:
pass
except Exception as E:
print(E)
await self.np.delete()
except discord.HTTPException:
pass
bit botched but could be cleaned up, this was the best solution i have found for me.

Resources