Making my discord bot listen for specific messages and answer back when it identifies one - discord

So, I'm new to python and even more to coding bots on discord. At the moment I'm using discord.py and red-bot (https://docs.discord.red/en/stable/index.html).
At the moment I'm trying to make the bot listen to a new message and print something in response to it, but I just can't figure it out. Since I'm using red-bot I didn't go through the steps of using client = discord.Client() and setting a token on the code itself so using #client.event() doesn't seem to work, nor #bot.event(), and I can't really find any other way to make the bot listen for an on_message() event.
Edit with part of my code:
import discord
from discord.ext import commands
from redbot.core import commands
class MyCog(commands.Cog):
client = discord.Client()
def __init__(self, bot):
self.bot = bot
#bot.event()
async def on_message(self, message):
if 'test' in message.content:
await self.send_message(message.channel, 'it works!')
Console returns that bot in #bot.event() is not defined.
Also a separate initialization file, it's done this way to follow Red's guide of how to make a cog.
from .remind import MyCog
def setup(bot):
bot.add_cog(MyCog(bot))

Here is an example of a cog that replies to a specific word mentioned. It also has a cooldown to prevent the bot spamming which I find absolutely neccesary to include.
from curses.panel import bottom_panel
import discord
from discord.ext import commands
class brilliant(commands.Cog):
def __init__(self, bot):
self.bot = bot
self._cd = commands.CooldownMapping.from_cooldown(1, 60.0, commands.BucketType.member) # Change accordingly
# rate, per, BucketType
def ratelimit_check(self, message):
"""Returns the ratelimit left"""
bucket = self._cd.get_bucket(message)
return bucket.update_rate_limit()
#commands.Cog.listener()
async def on_message(self, message):
if message.author == self.bot.user:
return
msg = message.content.lower()
brilliant = ['brilliant', 'Brilliant', 'brilliant!', 'Brilliant!']
if any(word in msg for word in brilliant):
retry_after = self.ratelimit_check(message)
if retry_after is None:
await message.channel.send("Brilliant!")
await self.bot.process_commands(message)
else:
return
async def setup(bot):
await bot.add_cog(brilliant(bot))
If you want it in the main file, you can put something a lot simpler:
brilliant = ['brilliant', 'Brilliant', 'brilliant!', 'Brilliant!']
#bot.event
async def on_message(message):
if message.author == bot.user:
return
msg = message.content.lower()
if any(word in msg for word in brilliant):
await message.channel.send("Brilliant!")
await bot.process_commands(message)
Hope it helps.

Related

Discord py. How to get if user is online without commands

i need a help with a python code. All I need is to get if user selected (by myself) ID is currently online. How can I do that?
The code for now looks like this, but its dosnt print anserw
import discord
from discord.ext import commands
from discord import Member
TOKEN = "token"
intents = discord.Intents.default()
intents.message_content = True
intents.members = True
client = commands.Bot(command_prefix=".", intents=intents)
#client.event
async def on_ready():
return
#client.event
async def on_message(message, member : discord.Member=None):
if member == MyID:
print("draziv online")
if message.author == client.user:
return
if "hello" in message.content or "hi" in message.content:
return
# await message.channel.send(f'Hello there {message.author.mention}. I hope you have a fantastic day so far. ')
client.run(TOKEN)
I was trying all the methods I found over the internet, but almost all of them are outdated

Discord.py autorole issue

I'm new at programming.I want to create an autorole system in my Discord server.I tried this:
class MyClient(discord.Client):
async def on_member_join(member):
server = client.get_guild(serverid)
role = server.get_role(roleid)
await member.add_roles(role)
But it's not working.Thanks for helping.
This works for me so I guess this will be useful for you:
import discord
from discord.ext import commands
from discord.utils import get
client = commands.Bot(command_prefix='!', intents=discord.Intents.all())
#client.event
async def on_ready():
print(f'{client.user} Started!')
#client.event
async def on_member_join(member: discord.Member):
role_id = 1234567890123456
role = get(member.guild.roles, id=role_id)
await member.add_roles(role)
client.run('your bot token here')
role_id is Integer.
must have member intents turned on, if you don't know how to enable read this:
Here

How can I put discord.py events to another file?

I need to log many events on my Discord server and i am trying add logging feature to my bot. But it looks like this:
#bot.event
async def on_message_delete(m):
created_at = m.created_at.strftime('%d-%m-%Y %H:%M:%S')
log_content = f'{m.author} deleted message.\n[{created_at}] "{m.content}"'
await Logging().write_log(1, log_content)
#bot.event
async def on_message_edit(m_before, m_after):
created_at = m_after.created_at.strftime('%d-%m-%Y %H:%M:%S')
edited_at = m_after.edited_at.strftime('%d-%m-%Y %H:%M:%S')
log_content = f'{m_after.author} edited message.\n[{created_at}] "{m_before.content}"\n[{edited_at}] "{m_after.content}"'
await Logging().write_log(1, log_content)
#bot.event
async def on_raw_reaction_add(payload):
channel = bot.get_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
created_at = message.created_at.strftime('%d-%m-%Y %H:%M:%S')
log_content = f'{payload.member} addded reaction {payload.emoji} to message from {message.author}.\n[{created_at}] "{message.content}"'
await Logging().write_log(2, log_content)
#bot.event
async def on_raw_reaction_remove(payload):
channel = bot.get_channel(payload.channel_id)
message = await channel.fetch_message(payload.message_id)
created_at = message.created_at.strftime('%d-%m-%Y %H:%M:%S')
log_content = f'{payload.member} removed reaction {payload.emoji} from message by {message.author}.\n[{created_at}] "{message.content}"'
await Logging().write_log(2, log_content)
# and more
How can I put this to another file? Or something like that
What you are looking for is dpy's Cogs
There comes a point in your bot’s development when you want to organize a collection of commands, listeners, and some state into one class. Cogs allow you to do just that.
A quick example here would be :
class Logging(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.Cog.listener()
async def on_member_join(self, member):
# Do your logging stuff here
...
More details on adding and removing Cogs have been detailed in the documentation which you can read here
NOTE: In some versions of dpy add_cog, setup are coroutine functions and needs to be awaited. Be sure to crosscheck your version :D

AutoMod not reading correct word

I am attempting to add an automod cog to my discord bot. I have written a blacklist command and whitelist command in a different file and they work fine. What i can't figure out is when it loads the blacklisted words from the .csv file it loads them to the variable as ["['Test']"] and not as Test. If anyone knows how to fix this please let me know.
class AutoMod(commands.Cog):
def __init__ (self, bot):
self.bot = bot
self.words = Words
#commands.Cog.listener()
async def on_ready(self):
self.words = {}
with open(Wdir, 'r') as csv_file:
csvreader=csv.reader(csv_file)
for line in csvreader:
Words.append(str(line))
print(f'AutoMod {Words}')
#commands.Cog.listener()
async def on_message(self, message):
print(Words)
if str(Words) in message.content:
await message.delete()
await message.channel.send(f'{message.author.mention}, You are not allowed to say that')
else:
pass
def setup(bot):
bot.add_cog(AutoMod(bot))
You can do smth like this:
filtered_words = ["badword", "verybadword"]
#client.event
async def on_message(message):
for word in filtered_words:
if word in message.content:
await message.delete()
await message.channel.send("This word is blacklisted")
await client.process_commands(message)
Now bot will delete a message that contains any of filtered words. Bot will also send a message that says word is blacklisted.

Discord self bot slow

from discord.ext.commands import Bot
from discord.ext import commands
import asyncio
#TOKEN
TOKEN = "token"
client = discord.Client()
b = Bot(command_prefix = "!")
#b.event
async def on_ready():
print("on")
#b.event
async def on_message(message):
if "here" in message.content:
try:
await message.author.dm_channel.send("Message I choose")
except:
print('The DM could not be send due to privacy permissions')
b.run(TOKEN, bot = False)
So I have this self bot in discord. Basically it just checks when a person in a server says "#here" it will auto dm them with the message I choose as quick as possible. I would just like to know how would I make this self bot check if the person said that said #here faster.

Resources