i write bot on discord py with cogs.
main:
intents = discord.Intents.all()
client = discord.Bot(command_prefix = '$', intents = intents)
for files in os.listdir('./cogs'):
if files.endswith('.py'):
client.load_extension(f'cogs.{files[:-3]}')
token = os.environ.get('token')
client.run(token, bot=True)
and cog:
class textCommands(commands.Cog):
def __init__(self, client):
self.client = client
#commands.command()
async def ping(self, ctx):
await ctx.send(f'Pong! {round(self.client.latency * 1000)}ms')
def setup(client):
client.add_cog(textCommands(client))
And my bot send two messages if i send 'ping', i changed my token, but problem still have.
so, I found the answer. I remove await self.client.process_commands(message) from my code and twices messages lose
Related
Hello I began a discord bot but I can't give the message's content. I managed to get all the other things about message but the content return nothing. here is the code(ps: sorry if my english isn't very good, i'm French) :
import discord
class MyClient(discord.Client):
async def on_ready(self):
print('Logged in as')
print(self.user.name)
print(self.user.id)
print('------')
async def on_message(self, message: discord.message.Message):
# we do not want the bot to reply to itself
print(message.id)
if message.author.id == self.user.id:
return
if message.content.startswith('!hello'):
print('ok')
await message.channel.send('Hello {0.author.mention}'.format(message))
defIntents = discord.Intents.default()
defIntents.members = True
client = MyClient(intents=defIntents)
client.run('token')
You have to enable the Message Content Intent of your application from Discord Developer Portal and in your code you have to set the message_content intent to True like this.
defIntents = discord.Intents.default()
defIntents.members = True
defIntents.message_content = True
client = MyClient(intents=defIntents)
I made a confessions system but there’s some things that are wrong with it. How would I make it so when users want to type, they don’t have to put in *confess and they can just type whatever they want without needing to use a command? And how do I make a mod logs channel to log the deleted confessions with the author name, etc.?
import discord
from discord.ext import commands
class Confess(commands.Cog):
def __init__(self, client: discord.ext.commands.Bot):
self.client = client
#commands.command()
async def confess(self, ctx: commands.Context, *, message: str):
channel = self.client.get_channel(806649868314869760)
await ctx.message.delete()
embed = discord.Embed(title="Success", description=f"I've received your confession and sent it to the <#806649874379964487> channel!")
embed.set_footer(text="Confessions")
await ctx.send(embed=embed, delete_after=10)
channel = self.client.get_channel(806649874379964487)
embed = discord.Embed(title="Confession", description=f"{message}")
embed.set_footer(text="All confessions are anonymous.")
await channel.send(embed=embed)
def setup(client):
client.add_cog(Confess(client))
For the first question
If you want to use a "command" without actually using a command you could make an on_message event, check the id of the channel (like a confessions channel) and if it matches then do the thing
Example:
#commands.Cog.listener()
async def on_message(message):
if message.channel.id == some_channel_id_here:
channel = self.client.get_channel(806649868314869760)
await message.delete()
embed = discord.Embed(title="Success", description=f"I've received your confession and sent it to the <#806649874379964487> channel!")
embed.set_footer(text="Confessions")
await message.channel.send(embed=embed, delete_after=10)
channel = self.client.get_channel(806649874379964487)
embed = discord.Embed(title="Confession", description=f"{message}")
embed.set_footer(text="All confessions are anonymous.")
await channel.send(embed=embed)
For the second question
You can use get_channel again to get the log channel and post in there. (If you mean't on how to check if someone deleted a message/confession, use on_message_delete)
Example:
#commands.command()
async def confess(self, ctx: commands.Context, *, message: str):
channel = self.client.get_channel(806649868314869760)
log_channel = self.client.get_channel(log_channel_id)
await ctx.message.delete()
embed = discord.Embed(title="Success", description=f"I've received your confession and sent it to the <#806649874379964487> channel!")
embed.set_footer(text="Confessions")
await ctx.send(embed=embed, delete_after=10)
channel = self.client.get_channel(806649874379964487)
embed = discord.Embed(title="Confession", description=f"{message}")
embed.set_footer(text="All confessions are anonymous.")
await channel.send(embed=embed)
await logchannel.send("User confessed something!")
import discord
from discord.ext import commands
class AntiCog(commands.Cog):
def __init__(self, client):
self.client = client
#commands.Cog.listener()
async def on_message(self, message):
if message.author.id == 1234567891234567:
mention = f'<#!1234567891234567>'
if message.content == mention:
await message.channel.send("grow up")
user = message.author
print(str(user))
print(str(message.content))
muted_role = discord.utils.get(message.guild.roles, name="Muted")
await user.add_roles(muted_role)
else:
return
await self.client.process_commands(message)
def setup(client):
client.add_cog(AntiCog(client))
This's a working code for muting a person if they ping another person, however, I would like to make it a timed mute for 5 min. All of the resources I found were on_command timed mute, however, this's an auto one, how can I do so. thank you!
All you would have to do is add asyncio.sleep, and then remove the role, so:
import discord
from discord.ext import commands
import asyncio
class AntiCog(commands.Cog):
def __init__(self, client):
self.client = client
#commands.Cog.listener()
async def on_message(self, message):
if message.author.id == 1234567891234567:
mention = f'<#!1234567891234567>'
if message.content == mention:
await message.channel.send("grow up")
user = message.author
print(str(user))
print(str(message.content))
muted_role = discord.utils.get(message.guild.roles, name="Muted")
await user.add_roles(muted_role)
await asyncio.sleep(300) # you can change the time here
await user.remove_roles(muted_role)
else:
return
await self.client.process_commands(message)
def setup(client):
client.add_cog(AntiCog(client))
Be sure to import asyncio!
I want that the bot remove invites from channel if someone send one in all channels
Im using discord.py 1.6.0 and wrote it so but nothing happens.
rules = xxx
links = xxx
teamroom = xxx
# regex
DISCORD_INVITE = r'discord(?:\.com|app\.com|\.gg)[\/invite\/]?(?:[a-zA-Z0-9\-]{2,32})'
class Mod(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.links_allowed = (rules, teamroom, links)
self.url_regex = DISCORD_INVITE
#commands.Cog.listener()
async def on_message(self, message):
if search(self.url_regex, message.content):
await message.delete()
await message.channel.send("You cant send invites.", delete_after=10)
def setup(bot):
bot.add_cog(Mod(bot))
Might be late but try this:
import re
discordInviteFilter = re.compile("(...)?(?:https?://)?discord(?:(?:app)?\.com/invite|\.gg)/?[a-zA-Z0-9]+/?")
async def on_message(message):
if discordInviteFilter.match(message.content):
await message.delete()
await message.channel.send('no invites NOPPERS')
await client.process_commands(message)
You can check if the link posted starts with https://discord.gg and delete the message if the condition is met.
async def on_message(self, message):
if message.content.startswith("https://discord.gg"):
await message.delete()
await message.channel.send("You cannot send invites.")
You can check if the message has discord.gg in it I think having even if the message doesn't have HTTPS it still works with discord.gg if you add HTTPS:// then users will bypass by just using discord.gg only Hope you got your answer
I want to know in which text channels admin want to enable my bot functions. But in this case my code is not working.
The main idea was when admin typing !enable in text-chat, bot reacts to it and add text-chat id, guild id(ctx.channel.id) to the list, then bot responds in chat with bot has been enabled.
code where this command is not working:
channel = []
#bot.command()
async def enable(ctx):
global channel
print("Debug")
await ctx.send('Restriction bot has been enabled for this text channel.')
channel.append(ctx.channel.id)
full bot code:
import discord
from discord.ext import commands
bot = commands.Bot(command_prefix='!')
#bot.event
async def on_ready():
print(f'We have logged in as {bot.user.name}.')
channel = []
#bot.command()
async def enable(ctx):
global channel
print("Debug")
await ctx.send('Restriction bot has been enabled for this text channel.')
channel.append(ctx.channel.id)
#bot.event
async def on_message(ctx):
if ctx.author == bot.user:
return
#if ctx.channel.id != [for channnels in channel]:
# return
if ctx.attachments[0].height:
await ctx.author.send('Your media file is restricted!')
await ctx.delete()
The channel variable is initialized in your program so each time you will restart your bot, it will be emptied. One way you can solve your problem is by storing them in a file. The easiest way to do it would be to use the json library. You'll need to create a channels.json file.
The code :
from json import loads, dumps
def get_data():
with open('channels.json', 'r') as file:
return loads(file.read())
def set_data(chan):
with open('channels.json', 'w') as file:
file.write(dumps(chan, indent=2))
#bot.command()
async def enable(ctx):
channels = get_data()
channels.append(ctx.channel.id)
set_data(channels)
await ctx.send('Restriction bot has been enabled for this text channel.')
The channels.json file :
[]