Mute and delete messages antispam discord.py - python

async def on_message(message: object):
counter = 0
with open("spam_detect.txt", "r+") as file:
for lines in file:
if lines.strip("\n") == str(message.author.id):
counter += 1
file.writelines(f"{str(message.author.id)}\n")
if counter > 5 and not message.author.guild_permissions.administrator:
await message.author.send("Ai primit kick pentru spam. Poti intra in `60` secunde.")
await asyncio.sleep(2)
await message.guild.ban(message.author, reason="spam")
await message.channel.send(f"{message.author} a primit kick pentru `spam`.")
await asyncio.sleep(60)
await message.guild.unban(message.author)
Does anyone know how instead of banning and unbanning someone i can give them the Muted role and delete all messages in the past hour ?

Yes, we simply have to get their messages and delete it.
from datetime import datetime
await message.channel.purge(after=datetime.now() - timedelta(hours=1), check = lambda x: x.author.id == message.author.id, oldest_first=False) #purges the channel
muted_role = discord.utils.get(guild.roles, name='Muted')
await message.author.add_roles(muted_role)
await message.channel.send('muted spammer and deleted messages')
the check parameter makes it delete only the author's messages.

Related

Anti spam code keeps spamming to the bot too

This is an anti spam code to prevent spams and stuff.
time_window_milliseconds = 5000
max_msg_per_window = 5
author_msg_times = {}
# Struct:
# {
# "<author_id>": ["<msg_time", "<msg_time>", ...],
# "<author_id>": ["<msg_time"],
# }
#client.event
async def on_message(message):
global author_msg_counts
author_id = message.author.id
# Get current epoch time in milliseconds
curr_time = datetime.now().timestamp() * 1000
# Make empty list for author id, if it does not exist
if not author_msg_times.get(author_id, False):
author_msg_times[author_id] = []
# Append the time of this message to the users list of message times
author_msg_times[author_id].append(curr_time)
# Find the beginning of our time window.
expr_time = curr_time - time_window_milliseconds
# Find message times which occurred before the start of our window
expired_msgs = [
msg_time for msg_time in author_msg_times[author_id]
if msg_time < expr_time
]
# Remove all the expired messages times from our list
for msg_time in expired_msgs:
author_msg_times[author_id].remove(msg_time)
# ^ note: we probably need to use a mutex here. Multiple threads
# might be trying to update this at the same time. Not sure though.
if len(author_msg_times[author_id]) > max_msg_per_window:
await message.channel.send(f"{message.author.mention} stop spamming or i will mute you 😡")
await asyncio.sleep(4)
await message.channel.send(f"{message.author.mention} stop spamming or i will mute you 😡")
muted = discord.utils.get(message.guild.roles, name="Muted")
if not muted:
muted = await message.guild.create_role(name="Muted")
await message.author.send(f"You have been muted in {message.guild.name} for spamming | You'll be unmuted in 10 minutes.")
await message.author.add_roles(muted)
await message.channel.send(f"{message.author.mention} have been muted for 10 minutes.")
await asyncio.sleep(600)
await message.channel.send(f"{message.author.mention} have been unmuted | Reason: Time is over. ")
await message.author.remove_roles(muted)
await message.author.send(f"You have been unmuted from {message.guild.name}")
Hey guys, I'm getting an error here. It works OK, but when someone keeps spamming, the bot keeps spamming, and it becomes a mess. After about a minute, the bot keeps spamming, so stop spamming or I'll mute you.
You need to exclude your own bots messages in the event. So just this should work:
#client.event
async def on_message(message):
if message.author == client.user:
return
#rest of your code

How to send a message every x minutes?

fotddict = {}
#client.event
async def on_ready():
global fotddict
with open("factoftheday.json", "r") as f:
fotddict = json.load(f)
#client.command()
#commands.has_permissions(administrator=True)
async def fotd(ctx, channel : discord.TextChannel=None):
if channel is None:
embe=discord.Embed(title="<:redcross:781952086454960138>Error", description="**Please pass in all required arguments!**\nNeed help?** https://dsc.gg/otaysupport**", color=0x7289da)
await ctx.send(embed=embe)
else:
#are you sure embed
msg = await ctx.send(embed=embed)
def checkifnotbotfact(reaction, user):
return user != client.user
await msg.add_reaction('💡')
reaction, user = await client.wait_for("reaction_add", timeout=60.0, check=checkifnotbotfact)
if str(reaction.emoji) == "💡":
#confirm embed
global fotddict
fotddict[str(ctx.guild.id)] = channel.id
with open("factoftheday.json", "w") as f:
json.dump(fotddict, f)
#tasks.loop(seconds=10)
async def factsend(member):
x = randfacts.getFact()
channel_id = fotddict[str(member.guild.id)]
embed = discord.Embed(title="💡Fact of the day!", description=x, color=0x7289da)
await client.get_channel(channel_id).send(embed=embed)
#factsend.before_loop
async def before():
factsend.start()
await client.wait_until_ready()
Problem: This is my fact of the day command, it adds the channel id + guild id in a json file (so that isnt the problem). I think the problem is the loop, since that is the part that im not sure of if thats correct.
Goal: Bot sends a message with a fact every 24 hours (Task is set to 10 seconds for test purposes)
Firstly your #factsend.before_loop function is called just before the loop execution, so you have to start the loop in other place, not in the function. So you have to deplace factsend.start() outside of this function.
The corriged code will be:
#client.event
async def on_ready():
global fotddict
with open("factoftheday.json", "r") as f:
fotddict = json.load(f)
#client.command()
#commands.has_permissions(administrator=True)
async def fotd(ctx, channel : discord.TextChannel=None):
if channel is None:
embe=discord.Embed(title="<:redcross:781952086454960138>Error", description="**Please pass in all required arguments!**\nNeed help?** https://dsc.gg/otaysupport**", color=0x7289da)
await ctx.send(embed=embe)
else:
#are you sure embed
msg = await ctx.send(embed=embed)
def checkifnotbotfact(reaction, user):
return user != client.user
await msg.add_reaction('💡')
reaction, user = await client.wait_for("reaction_add", timeout=60.0, check=checkifnotbotfact)
if str(reaction.emoji) == "💡":
#confirm embed
global fotddict
fotddict[str(ctx.guild.id)] = channel.id
with open("factoftheday.json", "w") as f:
json.dump(fotddict, f)
#tasks.loop(seconds=10)
async def factsend(member):
x = randfacts.getFact()
channel_id = fotddict[str(member.guild.id)]
embed = discord.Embed(title="💡Fact of the day!", description=x, color=0x7289da)
await client.get_channel(channel_id).send(embed=embed)
#factsend.before_loop
async def before():
await client.wait_until_ready()
factsend.start() #deplaced outside of the function
Have a nice day!
If you are going to leave the bot running locally (or host it somewhere), then you should use Advance Python Scheduler
from apscheduler.schedulers.blocking import BlockingScheduler
#Code goes Here
scheduler = BlockingScheduler()
scheduler.add_job(function_name_you_want_to_run(), 'interval', hours=24)
scheduler.start()

Discord Bot in Python Reaction Response

I want that when someone reacts to one emoji the bot writes as a log on chat like this:
#Santa has press 4️⃣
I tried to make it but I'm stuck.
import discord
import time
import random
from discord.ext import commands
client = discord.Client()
bot = client.user
if message.content.startswith('ººrandgame'):
original = await message.channel.send('Discover the number I my mind...')
uno = await original.add_reaction('1️⃣')
dos = await original.add_reaction('2️⃣')
tres = await original.add_reaction('3️⃣')
cuatro = await original.add_reaction('4️⃣')
cinco = await original.add_reaction('5️⃣')
seis = await original.add_reaction('6️⃣')
siete = await original.add_reaction('7️⃣')
ocho = await original.add_reaction('8️⃣')
nueve = await original.add_reaction('9️⃣')
diez = await original.add_reaction('🔟')
numbers = ['1️⃣','2️⃣','3️⃣','4️⃣','5️⃣','6️⃣','7️⃣','8️⃣','9️⃣','🔟']
#this part fails::
if(reaction.emoji == "1️⃣"):
await message.channel.send(author + "has press 1️⃣")
#the same idea with the other numbers
time.sleep(15)
finalnum = random.choice(numbers)
await message.channel.send('My number is: ' + finalnum)
print(finalnum)
client.run('blabla')
You can use a reaction_wait_for, this will always wait for the author of the message input of the specified reaction.
Below I've made a simple user reaction command but I'll leave it up to you how you would further like to improve it.
message = await ctx.send("React to a number")
one = '1️⃣'
two = '2️⃣'
await message.add_reaction(one)
await message.add_reaction(two)
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) in [one, two]
member = ctx.author
while True:
try:
reaction, user = await client.wait_for("reaction_add", timeout=600.0, check=check)
if str(reaction.emoji) == one:
await ctx.send("You choose 1")
if str(reaction.emoji) == two:
await ctx.send("You choose 2")
In your code, I would also reccomend using asyncio.sleep(15) instead of time.sleep, as this causes the whole bot to stop, meaning no one can use it at all.
Make sure to import asyncio
You can also set it as a command, instead of using if message.content.startswith('ººrandgame'): , You can use
#client.command()
async def ººrandgame(ctx):
.... Rest of your code ...
Ibidem, I think that something is missing
import discord
import os
import random
import asyncio
from discord.ext import commands
client = discord.Client()
horaact = time.strftime('%H:%M:%S')
os.system('cls')
os.system('color 1f')
#client.event
async def on_ready():
print("Encendido")
print("logged in as {0.user}".format(client))
#client.command()
async def ººrandgame(ctx):
message = await ctx.send("React to a number")
one = '1️⃣'
two = '2️⃣'
await message.add_reaction(one)
await message.add_reaction(two)
def check(reaction, user):
return user == ctx.author and str(reaction.emoji) in [one, two]
member = ctx.author
while True:
try:
reaction, user = await client.wait_for("reaction_add", timeout=600.0, check=check)
if str(reaction.emoji) == one:
await ctx.send("You choose 1")
if str(reaction.emoji) == two:
await ctx.send("You choose 2")
client.run('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
Remember, this is not the original code, it's just a test for trying your funtion

Remove all member roles and return them back some time later

I need to remove all member roles and return them back later, I had started working on it but when I had executed this function (just writing command to Discord chat), I got following message: discord.errors.NotFound: 404 Not Found (error code: 10011): Unknown Role
And here's the code I executed:
import asyncio
import discord
from discord.ext import commands
from discord.utils import get
TOKEN = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
bot = commands.Bot(command_prefix='e!')
bot.remove_command("help")
#bot.command()
async def hardmute(ctx, time : str, member : discord.Member = None):
if time[-1]=='s':
tme = int(time[:-1])
elif time[-1]=='m':
tme = int(time[:-1])*60
elif time[-1]=='h':
tme = int(time[:-1])*60*60
elif time[-1]=='d':
tme = int(time[:-1])*60*60*60*24
else:
tme = False
permissionrole = get(ctx.guild.roles, id=544069068777324579)
hardmutedrole = get(ctx.guild.roles, id=717877658259554396)
if member is None and tme and not ctx.author.roles[-1] >= ctx.guild.me.roles[-1]:
await ctx.channel.send('{}, you're going to be hardmuted for {}'.format(ctx.author.mention, time))
roles = ctx.author.roles
await asyncio.sleep(3)
await ctx.author.remove_roles(*ctx.author.roles)
await ctx.author.add_roles(hardmutedrole)
await asyncio.sleep(tme)
await ctx.author.remove_roles(hardmutedrole)
await ctx.author.add_roles(*roles)
await ctx.channel.send('{} came back from hardmute!'.format(ctx.author.mention))
elif member is not None and tme and not member.roles[-1] >= member.guild.me.roles[-1]:
if permissionrole in ctx.author.roles:
await ctx.channel.send('{}, you're going to be hardmuted for {}'.format(member.mention, time))
roles = member.roles
await asyncio.sleep(3)
await member.remove_roles(*ctx.author.roles)
await member.add_roles(hardmutedrole)
await asyncio.sleep(tme)
await member.remove_roles(hardmutedrole)
await member.add_roles(*roles)
await ctx.channel.send('{} came back from hardmute!'.format(member.mention))
else:
await ctx.channel.send('You dont have permission role')
elif ctx.author.roles[-1] >= ctx.guild.me.roles[-1] and member is None:
await ctx.channel.send('{}, you have a role "{}", that is high or equal in role hierarchy than "{}"'.format(ctx.author.mention, ctx.author.roles[-1].name, ctx.guild.me.roles[-1].name))
elif ctx.author.roles[-1] >= member.guild.me.roles[-1]:
await ctx.channel.send('User {} have role "{}", that is high or equal in role hierarchy than "{}"'.format(member.name, member.roles[-1].name, ctx.guild.me.roles[-1].name))
bot.run(TOKEN)
I'm not pretty sure but ctx.author.roles returns a list, and you tried to remove role from list, you can try this instead:
roles = member.roles
await asyncio.sleep(3)
for role in ctx.author.roles:
await member.remove_roles(role)
await member.add_roles(hardmutedrole)
await asyncio.sleep(tme)
await member.remove_roles(hardmutedrole)
for role in roles:
await member.add_roles(role)

I am tring to make a discord bot that wait for the user message and if three tags are mentioned it give tick reaction

when so many people type at once my bot skips some of the messages
Here is some of my code
while True:
m=await bot.wait_for('message',check=lambda message: message.channel==ctx.message.channel and message.author!=bot.user)
tags =m.mentions
if len(tags) >= 3:
await m.add_reaction("✅")
else:
await m.add_reaction("❌")```
You can use the on_message event to catch every message and do what you like with it. This is better than waiting for a message and executing code as this is faster. The downside is the channel must be hard-coded or use a global variable. Or, you could recreate the whole command in the function (though I don't know if there are any other implications with this).
#bot.event
async def on_message(message):
if message.channel == bot.get_channel(CHANNEL_ID_HERE_AS_INT):
tags = message.mentions
if len(tags) >= 3:
await message.add_reaction("✅")
else:
await message.add_reaction("❌")
thanks for your ans but how i can use on_message here
await ctx.send( '__**Registrations Open**__ \n<#&711760180848885870>')
teamlist=[]
messlist=[]
while True:
m=await bot.wait_for('message',check=lambda message: message.channel==ctx.message.channel and message.author!=bot.user)
tags =m.mentions
if len(tags) >= 3:
await m.add_reaction("✅")
else:
await m.add_reaction("❌")
continue
messlist.append(m)
if len(messlist)==22:
break
for m in messlist:
role=get(m.author.guild.roles , name="IDP-7pm")
await m.author.add_roles(role)
strr=m.content
n=strr.find("\n")
strr=strr[:n]
n=strr.find(":")
if n==-1:
n=strr.find("-")
if n!=-1:
strr =strr[n+1:]
print(strr)
for s in strr:
if s.isalpha() or s.isnumeric():
break
else:
strr =strr[1:]
teamlist.append(strr)
await ctx.send( '__**Registrations Closed**__ \n<#&711760180848885870>')
await ch.send(f"```{Newlist}```")
print(Newlist)```

Categories

Resources