I made a Discord bot that tells you a Minecraft's server status!
It works fine on the console with the print function, but it doesn’t work as a command! The bot just doesn’t respond. Also I tested it without the mcstatus library and the command worked. (Without what it's supposed to do, of course.)
This is my code:
import discord
from discord.ext import commands
from mcstatus import JavaServer
client = commands.Bot(command_prefix = "!")
client.remove_command("help")
server = JavaServer.lookup("mc.elitesmp.co:25588")
status = server.status()
#client.event
async def on_ready():
print('Logged in as: "' + str(client.user) + '"')
print(f"Elite SMP has {status.players.online} players online!")
#client.command() # <--- This is the command that doesn't work!
async def info(ctx):
await ctx.send("test")
client.run("token")
Any ideas?
I think it’s because you need to enable intents in your Discord bot, and also declare them in the code by adding:
intents = discord.Intents.default()
And also putting , intents=intents in the space where you declare your bot's prefix.
This is also an example of a bot I just made, to help with some command also.
import discord
from discord.ext import commands
from mcstatus import JavaServer
from mcstatus import BedrockServer
intents = discord.Intents.default()
bot = commands.Bot(command_prefix='?', intents=intents)
TOKEN = "removed for obvious reasons"
#bot.event
async def on_ready():
print('ready')
await bot.change_presence(activity=discord.Activity(type=discord.ActivityType.watching,name="Minecraft Servers"))
#bot.event
async def on_command_error(ctx, error):
if isinstance(error,commands.CommandInvokeError):
await ctx.reply("No such server was found")
#bot.command()
async def java(ctx, message):
server = JavaServer.lookup(message)
status = server.status()
embed = discord.Embed(title=f"{message}", description=f"info on {message}")
embed.add_field(name="Players Online :green_circle:", value=f"The server has {status.players.online} players online", inline=False)
embed.add_field(name="Server Response :warning:", value=f"The server replied in {status.latency}ms", inline=False)
await ctx.reply(embed=embed)
#bot.command()
async def bedrock(ctx, message):
server = BedrockServer.lookup("message")
status = server.status()
embed = discord.Embed(title=f"{message}", description=f"info on {message}")
embed.add_field(name="Players Online :green_circle:", value=f"The server has {status.players.online} players online", inline=False)
embed.add_field(name="Server Response :warning:", value=f"The server replied in {status.latency}ms", inline=False)
await ctx.reply(embed=embed)
bot.run(TOKEN)
The following code works fine for me, as you can see here.
The following image shows how the commands work: command image
I think the command isn't working, because you haven't declared what intents you need in code. Discord bots now need to declare what events they need to access, such as reading messages. You can read about intents in the discord.py documentation here.
I also moved the "players online" part to a variable, and printed that instead, and that got your command to work.
intents = discord.Intents.default()
client = commands.Bot(command_prefix = "!", intents = intents)
client.remove_command("help")
player_text = f"Elite SMP has {status.players.online} players online!"
#client.event
async def on_ready():
print(player_text)
#client.command()
async def test(ctx):
await ctx.send("test")
Screenshots of it working in code here and Discord here.
Related
I am using this code but it crashes when i launch it, i want the bot to react with the custom emoji from my server (:okay:) to every image sent in a specific channel. Anyone knows why?
import discord
from discord.ext import commands
from discord.ext.commands import Bot
import asyncio
bot = commands.Bot(command_prefix = '//')
#bot.event
async def on_ready():
print ("I have awoken")
async def react(message):
custom_emojis = [
"<:okay:942697477507801098>"
]
guild_emoji_names = [str(guild_emoji) for guild_emoji in message.guild.emojis]
for emoji in custom_emojis:
#print(emoji, guild_emoji_names)
#print(emoji in guild_emoji_names)
if emoji in guild_emoji_names:
await message.add_reaction(emoji)
#bot.event
async def on_message(message):
if message.channel.id == 929345014205653014: and \
if message.attachment:
await react(message)
You need to have the message_content intent enabled to receive message attachments.
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix = '//', intents=intents)
There is no attachment attribute in the Message class it's, attachments instead. Also, this is how you use and operator in an if statement:
if message.channel.id == 929345014205653014 and message.attachments:
i have only started to look around and figure how things work with discord.py bot. Tried making a bot that welcomes people in a certain channel. But no matter what I do, it doesn't seem to be working. The code executes and the on_ready fires. But its not welcoming the user like its supposed to. Can someone help?
import discord
from discord.ext import commands
from discord.ext.commands import Bot
from discord import Color
import asyncio
import datetime
intents = discord.Intents.default()
intents.members = True
client = discord.Client(intents=intents)
client=commands.Bot(command_prefix="-")
client.remove_command("help")
#client.event
async def on_ready():
print("Created by Goodboi")
print(client.user.name)
print("-----")
#client.event
async def on_member_join(member):
embed = discord.Embed(colour=0xe8744f,
description=f"Welcome to the discord server",)
embed.set_author(name=f"{member.mention}",icon_url=f"{member.avatar_url}")
embed.set_footer(text=f"{member.guild}",icon_url=f"{member.guild.icon_url}")
embed.timestamp = datetime.datetime.utcnow
channel = client.get_channel(id=) #usedid
await channel.send(embed=embed)
client.run('token') #usedtoken
Hi you have to get channel like this
#client.event
async def on_member_join(member):
embed = discord.Embed(colour=0xe8744f,
description=f"Welcome to the discord server",)
embed.set_author(name=f"{member.mention}",icon_url=f"{member.avatar_url}")
embed.set_footer(text=f"{member.guild}",icon_url=f"{member.guild.icon_url}")
embed.timestamp = datetime.datetime.utcnow()
channel = member.guild.get_channel(channel_id) #usedid
await channel.send(embed=embed)
The only thing you did wrong is passing no brackets to your datetime.datetime.utcnow "function" which gives out the following error:
TypeError: Expected datetime.datetime or Embed.Empty received builtin_function_or_method instead
If you put brackets behind the definition of your timestamp it should work:
#client.event
async def on_member_join(member):
embed = discord.Embed(colour=0xe8744f,
description=f"Welcome to the discord server", )
embed.set_author(name=f"{member.mention}", icon_url=f"{member.avatar_url}")
embed.set_footer(text=f"{member.guild}", icon_url=f"{member.guild.icon_url}")
embed.timestamp = datetime.datetime.utcnow() # Added brackets
channel = client.get_channel(ChannelID) # No "id=" needed
await channel.send(embed=embed)
You can also have a look at the docs: https://docs.python.org/3/library/datetime.html#datetime.datetime
This should work for you, though, can be improved in many ways, but if you asked for this, then here is it.
#client.event
async def on_member_join(member) :
channel = client.get_channel(CHANNEL ID) # First we need to get the channel we want to post our welcome message.
embed = discord.Embed(
colour=0xe8744f ,
description='Welcome to the discord server' ,
timestamp=datetime.utcnow()
)
embed.set_author(name=f'{member.mention}' , icon_url=f'{member.avatar_url}')
embed.set_footer(text=f'{member.guild}' , icon_url=f'{member.guild.icon_url}')
await channel.send(embed=embed) #Send the embed
beforehand: I tried already a lot of potential fixes which are available on stack overflow. Sadly none of them worked.
Here is the Code:
import discord
import asyncio
import datetime
from discord.ext import commands
bot = commands.Bot(command_prefix='!', case_insensitive=True)
#bot.event
async def on_ready():
print('bot is online')
return await bot.change_presence(activity=discord.Activity(type=2, name='bla'))
#bot.event
async def on_member_join(member):
embed = discord.Embed(colour=0x95efcc, description=f"Welcome! You are the {len(list(member.guild.members))} Member!"),
embed.set_thumbnail(url=f"{member.avatar_url}")
embed.set_author(name=f"{member.name}", url=f"{member.avatar_url}", icon_url=f"{member.avatar_url}")
embed.set_footer(text=f"{member.guild}", icon_url=f"{member.guild.icon_url}")
embed.timestemp = datetime.datetime.utcnow()
channel = bot.get_channel(id=012391238123)
await channel.send(embed=embed)
bot.run('Token')
The bot logs in but it won't execute on_member_join. Has anybody an idea what might be wrong? on_message works fine.
intents = discord.Intents.all()
client = discord.Client(intents=intents)
didn't help and in discord developer it's also checked (Server Members Intent).
The bot also has administrator privileges
Greetings Eduard
Solution in short:
imports
intents = discord.Intents(messages=True, guilds=True, members=True)
bot = commands.Bot(command_prefix='!', intents=intents, case_insensitive=True)
#bot.event
async def on_member_join(member):
embed = discord.Embed(colour=0x95efcc, description=f"Welcome to my discord server! You are the {len(list(member.guild.members))} member!")
channel = bot.get_channel(id=12931203123)
await channel.send(embed=embed)
bot.run('token')
Ah, so that's it.
Since you are using commands.Bot, the bot.get_channel is no longer a function (since it is no longer discord.Client). Try using member.guild.get_channel instead.
Documentation
I just started with discord.py and found out that on_member_join and on_member_remove don't work for me. Keep in mind that on_ready function works perfectly fine.
import discord
from discord.ext import commands
bot = commands.Bot(command_prefix = "!")
#bot.event
async def on_ready():
print("""Bot ready""")
#bot.event
async def on_member_join(member):
channel = bot.get_channel(767370104814960640)
await channel.send(f"{member} has joined the server")
#bot.event
async def on_member_remove(member):
channel = bot.get_channel(766620766237753345)
await channel.send(f"{member} has left the server")
bot.run("my token")
So did I make a mistake with my code or something else went wrong?
discord.py 1.5.0 now supports discord API's Privileged Gateway Intents. In order to be able to exploit server data, you need to:
Enable Presence Intent and Server Members Intent in your discord application:
https://i.stack.imgur.com/h6IE4.png
Use discord.Intents at the beginning of your code:
intents = discord.Intents.all()
#If you use commands.Bot()
bot = commands.Bot(command_prefix="!", intents=intents)
#If you use discord.Client()
client = discord.Client(intents=intents)
I am looking for a way to allow a user to move him or her self and another user to a different voice channel. I already got the command to work for the author of the message, but I am having trouble finding out a way to move another user in the same message. The idea is that the user would be able to type "n!negotiate [Other User]" and it would move the author and the other user to the Negotiation channel.
I would love some help with how I might be able to do this. The code is provided below excluding the tokens and ids.
Code:
import discord
from discord.ext.commands import Bot
from discord.ext import commands
import asyncio
import time
Client = discord.Client() #Initialise Client
client = commands.Bot(command_prefix = "n!") #Initialise client bot and prefix
#client.event
async def on_ready():
print("Logged in as:")
print(client.user.name)
print("ID:")
print(client.user.id)
print("Ready to use!")
#client.event
async def on_message(check): #Bot verification command.
if check.author == client.user:
return
elif check.content.startswith("n!check"):
await client.send_message(check.channel, "Nations Bot is online and well!")
async def on_message(negotiation): #Negotiate command. Allows users to move themselves and other users to the Negotiation voice channel.
if negotiation.author == client.user:
return
elif negotiation.content.startswith("n!negotiate"):
author = negotiation.author
voice_channel = client.get_channel('CHANNELID')
await client.move_member(author, voice_channel)
client.run("TOKEN")
You should use discord.ext.commands. You're importing it, but not actually using any of the features.
from discord.ext import commands
import discord
bot = commands.Bot(command_prefix = "n!") #Initialize bot with prefix
#bot.command(pass_context=True)
async def check(ctx):
await bot.say("Nations Bot is online and well!")
#bot.command(pass_context=True)
async def negotiate(ctx, member: discord.Member):
voice_channel = bot.get_channel('channel_id')
author = ctx.message.author
await bot.move_member(author, voice_channel)
await bot.move_member(member, voice_channel)
bot.run('TOKEN')
Here we use a converter to accept a Member as input. Then we resolve the author of the message from the invocation context and move both Members to the voice channel.