Reputation: 553
Very new to discord bots and python in general and building an antispam bot, here's my code:
import discord
from discord.ext import commands
import time
b = commands.Bot(command_prefix='not a bot')
b.remove_command("help")
@b.event
async def on_ready():
print('Bot is Ready')
authors = {}
authors1 = []
@b.event
async def on_message(ctx):
global authors
global authors1
author_id = ctx.author.id
for author2 in authors1:
if author_id == author2:
authors[author_id] += 1
else:
authors[author_id] = 1
authors1.append(author_id)
stop = False
timer = 5
while stop == False:
if timer > 0:
time.sleep(0.985)
timer -= 1
if authors[author_id] > 5:
await ctx.send("Stop Spamming")
else:
timer = 5
authors[author_id] = 0
b.run('stack overflow')
Basically on every message it gets every users discord id and then assigns a value to it, default is 1 since the user just sent a message, where the while loop starts is a timer, every 5 seconds it resets and if the user who's sent the message has sent 5 messages, it tells them to stop spamming, I don't know why I'm getting errors, also since I'm new to python is I could make any code simpler it would be much appreciated if you could let me know.
Here's the error I keep getting
Bot is Ready
Ignoring exception in on_message
Traceback (most recent call last):
File "C:\Users\12488\AppData\Local\Programs\Python\Python38\lib\site-packages\discord\client.py", line 333, in _run_even
await coro(*args, **kwargs)
File "C:\Users\12488\Downloads\Bot\antispam.py", line 31, in on_message
if authors[author_id] > 5:
KeyError: 234295307759108106
Upvotes: 3
Views: 7560
Reputation: 2187
A few things:
Anyway, I think the following code will do what you'd like it to.
import discord
from discord.ext import commands
import datetime
import time
b = commands.Bot(command_prefix='not a bot')
b.remove_command("help")
time_window_milliseconds = 5000
max_msg_per_window = 5
author_msg_times = {}
# Struct:
# {
# "<author_id>": ["<msg_time>", "<msg_time>", ...],
# "<author_id>": ["<msg_time>"],
# }
@b.event
async def on_ready():
print('Bot is Ready')
@b.event
async def on_message(ctx):
global author_msg_counts
author_id = ctx.author.id
# Get current epoch time in milliseconds
curr_time = datetime.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 ctx.send("Stop Spamming")
b.run('stack overflow')
Upvotes: 7