discord.py delete messages apart from pinned ones - discord.py

I want to delete all the messages in a channel apart from the pinned ones, I tried this solution
On message delete message Discord.py
but it's the non-rewrite version so it's not working for me sadly.

You can only bulk delete (purge) a maximum of 100 messages at a time, but this should do the trick.
#client.command()
async def purge(ctx):
def not_pinned(msg):
return not msg.pinned
purged = await ctx.channel.purge(limit=100, check=not_pinned)
await ctx.send(f"Successfully removed {len(purged)} non-pinned messages!")
References:
TextChannel.purge()
Message.pinned

Related

discord.py save every message in specific channel (using channel id)

How can a python bot read every message that is sent in a certain channel or read every message that was sent in one using a command like $save 421345187663708161. Thanks in advance, havent been able to find the answer anywhere.
I made this in an on_message Function which scans the message content for "$save" on the beginning, then gets the channel per the given ID.
#client.event
async def on_message(message):
if message.content.startswith("$save"):
splittedcontent = message.content.split()
channel = client.get_channel(splittedcontent[1])
all_messages = channel.history()
What your job now is, is to understand this code, maybe inform about the things that are going on here (like channel.history) and implement this to your code (preferably also with some try/except cases).

How to delete all text & voice channels in a discord server with discord.py with one command?

I need to make a command to delete every channel (text and voice) in a discord server with discord.py. Can someone provide me with the code to do this. Right now i have this, which only deletes text channels. How do i make it for both at the same time?
#bot.command(name="deleteall")
async def delete_channels(context):
[await channel.delete()
for channel in context.guild.text_channels]
This seems like an oddly destructive command, you should be careful with its use and definitely add permissions checks.
To delete the voice channels, you'd just repeat the code you've already written, but just use the voice_channels list.
e.g.
[await channel.delete() for voiceChannel in context.guild.voice_channels]
#bot.command()
async def delchannels(ctx):
for c in ctx.guild.channels: # iterating through each guild channel
await c.delete()
You can also vary this specifically for text channels or voice channels using:
#bot.command()
async def delchannel(ctx, channel: discord.TextChannel):
await channel.delete()
And alter the argument type for specific channel types: "VoiceChannel" or "CategoryChannel".

storing messages with a discord bot

I'm trying to store messages with a discord bot, so that I can learn how the elements of messages vary between messages.
However i am new to some aspects of this coding- i.e. decorators. Currently the piece of my bots code that interacts with messages is this:
messages=[]
#bot.event
async def on_message(message,messages):
print("someone said something")
messages=messages+message
if message.author == bot.user:
return messages
I think this is wrong. What I am trying to do is add a message to messages each time the event happens, so that I can later go through that variable and see how the different elements of messages change.
How do i change the above to allow that?
You can use only 1 parameter in on_message event. Also, you can't append things to a list with +. And Also storing data in variable is not a good idea because whenever you restart the bot, it'll be deleted. You can simply store them in a txt file.
#bot.event
async def on_message(message):
print("someone said something")
file = open('messages.txt', 'a')
file.write(message.content + '\n')
file.close()
EDIT
If you want to store all the information of the message, you can do:
file.write(f'{message}\n')
or
file.write(str(message) + '\n')

How do I get a bot to forward its DMs

So my bot DM's users and asks them questions, but I need to be able to see their response in a channel.
So far I have this:
#bot.event
async def on_message(message):
channel = bot.get_channel(642759168247463937)
await channel.send('message')
but it begins when any message is sent in any channel and it also responds to itself, causing an endless loop of spam.
I'm new to Discord.py so I honestly don't have a clue on how to resolve this issue.
My approach would be to check if the message came from DMs:
#bot.event
async def on_message(message):
if not message.guild:
return
channel = bot.get_channel(642759168247463937)
await channel.send('message')
This works because message.guild is None if the message was sent in DMs. This prevents the spam problem, since the message is not forwarded to the bot's DMs.
However, to avoid the spam in general, it is good practice to avoid responding to bots altogether, unless necessary. Luckily, User and Member objects have an attribute called bot that helps us here:
if message.author.bot:
return
Note that this is done automatically for commands using the ext.commands framework.

Delete a target users message discord.py

I am trying to create a command that deletes a specific user's last message, so if 5 users sent 5 messages, I could use !>discard <usermention> (let's say the 3rd user) to delete user 3's last message.
I am having trouble with setting this command up and currently don't know how to make it with the skills I currently have.
You could have the on_message(msg): event that would place every message into a global list (maybe even a .txt file if you want to prevent losing the list when the bot shuts down)
#client.event
async def on_ready():
global messageList = []
#client.event
async def on_message(msg):
global messageList
messageList.append(msg)
And then delete the one you want with a command
#client.command()
async def discard(*args):
del messageList[int(args[0])+1]

Resources