I'm trying to make my Discord bot require a rank to execute the Say command but I cannot find a way to make it work. I would like to ask you guys if you could help me setup a role required to execute the command.
import asyncio
import discord
from discord.ext.commands import Bot
bot = Bot('>') # the <#4> is essential so people cannot share it via DMs.
#bot.command(pass_context = True)
async def Say(ctx, *args):
mesg = ' '.join(args)
await bot.delete_message(ctx.message)
return await bot.say(mesg)
bot.run('Token')
Discord.py provides a simple decorator commands.has_role that is used for verifying roles by name. The has_role utilise the check function and both functions are part of the undocumented commands extension.
from discord.ext import commands
bot = commands.Bot('>')
#bot.command(pass_context = True)
#commands.has_role('admin')
async def Say(ctx, *args):
mesg = ' '.join(args)
await bot.delete_message(ctx.message)
return await bot.say(mesg)
bot.run('Token')
Related
Im trying to make a bot that can create roles but the bot is not recognizing my command.
I have tried using OpenAI but its knowledge is limited. I just need a working way to receive commands and create the roles. This is one of the biggest
import sys
command_prefix = "!"
async def create_role(guild, role_name):
# Create the role
role = await guild.create_role(name=role_name)
return role
#client.event
async def on_message(message):
if message.content.startswith(f"{command_prefix}gr"):
# Split the message into a list of arguments
args = message.content.split(" ")
# The name of the role is the second argument
role_name = args[1]
print(f"Creating role {role_name}") # Debug statement
# Create the role
role = await create_role(message.guild, role_name)
# Give the role to the user who sent the message
await assign_role(message.author, role)
await message.channel.send(
f'Created role {role_name} and gave it to {message.author}')
client.run(
'TOKEN')
You should use commands
from discord.ext import commands
bot = commands.Bot(command_prefix = '!') # prefix
#bot.command(name = "gr") # gr would be an example command, !gr <something>
async def do_on_command_function(ctx, msg):
# msg will store the message after the command
await ctx.send(arg)
import discord
import os
flist = []
client = discord.Client()
#client.event
async def on_message(message):
if message.author == client.user:
return
if message.content.startswith('?ID'):
for i in ID.split()[1].split('#'):
flist.append(i)
print(flist)
print(discord.utils.get(client.get_all_members(), name = flist[0], discriminator = flist[1]).id)
client.run(TOKEN)
I want to have a bot get the id of a use just by entering the the name and the hashtag number but it returns an error that the final line has nonetype. How could I fix this so it shows the id as a string?
First of all let me recommend you to use the discord.ext.commands extension for discord.py, it will greatly help you to make commands.
You just need to get a discord.Member or discord.User in this case. Since these classes have built in converters, you can use them as typehints to create an instance:
from discord.ext import commands
bot = commands.Bot(command_prefix='?', ...)
#bot.command()
async def showid(ctx, member: discord.Member): # a Union could be used for extra 'coverage'
await ctx.send(f'ID: {member.id}')
Using a typehint in this case allows the command user to invoke the command like:
?showid <id>, ?showid <mention>, ?showid <name#tag>, ?showid <nickname> etc with the same result.
If you don't want to use discord.ext.commands, you can use discord.utils.get as well:
client = discord.Client(...)
#client.event
async def on_message(message):
...
if message.content.startswith('?ID'):
member = discord.utils.get(message.guild.members, name=message.content.split()[1])
await message.channel.send(member.id)
...
I am trying to create a python script that would mute the users of a specific voice channel when executed. Till now I am able to mute everyone by typing the command in the discord text channel, but I would like to mute everyone when another python script tells the bot to. Below is my attempt to do that.
bot.py is the python discord bot:
import discord
from discord.ext import commands
from time import sleep
client = commands.Bot(command_prefix="./")
#client.event
async def on_ready():
print("Bot is online. ")
#client.command()
async def play_music_test():
channel = await client.get_channel(voice_channel_number)
voice = await channel.connect()
await voice.play(
discord.FFmpegPCMAudio(executable="C:/Users/USER/ffmpeg/bin/ffmpeg.exe",
source="C:/Users/USER/Desktop/song.mp3"))
client.run(TOKEN)
abc.py is the other python script trying to call a function:
from bot import play_music_test
import asyncio
print("")
asyncio.run(play_music_test())
I ran the bot.py first and then tried to execute the abc.py next, bot came online but when executing abc.py, it didn't print or do anything at all. I just started to learn discord.py so if this is a silly question, forgive me.
Instead of running the python file you can import it, or making it a cog
heres an example:
importing: bot.py
import discord
from discord.ext import commands
from time import sleep
from abc import *
client = commands.Bot(command_prefix="./")
#client.event
async def on_ready():
print("Bot is online. ")
#client.command(name = "play_music", aliases = ["you can asign aliases like this", "multiple ones too"])
async def play_music_test(ctx, channel): # If the python file doesn't know what channel is, it can be asigned when calling the function in discord, think of it like sys.argv or argparse
if channel == None: channel = ctx.channel # This sets the current channel you are in if none was provided when executing it in discord
# channel = await client.get_channel(channel) now you don't need this line
voice = await channel.connect()
await voice.play(
discord.FFmpegPCMAudio(executable="C:/Users/USER/ffmpeg/bin/ffmpeg.exe",
source="C:/Users/USER/Desktop/song.mp3"))
client.run(TOKEN)
importing: abc.py
remove asyncio.run(play_music_test())
use it in discord instead! ex. play_music_test #general
Making it a cog: bot.py
import discord
from discord.ext import commands
from time import sleep
import os
client = commands.Bot(command_prefix="./")
#client.event
async def on_ready():
print("Bot is online. ")
for filename in os.listdir("./"):
if filename == "bot.py": continue
else: client.load_extension(f"cogs.{filename[:-3]}")
client.run(TOKEN)
Making it a cog: abc.py
from bot import play_music_test
import asyncio
class Mycog(commands.Cog):
def __init__(self, client):
self.client = client
#client.command(name = "play_music", aliases = ["you can asign aliases like this",
"multiple ones too"])
async def play_music_test(ctx, channel): # If the python file doesn't know what
channel is, it can be asigned when calling the function in discord, think of it like sys.argv or argparse
if channel == None: channel = ctx.channel # This sets the current channel you are in if none was provided when executing it in discord
# channel = await client.get_channel(channel) now you don't need this line
voice = await channel.connect()
await voice.play(
discord.FFmpegPCMAudio(executable="C:/Users/USER/ffmpeg/bin/ffmpeg.exe",
source="C:/Users/USER/Desktop/song.mp3"))
def setup(client):
client.add_cog(Mycog(client))
This anwser is not the best but hope this helps!
i'm not sure, if i really understand, what you try to do, but to open a script from another script, i use subprocess.Popen()
but i think, in your case it fits more, to change the way you try to solve your problem. maybe you should take a look into the on_message event and use message.content
?
You can importing your client variable (from bot import play_music_test, client) and then client.loop.create_task(play_music_test())
(Although I do not understand why you would do such a thing)
Im trying to make my custom bot sends a custom message using python
Me: ~repeat Hi
My Message deleted
custom-Bot: Hi
whenever I try using this I get error problems with this code specifically "client"
await client.delete_message(ctx.message)
return await client.say(mesg)
from discord.ext import commands
client = commands.Bot(command_prefix = '~') #sets prefix
#client.command(pass_context = True)
async def repeat(ctx, *args):
mesg = ' '.join(args)
await client.delete_message(ctx.message)
return await client.say(mesg)
client.run('Token')
client does not have an attribute called delete_message, to delete the author's message use ctx.message.delete. To send a message in the rewrite branch of discord.py, you use await ctx.send()
#client.command()
async def repeat(ctx, *args):
await ctx.message.delete()
await ctx.send(' '.join(args))
My friend does this using a node discord bot:
I want to have a command in discord server using:
discord.py bot
!eval await bot.change_presence(game=discord.Game(name='test'))
from discord.ext import commands
import inspect
bot = commands.Bot(command_prefix='!')
#bot.command(name='eval', pass_context=True)
async def eval_(ctx, *, command):
res = eval(command)
if inspect.isawaitable(res):
await bot.say(await res)
else:
await bot.say(res)
Here's a basic implementation. The eval function is doesn't seem to like await inside (I got syntax errors when I tried), so instead we can resolve a generator which we then await outside of the eval. You would call this like
!eval bot.change_presence(game=discord.Game(name='test'))
Keep in mind that eval is very dangerous. If you expose this functionality to untrusted people, they can do whatever they want on your machine. You should at least read eval really is dangerous to understand the risks before you proceed.
I edited the code and made it owner only.
#client.command(name='eval', pass_context=True)
#commands.is_owner()
async def eval_(ctx, *, command):
res = eval(command)
if inspect.isawaitable(res):
await ctx.send(await res)
else:
await ctx.send(res)