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!")
Related
whos have code on that maybe?
async def nuke(ctx, channel: discord.TextChannel = None):
if channel == None:
await ctx.send("You did not mention a channel!")
return
nuke_channel = discord.utils.get(ctx.guild.channels, name=channel.name)
if nuke_channel is not None:
new_channel = await nuke_channel.clone(reason="Has been Nuked!")
await nuke_channel.delete()
await new_channel.send("THIS CHANNEL HAS BEEN NUKED!")
await ctx.send("Nuked the Channel sucessfully!")
else:
await ctx.send(f"No channel named {channel.name} was found!")```
You will have to use the discord.TextChannel.purge() function.
channel # discord.TextChannel object (most likely the argument)
await channel.purge(limit=100) # Purge a certain amount of messages. You can choose
See the purge() function docs
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 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
I have a discord bot.
What I want it to do is when the bot detects a user is streaming, print the URL of their stream into chat.
I'm having a problem trying to find out how to get the user's twitch channel url...
this is what I have
#client.event
async def on_member_update(before, after):
aname = after.display_name
aactivity = after.activity.type
mactivity = str(after.activities)
role = after.guild.get_role(736271867836498031)
channel = client.get_channel(736269005651836985)
memberinfo = after.activities.streaming.url
print(memberinfo)
if "Streaming name" in mactivity:
await after.add_roles(role)
await channel.send('{} has started streaming!'.format(after.display_name))
print(aname + " is streaming!")
else:
await after.remove_roles(role)
streamchannel = discord.Profile
await channel.send('{} is not streaming!'.format(after.display_name))
print(aname + " is not streaming.")
print('member updated status')
Is there something I'm missing? I don't know how at all to either find the URL of the streamer, or get it from their connect accounts.
Member objects have a Activity attribute. You can check if before.activity or after.activity is an instance of the Streaming class.
If so, the user either stopped or started streaming and we can send a message in channel:
from discord import Streaming
from discord.utils import get
#client.event
async def on_member_update(before, after):
if not before.activity.type == after.activity.type:
return
role = get(after.guild.roles, id=736271867836498031)
channel = get(after.guild.channels, id=736269005651836985)
if isinstance(after.activity, Streaming):
await after.add_roles(role)
await channel.send(f"{before.mention} is streaming on {activity.platform}: {activity.name}.\nJoin here: {activity.url}")
elif isinstance(before.activity, Streaming):
await after.remove_roles(role)
await channel.send(f'{after.mention} is no longer streaming!')
else:
return
Reference: discord.py documentation
Hi I'm trying to return a message when the user uses the command !add in channels other than the channels in the check. This is how I'm checking for the channels the command should be used in:
#commands.check(lambda ctx: ctx.channel.id in [555913791615926302, 567769278351409174])
Here is how I'm trying to do this and having issues with:
if not ctx.channel.id:
await ctx.send("You can only use this command in botroom.")
return
and this is how I'd be using in the code:
#commands.command(pass_context=True)
#commands.check(lambda ctx: ctx.channel.id in [555913791615926302, 567769278351409174])
async def add(self, ctx, *, rolename):
author = ctx.message.author
role_dict = {
"members":557212810468392970,
"ps4":568761643916328960,
"lol":559792606364565505,
"pc":568725587322208287,
"nintendo switch":558649595102625795,
"ze/zir":569170061592494083}
if not ctx.channel.id:
await ctx.send("You can only use this command in botroom.")
return
role_id = role_dict.get(rolename.lower())
if not role_id:
message = 'I cannot find the role **{}**.'
embed = discord.Embed(description=message.format(rolename))
await ctx.send(embed=embed)
return
role = discord.utils.get(ctx.message.guild.roles, id = role_id)
if role in author.roles:
message = 'It looks like you already have the role **{}**.'
embed = discord.Embed(description=message.format(role.name))
await ctx.send(embed=embed)
else:
await author.add_roles(role)
message = '{} added the role **{}**.'.format(author.display_name, role.name)
embed = discord.Embed(description=message.format(author.display_name, role.name), colour=0x56e011)
await ctx.send(embed=embed)
If the check fails, your coroutine will never be called. Instead, an error is raised, that you can then handle by defining an error handler for your command.
While you're at it, you can make that check look much nicer at the same time
def in_channel_with_id(*ids):
def predicate(ctx):
return ctx.channel.id in ids
return commands.check(predicate)
#commands.command()
#in_channel_with_id(555913791615926302, 567769278351409174)
async def add(self, ctx, *, rolename):
...
#add.error
async def add_error(ctx, error):
if isinstance(error, commands.CheckFailure):
await ctx.send("You can only use this command in botroom.")
else:
raise error