Can't Make A Command Only For specific Channel - bots

Disocord.py Rewrite
Error: No
The command below is not working as expected
#bot.event
async def on_message(message):
x = (559253532759425044)
er = bot.get_channel(559253532759425044)
if not message.channel.id != x:
return
else:
if "p/" in message.content.lower():
await message.channel.send('Write this command in {}'.format(er.mention))
The p/ is the bots prefix, This code above tells (Write this command in {}'.format(er.mention)) when used p/ in the right channl the bot doesn't say anything but i use any command like p/help it doesn't works.actually The event should allow members use bot commands (#bot.command) only in the channel specified not any other channel but the thing is no commands work in the channel specified nor in any channel in the server. Any help would be great :) Edit: (Specified my question and made it a bit clear)

Edit:
From the comments, you may actually want something like
#bot.event
async def on_message(message):
cmdChannel = bot.get_channel(559253532759425044)
if message.content.lower().startswith('p/'):
if message.channel.id == cmdChannel.id:
#command invoked in command channel - execute it
await bot.process_commands(message)
else:
#command attempted in non command channel - redirect user
await message.channel.send('Write this command in {}'.format(cmdChannel.mention))

Related

how to make a command that only works for a certain role in a certain channel, otherwise it sends them a message to ask for a role

I'm currently coding a discord bot on the side and I'm stuck on a command that I'm trying to only make certain role to use it, when the wrong role type the command he got a reply to get the right role and I'm wondering how I can mix those 2 commands in 1
thanks for your help, im a noob since i just start coding
#commands.has_any_role('Sluts', 'Customer')
#commands.cooldown(1, 17992, commands.BucketType.user)
async def generate(ctx):
if ctx.message.channel.name == 'Channel_id':
emoji2 = bot.get_emoji(932456512180338759)
await ctx.reply('Initialized')
await ctx.message.add_reaction(emoji1)
await ctx.message.add_reaction(emoji2)
#await main.script()
await ctx.author.send('DM: Done! Enjoy!')
else
await ctx.send('You can not use this command here: checkout #channel_id')
and this line
#bot.command()
#commands.has_any_role('Leaker', 'Customer')
#commands.cooldown(1, 300, commands.BucketType.user)
async def generate(ctx):
emoji2 = bot.get_emoji(877247467459084298)
await ctx.message.add_reaction(emoji2)
await ctx.send('You can not use this command here,open a ticket to get the right role')
await ctx.author.send('DM: ')
I suggest not using commands.has_any, because you need to use on_command_error which is not the nicest thing.
You should check if. a certain role is in the author
if special_user_id in [role.id for role in ctx.author.roles]

How make a typo message?

I want to add a similar commands suggestion when the user make a typo.
Example: Right command: clear // User input: Cler // Bot response: Did you mean 'clear'?
I'm heard about difflib.get_close_matches and I'm be able to make this works in a .py script but not with discord.py
You wanna have a list of all your bot commands.
Then you test with the on command error event if the command wasnt found. If it wasnt test for similar commands (Levenshtein distance: http://en.wikipedia.org/wiki/Levenshtein_distance). Then send the user a message with the expected command if similar commands are found. Here is an example of how I would do it):
import discord
from discord.ext import commands
from difflib import SequenceMatcher
BOT_PREFIX = '!'
bot = discord.Client(intents=discord.Intents.all(), status=discord.Status.dnd)
bot = commands.Bot(command_prefix=BOT_PREFIX)
bot_commands = [] # all cmd names
#bot.event
async def on_ready():
global bot_commands
bot_commands = [cmd.name for cmd in bot.commands]
#bot.event
async def on_message(message):
if message.author.id == bot.user.id:
return
await bot.process_commands(message)
#bot.event
async def on_command_error(ctx, error): #catch error
if isinstance(error, commands.CommandNotFound):
for i in bot_commands: #Looking for close matches in commands
if float(SequenceMatcher(a=str(ctx.message.content).replace(BOT_PREFIX, '').lower(), b=i.lower()).ratio()) > float(0.67): #You can adjust the second float
await ctx.send(f'Did you mean {i}?') #Your message
break #Ignore similiar matches
#raise error (optional)
bot.run('token')

Discord.py How to make something only available after something else

I want to make Yes or No only accessible after you Type !Version, Can you tell me How to do this? I cant figure it out. My Code makes Yes and No accessible every time.
async def on_message(message):
if message.content.startswith('!Version'):
await message.channel.send('Sure?')
if message.content.startswith('Yes'):
await message.channel.send('This is the Version 1.0')
if message.content.startswith('No')
await message.channel.send('Okay') ```
Instead of using a message event, it's best if you use a command function decorator in order to allow a message to be sent after the command was run. Instead, by using wait_for, this will make your bot essentially "wait for" a required message to be sent. In your case, after running the command, the bot will wait for "yes" or "no" to determine what next it can send.
Here is an example implying a command and wait_for in your question.
#client.command()
async def version(ctx):
await ctx.send(f"Sure?")
msg = await client.wait_for('message',timeout=10,check=lambda message: message.author == ctx.author)
if msg.content.lower() == "yes":
await ctx.send("This is the Version 1.0")
if msg.content.lower() == "no":
await ctx.send("Okay")

discord.py on_message cancel when new command is executed

How can I cancel my on_message event when I execute another command? My code:
#client.event
async def on_message(message):
channel = message.author
def check(m):
return m.channel == message.channel and m.author != client.user
if message.content.startswith("!order"):
await channel.send("in game name")
in_game_name = await client.wait_for('message', check=check)
await channel.send("in game ID")
in_game_ID = await client.wait_for('message', check=check)
else:
await client.process_commands(message)
on_message should realistically only be reserved for events that require an on_message event (say if you are writing an auto-moderation feature).
For commands, you should be using the #client.command or #bot.command decorators before a function. Here is the usage for commands. Here are a few reasons on why you should use commands (taken directly from the ?tag commands on the discord.py discord):
Prevents spaghetti code
Better performance
Easy handling and processing of command arguments
Argument type converters
Easy sub commands
Command cooldowns
Built-in help function
Easy prefix management
Command checks, for controlling when they're to be invoked
Ability to add command modules via extensions/cogs
Still able to do everything you can do with Client
If you have any questions, feel free to comment on this answer!
You can put your on_message event inside a cog. That way, the on_message event (or any other event/command) will only be triggered when the cog is active.
class Foo(commands.Cog):
#commands.Cog.listener()
async def on_message(self, message):
# Do something
To register the cog (activate):
bot.add_cog(Foo(bot))
To remove the cog (deactivate):
bot.remove_cog('Foo')
Link to cog doc

How can I delete bot message in DM?

I'm making a bot with a command that send a file with all the previously executed commands in DM but I can't find a way to delete bot messages. Is there a way to do it or it's just impossible ?
I've tried to make a clear command for this specific case, I've tried this : https://www.reddit.com/r/Discord_Bots/comments/c1tf6t/dm_message_deletion_scriptbot/
but it didn't work for me.
The reddit code :
#client.command()
async def clear_dm(ctx):
user_dm = (client.get_user(610774599684194307)).dm_channe
messages_to_remove = 1000
async for message in user_dm.history(limit=messages_to_remove):
if message.author.id == client.user.id:
await message.delete()
await asyncio.sleep(0.5)
The bot messages should be deleted but when I run the command I get an exception AttributeError: 'ClientUser' object has no attribute 'dm_channel' the others methodes that I've tried raised similar errors (but I can't show you the code since I've delted it :c)
Users have a User.history attribute that you can use directly.
#client.command()
async def clear_dm(ctx):
messages_to_remove = 1000
async for message in client.get_user(610774599684194307).history(limit=messages_to_remove):
if message.author.id == client.user.id:
await message.delete()
await asyncio.sleep(0.5)

Resources