Disord.py system_channel.send - discord.py

How can I send a message to the system message channel?
Error:
***AttributeError: module 'discord.guild' has no attribute 'system_channel'
I don't want to send message with channel ID
#Bot.event
async def on_message_edit(before, after):
.
.
.
await discord.guild.system_channel.send(embed=embed)

discord.guild is not the way you should be calling the guild, as this does not specify what guild you are trying to access. Instead, you can use either before.guild or after.guild, as these are message objects. Do view the revised code below.
#Bot.event
async def on_message_edit(before, after):
.
.
.
await before.guild.system_channel.send(embed=embed)

Related

Discord.py commands.BotMissingPermissions

I want to send an error message when my bot's role is insufficient, but I can't. I tried all the "MissingRole" commands but none of them work...
#Bot.event
async def on_command_error(ctx, error):
if isinstance(error, commands.BotMissingPermissions):
.
.
.
await ctx.channel.send(embed=embed)
if isinstance(error, commands.BotMissingPermissions):
await ctx.message.add_reaction("❌")
aEmbed = discord.Embed(
title=f"**__Error__**",
description="Whatever you want the bot to say to the user",
colour=discord.Colour.red()
)
await ctx.send(embed=aEmbed)
return
This is how I made the "BotMissingPermissions". The code is pretty basic, it just puts a "X" reaction to the message that made the error and then sends an embed saying what went wrong then returns so that it can continue functioning without any problems
Also the response you told the bot to do (await ctx.channel.send("Something something")) could be changed to await ctx.send("Something").

I want to make a command that deletes a channel discord.py

Here is what I got so far
It is saying that "await" is outside of async function and I am just confused on how to fix this. I copied part of the code from a giveaway command because that is my only source of Q&A code I have
#commands.has_permissions(administrator = True)
async def cdelete(ctx):
embed=discord.Embed(title = Which channel would you like to delete?)
await ctx.send(embed=embed)
answer = []
def check(m):
return m.author == cx.author and m.channel == ctx.channel
try:
await client.wait_for('message', timeout=15, check=check)
except asyncio.TimeoutError:
await ctx.send("Timeout. Please run the command again")
else:
answer.append(message.content)
try:
c_id= int(answer[0][2:-1])
await ctx.channel.delete
await ctx.send("Channel Deleted")
except:
await ctx.send("Thats not a valid channel!")```
If you just want a command you can make it a lot easier if you just execute a command with the channel name. You can have a look at the following:
#client.command()
#commands.has_permissions(administrator=True)
async def cdelete(ctx, channel_name):
"""Deletes a channel by name or ID."""
channel_id = int(''.join(i for i in channel_name if i.isdigit())) # Get channel ID
existing_channel = client.get_channel(channel_id) # Get channel ID with defined method
if existing_channel: # If channel with the name/ID exists
await existing_channel.delete()
else: # If the channel does not exist
await ctx.send(f'**No channel named `{channel_name}` was found.**')
We have a method to catch the channel ID and also pass that in as a valid argument. If the ID or channel name then exists we delete the channel.
You can here either mention the channel or pass in the ID.
Usage would be: cdelete #channel/ID.
If you want to avoid a long console output if you input no channel/ID/name you can build in an error handler:
#cdelete.error
async def cdelete_error(ctx, error):
if isinstance(error, commands.MissingRequiredArgument):
await ctx.send("You need to name a channel.")
The problem you have here is with the check() function. According to the doc you only can use await inside of an async function. To solve the problem change def check(m): into async def check(m):

Print error code doesn't work (PyCharm, Python 3.8)

I found this code in Stackoverflow which prints any error messages. But it doesn't print the error. Just to say if it is relevant, PyCharm said that Bot doesn't have attribute AppInfo.
Code:
#bot.event
async def on_error(event, *args, **kwargs):
embed = discord.Embed(title=':x: Event Error', colour=0xe74c3c)
embed.add_field(name='Event', value=event)
embed.description = '```py\n%s\n```' % traceback.format_exc()
embed.timestamp = datetime.datetime.utcnow()
await bot.AppInfo.owner.send(embed=embed)
The bot class does not have an AppInfo attribute by default. To create it, include on your on_ready() event that attribute:
#bot.event
async def on_ready():
if not hasattr(bot, 'AppInfo'):
bot.AppInfo = await bot.application_info()
Doing this, it will be available when it is used in your on_error event.
I found another Stackoverflow question (Discord.py-Rewrite Sending an Error message when there is an unknown command or other error) which has the answer. As it seems, there was no need to complicate the command as the case with my code.

How can i specify a discord text channel in my code?

Im trying to specify a channel to send a message in. The code below doesn't work.
async def on_message(ctx):
if channel == 793261911411654669 and ctx.author.id == 418643244284287024:
Is there a proper way to define the channel in this part?
You have to use ctx.channel.id to get the ID of the channel that the message was sent in.
So, your event would look like this:
#client.event
async def on_message(ctx):
if ctx.channel.id == 793261911411654669 and ctx.author.id == 418643244284287024:
await client.process_commands(ctx)
This event will run the defined commands only if the condition is True.

How do I set a in Discord.py a command without Prefix only with certain word to which bot replies and also bot replies to thaat only in dm with bot

Discord.py, how to set a command, without Prefix, only with certain word to which bot replies, and also bot replies to that command while Dm with the bot.
Remember about the errors for example, bot object has no attribute on_message, etc, errors.
You can write a function to pass to command_prefix that will check for one prefix in servers and another (or none) in private messages:
from discord.ext import commands
def command_prefix(bot, message):
if message.guild is None:
return ''
else:
return '$'
bot = commands.Bot(command_prefix=command_prefix)
#bot.command(name='hello')
async def hello(ctx):
await ctx.send("Hello")
bot.run("TOKEN")
If you are using this in a cog.
#commands.Cog.listener()
async def on_message(self,message):
await message.send("Hello!")
or in the main.py
#bot.event
async def on_message(message):
await message.send("Hello!")
Please reply back if you have an error with this.
message.guild will return None if the message is in dms.

Resources